Skip to content

Commit b6014e8

Browse files
committed
[AST] NFC: Move "is canonical type" bit outside of union
Fetching the canonical type is on the hot path.
1 parent b3c062c commit b6014e8

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

include/swift/AST/Types.h

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,14 @@ class alignas(1 << TypeAlignInBits) TypeBase {
255255
TypeBase(const TypeBase&) = delete;
256256
void operator=(const TypeBase&) = delete;
257257

258-
/// CanonicalType - This field is always set to the ASTContext for canonical
259-
/// types, and is otherwise lazily populated by ASTContext when the canonical
260-
/// form of a non-canonical type is requested.
261-
llvm::PointerUnion<TypeBase *, const ASTContext *> CanonicalType;
258+
/// This union contains to the ASTContext for canonical types, and is
259+
/// otherwise lazily populated by ASTContext when the canonical form of a
260+
/// non-canonical type is requested. The disposition of the union is stored
261+
/// outside of the union for performance. See Bits.TypeBase.IsCanonical.
262+
union {
263+
CanType CanonicalType;
264+
const ASTContext *Context;
265+
};
262266

263267
/// Returns true if the given type is a sugared type.
264268
///
@@ -275,11 +279,14 @@ class alignas(1 << TypeAlignInBits) TypeBase {
275279
union { uint64_t OpaqueBits;
276280

277281
SWIFT_INLINE_BITFIELD_BASE(TypeBase, bitmax(NumTypeKindBits,8) +
278-
RecursiveTypeProperties::BitWidth,
282+
RecursiveTypeProperties::BitWidth + 1,
279283
/// Kind - The discriminator that indicates what subclass of type this is.
280284
Kind : bitmax(NumTypeKindBits,8),
281285

282-
Properties : RecursiveTypeProperties::BitWidth
286+
Properties : RecursiveTypeProperties::BitWidth,
287+
288+
/// Whether this type is canonical or not.
289+
IsCanonical : 1
283290
);
284291

285292
SWIFT_INLINE_BITFIELD(ErrorType, TypeBase, 1,
@@ -384,12 +391,15 @@ class alignas(1 << TypeAlignInBits) TypeBase {
384391
protected:
385392
TypeBase(TypeKind kind, const ASTContext *CanTypeCtx,
386393
RecursiveTypeProperties properties)
387-
: CanonicalType((TypeBase*)nullptr) {
394+
: Context(nullptr) {
388395
Bits.OpaqueBits = 0;
389396
Bits.TypeBase.Kind = static_cast<unsigned>(kind);
397+
Bits.TypeBase.IsCanonical = false;
390398
// If this type is canonical, switch the CanonicalType union to ASTContext.
391-
if (CanTypeCtx)
392-
CanonicalType = CanTypeCtx;
399+
if (CanTypeCtx) {
400+
Bits.TypeBase.IsCanonical = true;
401+
Context = CanTypeCtx;
402+
}
393403
setRecursiveProperties(properties);
394404
}
395405

@@ -403,7 +413,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
403413
TypeKind getKind() const { return static_cast<TypeKind>(Bits.TypeBase.Kind); }
404414

405415
/// isCanonical - Return true if this is a canonical type.
406-
bool isCanonical() const { return CanonicalType.is<const ASTContext *>(); }
416+
bool isCanonical() const { return Bits.TypeBase.IsCanonical; }
407417

408418
/// hasCanonicalTypeComputed - Return true if we've already computed a
409419
/// canonical version of this type.
@@ -419,7 +429,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
419429
if (isCanonical())
420430
return CanType(const_cast<TypeBase*>(this));
421431
if (hasCanonicalTypeComputed())
422-
return CanType(CanonicalType.get<TypeBase*>());
432+
return CanonicalType;
423433
return const_cast<TypeBase*>(this)->computeCanonicalType();
424434
}
425435

@@ -434,11 +444,10 @@ class alignas(1 << TypeAlignInBits) TypeBase {
434444
/// getASTContext - Return the ASTContext that this type belongs to.
435445
ASTContext &getASTContext() {
436446
// If this type is canonical, it has the ASTContext in it.
437-
if (CanonicalType.is<const ASTContext *>())
438-
return const_cast<ASTContext&>(*CanonicalType.get<const ASTContext *>());
447+
if (isCanonical())
448+
return *const_cast<ASTContext*>(Context);
439449
// If not, canonicalize it to get the Context.
440-
return const_cast<ASTContext&>(*getCanonicalType()->
441-
CanonicalType.get<const ASTContext *>());
450+
return *const_cast<ASTContext*>(getCanonicalType()->Context);
442451
}
443452

444453
/// isEqual - Return true if these two types are equal, ignoring sugar.

lib/AST/Type.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,7 @@ CanType TypeBase::computeCanonicalType() {
12431243

12441244
// Cache the canonical type for future queries.
12451245
assert(Result && "Case not implemented!");
1246-
CanonicalType = Result;
1247-
return CanType(Result);
1246+
return CanonicalType = CanType(Result);
12481247
}
12491248

12501249
CanType TypeBase::getCanonicalType(GenericSignature *sig) {

0 commit comments

Comments
 (0)