From: Ted Kremenek Date: Wed, 3 Dec 2008 01:16:39 +0000 (+0000) Subject: PTH: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6183e4815a4019e97ad01bd880f12355599b75fd;p=clang PTH: 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 --- diff --git a/Driver/CacheTokens.cpp b/Driver/CacheTokens.cpp index 536fefca4d..7904954fce 100644 --- a/Driver/CacheTokens.cpp +++ b/Driver/CacheTokens.cpp @@ -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); diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index 3a45194410..c9b7b52ec1 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -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(); diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp index 846a17e8da..63f2722e99 100644 --- a/lib/Lex/PTHLexer.cpp +++ b/lib/Lex/PTHLexer.cpp @@ -23,13 +23,12 @@ #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 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.