Skip to content

Commit 4e22629

Browse files
committed
Extend the representation of layout constraints
- Add support for _Class and _NativeClass layout constraints, which are supposed to represent T: Superclass and P: class constraints in the future. - Use the re-factoring to also reduce the number of dynamic allocations when creating layout constraints. Simple non-parametrized layout constraints are now represented as statically allocated singletons (static members of LayoutConstraintInfo).
1 parent 49941c5 commit 4e22629

File tree

7 files changed

+128
-11
lines changed

7 files changed

+128
-11
lines changed

include/swift/AST/LayoutConstraint.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,16 @@ enum class LayoutConstraintKind : unsigned char {
4040
TrivialOfAtMostSize,
4141
// It is a layout constraint representing a trivial type of an unknown size.
4242
Trivial,
43+
// It is a layout constraint representing a reference counted class instance.
44+
Class,
45+
// It is a layout constraint representing a reference counted native class
46+
// instance.
47+
NativeClass,
4348
// It is a layout constraint representing a reference counted object.
4449
RefCountedObject,
4550
// It is a layout constraint representing a native reference counted object.
4651
NativeRefCountedObject,
52+
LastLayout = NativeRefCountedObject,
4753
};
4854

4955
/// This is a class representing the layout constraint.
@@ -108,6 +114,22 @@ class LayoutConstraintInfo : public llvm::FoldingSetNode {
108114
return isNativeRefCountedObject(Kind);
109115
}
110116

117+
bool isClass() const {
118+
return isClass(Kind);
119+
}
120+
121+
bool isNativeClass() const {
122+
return isNativeClass(Kind);
123+
}
124+
125+
bool isRefCounted() const {
126+
return isRefCounted(Kind);
127+
}
128+
129+
bool isNativeRefCounted() const {
130+
return isNativeRefCounted(Kind);
131+
}
132+
111133
unsigned getTrivialSizeInBytes() const {
112134
assert(isKnownSizeTrivial());
113135
return (SizeInBits + 7) / 8;
@@ -170,6 +192,16 @@ class LayoutConstraintInfo : public llvm::FoldingSetNode {
170192

171193
static bool isNativeRefCountedObject(LayoutConstraintKind Kind);
172194

195+
static bool isAnyRefCountedObject(LayoutConstraintKind Kind);
196+
197+
static bool isClass(LayoutConstraintKind Kind);
198+
199+
static bool isNativeClass(LayoutConstraintKind Kind);
200+
201+
static bool isRefCounted(LayoutConstraintKind Kind);
202+
203+
static bool isNativeRefCounted(LayoutConstraintKind Kind);
204+
173205
/// Uniquing for the LayoutConstraintInfo.
174206
void Profile(llvm::FoldingSetNodeID &ID) {
175207
Profile(ID, Kind, SizeInBits, Alignment);
@@ -189,6 +221,14 @@ class LayoutConstraintInfo : public llvm::FoldingSetNode {
189221
void *operator new(size_t bytes, const ASTContext &ctx,
190222
AllocationArena arena, unsigned alignment = 8);
191223
void *operator new(size_t Bytes, void *Mem) throw() { return Mem; }
224+
225+
// Representation of the non-parametrized layouts.
226+
static LayoutConstraintInfo UnknownLayoutConstraintInfo;
227+
static LayoutConstraintInfo RefCountedObjectConstraintInfo;
228+
static LayoutConstraintInfo NativeRefCountedObjectConstraintInfo;
229+
static LayoutConstraintInfo ClassConstraintInfo;
230+
static LayoutConstraintInfo NativeClassConstraintInfo;
231+
static LayoutConstraintInfo TrivialConstraintInfo;
192232
};
193233

194234
/// A wrapper class containing a reference to the actual LayoutConstraintInfo
@@ -204,12 +244,14 @@ class LayoutConstraint {
204244
static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind,
205245
ASTContext &C);
206246

247+
static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind);
248+
207249
static LayoutConstraint getLayoutConstraint(LayoutConstraintKind Kind,
208250
unsigned SizeInBits,
209251
unsigned Alignment,
210252
ASTContext &C);
211253

212-
static LayoutConstraint getUnknownLayout(ASTContext &C);
254+
static LayoutConstraint getUnknownLayout();
213255

214256
LayoutConstraintInfo *getPointer() const { return Ptr; }
215257

lib/AST/ASTContext.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4074,6 +4074,12 @@ LayoutConstraint LayoutConstraint::getLayoutConstraint(LayoutConstraintKind Kind
40744074
unsigned SizeInBits,
40754075
unsigned Alignment,
40764076
ASTContext &C) {
4077+
if (!LayoutConstraintInfo::isKnownSizeTrivial(Kind)) {
4078+
assert(SizeInBits == 0);
4079+
assert(Alignment == 0);
4080+
return getLayoutConstraint(Kind);
4081+
}
4082+
40774083
// Check to see if we've already seen this tuple before.
40784084
llvm::FoldingSetNodeID ID;
40794085
LayoutConstraintInfo::Profile(ID, Kind, SizeInBits, Alignment);
@@ -4094,7 +4100,4 @@ LayoutConstraint LayoutConstraint::getLayoutConstraint(LayoutConstraintKind Kind
40944100
return LayoutConstraint(New);
40954101
}
40964102

4097-
LayoutConstraint LayoutConstraint::getUnknownLayout(ASTContext &C) {
4098-
return getLayoutConstraint(LayoutConstraintKind::UnknownLayout, 0, 0, C);
4099-
}
41004103

lib/AST/LayoutConstraint.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ StringRef LayoutConstraintInfo::getName(LayoutConstraintKind Kind) {
5151
switch (Kind) {
5252
case LayoutConstraintKind::UnknownLayout:
5353
return "_UnknownLayout";
54+
case LayoutConstraintKind::Class:
55+
return "_Class";
56+
case LayoutConstraintKind::NativeClass:
57+
return "_NativeClass";
5458
case LayoutConstraintKind::RefCountedObject:
5559
return "_RefCountedObject";
5660
case LayoutConstraintKind::NativeRefCountedObject:
@@ -106,6 +110,28 @@ bool LayoutConstraintInfo::isNativeRefCountedObject(LayoutConstraintKind Kind) {
106110
return Kind == LayoutConstraintKind::NativeRefCountedObject;
107111
}
108112

113+
bool LayoutConstraintInfo::isAnyRefCountedObject(LayoutConstraintKind Kind) {
114+
return isRefCountedObject(Kind) || isNativeRefCountedObject(Kind);
115+
}
116+
117+
bool LayoutConstraintInfo::isClass(LayoutConstraintKind Kind) {
118+
return Kind == LayoutConstraintKind::Class ||
119+
Kind == LayoutConstraintKind::NativeClass;
120+
}
121+
122+
bool LayoutConstraintInfo::isNativeClass(LayoutConstraintKind Kind) {
123+
return Kind == LayoutConstraintKind::NativeClass;
124+
}
125+
126+
bool LayoutConstraintInfo::isRefCounted(LayoutConstraintKind Kind) {
127+
return isAnyRefCountedObject(Kind) || isClass(Kind);
128+
}
129+
130+
bool LayoutConstraintInfo::isNativeRefCounted(LayoutConstraintKind Kind) {
131+
return Kind == LayoutConstraintKind::NativeRefCountedObject ||
132+
Kind == LayoutConstraintKind::NativeClass;
133+
}
134+
109135
void *LayoutConstraintInfo::operator new(size_t bytes, const ASTContext &ctx,
110136
AllocationArena arena,
111137
unsigned alignment) {
@@ -114,4 +140,50 @@ void *LayoutConstraintInfo::operator new(size_t bytes, const ASTContext &ctx,
114140

115141
SourceRange LayoutConstraintLoc::getSourceRange() const { return getLoc(); }
116142

143+
144+
LayoutConstraint
145+
LayoutConstraint::getLayoutConstraint(LayoutConstraintKind Kind) {
146+
assert(!LayoutConstraintInfo::isKnownSizeTrivial(Kind));
147+
switch(Kind) {
148+
case LayoutConstraintKind::Trivial:
149+
return LayoutConstraint(&LayoutConstraintInfo::TrivialConstraintInfo);
150+
case LayoutConstraintKind::NativeClass:
151+
return LayoutConstraint(&LayoutConstraintInfo::NativeClassConstraintInfo);
152+
case LayoutConstraintKind::Class:
153+
return LayoutConstraint(&LayoutConstraintInfo::ClassConstraintInfo);
154+
case LayoutConstraintKind::NativeRefCountedObject:
155+
return LayoutConstraint(
156+
&LayoutConstraintInfo::NativeRefCountedObjectConstraintInfo);
157+
case LayoutConstraintKind::RefCountedObject:
158+
return LayoutConstraint(
159+
&LayoutConstraintInfo::RefCountedObjectConstraintInfo);
160+
case LayoutConstraintKind::UnknownLayout:
161+
return LayoutConstraint(&LayoutConstraintInfo::UnknownLayoutConstraintInfo);
162+
case LayoutConstraintKind::TrivialOfAtMostSize:
163+
case LayoutConstraintKind::TrivialOfExactSize:
164+
llvm_unreachable("Wrong layout constraint kind");
165+
}
166+
}
167+
168+
LayoutConstraint LayoutConstraint::getUnknownLayout() {
169+
return LayoutConstraint(&LayoutConstraintInfo::UnknownLayoutConstraintInfo);
170+
}
171+
172+
LayoutConstraintInfo LayoutConstraintInfo::UnknownLayoutConstraintInfo;
173+
174+
LayoutConstraintInfo LayoutConstraintInfo::RefCountedObjectConstraintInfo(
175+
LayoutConstraintKind::RefCountedObject);
176+
177+
LayoutConstraintInfo LayoutConstraintInfo::NativeRefCountedObjectConstraintInfo(
178+
LayoutConstraintKind::NativeRefCountedObject);
179+
180+
LayoutConstraintInfo LayoutConstraintInfo::ClassConstraintInfo(
181+
LayoutConstraintKind::Class);
182+
183+
LayoutConstraintInfo LayoutConstraintInfo::NativeClassConstraintInfo(
184+
LayoutConstraintKind::NativeClass);
185+
186+
LayoutConstraintInfo LayoutConstraintInfo::TrivialConstraintInfo(
187+
LayoutConstraintKind::Trivial);
188+
117189
} // end namespace swift

lib/IRGen/GenArchetype.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
282282
// If the archetype is class-constrained, use a class pointer
283283
// representation.
284284
if (archetype->requiresClass() ||
285-
(LayoutInfo && LayoutInfo->isRefCountedObject())) {
285+
(LayoutInfo && LayoutInfo->isRefCounted())) {
286286
ReferenceCounting refcount;
287287
llvm::PointerType *reprTy;
288288

lib/Parse/ParseType.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,24 @@ LayoutConstraint Parser::parseLayoutConstraint(Identifier LayoutConstraintID) {
111111
// There was an error during parsing.
112112
skipUntil(tok::r_paren);
113113
consumeIf(tok::r_paren);
114-
return LayoutConstraint::getUnknownLayout(Context);
114+
return LayoutConstraint::getUnknownLayout();
115115
}
116116

117117
if (!consumeIf(tok::r_paren)) {
118118
// Expected a closing r_paren.
119119
diagnose(Tok.getLoc(), diag::expected_rparen_layout_constraint);
120120
consumeToken();
121-
return LayoutConstraint::getUnknownLayout(Context);
121+
return LayoutConstraint::getUnknownLayout();
122122
}
123123

124124
if (size < 0) {
125125
diagnose(Tok.getLoc(), diag::layout_size_should_be_positive);
126-
return LayoutConstraint::getUnknownLayout(Context);
126+
return LayoutConstraint::getUnknownLayout();
127127
}
128128

129129
if (alignment < 0) {
130130
diagnose(Tok.getLoc(), diag::layout_alignment_should_be_positive);
131-
return LayoutConstraint::getUnknownLayout(Context);
131+
return LayoutConstraint::getUnknownLayout();
132132
}
133133

134134
// Otherwise it is a trivial layout constraint with

lib/SIL/TypeLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ namespace {
337337
return asImpl().handleTrivialAddressOnly(type);
338338
}
339339

340-
if (LayoutInfo->isRefCountedObject())
340+
if (LayoutInfo->isRefCounted())
341341
return asImpl().handleReference(type);
342342
}
343343
return asImpl().handleAddressOnly(type);

lib/SILOptimizer/IPO/EagerSpecializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ void EagerDispatch::emitDispatchTo(SILFunction *NewFunc) {
354354
// Emit a check that it is a trivial type of a certain size.
355355
emitTrivialAndSizeCheck(FailedTypeCheckBB, ParamTy,
356356
Replacement, LayoutInfo);
357-
} else if (LayoutInfo && LayoutInfo->isRefCountedObject()) {
357+
} else if (LayoutInfo && LayoutInfo->isRefCounted()) {
358358
// Emit a check that it is an object of a reference counted type.
359359
emitRefCountedObjectCheck(FailedTypeCheckBB, ParamTy,
360360
Replacement, LayoutInfo);

0 commit comments

Comments
 (0)