diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-18 20:56:22 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-18 20:56:22 +0000 |
commit | 057df20b3107cef764052d271c89b8591b98b3ce (patch) | |
tree | 656d5b6add01e885f09487b746d302e7794f7a9b /lib | |
parent | c2a8d6cee01fc4845f5409bf5c021a64616ac8c3 (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')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 49 | ||||
-rw-r--r-- | lib/Serialization/Module.cpp | 4 | ||||
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 5 |
3 files changed, 43 insertions, 15 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), diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp index cb8c9cca06..bed545a0b2 100644 --- a/lib/Serialization/Module.cpp +++ b/lib/Serialization/Module.cpp @@ -20,8 +20,8 @@ using namespace clang; using namespace serialization; using namespace reader; -ModuleFile::ModuleFile(ModuleKind Kind) - : Kind(Kind), DirectlyImported(false), SizeInBits(0), +ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation) + : Kind(Kind), DirectlyImported(false), Generation(Generation), SizeInBits(0), LocalNumSLocEntries(0), SLocEntryBaseID(0), SLocEntryBaseOffset(0), SLocEntryOffsets(0), SLocFileOffsets(0), LocalNumIdentifiers(0), diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 4470855ec7..ab364b7ebd 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -35,7 +35,8 @@ llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { std::pair<ModuleFile *, bool> ModuleManager::addModule(StringRef FileName, ModuleKind Type, - ModuleFile *ImportedBy, std::string &ErrorStr) { + ModuleFile *ImportedBy, unsigned Generation, + std::string &ErrorStr) { const FileEntry *Entry = FileMgr.getFile(FileName); if (!Entry && FileName != "-") { ErrorStr = "file not found"; @@ -47,7 +48,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, bool NewModule = false; if (!ModuleEntry) { // Allocate a new module. - ModuleFile *New = new ModuleFile(Type); + ModuleFile *New = new ModuleFile(Type, Generation); New->FileName = FileName.str(); Chain.push_back(New); NewModule = true; |