[cfe-commits] r61909 - /cfe/trunk/Driver/CacheTokens.cpp

Ted Kremenek kremenek at apple.com
Wed Jan 7 18:44:06 PST 2009


Author: kremenek
Date: Wed Jan  7 20:44:06 2009
New Revision: 61909

URL: http://llvm.org/viewvc/llvm-project?rev=61909&view=rev
Log:
Cache the "spellings" of string, character, and numeric literals in the PTH
file. For Cocoa.h, this enlarges the PTH file by 310K (4%).

Modified:
    cfe/trunk/Driver/CacheTokens.cpp

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

==============================================================================
--- cfe/trunk/Driver/CacheTokens.cpp (original)
+++ cfe/trunk/Driver/CacheTokens.cpp Wed Jan  7 20:44:06 2009
@@ -19,6 +19,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
@@ -28,8 +29,33 @@
 
 typedef uint32_t Offset;
 
-typedef llvm::DenseMap<const FileEntry*,std::pair<Offset,Offset> > PCHMap;
+typedef std::vector<std::pair<Offset, llvm::StringMapEntry<Offset>*> >
+  SpellMapTy;
+
+namespace {
+class VISIBILITY_HIDDEN PCHEntry {
+  Offset TokenData, PPCondData;  
+  union { Offset SpellingOff; SpellMapTy* Spellings; };
+
+public:  
+  PCHEntry() {}
+
+  PCHEntry(Offset td, Offset ppcd, SpellMapTy* sp)
+    : TokenData(td), PPCondData(ppcd), Spellings(sp) {}
+  
+  Offset getTokenOffset() const { return TokenData; }
+  Offset getPPCondTableOffset() const { return PPCondData; }
+  SpellMapTy& getSpellings() const { return *Spellings; }
+  
+  void setSpellingTableOffset(Offset off) { SpellingOff = off; }
+  Offset getSpellingTableOffset() const { return SpellingOff; }
+  
+};
+} // end anonymous namespace
+
+typedef llvm::DenseMap<const FileEntry*, PCHEntry> PCHMap;
 typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap;
+typedef llvm::StringMap<Offset, llvm::BumpPtrAllocator> CachedStrsTy;
 
 namespace {
 class VISIBILITY_HIDDEN PTHWriter {
@@ -38,6 +64,9 @@
   Preprocessor& PP;
   uint32_t idcount;
   PCHMap PM;
+  CachedStrsTy CachedStrs;
+  
+  SpellMapTy* CurSpellMap;
 
   //// Get the persistent id for the given IdentifierInfo*.
   uint32_t ResolveID(const IdentifierInfo* II);
@@ -75,8 +104,9 @@
   
   std::pair<Offset,Offset> EmitIdentifierTable();
   Offset EmitFileTable();
-  std::pair<Offset,Offset> LexTokens(Lexer& L);
-
+  PCHEntry LexTokens(Lexer& L);
+  void EmitCachedSpellings();
+  
 public:
   PTHWriter(llvm::raw_fd_ostream& out, Preprocessor& pp) 
     : Out(out), PP(pp), idcount(0) {}
@@ -108,7 +138,6 @@
   Emit32(fpos);
   Emit16(T.getLength());
 
-#if 0
   // For specific tokens we cache their spelling.
   if (T.getIdentifierInfo())
     return;
@@ -120,11 +149,22 @@
     case tok::wide_string_literal:
     case tok::angle_string_literal:
     case tok::numeric_constant:
-    case tok::char_constant:
-      CacheSpelling(T, fpos);
+    case tok::char_constant: {
+      // FIXME: This uses the slow getSpelling().  Perhaps we do better
+      // in the future?  This only slows down PTH generation.
+      const std::string& spelling = PP.getSpelling(T);
+      const char* s = spelling.c_str();
+      
+      // Get the string entry.
+      llvm::StringMapEntry<Offset> *E =
+        &CachedStrs.GetOrCreateValue(s, s+spelling.size());
+
+      // Store the address of the string entry in our spelling map.
+      (*CurSpellMap).push_back(std::make_pair(fpos, E));
+
       break;
+    }
   }
-#endif
 }
 
 namespace {
@@ -197,14 +237,15 @@
     unsigned size = strlen(Name);
     Emit32(size);
     EmitBuf(Name, Name+size);
-    Emit32(I->second.first);
-    Emit32(I->second.second);
+    Emit32(I->second.getTokenOffset());
+    Emit32(I->second.getPPCondTableOffset());
+    Emit32(I->second.getSpellingTableOffset());
   }
 
   return off;
 }
 
-std::pair<Offset,Offset> PTHWriter::LexTokens(Lexer& L) {
+PCHEntry PTHWriter::LexTokens(Lexer& L) {
 
   // Record the location within the token file.
   Offset off = (Offset) Out.tell();
@@ -215,6 +256,10 @@
   std::vector<unsigned> PPStartCond;
   bool ParsingPreprocessorDirective = false;
 
+  // Allocate a spelling map for this source file.
+  llvm::OwningPtr<SpellMapTy> Spellings(new SpellMapTy());
+  CurSpellMap = Spellings.get();
+
   Token Tok;
   
   do {
@@ -343,7 +388,54 @@
     Emit32(x == i ? 0 : x);
   }
 
-  return std::make_pair(off,PPCondOff);
+  return PCHEntry(off, PPCondOff, Spellings.take());
+}
+
+void PTHWriter::EmitCachedSpellings() {
+  // Write each cached string to the PTH file and update the
+  // the string map entry to contain the relevant offset.
+  //
+  // FIXME: We can write the strings out in order of their frequency.  This
+  //  may result in better locality.
+  //
+  for (CachedStrsTy::iterator I = CachedStrs.begin(), E = CachedStrs.end();
+       I!=E; ++I) {
+    
+    Offset off = Out.tell();
+
+    // Write out the length of the string before the string itself.
+    unsigned len = I->getKeyLength();
+    Emit16(len);
+
+    // Write out the string data.
+    const char* data = I->getKeyData();
+    EmitBuf(data, data+len);
+    
+    // Now patch the offset of the string in the PTH file into the string map.
+    I->setValue(off);
+  }
+  
+  // Now emit the spelling tables.
+  for (PCHMap::iterator I=PM.begin(), E=PM.end(); I!=E; ++I) {
+    SpellMapTy& spellings = I->second.getSpellings();
+    I->second.setSpellingTableOffset(Out.tell());
+    
+    // Write out the number of spellings.
+    unsigned n = spellings.size();
+    Emit32(n);
+    
+    for (unsigned i = 0; i < n; ++i) {
+      ++count;
+      // Write out the offset of the token within the source file.
+      Emit32(spellings[i].first);
+      
+      // Write out the offset of the spelling data within the PTH file.
+      Emit32(spellings[i].second->getValue());
+    }
+    
+    // Delete the spelling map for this source file.
+    delete &spellings;
+  }
 }
 
 void PTHWriter::GeneratePTH() {
@@ -381,6 +473,9 @@
   // Write out the identifier table.
   std::pair<Offset,Offset> IdTableOff = EmitIdentifierTable();
   
+  // Write out the cached strings table.
+  EmitCachedSpellings();
+  
   // Write out the file table.
   Offset FileTableOff = EmitFileTable();  
   





More information about the cfe-commits mailing list