aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorAdam Czachorowski <adamcz@google.com>2022-02-25 17:21:32 +0100
committerAdam Czachorowski <adamcz@google.com>2022-03-01 15:56:23 +0100
commit8f4ea36bfe4caf7d08f9778ee2a347b78f02bc0f (patch)
tree7389bb16be1e62438077b85a03e87f3a2f490787 /clang/lib/Lex/ModuleMap.cpp
parent68895098d11f5c20969f3e14b5c11633399ee19e (diff)
downloadllvm-8f4ea36bfe4caf7d08f9778ee2a347b78f02bc0f.zip
llvm-8f4ea36bfe4caf7d08f9778ee2a347b78f02bc0f.tar.gz
llvm-8f4ea36bfe4caf7d08f9778ee2a347b78f02bc0f.tar.bz2
[clang] Improve laziness of resolving module map headers.
clang has support for lazy headers in module maps - if size and/or modtime and provided in the cppmap file, headers are only resolved when an include directive for a file with that size/modtime is encoutered. Before this change, the lazy resolution was all-or-nothing per module. That means as soon as even one file in that module potentially matched an include, all lazy files in that module were resolved. With this change, only files with matching size/modtime will be resolved. The goal is to avoid unnecessary stat() calls on non-included files, which is especially valuable on networked file systems, with higher latency. Differential Revision: https://reviews.llvm.org/D120569
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp28
1 files changed, 19 insertions, 9 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 0b136ae..824b2bb 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -482,7 +482,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (RequestingModule) {
resolveUses(RequestingModule, /*Complain=*/false);
- resolveHeaderDirectives(RequestingModule);
+ resolveHeaderDirectives(RequestingModule, /*File=*/llvm::None);
}
bool Excluded = false;
@@ -1191,25 +1191,35 @@ void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
auto BySize = LazyHeadersBySize.find(File->getSize());
if (BySize != LazyHeadersBySize.end()) {
for (auto *M : BySize->second)
- resolveHeaderDirectives(M);
+ resolveHeaderDirectives(M, File);
LazyHeadersBySize.erase(BySize);
}
auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
if (ByModTime != LazyHeadersByModTime.end()) {
for (auto *M : ByModTime->second)
- resolveHeaderDirectives(M);
+ resolveHeaderDirectives(M, File);
LazyHeadersByModTime.erase(ByModTime);
}
}
-void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
+void ModuleMap::resolveHeaderDirectives(
+ Module *Mod, llvm::Optional<const FileEntry *> File) const {
bool NeedsFramework = false;
- for (auto &Header : Mod->UnresolvedHeaders)
- // This operation is logically const; we're just changing how we represent
- // the header information for this file.
- const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header, NeedsFramework);
- Mod->UnresolvedHeaders.clear();
+ SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders;
+ const auto Size = File ? File.getValue()->getSize() : 0;
+ const auto ModTime = File ? File.getValue()->getModificationTime() : 0;
+
+ for (auto &Header : Mod->UnresolvedHeaders) {
+ if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
+ (Header.Size && Header.Size != Size)))
+ NewHeaders.push_back(Header);
+ else
+ // This operation is logically const; we're just changing how we represent
+ // the header information for this file.
+ const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
+ }
+ Mod->UnresolvedHeaders.swap(NewHeaders);
}
void ModuleMap::addHeader(Module *Mod, Module::Header Header,