Author: Reid Kleckner Date: 2020-02-27T10:18:06-08:00 New Revision: bc8836651fba3304d92e1025ff6a918f25e9e209
URL: https://github.com/llvm/llvm-project/commit/bc8836651fba3304d92e1025ff6a918f25e9e209 DIFF: https://github.com/llvm/llvm-project/commit/bc8836651fba3304d92e1025ff6a918f25e9e209.diff LOG: Forward declare FileEntry and DirectoryEntry in Module.h FileManager.h is an expensive header (~350ms for me in isolation), so try to do without it. Notably, we need to avoid checking the alignment of FileEntry, which happens for DenseMap<FileEntry*> and PointerUnion<FileEntry*>. I adjusted the code to avoid PointerUnion, and moved the DenseMap insertion to the .cpp file. Globally, this only saved about ~17 includes of the related headers because SourceManager.h still includes FileManager.h, and it is more popular than Module.h. Added: Modified: clang/include/clang/Basic/Module.h clang/include/clang/Serialization/ModuleFile.h clang/lib/Basic/Module.cpp clang/lib/Lex/ModuleMap.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 953d18352dac..d2e7f84ecca5 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -15,13 +15,11 @@ #ifndef LLVM_CLANG_BASIC_MODULE_H #define LLVM_CLANG_BASIC_MODULE_H -#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" @@ -44,6 +42,9 @@ class raw_ostream; namespace clang { +class DirectoryEntry; +class FileEntry; +class FileManager; class LangOptions; class TargetInfo; @@ -101,7 +102,7 @@ class Module { std::string PresumedModuleMapFile; /// The umbrella header or directory. - llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella; + const void *Umbrella = nullptr; /// The module signature. ASTFileSignature Signature; @@ -268,6 +269,9 @@ class Module { /// to a regular (public) module map. unsigned ModuleMapIsPrivate : 1; + /// Whether Umbrella is a directory or header. + unsigned HasUmbrellaDir : 1; + /// Describes the visibility of the various names within a /// particular module. enum NameVisibilityKind { @@ -487,22 +491,18 @@ class Module { /// Retrieve the header that serves as the umbrella header for this /// module. Header getUmbrellaHeader() const { - if (auto *E = Umbrella.dyn_cast<const FileEntry *>()) - return Header{UmbrellaAsWritten, E}; + if (!HasUmbrellaDir) + return Header{UmbrellaAsWritten, + static_cast<const FileEntry *>(Umbrella)}; return Header{}; } /// Determine whether this module has an umbrella directory that is /// not based on an umbrella header. - bool hasUmbrellaDir() const { - return Umbrella && Umbrella.is<const DirectoryEntry *>(); - } + bool hasUmbrellaDir() const { return Umbrella && HasUmbrellaDir; } /// Add a top-level header associated with this module. - void addTopHeader(const FileEntry *File) { - assert(File); - TopHeaders.insert(File); - } + void addTopHeader(const FileEntry *File); /// Add a top-level header filename associated with this module. void addTopHeaderFilename(StringRef Filename) { diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 8f3eb0220637..90d2745e080c 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_MODULEFILE_H #define LLVM_CLANG_SERIALIZATION_MODULEFILE_H +#include "clang/Basic/FileManager.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ASTBitCodes.h" @@ -34,8 +35,6 @@ namespace clang { -class FileEntry; - namespace serialization { /// Specifies the kind of module that has been loaded. diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 92835c9aca7d..7fb6dee0ec8b 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -44,7 +44,7 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), - NameVisibility(Hidden) { + HasUmbrellaDir(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -239,7 +239,12 @@ Module::DirectoryName Module::getUmbrellaDir() const { if (Header U = getUmbrellaHeader()) return {"", U.Entry->getDir()}; - return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; + return {UmbrellaAsWritten, static_cast<const DirectoryEntry *>(Umbrella)}; +} + +void Module::addTopHeader(const FileEntry *File) { + assert(File); + TopHeaders.insert(File); } ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 66223397716a..1c340f352f1f 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -1105,6 +1105,7 @@ void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, Twine NameAsWritten) { Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); Mod->Umbrella = UmbrellaHeader; + Mod->HasUmbrellaDir = false; Mod->UmbrellaAsWritten = NameAsWritten.str(); UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; @@ -1116,6 +1117,7 @@ void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, Twine NameAsWritten) { Mod->Umbrella = UmbrellaDir; + Mod->HasUmbrellaDir = true; Mod->UmbrellaAsWritten = NameAsWritten.str(); UmbrellaDirs[UmbrellaDir] = Mod; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits