diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-01-28 16:46:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-01-28 16:46:33 +0000 |
commit | e97cd90a67ecdd7599eff82ed16231d3e83d2457 (patch) | |
tree | 2606e61a9cbf2162d6435eb94acf99fc66d4467b /clang/lib/Serialization/ModuleManager.cpp | |
parent | 1258519674ad4c2f6c31d3754e13931881600c93 (diff) | |
download | bcm5719-llvm-e97cd90a67ecdd7599eff82ed16231d3e83d2457.tar.gz bcm5719-llvm-e97cd90a67ecdd7599eff82ed16231d3e83d2457.zip |
Eliminate memory allocation from most invocations of
ModuleManager::visit() by keeping a free list of the two data
structures used to store state (a preallocated stack and a visitation
number vector). Improves -fsyntax-only performance for my modules test
case by 2.8%. Modules has pulled ahead by almost 10% with the global
module index.
llvm-svn: 173692
Diffstat (limited to 'clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index 97c86a7bb8a..bc9917b5822 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -162,17 +162,37 @@ void ModuleManager::updateModulesInCommonWithGlobalIndex() { } } +ModuleManager::VisitState *ModuleManager::allocateVisitState() { + // Fast path: if we have a cached state, use it. + if (FirstVisitState) { + VisitState *Result = FirstVisitState; + FirstVisitState = FirstVisitState->NextState; + Result->NextState = 0; + return Result; + } + + // Allocate and return a new state. + return new VisitState(size()); +} + +void ModuleManager::returnVisitState(VisitState *State) { + assert(State->NextState == 0 && "Visited state is in list?"); + State->NextState = FirstVisitState; + FirstVisitState = State; +} + void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) { GlobalIndex = Index; updateModulesInCommonWithGlobalIndex(); } ModuleManager::ModuleManager(FileManager &FileMgr) - : FileMgr(FileMgr), GlobalIndex() { } + : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(0) { } ModuleManager::~ModuleManager() { for (unsigned i = 0, e = Chain.size(); i != e; ++i) delete Chain[e - i - 1]; + delete FirstVisitState; } void @@ -230,10 +250,13 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), // global module index, since modules could have been added to the module // manager since we loaded the global module index. updateModulesInCommonWithGlobalIndex(); + + delete FirstVisitState; + FirstVisitState = 0; } - SmallVector<ModuleFile *, 4> Stack; - SmallVector<bool, 4> Visited(size(), false); + VisitState *State = allocateVisitState(); + unsigned VisitNumber = State->NextVisitNumber++; // If the caller has provided us with a hit-set that came from the global // module index, mark every module file in common with the global module @@ -243,18 +266,19 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), { ModuleFile *M = ModulesInCommonWithGlobalIndex[I]; if (!ModuleFilesHit->count(M->File)) - Visited[M->Index] = true; + State->VisitNumber[M->Index] = VisitNumber; } } for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) { ModuleFile *CurrentModule = VisitOrder[I]; // Should we skip this module file? - if (Visited[CurrentModule->Index]) + if (State->VisitNumber[CurrentModule->Index] == VisitNumber) continue; // Visit the module. - Visited[CurrentModule->Index] = true; + assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1); + State->VisitNumber[CurrentModule->Index] = VisitNumber; if (!Visitor(*CurrentModule, UserData)) continue; @@ -262,7 +286,6 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), // module that the current module depends on. To indicate this // behavior, we mark all of the reachable modules as having been visited. ModuleFile *NextModule = CurrentModule; - Stack.reserve(size()); do { // For any module that this module depends on, push it on the // stack (if it hasn't already been marked as visited). @@ -270,20 +293,22 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), M = NextModule->Imports.begin(), MEnd = NextModule->Imports.end(); M != MEnd; ++M) { - if (!Visited[(*M)->Index]) { - Stack.push_back(*M); - Visited[(*M)->Index] = true; + if (State->VisitNumber[(*M)->Index] != VisitNumber) { + State->Stack.push_back(*M); + State->VisitNumber[(*M)->Index] = VisitNumber; } } - if (Stack.empty()) + if (State->Stack.empty()) break; // Pop the next module off the stack. - NextModule = Stack.back(); - Stack.pop_back(); + NextModule = State->Stack.back(); + State->Stack.pop_back(); } while (true); } + + returnVisitState(State); } /// \brief Perform a depth-first visit of the current module. |