Skip to content

Commit a7a19a0

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 a7a19a0

File tree

2 files changed

+120
-83
lines changed

2 files changed

+120
-83
lines changed

include/swift/Sema/Constraint.h

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ 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

@@ -345,7 +346,12 @@ class Constraint final : public llvm::ilist_node<Constraint>,
345346
/// The kind of restriction placed on this constraint.
346347
ConversionRestrictionKind Restriction : 8;
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,19 @@ 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+
395+
// 23 bits remaining
396+
386397
union {
387398
struct {
388399
/// The first type.
@@ -433,10 +444,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
433444
struct {
434445
/// The node itself.
435446
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;
440447
} SyntacticElement;
441448

442449
struct {
@@ -447,9 +454,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
447454
/// The type being called, primarily a function type, but could
448455
/// be a metatype, a tuple or a nominal type.
449456
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;
453457
/// The declaration context in which the application appears.
454458
DeclContext *UseDC;
455459
} Apply;
@@ -527,6 +531,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
527531
return HasFix ? 1 : 0;
528532
}
529533

534+
size_t numTrailingObjects(OverloadToken<ContextualTypeInfo>) const {
535+
return Kind == ConstraintKind::SyntacticElement ? 1 : 0;
536+
}
537+
530538
size_t numTrailingObjects(OverloadToken<OverloadChoice>) const {
531539
return Kind == ConstraintKind::BindOverload ? 1 : 0;
532540
}
@@ -604,15 +612,15 @@ class Constraint final : public llvm::ilist_node<Constraint>,
604612
DeclContext *useDC, ConstraintLocator *locator);
605613

606614
static Constraint *createSyntacticElement(ConstraintSystem &cs,
607-
ASTNode node,
608-
ConstraintLocator *locator,
609-
bool isDiscarded = false);
615+
ASTNode node,
616+
ConstraintLocator *locator,
617+
bool isDiscarded = false);
610618

611619
static Constraint *createSyntacticElement(ConstraintSystem &cs,
612-
ASTNode node,
613-
ContextualTypeInfo context,
614-
ConstraintLocator *locator,
615-
bool isDiscarded = false);
620+
ASTNode node,
621+
ContextualTypeInfo context,
622+
ConstraintLocator *locator,
623+
bool isDiscarded = false);
616624

617625
/// Determine the kind of constraint.
618626
ConstraintKind getKind() const { return Kind; }
@@ -903,13 +911,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
903911
}
904912

905913
ContextualTypeInfo getElementContext() const {
906-
assert(Kind == ConstraintKind::SyntacticElement);
907-
return SyntacticElement.Context;
914+
ASSERT(Kind == ConstraintKind::SyntacticElement);
915+
return *getTrailingObjects<ContextualTypeInfo>();
908916
}
909917

910918
bool isDiscardedElement() const {
911919
assert(Kind == ConstraintKind::SyntacticElement);
912-
return SyntacticElement.IsDiscarded;
920+
return isDiscarded;
913921
}
914922

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

0 commit comments

Comments
 (0)