r209482 - Avoid allocating extra memory to handle the lazy definition data pointer for

Richard Smith richard-llvm at metafoo.co.uk
Thu May 22 16:19:02 PDT 2014


Author: rsmith
Date: Thu May 22 18:19:02 2014
New Revision: 209482

URL: http://llvm.org/viewvc/llvm-project?rev=209482&view=rev
Log:
Avoid allocating extra memory to handle the lazy definition data pointer for
CXXRecordDecls when modules is enabled.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=209482&r1=209481&r2=209482&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu May 22 18:19:02 2014
@@ -257,10 +257,31 @@ public:
   TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
 };
 
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+  llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+  LazyDefinitionDataPtr update() {
+    if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+      if (Canon->isCanonicalDecl())
+        Canon->getMostRecentDecl();
+      else
+        // Declaration isn't canonical any more;
+        // update it and perform path compression.
+        *this = Canon->getPreviousDecl()->DefinitionData.update();
+    }
+    return *this;
+  }
+
+public:
+  LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+  LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+  T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+  T *get() { return update().getNotUpdated(); }
+};
+
 /// \brief Represents a C++ struct/union/class.
-///
-/// FIXME: This class will disappear once we've properly taught RecordDecl
-/// to deal with C++-specific things.
 class CXXRecordDecl : public RecordDecl {
 
   friend void TagDecl::startDefinition();
@@ -496,9 +517,9 @@ class CXXRecordDecl : public RecordDecl
     CXXBaseSpecifier *getVBasesSlowCase() const;
   };
 
-  typedef LazyGenerationalUpdatePtr<const Decl*, struct DefinitionData*,
-                                    &ExternalASTSource::CompleteRedeclChain>
+  typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
       DefinitionDataPtr;
+  friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
 
   mutable DefinitionDataPtr DefinitionData;
 
@@ -558,7 +579,7 @@ class CXXRecordDecl : public RecordDecl
   };
 
   struct DefinitionData &data() const {
-    auto *DD = DefinitionData.get(this);
+    auto *DD = DefinitionData.get();
     assert(DD && "queried property of class with no definition");
     return *DD;
   }
@@ -643,11 +664,11 @@ public:
   }
 
   CXXRecordDecl *getDefinition() const {
-    auto *DD = DefinitionData.get(this);
+    auto *DD = DefinitionData.get();
     return DD ? DD->Definition : nullptr;
   }
 
-  bool hasDefinition() const { return DefinitionData.get(this); }
+  bool hasDefinition() const { return DefinitionData.get(); }
 
   static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation StartLoc, SourceLocation IdLoc,

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=209482&r1=209481&r2=209482&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu May 22 18:19:02 2014
@@ -3240,7 +3240,7 @@ void TagDecl::startDefinition() {
     struct CXXRecordDecl::DefinitionData *Data =
       new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
     for (auto I : redecls())
-      cast<CXXRecordDecl>(I)->DefinitionData.setNotUpdated(Data);
+      cast<CXXRecordDecl>(I)->DefinitionData = Data;
   }
 }
 

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=209482&r1=209481&r2=209482&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu May 22 18:19:02 2014
@@ -88,7 +88,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, Tag
                              CXXRecordDecl *PrevDecl)
     : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
       DefinitionData(PrevDecl ? PrevDecl->DefinitionData
-                              : DefinitionDataPtr(C)),
+                              : DefinitionDataPtr(this)),
       TemplateOrInstantiation() {}
 
 CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
@@ -115,9 +115,9 @@ CXXRecordDecl::CreateLambda(const ASTCon
       new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
                                 nullptr, nullptr);
   R->IsBeingDefined = true;
-  R->DefinitionData.setNotUpdated(
+  R->DefinitionData =
       new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
-                                          CaptureDefault));
+                                          CaptureDefault);
   R->MayHaveOutOfDateDef = false;
   R->setImplicit(true);
   C.getTypeDeclType(R, /*PrevDecl=*/nullptr);

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=209482&r1=209481&r2=209482&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu May 22 18:19:02 2014
@@ -1405,7 +1405,7 @@ void ASTDeclReader::ReadCXXRecordDefinit
   // that all other deserialized declarations will see it.
   CXXRecordDecl *Canon = D->getCanonicalDecl();
   if (Canon == D) {
-    D->DefinitionData.setNotUpdated(DD);
+    D->DefinitionData = DD;
     D->IsCompleteDefinition = true;
   } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
     // We have already deserialized a definition of this record. This
@@ -1417,7 +1417,7 @@ void ASTDeclReader::ReadCXXRecordDefinit
     D->IsCompleteDefinition = false;
     MergeDefinitionData(D, *DD);
   } else {
-    Canon->DefinitionData.setNotUpdated(DD);
+    Canon->DefinitionData = DD;
     D->DefinitionData = Canon->DefinitionData;
     D->IsCompleteDefinition = true;
 





More information about the cfe-commits mailing list