aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-12-03 01:16:39 +0000
committerTed Kremenek <kremenek@apple.com>2008-12-03 01:16:39 +0000
commit6183e4815a4019e97ad01bd880f12355599b75fd (patch)
tree589e27bf701ddb8451dcf14128bef726733a3477
parent15f081de2c8ac7deadf5d938b458b20732230cd9 (diff)
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
-rw-r--r--Driver/CacheTokens.cpp5
-rw-r--r--include/clang/Lex/PTHManager.h4
-rw-r--r--lib/Lex/PTHLexer.cpp36
3 files changed, 29 insertions, 16 deletions
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<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.