[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