Skip to content

Commit f92f28d

Browse files
committed
Sema: Optimize Constraint layout to save 16 bytes
The largest union member was for SyntacticElement constraints; let's tail-allocate the ContextualTypeInfo instead of storing one in every constraint.
1 parent 4eaa5ce commit f92f28d

File tree

2 files changed

+119
-84
lines changed

2 files changed

+119
-84
lines changed

include/swift/Sema/Constraint.h

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -336,16 +336,22 @@ class Constraint final : public llvm::ilist_node<Constraint>,
336336
private llvm::TrailingObjects<Constraint,
337337
TypeVariableType *,
338338
ConstraintFix *,
339+
ContextualTypeInfo,
339340
OverloadChoice> {
340341
friend TrailingObjects;
341342

342343
/// The kind of constraint.
343344
ConstraintKind Kind : 8;
344345

345346
/// The kind of restriction placed on this constraint.
346-
ConversionRestrictionKind Restriction : 8;
347+
ConversionRestrictionKind Restriction : 5;
347348

348-
/// Whether we have a fix.
349+
/// The number of type variables referenced by this constraint.
350+
///
351+
/// The type variables themselves are tail-allocated.
352+
unsigned NumTypeVariables : 11;
353+
354+
/// Whether we have a tail-allocated fix.
349355
unsigned HasFix : 1;
350356

351357
/// Whether the \c Restriction field is valid.
@@ -375,14 +381,17 @@ class Constraint final : public llvm::ilist_node<Constraint>,
375381
/// the rest of the constraint system. Currently only applies to conjunctions.
376382
unsigned IsIsolated : 1;
377383

378-
/// The number of type variables referenced by this constraint.
379-
///
380-
/// The type variables themselves are tail-allocated.
381-
unsigned NumTypeVariables : 11;
382-
383384
/// The kind of function reference, for member references.
384385
unsigned TheFunctionRefInfo : 3;
385386

387+
/// The trailing closure matching for an applicable function constraint,
388+
/// if any. 0 = None, 1 = Forward, 2 = Backward.
389+
unsigned trailingClosureMatching : 2;
390+
391+
/// For a SyntacticElement constraint, identify whether the result of this
392+
/// node is unused.
393+
unsigned isDiscarded : 1;
394+
386395
union {
387396
struct {
388397
/// The first type.
@@ -433,10 +442,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
433442
struct {
434443
/// The node itself.
435444
ASTNode Element;
436-
/// Contextual information associated with the element (if any).
437-
ContextualTypeInfo Context;
438-
/// Identifies whether result of this node is unused.
439-
bool IsDiscarded;
440445
} SyntacticElement;
441446

442447
struct {
@@ -447,9 +452,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
447452
/// The type being called, primarily a function type, but could
448453
/// be a metatype, a tuple or a nominal type.
449454
Type Callee;
450-
/// The trailing closure matching for an applicable function constraint,
451-
/// if any. 0 = None, 1 = Forward, 2 = Backward.
452-
unsigned TrailingClosureMatching : 2;
453455
/// The declaration context in which the application appears.
454456
DeclContext *UseDC;
455457
} Apply;
@@ -527,6 +529,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
527529
return HasFix ? 1 : 0;
528530
}
529531

532+
size_t numTrailingObjects(OverloadToken<ContextualTypeInfo>) const {
533+
return Kind == ConstraintKind::SyntacticElement ? 1 : 0;
534+
}
535+
530536
size_t numTrailingObjects(OverloadToken<OverloadChoice>) const {
531537
return Kind == ConstraintKind::BindOverload ? 1 : 0;
532538
}
@@ -604,15 +610,15 @@ class Constraint final : public llvm::ilist_node<Constraint>,
604610
DeclContext *useDC, ConstraintLocator *locator);
605611

606612
static Constraint *createSyntacticElement(ConstraintSystem &cs,
607-
ASTNode node,
608-
ConstraintLocator *locator,
609-
bool isDiscarded = false);
613+
ASTNode node,
614+
ConstraintLocator *locator,
615+
bool isDiscarded = false);
610616

611617
static Constraint *createSyntacticElement(ConstraintSystem &cs,
612-
ASTNode node,
613-
ContextualTypeInfo context,
614-
ConstraintLocator *locator,
615-
bool isDiscarded = false);
618+
ASTNode node,
619+
ContextualTypeInfo context,
620+
ConstraintLocator *locator,
621+
bool isDiscarded = false);
616622

617623
/// Determine the kind of constraint.
618624
ConstraintKind getKind() const { return Kind; }
@@ -903,13 +909,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
903909
}
904910

905911
ContextualTypeInfo getElementContext() const {
906-
assert(Kind == ConstraintKind::SyntacticElement);
907-
return SyntacticElement.Context;
912+
ASSERT(Kind == ConstraintKind::SyntacticElement);
913+
return *getTrailingObjects<ContextualTypeInfo>();
908914
}
909915

910916
bool isDiscardedElement() const {
911917
assert(Kind == ConstraintKind::SyntacticElement);
912-
return SyntacticElement.IsDiscarded;
918+
return isDiscarded;
913919
}
914920

915921
/// For an applicable function constraint, retrieve the trailing closure

0 commit comments

Comments
 (0)