[cfe-commits] r69815 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Builtins.h include/clang/Frontend/PCHWriter.h lib/AST/ASTContext.cpp lib/AST/Builtins.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp tools/clang-cc/clang-cc.cpp

Douglas Gregor dgregor at apple.com
Wed Apr 22 11:49:14 PDT 2009


Author: dgregor
Date: Wed Apr 22 13:49:13 2009
New Revision: 69815

URL: http://llvm.org/viewvc/llvm-project?rev=69815&view=rev
Log:
Lazy loading of builtins for precompiled headers.

PCH files now contain complete information about builtins, including
any declarations that have been synthesized as part of building the
PCH file. When using a PCH file, we do not initialize builtins at all;
when needed, they'll be found in the PCH file.

This optimization translations into a 9% speedup for "Hello, World!"
with Carbon.h as a prefix header and roughly a 5% speedup for 403.gcc
with its prefix header. We're also reading less of the PCH file for
"Hello, World!":

*** PCH Statistics:
  286/20693 types read (1.382110%)
  1630/59230 declarations read (2.751984%)
  764/44914 identifiers read (1.701029%)
  1/32954 statements read (0.003035%)
  5/6187 macros read (0.080815%)

down from

*** PCH Statistics:
  411/20693 types read (1.986179%)
  2553/59230 declarations read (4.310316%)
  1093/44646 identifiers read (2.448148%)
  1/32954 statements read (0.003035%)
  21/6187 macros read (0.339421%)


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Builtins.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Builtins.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/tools/clang-cc/clang-cc.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Apr 22 13:49:13 2009
@@ -170,6 +170,8 @@
   /// This is intentionally not serialized.  It is populated by the
   /// ASTContext ctor, and there are no external pointers/references to
   /// internal variables of BuiltinInfo.
+  // FIXME: PCH does serialize this information, so that we don't have to
+  // construct it again when the PCH is loaded.
   Builtin::Context BuiltinInfo;
 
   // Builtin Types.
@@ -188,10 +190,20 @@
 
   ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
              IdentifierTable &idents, SelectorTable &sels, 
-             bool FreeMemory = true, unsigned size_reserve=0);
+             bool FreeMemory = true, unsigned size_reserve=0,
+             bool InitializeBuiltins = true);
 
   ~ASTContext();
 
+  /// \brief Initialize builtins.
+  ///
+  /// Typically, this routine will be called automatically by the
+  /// constructor. However, in certain cases (e.g., when there is a
+  /// PCH file to be loaded), the constructor does not perform
+  /// initialization for builtins. This routine can be called to
+  /// perform the initialization.
+  void InitializeBuiltins(IdentifierTable &idents);
+
   /// \brief Attach an external AST source to the AST context.
   ///
   /// The external AST source provides the ability to load parts of

Modified: cfe/trunk/include/clang/AST/Builtins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Builtins.h?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Builtins.h (original)
+++ cfe/trunk/include/clang/AST/Builtins.h Wed Apr 22 13:49:13 2009
@@ -17,6 +17,7 @@
 
 #include <cstring>
 #include <string>
+#include "llvm/ADT/SmallVector.h"
 
 namespace clang {
   class TargetInfo;
@@ -60,6 +61,10 @@
   /// appropriate builtin ID # and mark any non-portable builtin identifiers as
   /// such.
   void InitializeBuiltins(IdentifierTable &Table, bool NoBuiltins = false);
+
+  /// \brief Popular the vector with the names of all of the builtins.
+  void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+                       bool NoBuiltins);
   
   /// Builtin::GetName - Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Wed Apr 22 13:49:13 2009
@@ -171,6 +171,10 @@
   /// \brief Emit a reference to an identifier
   void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
 
+  /// \brief Get the unique number used to refer to the given
+  /// identifier.
+  pch::IdentID getIdentifierRef(const IdentifierInfo *II);
+
   /// \brief Retrieve the offset of the macro definition for the given
   /// identifier.
   ///

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Apr 22 13:49:13 2009
@@ -34,16 +34,17 @@
 ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
                        TargetInfo &t,
                        IdentifierTable &idents, SelectorTable &sels,
-                       bool FreeMem, unsigned size_reserve) : 
+                       bool FreeMem, unsigned size_reserve,
+                       bool InitializeBuiltins) : 
   GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0), 
   ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts), 
   FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels),
   ExternalSource(0) {  
   if (size_reserve > 0) Types.reserve(size_reserve);    
   InitBuiltinTypes();
-  BuiltinInfo.InitializeTargetBuiltins(Target);
-  BuiltinInfo.InitializeBuiltins(idents, LangOpts.NoBuiltin);
   TUDecl = TranslationUnitDecl::Create(*this);
+  if (InitializeBuiltins)
+    this->InitializeBuiltins(idents);
 }
 
 ASTContext::~ASTContext() {
@@ -94,6 +95,11 @@
   TUDecl->Destroy(*this);
 }
 
+void ASTContext::InitializeBuiltins(IdentifierTable &idents) {
+  BuiltinInfo.InitializeTargetBuiltins(Target);
+  BuiltinInfo.InitializeBuiltins(idents, LangOpts.NoBuiltin);
+}
+
 void 
 ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) {
   ExternalSource.reset(Source.take());

Modified: cfe/trunk/lib/AST/Builtins.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Builtins.cpp?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Builtins.cpp (original)
+++ cfe/trunk/lib/AST/Builtins.cpp Wed Apr 22 13:49:13 2009
@@ -58,6 +58,24 @@
       Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
 }
 
+void 
+Builtin::Context::GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+                                  bool NoBuiltins) {
+  // Final all target-independent names
+  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
+    if (!BuiltinInfo[i].Suppressed &&
+        (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f')))
+      Names.push_back(BuiltinInfo[i].Name);
+  
+  // Find target-specific names.
+  for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
+    if (!TSRecords[i].Suppressed &&
+        (!NoBuiltins || 
+         (TSRecords[i].Attributes && 
+          !strchr(TSRecords[i].Attributes, 'f'))))
+      Names.push_back(TSRecords[i].Name);
+}
+
 bool 
 Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx, 
                                bool &HasVAListArg) {

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Apr 22 13:49:13 2009
@@ -1110,10 +1110,21 @@
                            unsigned DataLen) {
     using namespace clang::io;
     uint32_t Bits = ReadUnalignedLE32(d); // FIXME: use these?
-    (void)Bits;
-    bool hasMacroDefinition = (Bits >> 3) & 0x01;
-    
+    bool CPlusPlusOperatorKeyword = Bits & 0x01;
+    Bits >>= 1;
+    bool Poisoned = Bits & 0x01;
+    Bits >>= 1;
+    bool ExtensionToken = Bits & 0x01;
+    Bits >>= 1;
+    bool hasMacroDefinition = Bits & 0x01;
+    Bits >>= 1;
+    unsigned ObjCOrBuiltinID = Bits & 0x3FF;
+    Bits >>= 10;
+    unsigned TokenID = Bits & 0xFF;
+    Bits >>= 8;
+
     pch::IdentID ID = ReadUnalignedLE32(d);
+    assert(Bits == 0 && "Extra bits in the identifier?");
     DataLen -= 8;
 
     // Build the IdentifierInfo itself and link the identifier ID with
@@ -1124,6 +1135,20 @@
                                                  k.first, k.first + k.second);
     Reader.SetIdentifierInfo(ID, II);
 
+    // Set or check the various bits in the IdentifierInfo structure.
+    // FIXME: Load token IDs lazily, too?
+    assert((unsigned)II->getTokenID() == TokenID && 
+           "Incorrect token ID loaded"); 
+    (void)TokenID;
+    II->setObjCOrBuiltinID(ObjCOrBuiltinID);
+    assert(II->isExtensionToken() == ExtensionToken && 
+           "Incorrect extension token flag");
+    (void)ExtensionToken;
+    II->setIsPoisoned(Poisoned);
+    assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
+           "Incorrect C++ operator keyword flag");
+    (void)CPlusPlusOperatorKeyword;
+
     // If this identifier is a macro, deserialize the macro
     // definition.
     if (hasMacroDefinition) {

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Apr 22 13:49:13 2009
@@ -1800,8 +1800,8 @@
       II->hasMacroDefinition() && 
       !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro();
     Bits = Bits | (uint32_t)II->getTokenID();
-    Bits = (Bits << 8) | (uint32_t)II->getObjCOrBuiltinID();
-    Bits = (Bits << 10) | hasMacroDefinition;
+    Bits = (Bits << 10) | (uint32_t)II->getObjCOrBuiltinID();
+    Bits = (Bits << 1) | hasMacroDefinition;
     Bits = (Bits << 1) | II->isExtensionToken();
     Bits = (Bits << 1) | II->isPoisoned();
     Bits = (Bits << 1) | II->isCPlusPlusOperatorKeyword();
@@ -2028,6 +2028,17 @@
   DeclIDs[Context.getTranslationUnitDecl()] = 1;
   DeclsToEmit.push(Context.getTranslationUnitDecl());
 
+  // Make sure that we emit IdentifierInfos (and any attached
+  // declarations) for builtins.
+  {
+    IdentifierTable &Table = PP.getIdentifierTable();
+    llvm::SmallVector<const char *, 32> BuiltinNames;
+    Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
+                                        Context.getLangOptions().NoBuiltin);
+    for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
+      getIdentifierRef(&Table.get(BuiltinNames[I]));
+  }
+
   // Write the remaining PCH contents.
   RecordData Record;
   Stream.EnterSubblock(pch::PCH_BLOCK_ID, 3);
@@ -2079,16 +2090,17 @@
 }
 
 void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
-  if (II == 0) {
-    Record.push_back(0);
-    return;
-  }
+  Record.push_back(getIdentifierRef(II));
+}
+
+pch::IdentID PCHWriter::getIdentifierRef(const IdentifierInfo *II) {
+  if (II == 0)
+    return 0;
 
   pch::IdentID &ID = IdentifierIDs[II];
   if (ID == 0)
     ID = IdentifierIDs.size();
-  
-  Record.push_back(ID);
+  return ID;
 }
 
 void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {

Modified: cfe/trunk/tools/clang-cc/clang-cc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/clang-cc.cpp?rev=69815&r1=69814&r2=69815&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/clang-cc.cpp (original)
+++ cfe/trunk/tools/clang-cc/clang-cc.cpp Wed Apr 22 13:49:13 2009
@@ -1760,7 +1760,9 @@
                                       PP.getTargetInfo(),
                                       PP.getIdentifierTable(),
                                       PP.getSelectorTable(),
-                                      /* FreeMemory = */ !DisableFree));
+                                      /* FreeMemory = */ !DisableFree,
+                                      /* size_reserve = */0,
+                       /* InitializeBuiltins = */ImplicitIncludePCH.empty()));
     
     if (!ImplicitIncludePCH.empty()) {
       // The user has asked us to include a precompiled header. Load
@@ -1788,6 +1790,11 @@
       case PCHReader::IgnorePCH:
         // No suitable PCH file could be found. Just ignore the
         // -include-pch option entirely.
+        
+        // We delayed the initialization of builtins in the hope of
+        // loading the PCH file. Since the PCH file could not be
+        // loaded, initialize builtins now.
+        ContextOwner->InitializeBuiltins(PP.getIdentifierTable());
         break;
       }
 





More information about the cfe-commits mailing list