]> granicus.if.org Git - clang/commitdiff
PTH: Hook up getSpelling() caching in PTHLexer. This results in a nice
authorTed Kremenek <kremenek@apple.com>
Thu, 8 Jan 2009 04:30:32 +0000 (04:30 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 8 Jan 2009 04:30:32 +0000 (04:30 +0000)
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)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61913 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/PTHLexer.h
include/clang/Lex/PTHManager.h
lib/Lex/PTHLexer.cpp

index 8e23924abc88e36a26df9d9e5c008f43ff5b9011..8928ad4aa886be2c9a4f3e7940153929104cd4c8 100644 (file)
@@ -41,6 +41,13 @@ class PTHLexer : public PreprocessorLexer {
   /// 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 @@ public:
 
   /// 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() {}
     
index 1d023e096ccdb6cab0980fb1c69b271e3c91def8..fc814d006320f53905d425385ffd111158247689 100644 (file)
@@ -69,6 +69,10 @@ class PTHManager {
   /// 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:
   
index ef7cfb18d6174dac760eb5178df16a350f28102d..cfd5c6492a83f992133f933bebb8d53ac617ea91 100644 (file)
@@ -49,9 +49,13 @@ static inline uint32_t Read32(const char*& data) {
 //===----------------------------------------------------------------------===//
 
 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 @@ SourceLocation PTHLexer::getSourceLocation() {
   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 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
   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); 
 }