diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-03-22 18:50:14 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-03-22 18:50:14 +0000 |
commit | fa69fc19121da3fc5673ccc00d4e8afa5b540a4f (patch) | |
tree | c31c1dbf88a4ea5bc0615fe6e3c6930468b9b940 /include/clang/Serialization | |
parent | c02ddb23c0a27ff95859b3eacab134613b0b1d1d (diff) |
<rdar://problem/13479539> Simplify ModuleManager/GlobalModuleIndex interaction to eliminate a pile of extraneous stats().
The refactoring in r177367 introduced a serious performance bug where
the "lazy" resolution of module file names in the global module index
to actual module file entries in the module manager would perform
repeated negative stats(). The new interaction requires the module
manager to inform the global module index when a module file has been
loaded, eliminating the extraneous stat()s and a bunch of bookkeeping
on both sides.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177750 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r-- | include/clang/Serialization/GlobalModuleIndex.h | 65 | ||||
-rw-r--r-- | include/clang/Serialization/ModuleManager.h | 18 |
2 files changed, 21 insertions, 62 deletions
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h index c7e9ab4535..eaf26d1df1 100644 --- a/include/clang/Serialization/GlobalModuleIndex.h +++ b/include/clang/Serialization/GlobalModuleIndex.h @@ -20,6 +20,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include <utility> @@ -43,36 +44,6 @@ using llvm::SmallVectorImpl; using llvm::StringRef; using serialization::ModuleFile; -/// \brief Abstract class that resolves a module file name to a ModuleFile -/// pointer, which is used to uniquely describe a module file. -class ModuleFileNameResolver { -public: - virtual ~ModuleFileNameResolver(); - - /// \brief Attempt to resolve the given module file name to a specific, - /// already-loaded module. - /// - /// \param FileName The name of the module file. - /// - /// \param ExpectedSize The size that the module file is expected to have. - /// If the actual size differs, the resolver should return \c true. - /// - /// \param ExpectedModTime The modification time that the module file is - /// expected to have. If the actual modification time differs, the resolver - /// should return \c true. - /// - /// \param File Will be set to the module file if there is one, or null - /// otherwise. - /// - /// \returns True if a module file exists but does not meet the size/ - /// modification time criteria, false if the module file is available or has - /// not yet been loaded. - virtual bool resolveModuleFileName(StringRef FileName, - off_t ExpectedSize, - time_t ExpectedModTime, - ModuleFile *&File) = 0; -}; - /// \brief A global index for a set of module files, providing information about /// the identifiers within those module files. /// @@ -89,9 +60,6 @@ class GlobalModuleIndex { /// as the global module index is live. llvm::OwningPtr<llvm::MemoryBuffer> Buffer; - /// \brief The module file name resolver. - ModuleFileNameResolver *Resolver; - /// \brief The hash table. /// /// This pointer actually points to a IdentifierIndexTable object, @@ -103,7 +71,7 @@ class GlobalModuleIndex { struct ModuleInfo { ModuleInfo() : File(), Size(), ModTime() { } - /// \brief The module file, if it is known. + /// \brief The module file, once it has been resolved. ModuleFile *File; /// \brief The module file name. @@ -119,9 +87,6 @@ class GlobalModuleIndex { /// \brief The module IDs on which this module directly depends. /// FIXME: We don't really need a vector here. llvm::SmallVector<unsigned, 4> Dependencies; - - /// \brief The module IDs that directly depend on this module. - llvm::SmallVector<unsigned, 4> ImportedBy; }; /// \brief A mapping from module IDs to information about each module. @@ -135,13 +100,19 @@ class GlobalModuleIndex { /// corresponding index into the \c Modules vector. llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile; + /// \brief The set of modules that have not yet been resolved. + /// + /// The string is just the name of the module itself, which maps to the + /// module ID. + llvm::StringMap<unsigned> UnresolvedModules; + /// \brief The number of identifier lookups we performed. unsigned NumIdentifierLookups; /// \brief The number of identifier lookup hits, where we recognize the /// identifier. unsigned NumIdentifierLookupHits; - + /// \brief Internal constructor. Use \c readIndex() to read an index. explicit GlobalModuleIndex(llvm::MemoryBuffer *Buffer, llvm::BitstreamCursor Cursor); @@ -200,19 +171,11 @@ public: /// \returns true if the identifier is known to the index, false otherwise. bool lookupIdentifier(StringRef Name, HitSet &Hits); - /// \brief Set the module file name resolver. - void setResolver(ModuleFileNameResolver *Resolver) { - this->Resolver = Resolver; - } - - /// \brief Note that additional modules have been loaded, which invalidates - /// the module file -> module cache. - void noteAdditionalModulesLoaded() { - ModulesByFile.clear(); - } - - /// \brief Resolve the module file for the module with the given ID. - ModuleFile *resolveModuleFile(unsigned ID); + /// \brief Note that the given module file has been loaded. + /// + /// \returns false if the global module index has information about this + /// module file, and true otherwise. + bool loadedModuleFile(ModuleFile *File); /// \brief Print statistics to standard error. void printStats(); diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h index 9b58b75ebb..c6e3265b3b 100644 --- a/include/clang/Serialization/ModuleManager.h +++ b/include/clang/Serialization/ModuleManager.h @@ -16,18 +16,18 @@ #define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H #include "clang/Basic/FileManager.h" -#include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/Module.h" #include "llvm/ADT/DenseMap.h" namespace clang { +class GlobalModuleIndex; class ModuleMap; namespace serialization { - + /// \brief Manages the set of modules loaded by an AST reader. -class ModuleManager : public ModuleFileNameResolver { +class ModuleManager { /// \brief The chain of AST files. The first entry is the one named by the /// user, the last one is the one that doesn't depend on anything further. SmallVector<ModuleFile *, 2> Chain; @@ -61,9 +61,6 @@ class ModuleManager : public ModuleFileNameResolver { /// just an non-owning pointer. GlobalModuleIndex *GlobalIndex; - /// \brief Update the set of modules files we know about known to the global index. - void updateModulesInCommonWithGlobalIndex(); - /// \brief State used by the "visit" operation to avoid malloc traffic in /// calls to visit(). struct VisitState { @@ -202,6 +199,10 @@ public: /// \brief Set the global module index. void setGlobalIndex(GlobalModuleIndex *Index); + /// \brief Notification from the AST reader that the given module file + /// has been "accepted", and will not (can not) be unloaded. + void moduleFileAccepted(ModuleFile *MF); + /// \brief Visit each of the modules. /// /// This routine visits each of the modules, starting with the @@ -270,11 +271,6 @@ public: time_t ExpectedModTime, const FileEntry *&File); - virtual bool resolveModuleFileName(StringRef FileName, - off_t ExpectedSize, - time_t ExpectedModTime, - ModuleFile *&File); - /// \brief View the graphviz representation of the module graph. void viewGraph(); }; |