[cfe-commits] r61913 - in /cfe/trunk: include/clang/Lex/PTHLexer.h include/clang/Lex/PTHManager.h lib/Lex/PTHLexer.cpp

Ted Kremenek kremenek at apple.com
Wed Jan 7 20:30:34 PST 2009


Author: kremenek
Date: Wed Jan  7 22:30:32 2009
New Revision: 61913

URL: http://llvm.org/viewvc/llvm-project?rev=61913&view=rev
Log:
PTH: Hook up getSpelling() caching in PTHLexer. This results in a nice
performance gain. Here's what we see for -Eonly on Cocoa.h (using PTH):

- wall time decreases by 21% (26% speedup overall)
- system time decreases by 35%
- user time decreases by 6%

These reductions are due to not paging source files just to get spellings for
literals. The solution in place doesn't appear to be 100% yet, as we still see
some of the pages for source files getting mapped in. Using -print-stats, we see
that SourceManager maps in 7179K less bytes of source text (reduction of 75%).
Will investigate why the remaining 25% are getting paged in.

With these changes, here's how PTH compares to non-PTH on Cocoa.h:
  -Eonly: PTH takes 64% of the time as non-PTH (54% speedup)
  -fsyntax-only: PTH takes 89% of the time as non-PTH (11% speedup)

Modified:
    cfe/trunk/include/clang/Lex/PTHLexer.h
    cfe/trunk/include/clang/Lex/PTHManager.h
    cfe/trunk/lib/Lex/PTHLexer.cpp

Modified: cfe/trunk/include/clang/Lex/PTHLexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PTHLexer.h?rev=61913&r1=61912&r2=61913&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/PTHLexer.h (original)
+++ cfe/trunk/include/clang/Lex/PTHLexer.h Wed Jan  7 22:30:32 2009
@@ -41,6 +41,13 @@
   /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
   ///  to process when doing quick skipping of preprocessor blocks.
   const char* CurPPCondPtr;
+  
+  /// Pointer to a side table containing offsets in the PTH file
+  ///  for token spellings.
+  const char* SpellingTable;
+  
+  /// Number of cached spellings left in the cached source file.
+  unsigned SpellingsLeft;
 
   PTHLexer(const PTHLexer&);  // DO NOT IMPLEMENT
   void operator=(const PTHLexer&); // DO NOT IMPLEMENT
@@ -57,7 +64,8 @@
 
   /// Create a PTHLexer for the specified token stream.
   PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D, 
-           const char* ppcond, PTHManager& PM);
+           const char* ppcond, const char* spellingTable, unsigned numSpellings,
+           PTHManager& PM);
   
   ~PTHLexer() {}
     

Modified: cfe/trunk/include/clang/Lex/PTHManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PTHManager.h?rev=61913&r1=61912&r2=61913&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/PTHManager.h (original)
+++ cfe/trunk/include/clang/Lex/PTHManager.h Wed Jan  7 22:30:32 2009
@@ -69,6 +69,10 @@
   /// GetIdentifierInfo - Used by PTHManager to reconstruct IdentifierInfo
   ///  objects from the PTH file.
   IdentifierInfo* GetIdentifierInfo(unsigned);
+  
+  /// GetSpelling - Used by PTHLexer classes to get the cached spelling
+  ///  for a token.
+  unsigned GetSpelling(unsigned PTHOffset, const char*& Buffer);
 
 public:
   

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

==============================================================================
--- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
+++ cfe/trunk/lib/Lex/PTHLexer.cpp Wed Jan  7 22:30:32 2009
@@ -49,9 +49,13 @@
 //===----------------------------------------------------------------------===//
 
 PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
-                   const char* ppcond, PTHManager& PM)
+                   const char* ppcond,
+                   const char* spellingTable, unsigned NumSpellings,
+                   PTHManager& PM)
   : PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
-    PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {}
+    PPCond(ppcond), CurPPCondPtr(ppcond), 
+    SpellingTable(spellingTable), SpellingsLeft(NumSpellings),
+    PTHMgr(PM) {}
 
 void PTHLexer::Lex(Token& Tok) {
 LexNextToken:
@@ -285,8 +289,55 @@
   return SourceLocation::getFileLoc(FileID, offset);
 }
 
+unsigned PTHManager::GetSpelling(unsigned PTHOffset, const char *& Buffer) {
+  const char* p = Buf->getBufferStart() + PTHOffset;
+  assert(p < Buf->getBufferEnd());
+  
+  // The string is prefixed by 16 bits for its length, followed by the string
+  // itself.
+  unsigned len = ((unsigned) ((uint8_t) p[0]))
+    | (((unsigned) ((uint8_t) p[1])) << 8);
+
+  Buffer = p + 2;
+  return len;
+}
+
 unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
-  return 0;
+  const char* p = SpellingTable;
+  SourceManager& SM = PP->getSourceManager();
+  unsigned fpos = SM.getFullFilePos(SM.getPhysicalLoc(sloc));
+  unsigned len = 0;
+
+  while (SpellingsLeft) {
+    uint32_t TokOffset = 
+      ((uint32_t) ((uint8_t) p[0]))
+      | (((uint32_t) ((uint8_t) p[1])) << 8)
+      | (((uint32_t) ((uint8_t) p[2])) << 16)
+      | (((uint32_t) ((uint8_t) p[3])) << 24);
+    
+    if (TokOffset > fpos)
+      break;
+    
+    --SpellingsLeft;
+    
+    // Did we find a matching token offset for this spelling?
+    if (TokOffset == fpos) {
+      uint32_t SpellingPTHOffset = 
+        ((uint32_t) ((uint8_t) p[4]))
+        | (((uint32_t) ((uint8_t) p[5])) << 8)
+        | (((uint32_t) ((uint8_t) p[6])) << 16)
+        | (((uint32_t) ((uint8_t) p[7])) << 24);
+      
+      len = PTHMgr.GetSpelling(SpellingPTHOffset, Buffer);
+      break;
+    }
+
+    // No match.  Keep on looking.
+    p += sizeof(uint32_t)*2;
+  }
+
+  SpellingTable = p;
+  return len;
 }
 
 //===----------------------------------------------------------------------===//
@@ -478,8 +529,15 @@
   const char* ppcond = Buf->getBufferStart() + FileData.getPPCondOffset();
   uint32_t len = Read32(ppcond);
   if (len == 0) ppcond = 0;
+  
+  // Get the location of the spelling table.
+  const char* spellingTable = Buf->getBufferStart() +
+                              FileData.getSpellingOffset();
+  
+  len = Read32(spellingTable);
+  if (len == 0) spellingTable = 0;
 
   assert(data < Buf->getBufferEnd());
   return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
-                      *this); 
+                      spellingTable, len, *this); 
 }





More information about the cfe-commits mailing list