Skip to content

Commit f232ebb

Browse files
[Caching] Don't parse LLVMArgs in cache replay instance
`llvm::cl::ParseCommandLineOptions()` is not thread-safe to be called from libSwiftScan so replaying multiple commands in parallel can crash the build system. Since the replay instance is not used for compilation and only need information from command-line arguments to create outputs and diagnostics, ignore LLVMArgs when replaying. rdar://120423882
1 parent e2f888b commit f232ebb

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %swift-scan-test -action compute_cache_key -cas-path %t/cas -input %s -- %target-swift-frontend -cache-compile-job -Rcache-compile-job %s \
4+
// RUN: -emit-module -emit-module-path %t/Test.swiftmodule -c -emit-dependencies -module-name Test -o %t/test.o -cas-path %t/cas \
5+
// RUN: -allow-unstable-cache-key-for-testing -Xllvm -aarch64-use-tbi > %t/key.casid
6+
7+
// RUN: not %swift-scan-test -action cache_query -id @%t/key.casid -cas-path %t/cas 2>&1 | %FileCheck %s --check-prefix=CHECK-QUERY-NOT-FOUND
8+
9+
// RUN: %target-swift-frontend -cache-compile-job -Rcache-compile-job %s -emit-module -emit-module-path %t/Test.swiftmodule -c -emit-dependencies \
10+
// RUN: -module-name Test -o %t/test.o -cas-path %t/cas -allow-unstable-cache-key-for-testing -Xllvm -aarch64-use-tbi
11+
12+
// RUN: %swift-scan-test -action cache_query -id @%t/key.casid -cas-path %t/cas | %FileCheck %s --check-prefix=CHECK-QUERY
13+
14+
// RUN: %swift-scan-test -action replay_result -cas-path %t/cas -id @%t/key.casid -threads 10 -- %target-swift-frontend -cache-compile-job -Rcache-compile-job %s \
15+
// RUN: -emit-module -emit-module-path %t/Test2.swiftmodule -c -emit-dependencies -module-name Test -o %t/test2.o -cas-path %t/cas \
16+
// RUN: -allow-unstable-cache-key-for-testing -Xllvm -aarch64-use-tbi
17+
18+
// CHECK-QUERY-NOT-FOUND: cached output not found
19+
// CHECK-QUERY: Cached Compilation for key "llvmcas://{{.*}}" has 4 outputs:
20+
// CHECK-QUERY-NEXT: object: llvmcas://
21+
// CHECK-QUERY-NEXT: dependencies: llvmcas://
22+
// CHECK-QUERY-NEXT: swiftmodule: llvmcas://
23+
// CHECK-QUERY-NEXT: cached-diagnostics: llvmcas://
24+
25+
func testFunc() {}

tools/libSwiftScan/SwiftCaching.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,12 @@ swiftscan_cache_replay_instance_create(int argc, const char **argv,
778778
return nullptr;
779779
}
780780

781+
// Clear the LLVMArgs as `llvm::cl::ParseCommandLineOptions` is not
782+
// thread-safe to be called in libSwiftScan. The replay instance should not be
783+
// used to do compilation so clearing `-Xllvm` should not affect replay
784+
// result.
785+
Instance->Invocation.getFrontendOptions().LLVMArgs.clear();
786+
781787
return wrap(Instance);
782788
}
783789

tools/swift-scan-test/swift-scan-test.cpp

+25-10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/Support/Allocator.h"
2222
#include "llvm/Support/CommandLine.h"
2323
#include "llvm/Support/StringSaver.h"
24+
#include "llvm/Support/ThreadPool.h"
2425

2526
using namespace llvm;
2627

@@ -39,6 +40,9 @@ llvm::cl::opt<std::string> CASID("id", llvm::cl::desc("<casid>"),
3940
llvm::cl::cat(Category));
4041
llvm::cl::opt<std::string> Input("input", llvm::cl::desc("<file|index>"),
4142
llvm::cl::cat(Category));
43+
llvm::cl::opt<unsigned> Threads("threads",
44+
llvm::cl::desc("<number of threads>"),
45+
llvm::cl::cat(Category), cl::init(1));
4246
llvm::cl::opt<Actions>
4347
Action("action", llvm::cl::desc("<action>"),
4448
llvm::cl::values(clEnumVal(compute_cache_key, "compute cache key"),
@@ -216,16 +220,27 @@ int main(int argc, char *argv[]) {
216220
llvm::StringSaver Saver(Alloc);
217221
auto Args = createArgs(SwiftCommands, Saver);
218222

219-
switch (Action) {
220-
case compute_cache_key:
221-
return action_compute_cache_key(cas, Input, Args);
222-
case compute_cache_key_from_index:
223-
return action_compute_cache_key_from_index(cas, Input, Args);
224-
case cache_query:
225-
return action_cache_query(cas, CASID.c_str());
226-
case replay_result:
227-
return action_replay_result(cas, CASID.c_str(), Args);
223+
std::atomic<int> Ret = 0;
224+
llvm::ThreadPool Pool(llvm::hardware_concurrency(Threads));
225+
for (unsigned i = 0; i < Threads; ++i) {
226+
Pool.async([&]() {
227+
switch (Action) {
228+
case compute_cache_key:
229+
Ret += action_compute_cache_key(cas, Input, Args);
230+
break;
231+
case compute_cache_key_from_index:
232+
Ret += action_compute_cache_key_from_index(cas, Input, Args);
233+
break;
234+
case cache_query:
235+
Ret += action_cache_query(cas, CASID.c_str());
236+
break;
237+
case replay_result:
238+
Ret += action_replay_result(cas, CASID.c_str(), Args);
239+
break;
240+
}
241+
});
228242
}
243+
Pool.wait();
229244

230-
return EXIT_SUCCESS;
245+
return Ret;
231246
}

0 commit comments

Comments
 (0)