aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorJan Svoboda <jan_svoboda@apple.com>2023-07-06 18:30:06 +0200
committerJan Svoboda <jan_svoboda@apple.com>2023-07-17 13:50:24 -0700
commit227f71995804fa5df3f917ae3a7b1499cd24726c (patch)
treeba06a52e7e2002963fcee178b08630ce45164977 /clang
parentabcf7ce45794839a473a236d55d163016cde5ba6 (diff)
downloadllvm-227f71995804fa5df3f917ae3a7b1499cd24726c.zip
llvm-227f71995804fa5df3f917ae3a7b1499cd24726c.tar.gz
llvm-227f71995804fa5df3f917ae3a7b1499cd24726c.tar.bz2
[clang][modules][deps] Avoid checks for relocated modules
Currently, `ASTReader` performs some checks to diagnose relocated modules. This can add quite a bit of overhead to the scanner: it requires looking up, parsing and resolving module maps for all transitively loaded module files (and all the module maps encountered in the search paths on the way). Most of those checks are not really useful in the scanner anyway, since it uses strict context hash and immutable filesystem, which prevent those scenarios in the first place. This can speed up scanning by up to 30%. Depends on D150292. Reviewed By: benlangmuir Differential Revision: https://reviews.llvm.org/D150320
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Lex/PreprocessorOptions.h3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp8
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp3
-rw-r--r--clang/test/ClangScanDeps/header-search-pruning-transitive.c26
4 files changed, 24 insertions, 16 deletions
diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h
index 432f5df..058194bc 100644
--- a/clang/include/clang/Lex/PreprocessorOptions.h
+++ b/clang/include/clang/Lex/PreprocessorOptions.h
@@ -69,6 +69,9 @@ public:
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
+ /// Perform extra checks when loading PCM files for mutable file systems.
+ bool ModulesCheckRelocated = true;
+
/// Initialize the preprocessor with the compiler and target specific
/// predefines.
bool UsePredefines = true;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 0671f791..5f75696 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2990,6 +2990,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
BaseDirectoryAsWritten = Blob;
assert(!F.ModuleName.empty() &&
"MODULE_DIRECTORY found before MODULE_NAME");
+ F.BaseDirectory = std::string(Blob);
+ if (!PP.getPreprocessorOpts().ModulesCheckRelocated)
+ break;
// If we've already loaded a module map file covering this module, we may
// have a better path for it (relative to the current build).
Module *M = PP.getHeaderSearchInfo().lookupModule(
@@ -3011,8 +3014,6 @@ ASTReader::ReadControlBlock(ModuleFile &F,
}
}
F.BaseDirectory = std::string(M->Directory->getName());
- } else {
- F.BaseDirectory = std::string(Blob);
}
break;
}
@@ -3990,7 +3991,8 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
// usable header search context.
assert(!F.ModuleName.empty() &&
"MODULE_NAME should come before MODULE_MAP_FILE");
- if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
+ if (PP.getPreprocessorOpts().ModulesCheckRelocated &&
+ F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
// An implicitly-loaded module file should have its module listed in some
// module map file that we've already loaded.
Module *M =
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index baf76f0..28206dc 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -253,6 +253,9 @@ public:
// context hashing.
ScanInstance.getHeaderSearchOpts().ModulesStrictContextHash = true;
+ // Avoid some checks and module map parsing when loading PCM files.
+ ScanInstance.getPreprocessorOpts().ModulesCheckRelocated = false;
+
std::unique_ptr<FrontendAction> Action;
if (ModuleName)
diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
index 512bf5e..b56e10c 100644
--- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c
+++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
@@ -72,8 +72,8 @@ module X { header "X.h" }
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[HASH_X:.*]]",
// CHECK-NEXT: "file-deps": [
-// CHECK-NEXT: "[[PREFIX]]/./X.h",
-// CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/X.h",
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "name": "X"
// CHECK-NEXT: },
@@ -84,11 +84,11 @@ module X { header "X.h" }
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A]]",
// CHECK-NEXT: "file-deps": [
-// CHECK-NEXT: "[[PREFIX]]/./Y.h",
-// CHECK-NEXT: "[[PREFIX]]/./a/a.h",
-// CHECK-NEXT: "[[PREFIX]]/./begin/begin.h",
-// CHECK-NEXT: "[[PREFIX]]/./end/end.h",
-// CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/Y.h",
+// CHECK-NEXT: "[[PREFIX]]/a/a.h",
+// CHECK-NEXT: "[[PREFIX]]/begin/begin.h",
+// CHECK-NEXT: "[[PREFIX]]/end/end.h",
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "name": "Y"
// CHECK-NEXT: }
@@ -126,8 +126,8 @@ module X { header "X.h" }
// also has a different context hash from the first version of module X.
// CHECK-NOT: "context-hash": "[[HASH_X]]",
// CHECK: "file-deps": [
-// CHECK-NEXT: "[[PREFIX]]/./X.h",
-// CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/X.h",
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "name": "X"
// CHECK-NEXT: },
@@ -138,10 +138,10 @@ module X { header "X.h" }
// CHECK: ],
// CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A]]",
// CHECK-NEXT: "file-deps": [
-// CHECK-NEXT: "[[PREFIX]]/./Y.h",
-// CHECK-NEXT: "[[PREFIX]]/./begin/begin.h",
-// CHECK-NEXT: "[[PREFIX]]/./end/end.h",
-// CHECK-NEXT: "[[PREFIX]]/./module.modulemap"
+// CHECK-NEXT: "[[PREFIX]]/Y.h",
+// CHECK-NEXT: "[[PREFIX]]/begin/begin.h",
+// CHECK-NEXT: "[[PREFIX]]/end/end.h",
+// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
// CHECK-NEXT: ],
// CHECK-NEXT: "name": "Y"
// CHECK-NEXT: }