[llvm-branch-commits] [cfe-branch] r122479 - in /cfe/branches/Apple/whitney: include/clang/AST/CanonicalType.h include/clang/AST/Decl.h include/clang/AST/DeclTemplate.h include/clang/AST/Type.h include/clang/Checker/PathSensitive/MemRegion.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp tools/libclang/CXType.cpp
Daniel Dunbar
daniel at zuster.org
Wed Dec 22 21:40:21 PST 2010
Author: ddunbar
Date: Wed Dec 22 23:40:21 2010
New Revision: 122479
URL: http://llvm.org/viewvc/llvm-project?rev=122479&view=rev
Log:
Merge r121489:
--
Author: Douglas Gregor <dgregor at apple.com>
Date: Fri Dec 10 17:03:06 2010 +0000
Eliminate the branching in QualType::getTypePtr() by providing a
common base for ExtQuals and Type that stores the underlying type
pointer. This results in a 2% performance win for -emit-llvm on a
typical C file, with 1% memory growth in the AST.
Note that there is an API change in this optimization:
QualType::getTypePtr() can no longer be invoked on a NULL
QualType. If the QualType might be NULL, use
QualType::getTypePtrOrNull(). I've audited all uses of getTypePtr() in
the code base and changed the appropriate uses over to
getTypePtrOrNull().
A future optimization opportunity would be to distinguish between
cast/dyn_cast and cast_or_null/dyn_cast_or_null; for the former, we
could use getTypePtr() rather than getTypePtrOrNull(), to take another
branch out of the cast/dyn_cast implementation.
*** MANUAL MERGE ***
Modified:
cfe/branches/Apple/whitney/include/clang/AST/CanonicalType.h
cfe/branches/Apple/whitney/include/clang/AST/Decl.h
cfe/branches/Apple/whitney/include/clang/AST/DeclTemplate.h
cfe/branches/Apple/whitney/include/clang/AST/Type.h
cfe/branches/Apple/whitney/include/clang/Checker/PathSensitive/MemRegion.h
cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp
cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
cfe/branches/Apple/whitney/tools/libclang/CXType.cpp
Modified: cfe/branches/Apple/whitney/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/CanonicalType.h?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/CanonicalType.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/CanonicalType.h Wed Dec 22 23:40:21 2010
@@ -66,7 +66,16 @@
/// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type.
- T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
+ ///
+ /// The underlying pointer must not be NULL.
+ T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
+
+ /// \brief Retrieve the underlying type pointer, which refers to a
+ /// canonical type, or NULL.
+ ///
+ T *getTypePtrOrNull() const {
+ return cast_or_null<T>(Stored.getTypePtrOrNull());
+ }
/// \brief Implicit conversion to a qualified type.
operator QualType() const { return Stored; }
@@ -225,7 +234,7 @@
/// @code
/// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
/// @endcode
- operator const T*() const { return this->Stored.getTypePtr(); }
+ operator const T*() const { return this->Stored.getTypePtrOrNull(); }
/// \brief Try to convert the given canonical type to a specific structural
/// type.
@@ -338,7 +347,7 @@
struct simplify_type<const ::clang::CanQual<T> > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) {
- return Val.getTypePtr();
+ return Val.getTypePtrOrNull();
}
};
template<typename T>
Modified: cfe/branches/Apple/whitney/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/Decl.h?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/Decl.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/Decl.h Wed Dec 22 23:40:21 2010
@@ -2212,7 +2212,7 @@
}
/// \brief Set the underlying integer type.
- void setIntegerType(QualType T) { IntegerType = T.getTypePtr(); }
+ void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
/// \brief Set the underlying integer type source info.
void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; }
Modified: cfe/branches/Apple/whitney/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/DeclTemplate.h?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/DeclTemplate.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/DeclTemplate.h Wed Dec 22 23:40:21 2010
@@ -958,7 +958,7 @@
bool Typename, QualType Type, bool ParameterPack)
: TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
- TypeForDecl = Type.getTypePtr();
+ TypeForDecl = Type.getTypePtrOrNull();
}
public:
Modified: cfe/branches/Apple/whitney/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/Type.h?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/Type.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/Type.h Wed Dec 22 23:40:21 2010
@@ -326,7 +326,24 @@
static const uint32_t AddressSpaceShift = 5;
};
-
+/// \brief Base class that is common to both the \c ExtQuals and \c Type
+/// classes, which allows \c QualType to access the common fields between the
+/// two.
+///
+class ExtQualsTypeCommonBase {
+protected:
+ ExtQualsTypeCommonBase(const Type *BaseType) : BaseType(BaseType) { }
+
+ /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
+ /// a self-referential pointer (for \c Type).
+ ///
+ /// This pointer allows an efficient mapping from a QualType to its
+ /// underlying type pointer.
+ const Type *BaseType;
+
+ friend class QualType;
+};
+
/// ExtQuals - We can encode up to three bits in the low bits of a
/// type pointer, but there are many more type qualifiers that we want
/// to be able to apply to an arbitrary type. Therefore we have this
@@ -341,7 +358,7 @@
/// 'restrict' in user code, but many standard C headers are saturated
/// with 'restrict' declarations, so that representing them efficiently
/// is a critical goal of this representation.
-class ExtQuals : public llvm::FoldingSetNode {
+class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
// NOTE: changing the fast qualifiers should be straightforward as
// long as you don't make 'const' non-fast.
// 1. Qualifiers:
@@ -361,16 +378,13 @@
/// be pushed through every single API dealing with qualifiers.
ASTContext& Context;
- /// BaseType - the underlying type that this qualifies
- const Type *BaseType;
-
/// Quals - the immutable set of qualifiers applied by this
/// node; always contains extended qualifiers.
Qualifiers Quals;
public:
ExtQuals(ASTContext& Context, const Type *Base, Qualifiers Quals)
- : Context(Context), BaseType(Base), Quals(Quals)
+ : ExtQualsTypeCommonBase(Base), Context(Context), Quals(Quals)
{
assert(Quals.hasNonFastQualifiers()
&& "ExtQuals created with no fast qualifiers");
@@ -456,10 +470,25 @@
/// Retrieves a pointer to the underlying (unqualified) type.
/// This should really return a const Type, but it's not worth
/// changing all the users right now.
+ ///
+ /// This function requires that the type not be NULL. If the type might be
+ /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
Type *getTypePtr() const {
- if (hasLocalNonFastQualifiers())
- return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
- return const_cast<Type*>(getTypePtrUnsafe());
+ assert(!isNull() && "Cannot retrieve a NULL type pointer");
+ uintptr_t CommonPtrVal
+ = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
+ CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
+ ExtQualsTypeCommonBase *CommonPtr
+ = reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
+ return const_cast<Type *>(CommonPtr->BaseType);
+ }
+
+ Type *getTypePtrOrNull() const {
+ uintptr_t TypePtrPtrVal
+ = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
+ TypePtrPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
+ Type **TypePtrPtr = reinterpret_cast<Type**>(TypePtrPtrVal);
+ return TypePtrPtr? *TypePtrPtr : 0;
}
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
@@ -716,7 +745,7 @@
template<> struct simplify_type<const ::clang::QualType> {
typedef ::clang::Type* SimpleType;
static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
- return Val.getTypePtr();
+ return Val.getTypePtrOrNull();
}
};
template<> struct simplify_type< ::clang::QualType>
@@ -765,7 +794,7 @@
///
/// Types, once created, are immutable.
///
-class Type {
+class Type : public ExtQualsTypeCommonBase {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
@@ -956,7 +985,8 @@
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool Dependent, bool VariablyModified)
- : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical) {
+ : ExtQualsTypeCommonBase(this),
+ CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical) {
TypeBits.TC = tc;
TypeBits.Dependent = Dependent;
TypeBits.VariablyModified = VariablyModified;
Modified: cfe/branches/Apple/whitney/include/clang/Checker/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/Checker/PathSensitive/MemRegion.h?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/Checker/PathSensitive/MemRegion.h (original)
+++ cfe/branches/Apple/whitney/include/clang/Checker/PathSensitive/MemRegion.h Wed Dec 22 23:40:21 2010
@@ -358,7 +358,7 @@
QualType getDesugaredValueType() const {
QualType T = getValueType();
- return T.getTypePtr() ? T.getDesugaredType() : T;
+ return T.getTypePtrOrNull() ? T.getDesugaredType() : T;
}
QualType getDesugaredLocationType() const {
Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReader.cpp Wed Dec 22 23:40:21 2010
@@ -2778,6 +2778,9 @@
}
QualType PointeeType = GetType(Record[0]);
QualType ClassType = GetType(Record[1]);
+ if (PointeeType.isNull() || ClassType.isNull())
+ return QualType();
+
return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
}
@@ -4356,7 +4359,10 @@
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- Type *T = GetType(Record[Idx++]).getTypePtr();
+ Type *T = GetType(Record[Idx++]).getTypePtrOrNull();
+ if (!T)
+ return 0;
+
bool Template = Record[Idx++];
NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
break;
Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp Wed Dec 22 23:40:21 2010
@@ -166,7 +166,7 @@
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
// if we have a fully initialized TypeDecl, we can safely read its type now.
- TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
+ TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// FunctionDecl's body was written last after all other Stmts/Exprs.
if (Record[Idx++])
@@ -441,7 +441,7 @@
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+ ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtrOrNull());
ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
(Reader.GetDecl(Record[Idx++])));
Modified: cfe/branches/Apple/whitney/tools/libclang/CXType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/tools/libclang/CXType.cpp?rev=122479&r1=122478&r2=122479&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/tools/libclang/CXType.cpp (original)
+++ cfe/branches/Apple/whitney/tools/libclang/CXType.cpp Wed Dec 22 23:40:21 2010
@@ -63,7 +63,7 @@
}
static CXTypeKind GetTypeKind(QualType T) {
- Type *TP = T.getTypePtr();
+ Type *TP = T.getTypePtrOrNull();
if (!TP)
return CXType_Invalid;
@@ -186,7 +186,7 @@
CXType clang_getPointeeType(CXType CT) {
QualType T = GetQualType(CT);
- Type *TP = T.getTypePtr();
+ Type *TP = T.getTypePtrOrNull();
if (!TP)
return MakeCXType(QualType(), GetTU(CT));
@@ -217,7 +217,7 @@
return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
QualType T = GetQualType(CT);
- Type *TP = T.getTypePtr();
+ Type *TP = T.getTypePtrOrNull();
if (!TP)
return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
@@ -254,7 +254,7 @@
// FIXME: Template type parameters!
case Type::Elaborated:
- TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtr();
+ TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
goto try_again;
default:
@@ -324,7 +324,7 @@
CXType clang_getResultType(CXType X) {
QualType T = GetQualType(X);
- if (!T.getTypePtr())
+ if (!T.getTypePtrOrNull())
return MakeCXType(QualType(), GetTU(X));
if (const FunctionType *FD = T->getAs<FunctionType>())
@@ -347,7 +347,7 @@
unsigned clang_isPODType(CXType X) {
QualType T = GetQualType(X);
- if (!T.getTypePtr())
+ if (!T.getTypePtrOrNull())
return 0;
return T->isPODType() ? 1 : 0;
}
More information about the llvm-branch-commits
mailing list