aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-18 20:56:22 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-18 20:56:22 +0000
commit057df20b3107cef764052d271c89b8591b98b3ce (patch)
tree656d5b6add01e885f09487b746d302e7794f7a9b /lib/Serialization/ASTReader.cpp
parentc2a8d6cee01fc4845f5409bf5c021a64616ac8c3 (diff)
Optimize unqualified/global name lookup in modules by introducing a
generational scheme for identifiers that avoids searching the hash tables of a given module more than once for a given identifier. Previously, loading any new module invalidated all of the previous lookup results for all identifiers, causing us to perform the lookups repeatedly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp49
1 files changed, 38 insertions, 11 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 245e8b1b18..5842bbb468 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -514,7 +514,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
Reader.SetIdentifierInfo(ID, II);
II->setIsFromAST();
- II->setOutOfDate(false);
+ Reader.markIdentifierUpToDate(II);
return II;
}
@@ -540,7 +540,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
IdentifierInfo *II = KnownII;
if (!II)
II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
- II->setOutOfDate(false);
+ Reader.markIdentifierUpToDate(II);
II->setIsFromAST();
// Set or check the various bits in the IdentifierInfo structure.
@@ -1560,14 +1560,20 @@ namespace {
/// \brief Visitor class used to look up identifirs in an AST file.
class IdentifierLookupVisitor {
StringRef Name;
+ unsigned PriorGeneration;
IdentifierInfo *Found;
public:
- explicit IdentifierLookupVisitor(StringRef Name) : Name(Name), Found() { }
+ IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration)
+ : Name(Name), PriorGeneration(PriorGeneration), Found() { }
static bool visit(ModuleFile &M, void *UserData) {
IdentifierLookupVisitor *This
= static_cast<IdentifierLookupVisitor *>(UserData);
+ // If we've already searched this module file, skip it now.
+ if (M.Generation <= This->PriorGeneration)
+ return true;
+
ASTIdentifierLookupTable *IdTable
= (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
if (!IdTable)
@@ -1593,7 +1599,24 @@ namespace {
}
void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
- get(II.getName());
+ unsigned PriorGeneration = 0;
+ if (getContext().getLangOptions().Modules)
+ PriorGeneration = IdentifierGeneration[&II];
+
+ IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration);
+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
+ markIdentifierUpToDate(&II);
+}
+
+void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
+ if (!II)
+ return;
+
+ II->setOutOfDate(false);
+
+ // Update the generation for this identifier.
+ if (getContext().getLangOptions().Modules)
+ IdentifierGeneration[II] = CurrentGeneration;
}
const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
@@ -2612,6 +2635,9 @@ void ASTReader::makeModuleVisible(Module *Mod,
ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ModuleKind Type) {
+ // Bump the generation number.
+ ++CurrentGeneration;
+
switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0)) {
case Failure: return Failure;
case IgnorePCH: return IgnorePCH;
@@ -2619,7 +2645,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
}
// Here comes stuff that we only do once the entire chain is loaded.
-
+
// Check the predefines buffers.
if (!DisableValidation && Type == MK_PCH &&
// FIXME: CheckPredefinesBuffers also sets the SuggestedPredefines;
@@ -2635,7 +2661,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
IdEnd = PP.getIdentifierTable().end();
Id != IdEnd; ++Id)
Id->second->setOutOfDate(true);
-
+
// Resolve any unresolved module exports.
for (unsigned I = 0, N = UnresolvedModuleImportExports.size(); I != N; ++I) {
UnresolvedModuleImportExport &Unresolved = UnresolvedModuleImportExports[I];
@@ -2683,7 +2709,7 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
bool NewModule;
std::string ErrorStr;
llvm::tie(M, NewModule) = ModuleMgr.addModule(FileName, Type, ImportedBy,
- ErrorStr);
+ CurrentGeneration, ErrorStr);
if (!M) {
// We couldn't load the module.
@@ -5109,11 +5135,11 @@ void ASTReader::InitializeSema(Sema &S) {
}
IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
- IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart));
+ IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart),
+ /*PriorGeneration=*/0);
ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
IdentifierInfo *II = Visitor.getIdentifierInfo();
- if (II)
- II->setOutOfDate(false);
+ markIdentifierUpToDate(II);
return II;
}
@@ -6236,7 +6262,8 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
Consumer(0), ModuleMgr(FileMgr.getFileSystemOptions()),
RelocatablePCH(false), isysroot(isysroot),
DisableValidation(DisableValidation),
- DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0),
+ DisableStatCache(DisableStatCache),
+ CurrentGeneration(0), NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),