Sema: Shave another 8 bytes off of Constraint

This commit is contained in:
Slava Pestov
2025-03-10 14:40:26 -04:00
parent ada6f77655
commit 83118a73ed
4 changed files with 73 additions and 84 deletions

View File

@@ -336,6 +336,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
private llvm::TrailingObjects<Constraint,
TypeVariableType *,
ConstraintFix *,
DeclContext *,
ContextualTypeInfo,
OverloadChoice> {
friend TrailingObjects;
@@ -354,6 +355,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// Whether we have a tail-allocated fix.
unsigned HasFix : 1;
/// Whether we have a tail-allocated DeclContext.
unsigned HasDeclContext : 1;
/// Whether the \c Restriction field is valid.
unsigned HasRestriction : 1;
@@ -392,7 +396,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// node is unused.
unsigned isDiscarded : 1;
// 23 bits remaining
// 22 bits remaining
union {
struct {
@@ -425,20 +429,14 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// Used for ValueWitness constraints.
ValueDecl *Ref;
} Member;
/// The DC in which the use appears.
DeclContext *UseDC;
} Member;
/// The set of constraints for a disjunction.
ArrayRef<Constraint *> Nested;
struct {
/// The first type
/// The first type.
Type First;
/// The DC in which the use appears.
DeclContext *UseDC;
} Overload;
struct {
@@ -454,8 +452,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// The type being called, primarily a function type, but could
/// be a metatype, a tuple or a nominal type.
Type Callee;
/// The declaration context in which the application appears.
DeclContext *UseDC;
} Apply;
};
@@ -531,6 +527,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
return HasFix ? 1 : 0;
}
size_t numTrailingObjects(OverloadToken<DeclContext *>) const {
return HasDeclContext ? 1 : 0;
}
size_t numTrailingObjects(OverloadToken<ContextualTypeInfo>) const {
return Kind == ConstraintKind::SyntacticElement ? 1 : 0;
}
@@ -876,20 +876,6 @@ public:
return *getTrailingObjects<OverloadChoice>();
}
/// Retrieve the DC in which the overload was used.
DeclContext *getOverloadUseDC() const {
assert(Kind == ConstraintKind::BindOverload);
return Overload.UseDC;
}
/// Retrieve the DC in which the member was used.
DeclContext *getMemberUseDC() const {
assert(Kind == ConstraintKind::ValueMember ||
Kind == ConstraintKind::UnresolvedValueMember ||
Kind == ConstraintKind::ValueWitness);
return Member.UseDC;
}
FunctionType *getAppliedFunctionType() const {
assert(Kind == ConstraintKind::ApplicableFunction);
return Apply.AppliedFn;
@@ -900,11 +886,6 @@ public:
return Apply.Callee;
}
DeclContext *getApplicationDC() const {
assert(Kind == ConstraintKind::ApplicableFunction);
return Apply.UseDC;
}
ASTNode getSyntacticElement() const {
assert(Kind == ConstraintKind::SyntacticElement);
return SyntacticElement.Element;
@@ -920,6 +901,12 @@ public:
return isDiscarded;
}
/// Retrieve the DC in which the overload was used.
DeclContext *getDeclContext() const {
assert(HasDeclContext);
return *getTrailingObjects<DeclContext *>();
}
/// For an applicable function constraint, retrieve the trailing closure
/// matching rule.
std::optional<TrailingClosureMatching> getTrailingClosureMatching() const;

View File

@@ -13089,7 +13089,7 @@ retry_after_fail:
// Determine the type that this choice will have.
Type choiceType = getEffectiveOverloadType(
constraint->getLocator(), choice, /*allowMembers=*/true,
constraint->getOverloadUseDC());
constraint->getDeclContext());
if (!choiceType) {
hasUnhandledConstraints = true;
return true;
@@ -16335,7 +16335,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
return simplifyApplicableFnConstraint(
constraint.getAppliedFunctionType(), constraint.getCalleeType(),
constraint.getTrailingClosureMatching(),
constraint.getApplicationDC(), /*flags=*/std::nullopt,
constraint.getDeclContext(), /*flags=*/std::nullopt,
constraint.getLocator());
case ConstraintKind::DynamicCallableApplicableFunction:
@@ -16382,7 +16382,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
resolveOverload(constraint.getLocator(), constraint.getFirstType(),
constraint.getOverloadChoice(),
constraint.getOverloadUseDC());
constraint.getDeclContext());
return SolutionKind::Solved;
case ConstraintKind::SubclassOf:
@@ -16429,7 +16429,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
case ConstraintKind::UnresolvedValueMember:
return simplifyMemberConstraint(
constraint.getKind(), constraint.getFirstType(), constraint.getMember(),
constraint.getSecondType(), constraint.getMemberUseDC(),
constraint.getSecondType(), constraint.getDeclContext(),
constraint.getFunctionRefInfo(),
/*outerAlternatives=*/{},
/*flags*/ std::nullopt, constraint.getLocator());
@@ -16438,7 +16438,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
return simplifyValueWitnessConstraint(
constraint.getKind(), constraint.getFirstType(),
constraint.getRequirement(), constraint.getSecondType(),
constraint.getMemberUseDC(), constraint.getFunctionRefInfo(),
constraint.getDeclContext(), constraint.getFunctionRefInfo(),
/*flags*/ std::nullopt, constraint.getLocator());
case ConstraintKind::Defaultable:

View File

@@ -31,8 +31,8 @@ Constraint::Constraint(ConstraintKind kind, ArrayRef<Constraint *> constraints,
bool isIsolated, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(kind), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false),
HasFix(false), HasDeclContext(false), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(isIsolated),
Nested(constraints), Locator(locator) {
assert(kind == ConstraintKind::Disjunction ||
@@ -56,8 +56,8 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(Kind), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false),
HasFix(false), HasDeclContext(false), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Types{First, Second, Type()},
Locator(locator) {
@@ -138,8 +138,8 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(Kind), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false),
HasFix(false), HasDeclContext(false), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Types{First, Second, Third},
Locator(locator) {
@@ -205,10 +205,10 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(kind), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false),
HasFix(false), HasDeclContext(true), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Member{first, second, {member}, useDC},
Member{first, second, {member}},
Locator(locator) {
assert(kind == ConstraintKind::ValueMember ||
kind == ConstraintKind::UnresolvedValueMember);
@@ -218,6 +218,7 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
assert(useDC && "Member constraint has no use DC");
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
*getTrailingObjects<DeclContext *>() = useDC;
}
Constraint::Constraint(ConstraintKind kind, Type first, Type second,
@@ -226,14 +227,13 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(kind), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false),
HasFix(false), HasDeclContext(true), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Locator(locator) {
Member.First = first;
Member.Second = second;
Member.Member.Ref = requirement;
Member.UseDC = useDC;
TheFunctionRefInfo = functionRefInfo.getOpaqueValue();
assert(kind == ConstraintKind::ValueWitness);
@@ -242,20 +242,21 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
assert(useDC && "Member constraint has no use DC");
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
*getTrailingObjects<DeclContext *>() = useDC;
}
Constraint::Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
ConstraintFix *fix, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(ConstraintKind::BindOverload), NumTypeVariables(typeVars.size()),
HasFix(fix != nullptr), HasRestriction(false), IsActive(false),
IsDisabled(bool(fix)), IsDisabledForPerformance(false),
HasFix(fix != nullptr), HasDeclContext(true), HasRestriction(false),
IsActive(false), IsDisabled(bool(fix)), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Overload{type, useDC},
Locator(locator) {
Overload{type}, Locator(locator) {
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
if (fix)
*getTrailingObjects<ConstraintFix *>() = fix;
*getTrailingObjects<DeclContext *>() = useDC;
*getTrailingObjects<OverloadChoice>() = choice;
}
@@ -264,9 +265,9 @@ Constraint::Constraint(ConstraintKind kind,
Type second, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(kind), Restriction(restriction), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(true), IsActive(false), IsDisabled(false),
IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false),
IsIsolated(false), Types{first, second, Type()},
HasFix(false), HasDeclContext(false), HasRestriction(true), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false),
IsFavored(false), IsIsolated(false), Types{first, second, Type()},
Locator(locator) {
ASSERT(isAdmissibleType(first));
ASSERT(isAdmissibleType(second));
@@ -277,9 +278,9 @@ Constraint::Constraint(ConstraintKind kind, ConstraintFix *fix, Type first,
Type second, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(kind), NumTypeVariables(typeVars.size()),
HasFix(fix != nullptr), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false),
IsFavored(false), IsIsolated(false),
HasFix(fix != nullptr), HasDeclContext(false), HasRestriction(false),
IsActive(false), IsDisabled(false), IsDisabledForPerformance(false),
RememberChoice(false), IsFavored(false), IsIsolated(false),
Types{first, second, Type()},
Locator(locator) {
ASSERT(isAdmissibleType(first));
@@ -293,7 +294,7 @@ Constraint::Constraint(ASTNode node, ContextualTypeInfo context,
bool isDiscarded, ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(ConstraintKind::SyntacticElement), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false),
HasFix(false), HasDeclContext(false), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false),
IsFavored(false), IsIsolated(false), isDiscarded(isDiscarded),
SyntacticElement{node},
@@ -307,9 +308,10 @@ Constraint::Constraint(FunctionType *appliedFn, Type calleeType,
ConstraintLocator *locator,
SmallPtrSetImpl<TypeVariableType *> &typeVars)
: Kind(ConstraintKind::ApplicableFunction), NumTypeVariables(typeVars.size()),
HasFix(false), HasRestriction(false), IsActive(false), IsDisabled(false),
IsDisabledForPerformance(false), RememberChoice(false), IsFavored(false),
IsIsolated(false), trailingClosureMatching(trailingClosureMatching),
HasFix(false), HasDeclContext(true), HasRestriction(false), IsActive(false),
IsDisabled(false), IsDisabledForPerformance(false), RememberChoice(false),
IsFavored(false), IsIsolated(false),
trailingClosureMatching(trailingClosureMatching),
Locator(locator) {
ASSERT(isAdmissibleType(appliedFn));
ASSERT(isAdmissibleType(calleeType));
@@ -318,9 +320,9 @@ Constraint::Constraint(FunctionType *appliedFn, Type calleeType,
Apply.AppliedFn = appliedFn;
Apply.Callee = calleeType;
Apply.UseDC = useDC;
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
*getTrailingObjects<DeclContext *>() = useDC;
}
ProtocolDecl *Constraint::getProtocol() const {
@@ -789,9 +791,9 @@ Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind,
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return ::new (mem) Constraint(kind, first, second, locator, typeVars);
@@ -812,9 +814,9 @@ Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind,
third->getTypeVariables(typeVars);
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return ::new (mem) Constraint(kind,
@@ -857,9 +859,9 @@ Constraint *Constraint::createMember(ConstraintSystem &cs, ConstraintKind kind,
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(kind, first, second, member, useDC,
@@ -881,9 +883,9 @@ Constraint *Constraint::createValueWitness(
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(kind, first, second, requirement, useDC,
@@ -905,9 +907,9 @@ Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type,
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), fix ? 1 : 0,
typeVars.size(), fix ? 1 : 0, /*hasDeclContext=*/1,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/1);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(type, choice, useDC, fix, locator, typeVars);
@@ -927,9 +929,9 @@ Constraint *Constraint::createRestricted(ConstraintSystem &cs,
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(kind, restriction, first, second, locator,
@@ -948,9 +950,9 @@ Constraint *Constraint::createFixed(ConstraintSystem &cs, ConstraintKind kind,
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), fix ? 1 : 0,
typeVars.size(), fix ? 1 : 0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(kind, fix, first, second, locator, typeVars);
@@ -1022,9 +1024,9 @@ Constraint *Constraint::createDisjunction(ConstraintSystem &cs,
// Create the disjunction constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
auto disjunction = new (mem)
@@ -1045,9 +1047,9 @@ Constraint *Constraint::createConjunction(
assert(!constraints.empty() && "Empty conjunction constraint");
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
auto conjunction = new (mem)
@@ -1083,9 +1085,9 @@ Constraint *Constraint::createApplicableFunction(
// Create the constraint.
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/1,
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
auto constraint = new (mem)
@@ -1114,9 +1116,9 @@ Constraint *Constraint::createSyntacticElement(ConstraintSystem &cs,
contextTy->getTypeVariables(typeVars);
auto size =
totalSizeToAlloc<TypeVariableType *, ConstraintFix *,
totalSizeToAlloc<TypeVariableType *, ConstraintFix *, DeclContext *,
ContextualTypeInfo, OverloadChoice>(
typeVars.size(), /*hasFix=*/0,
typeVars.size(), /*hasFix=*/0, /*hasDeclContext=*/0,
/*hasContextualTypeInfo=*/1, /*hasOverloadChoice=*/0);
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
return new (mem) Constraint(node, context, isDiscarded, locator, typeVars);

View File

@@ -218,7 +218,7 @@ TEST_F(SemaTest, TestInitializerUseDCIsSetCorrectlyInClosure) {
->isLastElement<LocatorPathElt::ConstructorMember>());
for (auto *choice : constraint->getNestedConstraints())
ASSERT_EQ(choice->getOverloadUseDC(), closure);
ASSERT_EQ(choice->getDeclContext(), closure);
}
}
}