[clang] [clang] Unique more ASTContext type pools in a UniquingSet. NFC (PR #221898)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 00:28:12 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
Similar to #<!-- -->221850.
Eight pools key on a small tuple of types, integers and pointers, yet
each get*Type() serializes that into a FoldingSetNodeID and hashes it
out of line before probing. Switch to UniquingSet.
These getters re-probe after building the canonical type. A token is a
hash (#<!-- -->218190), not a bucket, so nothing invalidates it. Drop unneeded
assertions.
---
Full diff: https://github.com/llvm/llvm-project/pull/221898.diff
5 Files Affected:
- (modified) clang/include/clang/AST/ASTContext.h (+9-9)
- (modified) clang/include/clang/AST/TypeBase.h (+22-62)
- (modified) clang/lib/AST/ASTContext.cpp (+20-52)
- (modified) clang/lib/AST/StmtProfile.cpp (+6-3)
- (modified) clang/lib/AST/Type.cpp (-28)
``````````diff
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 8277f1fcced95..90843f70aa9f0 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -243,7 +243,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::UniquingSet<ComplexType> ComplexTypes;
mutable llvm::UniquingSet<PointerType> PointerTypes{GeneralTypesLog2InitSize};
- mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
+ mutable llvm::UniquingSet<AdjustedType> AdjustedTypes;
mutable llvm::UniquingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::UniquingSet<LValueReferenceType, QualTypeBoolInfo>
LValueReferenceTypes;
@@ -277,10 +277,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<PackIndexingType, ASTContext &>
DependentPackIndexingTypes;
- mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
- mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
- mutable llvm::FoldingSet<SubstTemplateTypeParmType>
- SubstTemplateTypeParmTypes;
+ mutable llvm::UniquingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+ mutable llvm::UniquingSet<ObjCTypeParamType> ObjCTypeParamTypes;
+ mutable llvm::UniquingSet<SubstTemplateTypeParmType>
+ SubstTemplateTypeParmTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
SubstTemplateTypeParmPackTypes;
mutable llvm::FoldingSet<SubstBuiltinTemplatePackType>
@@ -294,10 +294,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<UsingType> UsingTypes;
mutable llvm::FoldingSet<FoldingSetPlaceholder<TypedefType>> TypedefTypes;
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
- mutable llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
+ mutable llvm::UniquingSet<PackExpansionType> PackExpansionTypes;
mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
- mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- mutable llvm::FoldingSet<UnaryTransformType> UnaryTransformTypes;
+ mutable llvm::UniquingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
+ mutable llvm::UniquingSet<UnaryTransformType> UnaryTransformTypes;
// An AutoType can have a dependency on another AutoType via its template
// arguments. Since both dependent and dependency are on the same set,
// we can end up in an infinite recursion when looking for a node if we used
@@ -311,7 +311,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<AttributedType, ASTContext &>
AttributedTypes;
mutable llvm::UniquingSet<PipeType, QualTypeBoolInfo> PipeTypes;
- mutable llvm::FoldingSet<BitIntType> BitIntTypes;
+ mutable llvm::UniquingSet<BitIntType> BitIntTypes;
mutable llvm::ContextualFoldingSet<DependentBitIntType, ASTContext &>
DependentBitIntTypes;
mutable llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index 9edf8a0ce9c68..69aa4cde3eecb 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -3603,13 +3603,8 @@ class AdjustedType : public Type, public llvm::FoldingSetNode {
bool isSugared() const { return true; }
QualType desugar() const { return AdjustedTy; }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, OriginalTy, AdjustedTy);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
- ID.AddPointer(Orig.getAsOpaquePtr());
- ID.AddPointer(New.getAsOpaquePtr());
+ std::pair<QualType, QualType> getKey() const {
+ return {OriginalTy, AdjustedTy};
}
static bool classof(const Type *T) {
@@ -6514,15 +6509,8 @@ class UnaryTransformType : public Type, public llvm::FoldingSetNode {
return T->getTypeClass() == UnaryTransform;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getBaseType(), getUnderlyingType(), getUTTKind());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType,
- QualType UnderlyingType, UTTKind UKind) {
- BaseType.Profile(ID);
- UnderlyingType.Profile(ID);
- ID.AddInteger(UKind);
+ std::tuple<QualType, QualType, UTTKind> getKey() const {
+ return {getBaseType(), getUnderlyingType(), getUTTKind()};
}
};
@@ -7110,17 +7098,9 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
- unsigned Index, bool ParameterPack,
- TemplateTypeParmDecl *TTPDecl) {
- ID.AddInteger(Depth);
- ID.AddInteger(Index);
- ID.AddBoolean(ParameterPack);
- ID.AddPointer(TTPDecl);
+ std::tuple<unsigned, unsigned, unsigned, TemplateTypeParmDecl *>
+ getKey() const {
+ return {getDepth(), getIndex(), isParameterPack(), getDecl()};
}
static bool classof(const Type *T) {
@@ -7181,15 +7161,12 @@ class SubstTemplateTypeParmType final
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
- getPackIndex(), getFinal());
+ std::tuple<QualType, Decl *, unsigned, unsigned, unsigned> getKey() const {
+ return {getReplacementType(), getAssociatedDecl(), getIndex(),
+ SubstTemplateTypeParmTypeBits.PackIndex,
+ SubstTemplateTypeParmTypeBits.Final};
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
- const Decl *AssociatedDecl, unsigned Index,
- UnsignedOrNone PackIndex, bool Final);
-
static bool classof(const Type *T) {
return T->getTypeClass() == SubstTemplateTypeParm;
}
@@ -7682,14 +7659,8 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPattern(), getNumExpansions());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- UnsignedOrNone NumExpansions) {
- ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddInteger(NumExpansions.toInternalRepresentation());
+ std::pair<QualType, unsigned> getKey() const {
+ return {getPattern(), getNumExpansions().toInternalRepresentation()};
}
static bool classof(const Type *T) {
@@ -7793,13 +7764,13 @@ class ObjCTypeParamType : public Type,
return T->getTypeClass() == ObjCTypeParam;
}
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ObjCTypeParamDecl *OTPDecl,
- QualType CanonicalType,
- ArrayRef<ObjCProtocolDecl *> protocols);
-
ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
+
+ std::tuple<const ObjCTypeParamDecl *, QualType, ArrayRef<ObjCProtocolDecl *>>
+ getKey() const {
+ return {getDecl(), getCanonicalTypeInternal(),
+ llvm::ArrayRef(qual_begin(), getNumProtocols())};
+ }
};
/// Represents a class type in Objective C.
@@ -8242,13 +8213,8 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals(
const ASTContext &ctx) const;
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
+ QualType getKey() const { return getPointeeType(); }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
- ID.AddPointer(T.getAsOpaquePtr());
- }
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
@@ -8324,14 +8290,8 @@ class BitIntType final : public Type, public llvm::FoldingSetNode {
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, isUnsigned(), getNumBits());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned,
- unsigned NumBits) {
- ID.AddBoolean(IsUnsigned);
- ID.AddInteger(NumBits);
+ std::pair<unsigned, unsigned> getKey() const {
+ return {isUnsigned(), getNumBits()};
}
static bool classof(const Type *T) { return T->getTypeClass() == BitInt; }
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a8b256167fd64..f4a63073aaed1 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4013,19 +4013,13 @@ QualType ASTContext::getPointerType(QualType T) const {
}
QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
- llvm::FoldingSetNodeID ID;
- AdjustedType::Profile(ID, Orig, New);
llvm::FoldingSetInsertToken Token;
- AdjustedType *AT = AdjustedTypes.lookup(ID, Token);
+ AdjustedType *AT = AdjustedTypes.lookup({Orig, New}, Token);
if (AT)
return QualType(AT, 0);
QualType Canonical = getCanonicalType(New);
- // Get the new insert position for the node we care about.
- AT = AdjustedTypes.lookup(ID, Token);
- assert(!AT && "Shouldn't be in the map!");
-
AT = new (*this, alignof(AdjustedType))
AdjustedType(Type::Adjusted, Orig, New, Canonical);
Types.push_back(AT);
@@ -4034,19 +4028,13 @@ QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
}
QualType ASTContext::getDecayedType(QualType Orig, QualType Decayed) const {
- llvm::FoldingSetNodeID ID;
- AdjustedType::Profile(ID, Orig, Decayed);
llvm::FoldingSetInsertToken Token;
- AdjustedType *AT = AdjustedTypes.lookup(ID, Token);
+ AdjustedType *AT = AdjustedTypes.lookup({Orig, Decayed}, Token);
if (AT)
return QualType(AT, 0);
QualType Canonical = getCanonicalType(Decayed);
- // Get the new insert position for the node we care about.
- AT = AdjustedTypes.lookup(ID, Token);
- assert(!AT && "Shouldn't be in the map!");
-
AT = new (*this, alignof(DecayedType)) DecayedType(Orig, Decayed, Canonical);
Types.push_back(AT);
AdjustedTypes.insert(AT, Token);
@@ -5219,11 +5207,10 @@ QualType ASTContext::getWritePipeType(QualType T) const {
}
QualType ASTContext::getBitIntType(bool IsUnsigned, unsigned NumBits) const {
- llvm::FoldingSetNodeID ID;
- BitIntType::Profile(ID, IsUnsigned, NumBits);
+ auto Key = std::make_pair(unsigned(IsUnsigned), NumBits);
llvm::FoldingSetInsertToken Token;
- if (BitIntType *EIT = BitIntTypes.lookup(ID, Token))
+ if (BitIntType *EIT = BitIntTypes.lookup(Key, Token))
return QualType(EIT, 0);
auto *New = new (*this, alignof(BitIntType)) BitIntType(IsUnsigned, NumBits);
@@ -5899,12 +5886,12 @@ QualType ASTContext::getSubstTemplateTypeParmType(QualType Replacement,
unsigned Index,
UnsignedOrNone PackIndex,
bool Final) const {
- llvm::FoldingSetNodeID ID;
- SubstTemplateTypeParmType::Profile(ID, Replacement, AssociatedDecl, Index,
- PackIndex, Final);
+ auto Key =
+ std::make_tuple(Replacement, AssociatedDecl, Index,
+ PackIndex.toInternalRepresentation(), unsigned(Final));
llvm::FoldingSetInsertToken Token;
SubstTemplateTypeParmType *SubstParm =
- SubstTemplateTypeParmTypes.lookup(ID, Token);
+ SubstTemplateTypeParmTypes.lookup(Key, Token);
if (!SubstParm) {
void *Mem = Allocate(SubstTemplateTypeParmType::totalSizeToAlloc<QualType>(
@@ -5999,10 +5986,10 @@ ASTContext::getTemplateTypeParmType(int Depth, int Index, bool ParameterPack,
assert(Depth >= 0 && "Depth must be non-negative");
assert(Index >= 0 && "Index must be non-negative");
- llvm::FoldingSetNodeID ID;
- TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
+ auto Key = std::make_tuple(unsigned(Depth), unsigned(Index),
+ unsigned(ParameterPack), TTPDecl);
llvm::FoldingSetInsertToken Token;
- TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.lookup(ID, Token);
+ TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.lookup(Key, Token);
if (TypeParm)
return QualType(TypeParm, 0);
@@ -6011,10 +5998,6 @@ ASTContext::getTemplateTypeParmType(int Depth, int Index, bool ParameterPack,
QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
TypeParm = new (*this, alignof(TemplateTypeParmType))
TemplateTypeParmType(Depth, Index, ParameterPack, TTPDecl, Canon);
-
- TemplateTypeParmType *TypeCheck = TemplateTypeParmTypes.lookup(ID, Token);
- assert(!TypeCheck && "Template type parameter canonical type broken");
- (void)TypeCheck;
} else
TypeParm = new (*this, alignof(TemplateTypeParmType)) TemplateTypeParmType(
Depth, Index, ParameterPack, /*TTPDecl=*/nullptr, /*Canon=*/QualType());
@@ -6287,11 +6270,10 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
assert((!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) &&
"Pack expansions must expand one or more parameter packs");
- llvm::FoldingSetNodeID ID;
- PackExpansionType::Profile(ID, Pattern, NumExpansions);
+ auto Key = std::make_pair(Pattern, NumExpansions.toInternalRepresentation());
llvm::FoldingSetInsertToken Token;
- PackExpansionType *T = PackExpansionTypes.lookup(ID, Token);
+ PackExpansionType *T = PackExpansionTypes.lookup(Key, Token);
if (T)
return QualType(T, 0);
@@ -6302,7 +6284,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
// Find the insert position again, in case we inserted an element into
// PackExpansionTypes and invalidated our insert position.
- PackExpansionTypes.lookup(ID, Token);
+ PackExpansionTypes.lookup(Key, Token);
}
T = new (*this, alignof(PackExpansionType))
@@ -6519,10 +6501,9 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
// Key on the canonical type the node is constructed with, which is what
// Profile() reports; the decl's underlying type can be updated later.
- llvm::FoldingSetNodeID ID;
- ObjCTypeParamType::Profile(ID, Decl, Canonical, protocols);
+ auto Key = std::make_tuple(Decl, Canonical, protocols);
llvm::FoldingSetInsertToken Token;
- if (ObjCTypeParamType *TypeParam = ObjCTypeParamTypes.lookup(ID, Token))
+ if (ObjCTypeParamType *TypeParam = ObjCTypeParamTypes.lookup(Key, Token))
return QualType(TypeParam, 0);
unsigned size = sizeof(ObjCTypeParamType);
@@ -6615,22 +6596,15 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
/// the given object type.
QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
- llvm::FoldingSetNodeID ID;
- ObjCObjectPointerType::Profile(ID, ObjectT);
-
llvm::FoldingSetInsertToken Token;
- if (ObjCObjectPointerType *QT = ObjCObjectPointerTypes.lookup(ID, Token))
+ if (ObjCObjectPointerType *QT = ObjCObjectPointerTypes.lookup(ObjectT, Token))
return QualType(QT, 0);
// Find the canonical object type.
QualType Canonical;
- if (!ObjectT.isCanonical()) {
+ if (!ObjectT.isCanonical())
Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT));
- // Regenerate Token.
- ObjCObjectPointerTypes.lookup(ID, Token);
- }
-
// No match.
void *Mem =
Allocate(sizeof(ObjCObjectPointerType), alignof(ObjCObjectPointerType));
@@ -6818,11 +6792,10 @@ ASTContext::getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
UnderlyingType = QualType();
}
- llvm::FoldingSetNodeID ID;
- UnaryTransformType::Profile(ID, BaseType, UnderlyingType, Kind);
+ auto Key = std::make_tuple(BaseType, UnderlyingType, Kind);
llvm::FoldingSetInsertToken Token;
- if (UnaryTransformType *UT = UnaryTransformTypes.lookup(ID, Token))
+ if (UnaryTransformType *UT = UnaryTransformTypes.lookup(Key, Token))
return QualType(UT, 0);
QualType CanonType;
@@ -6833,11 +6806,6 @@ ASTContext::getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
BaseType != CanonBase) {
CanonType = getUnaryTransformType(CanonBase, QualType(), Kind);
assert(CanonType.isCanonical());
-
- // Find the insertion position again.
- [[maybe_unused]] UnaryTransformType *UT =
- UnaryTransformTypes.lookup(ID, Token);
- assert(!UT && "broken canonicalization");
}
}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 0fd879e69bafc..ebc217adef971 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1486,10 +1486,13 @@ void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
if (Canonical)
T = T.getCanonicalType();
ID.AddInteger(T->getTypeClass());
- if (auto BitIntT = T->getAs<BitIntType>())
- BitIntT->Profile(ID);
- else
+ if (auto BitIntT = T->getAs<BitIntType>()) {
+ auto [IsUnsigned, NumBits] = BitIntT->getKey();
+ ID.AddInteger(IsUnsigned);
+ ID.AddInteger(NumBits);
+ } else {
ID.AddInteger(T->castAs<BuiltinType>()->getKind());
+ }
}
void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4b539b7c2b1f6..480f6d763fa85 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4630,18 +4630,6 @@ SubstTemplateTypeParmType::getReplacedParameter() const {
getReplacedTemplateParameter(getAssociatedDecl(), getIndex())));
}
-void SubstTemplateTypeParmType::Profile(llvm::FoldingSetNodeID &ID,
- QualType Replacement,
- const Decl *AssociatedDecl,
- unsigned Index,
- UnsignedOrNone PackIndex, bool Final) {
- Replacement.Profile(ID);
- ID.AddPointer(AssociatedDecl);
- ID.AddInteger(Index);
- ID.AddInteger(PackIndex.toInternalRepresentation());
- ID.AddBoolean(Final);
-}
-
SubstPackType::SubstPackType(TypeClass Derived, QualType Canon,
const TemplateArgument &ArgPack)
: Type(Derived, Canon,
@@ -4861,22 +4849,6 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {
isKindOfTypeAsWritten());
}
-void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID,
- const ObjCTypeParamDecl *OTPDecl,
- QualType CanonicalType,
- ArrayRef<ObjCProtocolDecl *> protocols) {
- ID.AddPointer(OTPDecl);
- ID.AddPointer(CanonicalType.getAsOpaquePtr());
- ID.AddInteger(protocols.size());
- for (auto *proto : protocols)
- ID.AddPointer(proto);
-}
-
-void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDecl(), getCanonicalTypeInternal(),
- llvm::ArrayRef(qual_begin(), getNumProtocols()));
-}
-
namespace {
/// The cached properties of a type.
``````````
</details>
https://github.com/llvm/llvm-project/pull/221898
More information about the cfe-commits
mailing list