diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-01-25 23:32:03 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-01-25 23:32:03 +0000 |
commit | 7211ac15bbd97fd9ea8016a6632cb039a1071f1d (patch) | |
tree | 13674728016d428fb1e74988296e7bf1155b3e33 /clang/lib/Serialization/ModuleManager.cpp | |
parent | 8653bcf024708d6d836b4e214d0ff4872798e0f8 (diff) | |
download | bcm5719-llvm-7211ac15bbd97fd9ea8016a6632cb039a1071f1d.tar.gz bcm5719-llvm-7211ac15bbd97fd9ea8016a6632cb039a1071f1d.zip |
Improve coordination between the module manager and the global module
index, optimizing the operation that skips lookup in modules where we
know the identifier will not be found. This makes the global module
index optimization actually useful, providing an 8.5% speedup over
modules without the global module index for -fsyntax-only.
llvm-svn: 173529
Diffstat (limited to 'clang/lib/Serialization/ModuleManager.cpp')
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index f3fe2b96d57..97c86a7bb8a 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// #include "clang/Serialization/ModuleManager.h" +#include "clang/Serialization/GlobalModuleIndex.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" @@ -140,17 +141,45 @@ void ModuleManager::addInMemoryBuffer(StringRef FileName, InMemoryBuffers[Entry] = Buffer; } -ModuleManager::ModuleManager(FileManager &FileMgr) : FileMgr(FileMgr) { } +void ModuleManager::updateModulesInCommonWithGlobalIndex() { + ModulesInCommonWithGlobalIndex.clear(); + + if (!GlobalIndex) + return; + + // Collect the set of modules known to the global index. + SmallVector<const FileEntry *, 16> KnownModules; + GlobalIndex->getKnownModules(KnownModules); + + // Map those modules to AST files known to the module manager. + for (unsigned I = 0, N = KnownModules.size(); I != N; ++I) { + llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known + = Modules.find(KnownModules[I]); + if (Known == Modules.end()) + continue; + + ModulesInCommonWithGlobalIndex.push_back(Known->second); + } +} + +void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) { + GlobalIndex = Index; + updateModulesInCommonWithGlobalIndex(); +} + +ModuleManager::ModuleManager(FileManager &FileMgr) + : FileMgr(FileMgr), GlobalIndex() { } ModuleManager::~ModuleManager() { for (unsigned i = 0, e = Chain.size(); i != e; ++i) delete Chain[e - i - 1]; } -void ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), - void *UserData) { - // If the visitation number array is the wrong size, resize it and recompute - // an order. +void +ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), + void *UserData, + llvm::SmallPtrSet<const FileEntry *, 4> *ModuleFilesHit) { + // If the visitation order vector is the wrong size, recompute the order. if (VisitOrder.size() != Chain.size()) { unsigned N = size(); VisitOrder.clear(); @@ -196,11 +225,28 @@ void ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), } assert(VisitOrder.size() == N && "Visitation order is wrong?"); + + // We may need to update the set of modules we have in common with the + // global module index, since modules could have been added to the module + // manager since we loaded the global module index. + updateModulesInCommonWithGlobalIndex(); } SmallVector<ModuleFile *, 4> Stack; SmallVector<bool, 4> Visited(size(), false); + // 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 + // index that is *not* in that set as 'visited'. + if (ModuleFilesHit && !ModulesInCommonWithGlobalIndex.empty()) { + for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I) + { + ModuleFile *M = ModulesInCommonWithGlobalIndex[I]; + if (!ModuleFilesHit->count(M->File)) + Visited[M->Index] = true; + } + } + for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) { ModuleFile *CurrentModule = VisitOrder[I]; // Should we skip this module file? |