[cfe-commits] r104139 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/Type.h lib/AST/Decl.cpp lib/AST/Type.cpp
Douglas Gregor
dgregor at apple.com
Wed May 19 11:39:19 PDT 2010
Author: dgregor
Date: Wed May 19 13:39:18 2010
New Revision: 104139
URL: http://llvm.org/viewvc/llvm-project?rev=104139&view=rev
Log:
Cache the linkage of a type within its canonical type, eliminating
some seriously non-linear performance with deeply nested template
instantiations, as shown in PR6998.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/Type.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=104139&r1=104138&r2=104139&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed May 19 13:39:18 2010
@@ -1807,8 +1807,9 @@
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
}
- void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
-
+
+ void setTypedefForAnonDecl(TypedefDecl *TDD);
+
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
}
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=104139&r1=104138&r2=104139&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed May 19 13:39:18 2010
@@ -768,15 +768,25 @@
/// Note that this should stay at the end of the ivars for Type so that
/// subclasses can pack their bitfields into the same word.
bool Dependent : 1;
-
+
+ /// \brief Whether the linkage of this type is already known.
+ mutable bool LinkageKnown : 1;
+
+ /// \brief Linkage of this type.
+ mutable unsigned CachedLinkage : 2;
+
protected:
- enum { BitsRemainingInType = 23 };
+ /// \brief Compute the linkage of this type.
+ virtual Linkage getLinkageImpl() const;
+
+ enum { BitsRemainingInType = 20 };
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
- TC(tc), Dependent(dependent) {}
+ TC(tc), Dependent(dependent), LinkageKnown(false),
+ CachedLinkage(NoLinkage) {}
virtual ~Type() {}
virtual void Destroy(ASTContext& C);
friend class ASTContext;
@@ -977,10 +987,13 @@
/// set of type specifiers.
bool isSpecifierType() const;
- const char *getTypeClassName() const;
-
/// \brief Determine the linkage of this type.
- virtual Linkage getLinkage() const;
+ Linkage getLinkage() const;
+
+ /// \brief Note that the linkage is no longer known.
+ void ClearLinkageCache();
+
+ const char *getTypeClassName() const;
QualType getCanonicalTypeInternal() const {
return CanonicalType;
@@ -1055,6 +1068,10 @@
};
private:
Kind TypeKind;
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent)),
@@ -1082,8 +1099,6 @@
return TypeKind >= Float && TypeKind <= LongDouble;
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@@ -1098,6 +1113,10 @@
ElementType(Element) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
@@ -1111,8 +1130,6 @@
ID.AddPointer(Element.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
static bool classof(const ComplexType *) { return true; }
};
@@ -1126,6 +1143,10 @@
Type(Pointer, CanonicalPtr, Pointee->isDependentType()), PointeeType(Pointee) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1140,8 +1161,6 @@
ID.AddPointer(Pointee.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
static bool classof(const PointerType *) { return true; }
};
@@ -1157,6 +1176,10 @@
PointeeType(Pointee) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
// Get the pointee type. Pointee is required to always be a function type.
@@ -1172,8 +1195,6 @@
ID.AddPointer(Pointee.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
@@ -1209,6 +1230,9 @@
PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
InnerRef(Referencee->isReferenceType()) {
}
+
+ virtual Linkage getLinkageImpl() const;
+
public:
bool isSpelledAsLValue() const { return SpelledAsLValue; }
bool isInnerRef() const { return InnerRef; }
@@ -1232,8 +1256,6 @@
ID.AddBoolean(SpelledAsLValue);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
@@ -1290,6 +1312,10 @@
PointeeType(Pointee), Class(Cls) {
}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1308,8 +1334,6 @@
ID.AddPointer(Class);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
@@ -1351,6 +1375,9 @@
ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
ArraySizeModifier getSizeModifier() const {
@@ -1361,8 +1388,6 @@
}
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
@@ -1638,6 +1663,9 @@
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
+
+ virtual Linkage getLinkageImpl() const;
+
public:
QualType getElementType() const { return ElementType; }
@@ -1664,8 +1692,6 @@
ID.AddBoolean(isPixel);
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
@@ -1873,6 +1899,10 @@
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
/*Dependent=*/false, Info) {}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
// No additional state past what FunctionType provides.
@@ -1890,8 +1920,6 @@
ID.AddPointer(ResultType.getAsOpaquePtr());
}
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
@@ -1955,6 +1983,9 @@
friend class ASTContext; // ASTContext creates these.
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
unsigned getNumArgs() const { return NumArgs; }
QualType getArgType(unsigned i) const {
@@ -1995,8 +2026,6 @@
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
@@ -2201,6 +2230,8 @@
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
+ virtual Linkage getLinkageImpl() const;
+
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@@ -2209,8 +2240,6 @@
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
- virtual Linkage getLinkage() const;
-
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2813,6 +2842,9 @@
NumProtocols(0),
BaseType(QualType(this_(), 0)) {}
+protected:
+ Linkage getLinkageImpl() const; // key function
+
public:
/// getBaseType - Gets the base type of this object type. This is
/// always (possibly sugar for) one of:
@@ -2864,8 +2896,6 @@
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- Linkage getLinkage() const; // key function
-
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObject ||
T->getTypeClass() == ObjCInterface;
@@ -2974,6 +3004,9 @@
PointeeType(Pointee) {}
friend class ASTContext; // ASTContext creates these.
+protected:
+ virtual Linkage getLinkageImpl() const;
+
public:
void Destroy(ASTContext& C);
@@ -3076,8 +3109,6 @@
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual Linkage getLinkage() const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType());
}
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=104139&r1=104138&r2=104139&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed May 19 13:39:18 2010
@@ -1469,6 +1469,12 @@
return getFirstDeclaration();
}
+void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) {
+ TypedefDeclOrQualifier = TDD;
+ if (TypeForDecl)
+ TypeForDecl->ClearLinkageCache();
+}
+
void TagDecl::startDefinition() {
if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
TagT->decl.setPointer(this);
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=104139&r1=104138&r2=104139&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed May 19 13:39:18 2010
@@ -1163,23 +1163,40 @@
Profile(ID, getBaseType(), qual_begin(), getNumProtocols());
}
-Linkage Type::getLinkage() const {
- // C++ [basic.link]p8:
- // Names not covered by these rules have no linkage.
+/// \brief Determine the linkage of this type.
+Linkage Type::getLinkage() const {
if (this != CanonicalType.getTypePtr())
return CanonicalType->getLinkage();
+
+ if (!LinkageKnown) {
+ CachedLinkage = getLinkageImpl();
+ LinkageKnown = true;
+ }
+
+ return static_cast<clang::Linkage>(CachedLinkage);
+}
+Linkage Type::getLinkageImpl() const {
+ // C++ [basic.link]p8:
+ // Names not covered by these rules have no linkage.
return NoLinkage;
}
-Linkage BuiltinType::getLinkage() const {
+void Type::ClearLinkageCache() {
+ if (this != CanonicalType.getTypePtr())
+ CanonicalType->ClearLinkageCache();
+ else
+ LinkageKnown = false;
+}
+
+Linkage BuiltinType::getLinkageImpl() const {
// C++ [basic.link]p8:
// A type is said to have linkage if and only if:
// - it is a fundamental type (3.9.1); or
return ExternalLinkage;
}
-Linkage TagType::getLinkage() const {
+Linkage TagType::getLinkageImpl() const {
// C++ [basic.link]p8:
// - it is a class or enumeration type that is named (or has a name for
// linkage purposes (7.1.3)) and the name has linkage; or
@@ -1190,39 +1207,39 @@
// C++ [basic.link]p8:
// - it is a compound type (3.9.2) other than a class or enumeration,
// compounded exclusively from types that have linkage; or
-Linkage ComplexType::getLinkage() const {
+Linkage ComplexType::getLinkageImpl() const {
return ElementType->getLinkage();
}
-Linkage PointerType::getLinkage() const {
+Linkage PointerType::getLinkageImpl() const {
return PointeeType->getLinkage();
}
-Linkage BlockPointerType::getLinkage() const {
+Linkage BlockPointerType::getLinkageImpl() const {
return PointeeType->getLinkage();
}
-Linkage ReferenceType::getLinkage() const {
+Linkage ReferenceType::getLinkageImpl() const {
return PointeeType->getLinkage();
}
-Linkage MemberPointerType::getLinkage() const {
+Linkage MemberPointerType::getLinkageImpl() const {
return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
}
-Linkage ArrayType::getLinkage() const {
+Linkage ArrayType::getLinkageImpl() const {
return ElementType->getLinkage();
}
-Linkage VectorType::getLinkage() const {
+Linkage VectorType::getLinkageImpl() const {
return ElementType->getLinkage();
}
-Linkage FunctionNoProtoType::getLinkage() const {
+Linkage FunctionNoProtoType::getLinkageImpl() const {
return getResultType()->getLinkage();
}
-Linkage FunctionProtoType::getLinkage() const {
+Linkage FunctionProtoType::getLinkageImpl() const {
Linkage L = getResultType()->getLinkage();
for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
A != AEnd; ++A)
@@ -1231,10 +1248,10 @@
return L;
}
-Linkage ObjCObjectType::getLinkage() const {
+Linkage ObjCObjectType::getLinkageImpl() const {
return ExternalLinkage;
}
-Linkage ObjCObjectPointerType::getLinkage() const {
+Linkage ObjCObjectPointerType::getLinkageImpl() const {
return ExternalLinkage;
}
More information about the cfe-commits
mailing list