[cfe-commits] r60911 - in /cfe/trunk: Driver/CacheTokens.cpp lib/Lex/PTHLexer.cpp

Ted Kremenek kremenek at apple.com
Thu Dec 11 15:36:40 PST 2008


Author: kremenek
Date: Thu Dec 11 17:36:38 2008
New Revision: 60911

URL: http://llvm.org/viewvc/llvm-project?rev=60911&view=rev
Log:
PTH:
- Added a side-table per each token-cached file with the preprocessor conditional stack.  This tracks what #if's are matched with what #endifs and where their respective tokens are in the PTH file.  This will allow for quick skipping of excluded conditional branches in the Preprocessor.
- Performance testing shows the addition of this information (without actually utilizing it) leads to no performance regressions.

Modified:
    cfe/trunk/Driver/CacheTokens.cpp
    cfe/trunk/lib/Lex/PTHLexer.cpp

Modified: cfe/trunk/Driver/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/CacheTokens.cpp?rev=60911&r1=60910&r2=60911&view=diff

==============================================================================
--- cfe/trunk/Driver/CacheTokens.cpp (original)
+++ cfe/trunk/Driver/CacheTokens.cpp Thu Dec 11 17:36:38 2008
@@ -27,7 +27,7 @@
 
 typedef uint32_t Offset;
 
-typedef llvm::DenseMap<const FileEntry*,Offset> PCHMap;
+typedef llvm::DenseMap<const FileEntry*,std::pair<Offset,Offset> > PCHMap;
 typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap;
 
 static void Emit32(llvm::raw_ostream& Out, uint32_t V) {
@@ -140,18 +140,25 @@
     unsigned size = strlen(Name);
     Emit32(Out, size);
     EmitBuf(Out, Name, Name+size);
-    Emit32(Out, I->second);    
+    Emit32(Out, I->second.first);
+    Emit32(Out, I->second.second);
   }
 
   return off;
 }
 
-static Offset LexTokens(llvm::raw_fd_ostream& Out, Lexer& L, Preprocessor& PP,
-                        uint32_t& idcount, IDMap& IM) {
+static std::pair<Offset,Offset>
+LexTokens(llvm::raw_fd_ostream& Out, Lexer& L, Preprocessor& PP,
+          uint32_t& idcount, IDMap& IM) {
   
   // Record the location within the token file.
   Offset off = (Offset) Out.tell();
   SourceManager& SMgr = PP.getSourceManager();
+  
+  // Keep track of matching '#if' ... '#endif'.
+  typedef std::vector<std::pair<Offset, unsigned> > PPCondTable;
+  PPCondTable PPCond;
+  std::vector<unsigned> PPStartCond;  
 
   Token Tok;
   
@@ -164,6 +171,7 @@
     else if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
       // Special processing for #include.  Store the '#' token and lex
       // the next token.
+      Offset HashOff = (Offset) Out.tell();
       EmitToken(Out, Tok, SMgr, idcount, IM);
       L.LexFromRawLexer(Tok);
       
@@ -189,11 +197,52 @@
         if (Tok.is(tok::identifier))
           Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok));
       }
+      else if (K == tok::pp_if || K == tok::pp_ifdef || K == tok::pp_ifndef) {
+        // Ad an entry for '#if' and friends.  We initially set the target index
+        // to 0.  This will get backpatched when we hit #endif.
+        PPStartCond.push_back(PPCond.size());
+        PPCond.push_back(std::make_pair((Offset) HashOff, 0U));
+      }
+      else if (K == tok::pp_endif) {
+        assert(!PPStartCond.empty());        
+        // Add an entry for '#endif'.  We set the target table index to itself.
+        unsigned index = PPCond.size();
+        PPCond.push_back(std::make_pair((Offset) HashOff, index));        
+        // Backpatch the opening '#if' entry.
+        assert(PPCond[PPStartCond.back()].second == 0);
+        PPCond[PPStartCond.back()].second = index;
+        PPStartCond.pop_back();        
+      }
+      else if (K == tok::pp_elif) {
+        assert(!PPStartCond.empty());
+        // Add an entry for '#elif'.  This serves as both a closing and
+        // opening of a conditional block.  This means that its entry
+        // will get backpatched later.
+        unsigned index = PPCond.size();
+        PPCond.push_back(std::make_pair((Offset) HashOff, 0U));
+        // Backpatch the previous '#if' entry.
+        assert(PPCond[PPStartCond.back()].second == 0);
+        PPCond[PPStartCond.back()].second = index;
+        PPStartCond.pop_back();
+        // Now add '#elif' as a new block opening.
+        PPStartCond.push_back(index);        
+      }
     }    
   }
   while (EmitToken(Out, Tok, SMgr, idcount, IM), Tok.isNot(tok::eof));
+  
+  // Next write out PPCond.
+  Offset PPCondOff = (Offset) Out.tell();
+  // Write out the size of PPCond so that clients can tell if the table is
+  // empty.
+  Emit32(Out, PPCond.size());
+
+  for (PPCondTable::iterator I=PPCond.begin(), E=PPCond.end(); I!=E; ++I) {
+    Emit32(Out, I->first - off);
+    Emit32(Out, I->second);
+  }
 
-  return off;
+  return std::make_pair(off,PPCondOff);
 }
 
 void clang::CacheTokens(Preprocessor& PP, const std::string& OutFile) {
@@ -243,7 +292,7 @@
     
     Lexer L(SourceLocation::getFileLoc(I.getFileID(), 0), LOpts,
             B->getBufferStart(), B->getBufferEnd(), B);
-    
+
     PM[FE] = LexTokens(Out, L, PP, idcount, IM);
   }
 

Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=60911&r1=60910&r2=60911&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
+++ cfe/trunk/lib/Lex/PTHLexer.cpp Thu Dec 11 17:36:38 2008
@@ -194,19 +194,24 @@
 class VISIBILITY_HIDDEN PTHFileLookup {
 public:
   class Val {
-    uint32_t v;
+    uint32_t TokenOff;
+    uint32_t PPCondOff;
     
   public:
-    Val() : v(~0) {}
-    Val(uint32_t x) : v(x) {}
+    Val() : TokenOff(~0) {}
+    Val(uint32_t toff, uint32_t poff) : TokenOff(toff), PPCondOff(poff) {}
     
-    operator uint32_t() const {
-      assert(v != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
-      return v;
+    uint32_t getTokenOffset() const {
+      assert(TokenOff != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
+      return TokenOff;
     }
     
-    Val& operator=(uint32_t x) { v = x; return *this; }
-    bool isValid() const { return v != ~((uint32_t)0); }
+    uint32_t gettPPCondOffset() const {
+      assert(TokenOff != ~((uint32_t)0) && "PTHFileLookup entry initialized.");
+      return PPCondOff;
+    }
+    
+    bool isValid() const { return TokenOff != ~((uint32_t)0); }
   };
   
 private:
@@ -228,7 +233,8 @@
       uint32_t len = Read32(D);
       const char* s = D;
       D += len;
-      FileMap.GetOrCreateValue(s, s+len).getValue() = Read32(D);
+      uint32_t TokenOff = Read32(D);
+      FileMap.GetOrCreateValue(s, s+len).getValue() = Val(TokenOff, Read32(D));      
     }
   }
 };
@@ -351,13 +357,13 @@
   // Lookup the FileEntry object in our file lookup data structure.  It will
   // return a variant that indicates whether or not there is an offset within
   // the PTH file that contains cached tokens.
-  PTHFileLookup::Val Off = ((PTHFileLookup*) FileLookup)->Lookup(FE);
+  PTHFileLookup::Val FileData = ((PTHFileLookup*) FileLookup)->Lookup(FE);
   
-  if (!Off.isValid()) // No tokens available.
+  if (!FileData.isValid()) // No tokens available.
     return 0;
   
   // Compute the offset of the token data within the buffer.
-  const char* data = Buf->getBufferStart() + Off;
+  const char* data = Buf->getBufferStart() + FileData.getTokenOffset();
   assert(data < Buf->getBufferEnd());
   return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, *this); 
 }





More information about the cfe-commits mailing list