[cfe-commits] r117750 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h include/clang/Lex/ExternalPreprocessorSource.h include/clang/Lex/Preprocessor.h include/clang/Serialization/ASTReader.h lib/Lex/PPMacroExpansion.cpp lib/Serialization/ASTReader.cpp

Douglas Gregor dgregor at apple.com
Fri Oct 29 17:23:06 PDT 2010


Author: dgregor
Date: Fri Oct 29 19:23:06 2010
New Revision: 117750

URL: http://llvm.org/viewvc/llvm-project?rev=117750&view=rev
Log:
Make the deserialization of macro definitions lazy, so that we can
load identifiers without loading their corresponding macro
definitions. This is likely to improve PCH performance slightly, and
reduces deserialization stack depth considerably when using
preprocessor metaprogramming.

Modified:
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Fri Oct 29 19:23:06 2010
@@ -71,7 +71,7 @@
   void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
 
   friend class IdentifierTable;
-
+  
 public:
   IdentifierInfo();
 

Modified: cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h (original)
+++ cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h Fri Oct 29 19:23:06 2010
@@ -27,6 +27,9 @@
   
   /// \brief Read the set of macros defined by this external macro source.
   virtual void ReadDefinedMacros() = 0;
+  
+  /// \brief Read the definition for the given macro.
+  virtual void LoadMacroDefinition(IdentifierInfo *II) = 0;
 };
   
 }

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Oct 29 19:23:06 2010
@@ -262,6 +262,8 @@
   /// allocation.
   MacroInfoChain *MICache;
 
+  MacroInfo *getInfoForMacro(IdentifierInfo *II) const;
+  
 public:
   Preprocessor(Diagnostic &diags, const LangOptions &opts,
                const TargetInfo &target,
@@ -335,7 +337,10 @@
   /// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to
   /// or null if it isn't #define'd.
   MacroInfo *getMacroInfo(IdentifierInfo *II) const {
-    return II->hasMacroDefinition() ? Macros.find(II)->second : 0;
+    if (!II->hasMacroDefinition())
+      return 0;
+    
+    return getInfoForMacro(II);
   }
 
   /// setMacroInfo - Specify a macro for this identifier.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Oct 29 19:23:06 2010
@@ -488,6 +488,11 @@
   /// \brief The macro definitions we have already loaded.
   llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded;
 
+  /// \brief Mapping from identifiers that represent macros whose definitions
+  /// have not yet been deserialized to the global offset where the macro
+  /// record resides.
+  llvm::DenseMap<IdentifierInfo *, uint64_t> UnreadMacroRecordOffsets;
+      
   /// \name CodeGen-relevant special data
   /// \brief Fields containing data that is relevant to CodeGen.
   //@{
@@ -1145,9 +1150,22 @@
   /// \brief Reads the macro record located at the given offset.
   void ReadMacroRecord(PerFileData &F, uint64_t Offset);
 
+  /// \brief Note that the identifier is a macro whose record will be loaded
+  /// from the given AST file at the given (file-local) offset.
+  void SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F,
+                            uint64_t Offset);
+      
   /// \brief Read the set of macros defined by this external macro source.
   virtual void ReadDefinedMacros();
 
+  /// \brief Read the macro definition for this identifier.
+  virtual void LoadMacroDefinition(IdentifierInfo *II);
+
+  /// \brief Read the macro definition corresponding to this iterator
+  /// into the unread macro record offsets table.
+  void LoadMacroDefinition(
+                     llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos);
+      
   /// \brief Retrieve the macro definition with the given ID.
   MacroDefinition *getMacroDefinition(serialization::MacroID ID);
 

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Oct 29 19:23:06 2010
@@ -20,12 +20,27 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
 #include <ctime>
 using namespace clang;
 
+MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const {
+  assert(II->hasMacroDefinition() && "Identifier is not a macro!");
+  
+  llvm::DenseMap<IdentifierInfo*, MacroInfo*>::const_iterator Pos
+    = Macros.find(II);
+  if (Pos == Macros.end()) {
+    // Load this macro from the external source.
+    getExternalSource()->LoadMacroDefinition(II);
+    Pos = Macros.find(II);
+  }
+  assert(Pos != Macros.end() && "Identifier macro info is missing!");
+  return Pos->second;
+}
+
 /// setMacroInfo - Specify a macro for this identifier.
 ///
 void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=117750&r1=117749&r2=117750&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Oct 29 19:23:06 2010
@@ -682,7 +682,7 @@
     // definition.
     if (hasMacroDefinition) {
       uint32_t Offset = ReadUnalignedLE32(d);
-      Reader.ReadMacroRecord(F, Offset);
+      Reader.SetIdentifierIsMacro(II, F, Offset);
       DataLen -= 4;
     }
 
@@ -1568,6 +1568,22 @@
   }
 }
 
+void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F,
+                                     uint64_t Offset) {
+  // Note that this identifier has a macro definition.
+  II->setHasMacroDefinition(true);
+  
+  // Adjust the offset based on our position in the chain.
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    if (Chain[I] == &F)
+      break;
+    
+    Offset += Chain[I]->SizeInBits;
+  }
+    
+  UnreadMacroRecordOffsets[II] = Offset;
+}
+
 void ASTReader::ReadDefinedMacros() {
   for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
     PerFileData &F = *Chain[N - I - 1];
@@ -1629,6 +1645,39 @@
       }
     }
   }
+  
+  // Drain the unread macro-record offsets map.
+  while (!UnreadMacroRecordOffsets.empty())
+    LoadMacroDefinition(UnreadMacroRecordOffsets.begin());
+}
+
+void ASTReader::LoadMacroDefinition(
+                     llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) {
+  assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition");
+  PerFileData *F = 0;
+  uint64_t Offset = Pos->second;
+  UnreadMacroRecordOffsets.erase(Pos);
+  
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    if (Offset < Chain[I]->SizeInBits) {
+      F = Chain[I];
+      break;
+    }
+    
+    Offset -= Chain[I]->SizeInBits;
+  }    
+  if (!F) {
+    Error("Malformed macro record offset");
+    return;
+  }
+  
+  ReadMacroRecord(*F, Offset);
+}
+
+void ASTReader::LoadMacroDefinition(IdentifierInfo *II) {
+  llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos
+    = UnreadMacroRecordOffsets.find(II);
+  LoadMacroDefinition(Pos);
 }
 
 MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {





More information about the cfe-commits mailing list