From 2fcdafb28109d2cc56da573d3725ec496f1a4cc3 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Thu, 13 Nov 2025 12:00:50 -0800 Subject: [PATCH] [Caching] Fix multi-threaded WMO with MCCAS MCCAS wasn't setup correctly when using parallel WMO. Make sure the CAS ObjectStore and ResultCallbacks are passed to LLVM backend when using parallel WMO. rdar://164409895 (cherry picked from commit b1d669bea1595304717a4e0e41c267932084fdb9) --- include/swift/AST/IRGenRequests.h | 39 +++++++---- include/swift/Subsystems.h | 24 +++++-- lib/DriverTool/sil_llvm_gen_main.cpp | 9 +-- lib/FrontendTool/FrontendTool.cpp | 41 ++++++------ lib/IRGen/IRGen.cpp | 64 ++++++++++++------- lib/IRGen/IRGenModule.h | 6 +- lib/Immediate/SwiftMaterializationUnit.cpp | 3 +- .../cache_replay_multiple_files_mccas.swift | 23 +++++-- test/CAS/mccas.swift | 28 ++++++-- 9 files changed, 158 insertions(+), 79 deletions(-) diff --git a/include/swift/AST/IRGenRequests.h b/include/swift/AST/IRGenRequests.h index 7e4228fe56839..7c346f1228286 100644 --- a/include/swift/AST/IRGenRequests.h +++ b/include/swift/AST/IRGenRequests.h @@ -33,6 +33,10 @@ class SILOptions; struct TBDGenOptions; class TBDGenDescriptor; +namespace cas { + class SwiftCASOutputBackend; +} + namespace irgen { class IRGenModule; } @@ -149,12 +153,15 @@ struct IRGenDescriptor { StringRef ModuleName; const PrimarySpecificPaths &PSPs; + std::shared_ptr CAS; StringRef PrivateDiscriminator; ArrayRef parallelOutputFilenames; ArrayRef parallelIROutputFilenames; llvm::GlobalVariable **outModuleHash; + swift::cas::SwiftCASOutputBackend *casBackend = nullptr; llvm::raw_pwrite_stream *out = nullptr; + friend llvm::hash_code hash_value(const IRGenDescriptor &owner) { return llvm::hash_combine(owner.Ctx, owner.SymbolsToEmit, owner.SILMod); } @@ -176,8 +183,10 @@ struct IRGenDescriptor { const TBDGenOptions &TBDOpts, const SILOptions &SILOpts, Lowering::TypeConverter &Conv, std::unique_ptr &&SILMod, StringRef ModuleName, const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, StringRef PrivateDiscriminator, SymsToEmit symsToEmit = std::nullopt, - llvm::GlobalVariable **outModuleHash = nullptr) { + llvm::GlobalVariable **outModuleHash = nullptr, + cas::SwiftCASOutputBackend *casBackend = nullptr) { return IRGenDescriptor{file, symsToEmit, Opts, @@ -187,20 +196,26 @@ struct IRGenDescriptor { SILMod.release(), ModuleName, PSPs, + std::move(CAS), PrivateDiscriminator, {}, {}, - outModuleHash}; + outModuleHash, + casBackend}; } - static IRGenDescriptor forWholeModule( - ModuleDecl *M, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts, - const SILOptions &SILOpts, Lowering::TypeConverter &Conv, - std::unique_ptr &&SILMod, StringRef ModuleName, - const PrimarySpecificPaths &PSPs, SymsToEmit symsToEmit = std::nullopt, - ArrayRef parallelOutputFilenames = {}, - ArrayRef parallelIROutputFilenames = {}, - llvm::GlobalVariable **outModuleHash = nullptr) { + static IRGenDescriptor + forWholeModule(ModuleDecl *M, const IRGenOptions &Opts, + const TBDGenOptions &TBDOpts, const SILOptions &SILOpts, + Lowering::TypeConverter &Conv, + std::unique_ptr &&SILMod, StringRef ModuleName, + const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, + SymsToEmit symsToEmit = std::nullopt, + ArrayRef parallelOutputFilenames = {}, + ArrayRef parallelIROutputFilenames = {}, + llvm::GlobalVariable **outModuleHash = nullptr, + cas::SwiftCASOutputBackend *casBackend = nullptr) { return IRGenDescriptor{M, symsToEmit, Opts, @@ -210,10 +225,12 @@ struct IRGenDescriptor { SILMod.release(), ModuleName, PSPs, + std::move(CAS), "", parallelOutputFilenames, parallelIROutputFilenames, - outModuleHash}; + outModuleHash, + casBackend}; } /// Retrieves the files to perform IR generation for. If the descriptor is diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h index a40041ceb3f38..38cf9daa77959 100644 --- a/include/swift/Subsystems.h +++ b/include/swift/Subsystems.h @@ -80,6 +80,10 @@ namespace swift { class TypeConverter; } + namespace cas { + class SwiftCASOutputBackend; + } + namespace fine_grained_dependencies { class SourceFileDepGraph; } @@ -243,7 +247,8 @@ namespace swift { /// Get the CPU, subtarget feature options, and triple to use when emitting code. std::tuple, std::string> - getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx); + getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx, + std::shared_ptr CAS = nullptr); /// Turn the given Swift module into LLVM IR and return the generated module. /// To compile and output the generated code, call \c performLLVM. @@ -252,19 +257,23 @@ namespace swift { const TBDGenOptions &TBDOpts, std::unique_ptr SILMod, StringRef ModuleName, const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, ArrayRef parallelOutputFilenames, ArrayRef parallelIROutputFilenames, - llvm::GlobalVariable **outModuleHash = nullptr); + llvm::GlobalVariable **outModuleHash = nullptr, + cas::SwiftCASOutputBackend *casBackend = nullptr); /// Turn the given Swift file into LLVM IR and return the generated module. /// To compile and output the generated code, call \c performLLVM. GeneratedModule - performIRGeneration(FileUnit *file, const IRGenOptions &Opts, + performIRGeneration(FileUnit *file, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts, - std::unique_ptr SILMod, - StringRef ModuleName, const PrimarySpecificPaths &PSPs, + std::unique_ptr SILMod, StringRef ModuleName, + const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, StringRef PrivateDiscriminator, - llvm::GlobalVariable **outModuleHash = nullptr); + llvm::GlobalVariable **outModuleHash = nullptr, + cas::SwiftCASOutputBackend *casBackend = nullptr); /// Given an already created LLVM module, construct a pass pipeline and run /// the Swift LLVM Pipeline upon it. This will include the emission of LLVM IR @@ -330,7 +339,8 @@ namespace swift { /// Creates a TargetMachine from the IRGen opts and AST Context. std::unique_ptr - createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx); + createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx, + std::shared_ptr CAS); /// A convenience wrapper for Parser functionality. class ParserUnit { diff --git a/lib/DriverTool/sil_llvm_gen_main.cpp b/lib/DriverTool/sil_llvm_gen_main.cpp index 713ad907ab005..6be0b4114df37 100644 --- a/lib/DriverTool/sil_llvm_gen_main.cpp +++ b/lib/DriverTool/sil_llvm_gen_main.cpp @@ -456,12 +456,13 @@ int sil_llvm_gen_main(ArrayRef argv, void *MainAddr) { if (options.PerformWMO) { return IRGenDescriptor::forWholeModule( mod, Opts, TBDOpts, SILOpts, SILTypes, - /*SILMod*/ nullptr, moduleName, PSPs); + /*SILMod*/ nullptr, moduleName, PSPs, /*CAS=*/nullptr); } - return IRGenDescriptor::forFile( - mod->getFiles()[0], Opts, TBDOpts, SILOpts, SILTypes, - /*SILMod*/ nullptr, moduleName, PSPs, /*discriminator*/ ""); + return IRGenDescriptor::forFile(mod->getFiles()[0], Opts, TBDOpts, SILOpts, + SILTypes, + /*SILMod*/ nullptr, moduleName, PSPs, + /*CAS=*/nullptr, /*discriminator*/ ""); }; auto &eval = CI.getASTContext().evaluator; diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index 34135af9a9bbe..dc0024e09d41b 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -1785,21 +1785,22 @@ static bool serializeModuleSummary(SILModule *SM, static GeneratedModule generateIR(const IRGenOptions &IRGenOpts, const TBDGenOptions &TBDOpts, std::unique_ptr SM, const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, + cas::SwiftCASOutputBackend *casBackend, StringRef OutputFilename, ModuleOrSourceFile MSF, llvm::GlobalVariable *&HashGlobal, ArrayRef parallelOutputFilenames, ArrayRef parallelIROutputFilenames) { - if (auto *SF = MSF.dyn_cast()) { - return performIRGeneration(SF, IRGenOpts, TBDOpts, - std::move(SM), OutputFilename, PSPs, - SF->getPrivateDiscriminator().str(), - &HashGlobal); - } else { - return performIRGeneration(cast(MSF), IRGenOpts, TBDOpts, - std::move(SM), OutputFilename, PSPs, - parallelOutputFilenames, - parallelIROutputFilenames, &HashGlobal); - } + if (auto *SF = MSF.dyn_cast()) + return performIRGeneration(SF, IRGenOpts, TBDOpts, std::move(SM), + OutputFilename, PSPs, std::move(CAS), + SF->getPrivateDiscriminator().str(), &HashGlobal, + casBackend); + + return performIRGeneration( + cast(MSF), IRGenOpts, TBDOpts, std::move(SM), + OutputFilename, PSPs, std::move(CAS), parallelOutputFilenames, + parallelIROutputFilenames, &HashGlobal, casBackend); } static bool processCommandLineAndRunImmediately(CompilerInstance &Instance, @@ -1950,10 +1951,8 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename, llvm::Module *IRModule, llvm::GlobalVariable *HashGlobal) { const auto &opts = Instance.getInvocation().getIRGenOptions(); - std::unique_ptr TargetMachine = - createTargetMachine(opts, Instance.getASTContext()); - - TargetMachine->Options.MCOptions.CAS = Instance.getSharedCASInstance(); + std::unique_ptr TargetMachine = createTargetMachine( + opts, Instance.getASTContext(), Instance.getSharedCASInstance()); if (Instance.getInvocation().getCASOptions().EnableCaching && opts.UseCASBackend) @@ -2162,10 +2161,14 @@ static bool performCompileStepsPostSILGen( options::OPT_ir_output_path); llvm::GlobalVariable *HashGlobal; - auto IRModule = - generateIR(IRGenOpts, Invocation.getTBDGenOptions(), std::move(SM), PSPs, - OutputFilename, MSF, HashGlobal, ParallelOutputFilenames, - ParallelIROutputFilenames); + cas::SwiftCASOutputBackend *casBackend = + Invocation.getCASOptions().EnableCaching && IRGenOpts.UseCASBackend + ? &Instance.getCASOutputBackend() + : nullptr; + auto IRModule = generateIR( + IRGenOpts, Invocation.getTBDGenOptions(), std::move(SM), PSPs, + Instance.getSharedCASInstance(), casBackend, OutputFilename, MSF, + HashGlobal, ParallelOutputFilenames, ParallelIROutputFilenames); // Write extra LLVM IR output if requested if (IRModule && !PSPs.SupplementaryOutputs.LLVMIROutputPath.empty()) { diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 7fa848208dd6e..96d8d6088e701 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -129,7 +129,8 @@ static cl::opt AlignModuleToPageSize( std::tuple, std::string> -swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) { +swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx, + std::shared_ptr CAS) { // Things that maybe we should collect from the command line: // - relocation model // - code model @@ -150,6 +151,9 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) { // Set option to select the CASBackendMode. TargetOpts.MCOptions.CASObjMode = Opts.CASObjMode; + // Set CAS and CASID callbacks. + TargetOpts.MCOptions.CAS = std::move(CAS); + auto *Clang = static_cast(Ctx.getClangModuleLoader()); // Set UseInitArray appropriately. @@ -1104,7 +1108,8 @@ static void setPointerAuthOptions(PointerAuthOptions &opts, } std::unique_ptr -swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) { +swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx, + std::shared_ptr CAS) { CodeGenOptLevel OptLevel = Opts.shouldOptimize() ? CodeGenOptLevel::Default // -Os : CodeGenOptLevel::None; @@ -1114,8 +1119,8 @@ swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) { std::string CPU; std::string EffectiveClangTriple; std::vector targetFeaturesArray; - std::tie(TargetOpts, CPU, targetFeaturesArray, EffectiveClangTriple) - = getIRTargetOptions(Opts, Ctx); + std::tie(TargetOpts, CPU, targetFeaturesArray, EffectiveClangTriple) = + getIRTargetOptions(Opts, Ctx, std::move(CAS)); const llvm::Triple &EffectiveTriple = llvm::Triple(EffectiveClangTriple); std::string targetFeatures; if (!targetFeaturesArray.empty()) { @@ -1168,12 +1173,12 @@ swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) { return std::unique_ptr(TargetMachine); } -IRGenerator::IRGenerator(const IRGenOptions &options, SILModule &module) - : Opts(options), SIL(module), QueueIndex(0) { -} +IRGenerator::IRGenerator(const IRGenOptions &options, SILModule &module, + std::shared_ptr CAS) + : Opts(options), SIL(module), CAS(std::move(CAS)), QueueIndex(0) {} std::unique_ptr IRGenerator::createTargetMachine() { - return ::createTargetMachine(Opts, SIL.getASTContext()); + return ::createTargetMachine(Opts, SIL.getASTContext(), CAS); } // With -embed-bitcode, save a copy of the llvm IR as data in the @@ -1479,7 +1484,7 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator, auto *primaryFile = dyn_cast_or_null(desc.Ctx.dyn_cast()); - IRGenerator irgen(Opts, *SILMod); + IRGenerator irgen(Opts, *SILMod, desc.CAS); auto targetMachine = irgen.createTargetMachine(); if (!targetMachine) return GeneratedModule::null(); @@ -1687,7 +1692,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) { auto SILMod = std::unique_ptr(desc.SILMod); auto *M = desc.getParentModule(); - IRGenerator irgen(Opts, *SILMod); + IRGenerator irgen(Opts, *SILMod, desc.CAS); // Enter a cleanup to delete all the IGMs and their associated LLVMContexts // that have been associated with the IRGenerator. @@ -1726,6 +1731,16 @@ static void performParallelIRGeneration(IRGenDescriptor desc) { // Create the IR emitter. auto outputName = *OutputIter++; + if (desc.casBackend) { + targetMachine->Options.MCOptions.ResultCallBack = + [=](const llvm::cas::CASID &id) -> llvm::Error { + if (auto Err = desc.casBackend->storeMCCASObjectID(outputName, id)) + return Err; + + return llvm::Error::success(); + }; + } + IRGenModule *IGM = new IRGenModule( irgen, std::move(targetMachine), nextSF, desc.ModuleName, outputName, nextSF->getFilename(), nextSF->getPrivateDiscriminator().str()); @@ -1929,16 +1944,19 @@ GeneratedModule swift::performIRGeneration( swift::ModuleDecl *M, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts, std::unique_ptr SILMod, StringRef ModuleName, const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, ArrayRef parallelOutputFilenames, ArrayRef parallelIROutputFilenames, - llvm::GlobalVariable **outModuleHash) { + llvm::GlobalVariable **outModuleHash, + cas::SwiftCASOutputBackend *casBackend) { // Get a pointer to the SILModule to avoid a potential use-after-move. const auto *SILModPtr = SILMod.get(); const auto &SILOpts = SILModPtr->getOptions(); auto desc = IRGenDescriptor::forWholeModule( M, Opts, TBDOpts, SILOpts, SILModPtr->Types, std::move(SILMod), - ModuleName, PSPs, /*symsToEmit*/ std::nullopt, parallelOutputFilenames, - parallelIROutputFilenames, outModuleHash); + ModuleName, PSPs, std::move(CAS), /*symsToEmit*/ std::nullopt, + parallelOutputFilenames, parallelIROutputFilenames, outModuleHash, + casBackend); if (Opts.shouldPerformIRGenerationInParallel() && !parallelOutputFilenames.empty() && @@ -1951,20 +1969,20 @@ GeneratedModule swift::performIRGeneration( return evaluateOrFatal(M->getASTContext().evaluator, IRGenRequest{desc}); } -GeneratedModule swift:: -performIRGeneration(FileUnit *file, const IRGenOptions &Opts, - const TBDGenOptions &TBDOpts, - std::unique_ptr SILMod, - StringRef ModuleName, const PrimarySpecificPaths &PSPs, - StringRef PrivateDiscriminator, - llvm::GlobalVariable **outModuleHash) { +GeneratedModule swift::performIRGeneration( + FileUnit *file, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts, + std::unique_ptr SILMod, StringRef ModuleName, + const PrimarySpecificPaths &PSPs, + std::shared_ptr CAS, StringRef PrivateDiscriminator, + llvm::GlobalVariable **outModuleHash, + cas::SwiftCASOutputBackend *casBackend) { // Get a pointer to the SILModule to avoid a potential use-after-move. const auto *SILModPtr = SILMod.get(); const auto &SILOpts = SILModPtr->getOptions(); auto desc = IRGenDescriptor::forFile( file, Opts, TBDOpts, SILOpts, SILModPtr->Types, std::move(SILMod), - ModuleName, PSPs, PrivateDiscriminator, - /*symsToEmit*/ std::nullopt, outModuleHash); + ModuleName, PSPs, std::move(CAS), PrivateDiscriminator, + /*symsToEmit*/ std::nullopt, outModuleHash, casBackend); return evaluateOrFatal(file->getASTContext().evaluator, IRGenRequest{desc}); } @@ -2038,7 +2056,7 @@ void swift::createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer, bool swift::performLLVM(const IRGenOptions &Opts, ASTContext &Ctx, llvm::Module *Module, StringRef OutputFilename) { // Build TargetMachine. - auto TargetMachine = createTargetMachine(Opts, Ctx); + auto TargetMachine = createTargetMachine(Opts, Ctx, /*CAS=*/nullptr); if (!TargetMachine) return true; diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index c2c86292b540f..4910b2bdbb77c 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -362,12 +362,16 @@ class IRGenerator { /// The queue of IRGenModules for multi-threaded compilation. SmallVector Queue; + + /// ObjectStore for MCCAS backend if used. + std::shared_ptr CAS; std::atomic QueueIndex; friend class CurrentIGMPtr; public: - explicit IRGenerator(const IRGenOptions &opts, SILModule &module); + explicit IRGenerator(const IRGenOptions &opts, SILModule &module, + std::shared_ptr CAS = nullptr); /// Attempt to create an llvm::TargetMachine for the current target. std::unique_ptr createTargetMachine(); diff --git a/lib/Immediate/SwiftMaterializationUnit.cpp b/lib/Immediate/SwiftMaterializationUnit.cpp index b22f26b59f3ca..9aeddbfc7c8ac 100644 --- a/lib/Immediate/SwiftMaterializationUnit.cpp +++ b/lib/Immediate/SwiftMaterializationUnit.cpp @@ -262,7 +262,8 @@ generateModule(const CompilerInstance &CI, std::unique_ptr SM) { // Lower the SIL module to LLVM IR auto GenModule = performIRGeneration( swiftModule, IRGenOpts, TBDOpts, std::move(SM), - swiftModule->getName().str(), PSPs, ArrayRef(), + swiftModule->getName().str(), PSPs, /*CAS=*/nullptr, + ArrayRef(), /*parallelIROutputFilenames*/ ArrayRef()); if (Context.hadError()) { diff --git a/test/CAS/cache_replay_multiple_files_mccas.swift b/test/CAS/cache_replay_multiple_files_mccas.swift index 9ef67de447de2..80c212c1e846b 100644 --- a/test/CAS/cache_replay_multiple_files_mccas.swift +++ b/test/CAS/cache_replay_multiple_files_mccas.swift @@ -26,15 +26,26 @@ // RUN: test -f %t/Test.swiftmodule /// Expect cache hit second time -// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift %t/foo.swift -emit-module -o %t/Test.swiftmodule \ +// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift %t/foo.swift -emit-module -o %t/Test1.swiftmodule \ // RUN: -module-name Test -cas-path %t/cas @%t/MyApp.cmd 2>&1 | %FileCheck --check-prefix=CACHE-HIT %s -// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job -primary-file %t/test.swift %t/foo.swift -c -o %t/test.o \ +// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job -primary-file %t/test.swift %t/foo.swift -c -o %t/test1.o \ // RUN: -module-name Test -cas-path %t/cas @%t/MyApp.cmd 2>&1 | %FileCheck --check-prefix=CACHE-HIT %s -// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift -primary-file %t/foo.swift -c -o %t/foo.o \ +// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift -primary-file %t/foo.swift -c -o %t/foo1.o \ // RUN: -module-name Test -cas-path %t/cas @%t/MyApp.cmd 2>&1 | %FileCheck --check-prefix=CACHE-HIT %s -// RUN: test -f %t/test.o -// RUN: test -f %t/foo.o -// RUN: test -f %t/Test.swiftmodule +// RUN: test -f %t/test1.o +// RUN: test -f %t/foo1.o +// RUN: test -f %t/Test1.swiftmodule + +/// Multithread IRGen. +// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift %t/foo.swift -c -o %t/test2.o -o %t/foo2.o \ +// RUN: -num-threads 2 -module-name Test -cas-path %t/cas @%t/MyApp.cmd 2>&1 | %FileCheck --check-prefix=CACHE-MISS %s +// RUN: test -f %t/test2.o +// RUN: test -f %t/foo2.o + +// RUN: %target-swift-frontend -cache-compile-job -cas-backend -cas-backend-mode=verify -Rcache-compile-job %t/test.swift %t/foo.swift -c -o %t/test3.o -o %t/foo3.o \ +// RUN: -num-threads 2 -module-name Test -cas-path %t/cas @%t/MyApp.cmd 2>&1 | %FileCheck --check-prefix=CACHE-HIT %s +// RUN: test -f %t/test3.o +// RUN: test -f %t/foo3.o //--- test.swift func testFunc() {} diff --git a/test/CAS/mccas.swift b/test/CAS/mccas.swift index 0b3ac17f91e0e..6c7289ddf7d8e 100644 --- a/test/CAS/mccas.swift +++ b/test/CAS/mccas.swift @@ -1,26 +1,40 @@ // REQUIRES: OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-backend-mode=verify -cas-path %t/cas -o %t/test-verify.o +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-backend-mode=verify -cas-path %t/cas -o %t/test-verify.o // RUN: %llvm-dwarfdump %t/test-verify.o | %FileCheck %s --check-prefix=VERIFY-FILE // VERIFY-FILE: .debug_info -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-backend-mode=native -cas-path %t/cas -o %t/test-native.o +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-backend-mode=native -cas-path %t/cas -o %t/test-native.o // RUN: %llvm-dwarfdump %t/test-native.o | %FileCheck %s --check-prefix=NATIVE-FILE // NATIVE-FILE: .debug_info -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-backend-mode=casid -cas-path %t/cas -o %t/test-casid.id +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-backend-mode=casid -cas-path %t/cas -o %t/test-casid.id // RUN: cat %t/test-casid.id | %FileCheck %s --check-prefix=CASID-FILE // CASID-FILE: llvmcas://{{.*}} -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-emit-casid-file -cas-backend-mode=verify -cas-path %t/cas -o %t/test-verify-emit.o +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-emit-casid-file -cas-backend-mode=verify -cas-path %t/cas -o %t/test-verify-emit.o // RUN: cat %t/test-verify-emit.o.casid | %FileCheck %s --check-prefix=VERIFY-EMIT // VERIFY-EMIT: llvmcas://{{.*}} -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-emit-casid-file -cas-backend-mode=native -cas-path %t/cas -o %t/test-native-emit.o +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-emit-casid-file -cas-backend-mode=native -cas-path %t/cas -o %t/test-native-emit.o // RUN: cat %t/test-native-emit.o.casid | %FileCheck %s --check-prefix=NATIVE-EMIT // NATIVE-EMIT: llvmcas://{{.*}} -// RUN: %target-swift-frontend -c %s -g -cas-backend -cas-emit-casid-file -cas-backend-mode=casid -cas-path %t/cas -o %t/test.id +// RUN: %target-swift-frontend -c %t/test.swift -g -cas-backend -cas-emit-casid-file -cas-backend-mode=casid -cas-path %t/cas -o %t/test.id // RUN: not cat %t/test.id.casid -func testFunc() {} \ No newline at end of file +// RUN: %target-swift-frontend -c %t/test.swift %t/main.swift -g -cas-backend -cas-path %t/cas -o %t/test-parallel.o -o %t/main-parallel.o -num-threads 2 +// RUN: %llvm-dwarfdump %t/test-parallel.o | %FileCheck %s --check-prefix=NATIVE-FILE +// RUN: %llvm-dwarfdump %t/main-parallel.o | %FileCheck %s --check-prefix=NATIVE-FILE + +// RUN: %target-swift-frontend -c %t/test.swift %t/main.swift -g -cas-backend -cas-backend-mode=casid -cas-path %t/cas -o %t/test.casid -o %t/main.casid -num-threads 2 +// RUN: cat %t/test.casid | %FileCheck %s --check-prefix=CASID-FILE +// RUN: cat %t/main.casid | %FileCheck %s --check-prefix=CASID-FILE + +//--- test.swift +func testFunc() {} + +//--- main.swift +func main() {}