]> granicus.if.org Git - clang/commitdiff
PTH:
authorTed Kremenek <kremenek@apple.com>
Wed, 3 Dec 2008 01:16:39 +0000 (01:16 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 3 Dec 2008 01:16:39 +0000 (01:16 +0000)
Use an array instead of a DenseMap to cache persistent IDs -> IdentifierInfo*.  This leads to a 4% speedup at -fsyntax-only using PTH.

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

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

index 536fefca4dbae88098a32e9239a61256c307293b..7904954fce48af7242a63f2de6e808e9a0d2c9b2 100644 (file)
@@ -104,7 +104,7 @@ EmitIdentifierTable(llvm::raw_fd_ostream& Out, uint32_t max,
   }
   
   Offset DataOff = Out.tell();
-  
+    
   for (InverseIDMap::iterator I=IIDMap.begin(), E=IIDMap.end(); I!=E; ++I) {
     // Record the location for this data.
     I->FileOffset = Out.tell();
@@ -118,6 +118,9 @@ EmitIdentifierTable(llvm::raw_fd_ostream& Out, uint32_t max,
   // Now emit the table mapping from persistent IDs to PTH file offsets.  
   Offset IDOff = Out.tell();
   
+  // Emit the number of identifiers.
+  Emit32(Out, max);
+
   for (InverseIDMap::iterator I=IIDMap.begin(), E=IIDMap.end(); I!=E; ++I)
     Emit32(Out, I->FileOffset);
 
index 3a4519441074dbe88920611c6fa69ade12d47bee..c9b7b52ec1a73085da79072e3a3d1bdbe4578688 100644 (file)
@@ -38,7 +38,7 @@ class PTHManager {
   
   /// IdMap - A lazily generated cache mapping from persistent identifiers to
   ///  IdentifierInfo*.
-  void* PersistentIDCache;
+  void* PerIDCache;
   
   /// FileLookup - Abstract data structure used for mapping between files
   ///  and token data in the PTH file.
@@ -59,7 +59,7 @@ class PTHManager {
   /// This constructor is intended to only be called by the static 'Create'
   /// method.
   PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
-             const char* idDataTable, Preprocessor& pp);
+             const char* idDataTable, void* perIDCache, Preprocessor& pp);
 
   // Do not implement.
   PTHManager();
index 846a17e8daf12c8b3fb6a5eafcd25d9c22d83cb9..63f2722e99b8c0018d1d91a9b8958be415ee5893 100644 (file)
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/DenseMap.h"
 
 using namespace clang;
 
 PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
                    PTHManager& PM)
-  : TokBuf(D), PreprocessorLexer(&pp, fileloc), CurTokenIdx(0), PTHMgr(PM), 
+  : PreprocessorLexer(&pp, fileloc), TokBuf(D), CurTokenIdx(0), PTHMgr(PM), 
     NeedsFetching(true) {
     // Make sure the EofToken is completely clean.
     EofToken.startToken();
@@ -184,7 +183,6 @@ void PTHLexer::ReadToken(Token& T) {
 // Internal Data Structures for PTH file lookup and resolving identifiers.
 //===----------------------------------------------------------------------===//
 
-typedef llvm::DenseMap<uint32_t, IdentifierInfo*> IDCache;
 
 /// PTHFileLookup - This internal data structure is used by the PTHManager
 ///  to map from FileEntry objects managed by FileManager to offsets within
@@ -238,14 +236,15 @@ public:
 //===----------------------------------------------------------------------===//
 
 PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
-                       const char* idDataTable, Preprocessor& pp)
-: Buf(buf), PersistentIDCache(0), FileLookup(fileLookup),
-IdDataTable(idDataTable), ITable(pp.getIdentifierTable()), PP(pp) {}
+                       const char* idDataTable, void* perIDCache, 
+                       Preprocessor& pp)
+: Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
+  IdDataTable(idDataTable), ITable(pp.getIdentifierTable()), PP(pp) {}
 
 PTHManager::~PTHManager() {
   delete Buf;
   delete (PTHFileLookup*) FileLookup;
-  delete (IDCache*) PersistentIDCache;
+  delete [] (IdentifierInfo**) PerIDCache;
 }
 
 PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
@@ -294,7 +293,22 @@ PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
     return 0; // FIXME: Proper error diagnostic?
   }
   
-  return new PTHManager(File.take(), FL.take(), IData, PP);
+  // Get the number of IdentifierInfos and pre-allocate the identifier cache.
+  uint32_t NumIds = Read32(IData);
+
+  // Pre-allocate the peristent ID -> IdentifierInfo* cache.  We use calloc()
+  // so that we in the best case only zero out memory once when the OS returns
+  // us new pages.
+  IdentifierInfo** PerIDCache =
+    (IdentifierInfo**) calloc(NumIds, sizeof(*PerIDCache));
+  
+  if (!PerIDCache) {
+    assert(false && "Could not allocate Persistent ID cache.");
+    return 0;
+  }
+  
+  // Create the new lexer.
+  return new PTHManager(File.take(), FL.take(), IData, PerIDCache, PP);
 }
 
 IdentifierInfo* PTHManager::ReadIdentifierInfo(const char*& D) {
@@ -310,11 +324,7 @@ IdentifierInfo* PTHManager::ReadIdentifierInfo(const char*& D) {
   --persistentID;
   
   // Check if the IdentifierInfo has already been resolved.
-  if (!PersistentIDCache)
-    PersistentIDCache = new IDCache();
-  
-  // FIXME: We can make this an array, but what is the performance tradeoff?
-  IdentifierInfo*& II = (*((IDCache*) PersistentIDCache))[persistentID];
+  IdentifierInfo*& II = ((IdentifierInfo**) PerIDCache)[persistentID];
   if (II) return II;
   
   // Look in the PTH file for the string data for the IdentifierInfo object.