summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp34
-rw-r--r--clang/lib/Serialization/GlobalModuleIndex.cpp31
-rw-r--r--clang/lib/Serialization/ModuleManager.cpp56
3 files changed, 71 insertions, 50 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index d8d5e664f08..fd1b8966ee2 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1378,17 +1378,15 @@ namespace {
class IdentifierLookupVisitor {
StringRef Name;
unsigned PriorGeneration;
- GlobalModuleIndex::SkipSet &SkipSet;
unsigned &NumIdentifierLookups;
unsigned &NumIdentifierLookupHits;
IdentifierInfo *Found;
public:
IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
- GlobalModuleIndex::SkipSet &SkipSet,
unsigned &NumIdentifierLookups,
unsigned &NumIdentifierLookupHits)
- : Name(Name), PriorGeneration(PriorGeneration), SkipSet(SkipSet),
+ : Name(Name), PriorGeneration(PriorGeneration),
NumIdentifierLookups(NumIdentifierLookups),
NumIdentifierLookupHits(NumIdentifierLookupHits),
Found()
@@ -1403,10 +1401,6 @@ namespace {
if (M.Generation <= This->PriorGeneration)
return true;
- // If this module file is in the skip set, don't bother looking in it.
- if (This->SkipSet.count(M.File))
- return false;
-
ASTIdentifierLookupTable *IdTable
= (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
if (!IdTable)
@@ -1443,18 +1437,18 @@ void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
// If there is a global index, look there first to determine which modules
// provably do not have any results for this identifier.
- GlobalModuleIndex::SkipSet SkipSet;
+ GlobalModuleIndex::HitSet Hits;
+ GlobalModuleIndex::HitSet *HitsPtr = 0;
if (!loadGlobalIndex()) {
- SmallVector<const FileEntry *, 4> ModuleFiles;
- if (GlobalIndex->lookupIdentifier(II.getName(), ModuleFiles)) {
- SkipSet = GlobalIndex->computeSkipSet(ModuleFiles);
+ if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) {
+ HitsPtr = &Hits;
}
}
- IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration, SkipSet,
+ IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration,
NumIdentifierLookups,
NumIdentifierLookupHits);
- ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);
markIdentifierUpToDate(&II);
}
@@ -2695,6 +2689,7 @@ bool ASTReader::loadGlobalIndex() {
return true;
GlobalIndex.reset(Result.first);
+ ModuleMgr.setGlobalIndex(GlobalIndex.get());
return false;
}
@@ -2725,6 +2720,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
// If we find that any modules are unusable, the global index is going
// to be out-of-date. Just remove it.
GlobalIndex.reset();
+ ModuleMgr.setGlobalIndex(0);
return ReadResult;
case Success:
@@ -5760,17 +5756,17 @@ IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
// If there is a global index, look there first to determine which modules
// provably do not have any results for this identifier.
- GlobalModuleIndex::SkipSet SkipSet;
+ GlobalModuleIndex::HitSet Hits;
+ GlobalModuleIndex::HitSet *HitsPtr = 0;
if (!loadGlobalIndex()) {
- SmallVector<const FileEntry *, 4> ModuleFiles;
- if (GlobalIndex->lookupIdentifier(Name, ModuleFiles)) {
- SkipSet = GlobalIndex->computeSkipSet(ModuleFiles);
+ if (GlobalIndex->lookupIdentifier(Name, Hits)) {
+ HitsPtr = &Hits;
}
}
- IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0, SkipSet,
+ IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0,
NumIdentifierLookups,
NumIdentifierLookupHits);
- ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor, HitsPtr);
IdentifierInfo *II = Visitor.getIdentifierInfo();
markIdentifierUpToDate(II);
return II;
diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp
index b1923982803..b778a72ba2e 100644
--- a/clang/lib/Serialization/GlobalModuleIndex.cpp
+++ b/clang/lib/Serialization/GlobalModuleIndex.cpp
@@ -127,7 +127,8 @@ struct LoadedModuleInfo {
GlobalModuleIndex::GlobalModuleIndex(FileManager &FileMgr,
llvm::MemoryBuffer *Buffer,
llvm::BitstreamCursor Cursor)
- : Buffer(Buffer), IdentifierIndex()
+ : Buffer(Buffer), IdentifierIndex(),
+ NumIdentifierLookups(), NumIdentifierLookupHits()
{
typedef llvm::DenseMap<unsigned, LoadedModuleInfo> LoadedModulesMap;
LoadedModulesMap LoadedModules;
@@ -368,10 +369,8 @@ void GlobalModuleIndex::getModuleDependencies(
Dependencies = Modules[Known->second].Dependencies;
}
-bool GlobalModuleIndex::lookupIdentifier(
- StringRef Name,
- SmallVectorImpl<const FileEntry *> &ModuleFiles) {
- ModuleFiles.clear();
+bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) {
+ Hits.clear();
// If there's no identifier index, there is nothing we can do.
if (!IdentifierIndex)
@@ -392,29 +391,13 @@ bool GlobalModuleIndex::lookupIdentifier(
if (ID >= Modules.size() || !Modules[ID].File)
continue;
- ModuleFiles.push_back(Modules[ID].File);
+ Hits.insert(Modules[ID].File);
}
++NumIdentifierLookupHits;
return true;
}
-GlobalModuleIndex::SkipSet
-GlobalModuleIndex::computeSkipSet(
- const SmallVectorImpl<const FileEntry *> &ModuleFiles) {
- llvm::SmallPtrSet<const FileEntry *, 8> Found(ModuleFiles.begin(),
- ModuleFiles.end());
-
- SkipSet Result;
- for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
- if (Modules[I].File && !Found.count(Modules[I].File))
- Result.insert(Modules[I].File);
- }
-
- NumIdentifierModulesSkipped += Result.size();
- return Result;
-}
-
void GlobalModuleIndex::printStats() {
std::fprintf(stderr, "*** Global Module Index Statistics:\n");
if (NumIdentifierLookups) {
@@ -422,10 +405,6 @@ void GlobalModuleIndex::printStats() {
NumIdentifierLookupHits, NumIdentifierLookups,
(double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
}
- if (NumIdentifierLookups && NumIdentifierModulesSkipped) {
- fprintf(stderr, " %f modules skipped per lookup (on average)\n",
- (double)NumIdentifierModulesSkipped/NumIdentifierLookups);
- }
std::fprintf(stderr, "\n");
}
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?
OpenPOWER on IntegriCloud