mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add driver options to swift to enable MCCAS.
To enable MCCAS, the following driver options have been added -cas-backend: Enable MCCAS backend in swift, the option -cache-compile-job must also be used. -cas-backend-mode=native: Set the CAS Backend mode to emit an object file after materializing it from the CAS. -cas-backend-mode=casid: Emit a file with the CASID for the CAS that was created. -cas-backend-mode=verify: Verify that the object file created is identical to the object file materialized from the CAS. -cas-emit-casid-file: Emit a .casid file next to the object file when CAS Backend is enabled.
This commit is contained in:
@@ -491,6 +491,15 @@ public:
|
||||
/// The calling convention used to perform non-swift calls.
|
||||
llvm::CallingConv::ID PlatformCCallingConvention;
|
||||
|
||||
/// Use CAS based object format as the output.
|
||||
bool UseCASBackend;
|
||||
|
||||
/// The output mode for the CAS Backend.
|
||||
llvm::CASBackendMode CASObjMode;
|
||||
|
||||
/// Emit a .casid file next to the object file if CAS Backend is used.
|
||||
bool EmitCASIDFile;
|
||||
|
||||
IRGenOptions()
|
||||
: DWARFVersion(2),
|
||||
OutputKind(IRGenOutputKind::LLVMAssemblyAfterOptimization),
|
||||
@@ -502,9 +511,9 @@ public:
|
||||
DebugInfoFormat(IRGenDebugInfoFormat::None),
|
||||
DisableClangModuleSkeletonCUs(false), UseJIT(false),
|
||||
DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false),
|
||||
Playground(false),
|
||||
EmitStackPromotionChecks(false), UseSingleModuleLLVMEmission(false),
|
||||
FunctionSections(false), PrintInlineTree(false), AlwaysCompile(false),
|
||||
Playground(false), EmitStackPromotionChecks(false),
|
||||
UseSingleModuleLLVMEmission(false), FunctionSections(false),
|
||||
PrintInlineTree(false), AlwaysCompile(false),
|
||||
EmbedMode(IRGenEmbedMode::None), LLVMLTOKind(IRGenLLVMLTOKind::None),
|
||||
SwiftAsyncFramePointer(SwiftAsyncFramePointerKind::Auto),
|
||||
HasValueNamesSetting(false), ValueNames(false),
|
||||
@@ -526,13 +535,12 @@ public:
|
||||
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
||||
InternalizeAtLink(false), InternalizeSymbols(false),
|
||||
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
|
||||
DisableReadonlyStaticObjects(false),
|
||||
CollocatedMetadataFunctions(false),
|
||||
ColocateTypeDescriptors(true),
|
||||
UseRelativeProtocolWitnessTables(false), CmdArgs(),
|
||||
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||
DisableReadonlyStaticObjects(false), CollocatedMetadataFunctions(false),
|
||||
ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false),
|
||||
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||
TypeInfoFilter(TypeInfoDumpFilter::All),
|
||||
PlatformCCallingConvention(llvm::CallingConv::C) {
|
||||
PlatformCCallingConvention(llvm::CallingConv::C), UseCASBackend(false),
|
||||
CASObjMode(llvm::CASBackendMode::Native) {
|
||||
#ifndef NDEBUG
|
||||
DisableRoundTripDebugTypes = false;
|
||||
#else
|
||||
|
||||
@@ -164,6 +164,10 @@ public:
|
||||
return LangOpts.Target.str();
|
||||
}
|
||||
|
||||
bool requiresCAS() const {
|
||||
return FrontendOpts.EnableCaching || FrontendOpts.UseCASBackend;
|
||||
}
|
||||
|
||||
void setClangModuleCachePath(StringRef Path) {
|
||||
ClangImporterOpts.ModuleCachePath = Path.str();
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
|
||||
|
||||
#include "swift/Basic/FileTypes.h"
|
||||
#include "swift/Basic/Version.h"
|
||||
#include "swift/Basic/PathRemapper.h"
|
||||
#include "swift/Basic/Version.h"
|
||||
#include "swift/Frontend/FrontendInputsAndOutputs.h"
|
||||
#include "swift/Frontend/InputFile.h"
|
||||
#include "clang/CAS/CASOptions.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "clang/CAS/CASOptions.h"
|
||||
#include "llvm/MC/MCTargetOptions.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
@@ -149,6 +150,15 @@ public:
|
||||
/// CacheKey for input file.
|
||||
std::string InputFileKey;
|
||||
|
||||
/// Enable using the LLVM MCCAS backend for object file output.
|
||||
bool UseCASBackend = false;
|
||||
|
||||
/// The output mode for the CAS Backend.
|
||||
llvm::CASBackendMode CASObjMode;
|
||||
|
||||
/// Emit a .casid file next to the object file if CAS Backend is used.
|
||||
bool EmitCASIDFile = false;
|
||||
|
||||
/// Number of retry opening an input file if the previous opening returns
|
||||
/// bad file descriptor error.
|
||||
unsigned BadFileDescriptorRetryCount = 0;
|
||||
|
||||
@@ -1859,6 +1859,19 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
|
||||
HelpText<"Add directory to the plugin search path with a plugin server executable">,
|
||||
MetaVarName<"<path>#<plugin-server-path>">;
|
||||
|
||||
def cas_backend: Flag<["-"], "cas-backend">,
|
||||
Flags<[FrontendOption, NoDriverOption]>,
|
||||
HelpText<"Enable using CASBackend for object file output">;
|
||||
|
||||
def cas_backend_mode: Joined<["-"], "cas-backend-mode=">,
|
||||
Flags<[FrontendOption, NoDriverOption]>,
|
||||
HelpText<"CASBackendMode for output kind">,
|
||||
MetaVarName<"native|casid|verify">;
|
||||
|
||||
def cas_emit_casid_file: Flag<["-"], "cas-emit-casid-file">,
|
||||
Flags<[FrontendOption, NoDriverOption]>,
|
||||
HelpText<"Emit .casid file next to object file when CAS Backend is enabled">;
|
||||
|
||||
def load_plugin_library:
|
||||
Separate<["-"], "load-plugin-library">, Group<plugin_search_Group>,
|
||||
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>,
|
||||
|
||||
@@ -263,7 +263,8 @@ namespace swift {
|
||||
const IRGenOptions &opts,
|
||||
UnifiedStatsReporter *stats, DiagnosticEngine &diags,
|
||||
llvm::raw_pwrite_stream &out,
|
||||
llvm::sys::Mutex *diagMutex = nullptr);
|
||||
llvm::sys::Mutex *diagMutex = nullptr,
|
||||
llvm::raw_pwrite_stream *casid = nullptr);
|
||||
|
||||
/// Wrap a serialized module inside a swift AST section in an object file.
|
||||
void createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer,
|
||||
|
||||
@@ -380,6 +380,17 @@ bool ArgsToFrontendOptionsConverter::convert(
|
||||
Opts.BlocklistConfigFilePaths.push_back(A);
|
||||
}
|
||||
|
||||
if (Arg *A = Args.getLastArg(OPT_cas_backend_mode)) {
|
||||
Opts.CASObjMode = llvm::StringSwitch<llvm::CASBackendMode>(A->getValue())
|
||||
.Case("native", llvm::CASBackendMode::Native)
|
||||
.Case("casid", llvm::CASBackendMode::CASID)
|
||||
.Case("verify", llvm::CASBackendMode::Verify)
|
||||
.Default(llvm::CASBackendMode::Native);
|
||||
}
|
||||
|
||||
Opts.UseCASBackend = Args.hasArg(OPT_cas_backend);
|
||||
Opts.EmitCASIDFile = Args.hasArg(OPT_cas_emit_casid_file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +266,10 @@ setIRGenOutputOptsFromFrontendOptions(IRGenOptions &IRGenOpts,
|
||||
}
|
||||
}(FrontendOpts.RequestedAction);
|
||||
|
||||
IRGenOpts.UseCASBackend = FrontendOpts.UseCASBackend;
|
||||
IRGenOpts.CASObjMode = FrontendOpts.CASObjMode;
|
||||
IRGenOpts.EmitCASIDFile = FrontendOpts.EmitCASIDFile;
|
||||
|
||||
// If we're in JIT mode, set the requisite flags.
|
||||
if (FrontendOpts.RequestedAction == FrontendOptions::ActionType::Immediate) {
|
||||
IRGenOpts.UseJIT = true;
|
||||
@@ -1440,7 +1444,8 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
|
||||
DiagnosticEngine &Diags,
|
||||
StringRef workingDirectory,
|
||||
const LangOptions &LangOpts,
|
||||
const FrontendOptions &FrontendOpts) {
|
||||
const FrontendOptions &FrontendOpts,
|
||||
bool RequiresCAS) {
|
||||
using namespace options;
|
||||
|
||||
if (const Arg *a = Args.getLastArg(OPT_tools_directory)) {
|
||||
@@ -1568,7 +1573,7 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
|
||||
|
||||
// Forward the FrontendOptions to clang importer option so it can be
|
||||
// accessed when creating clang module compilation invocation.
|
||||
if (FrontendOpts.EnableCaching)
|
||||
if (RequiresCAS)
|
||||
Opts.CASOpts = FrontendOpts.CASOpts;
|
||||
|
||||
return false;
|
||||
@@ -3025,7 +3030,7 @@ bool CompilerInvocation::parseArgs(
|
||||
}
|
||||
|
||||
if (ParseClangImporterArgs(ClangImporterOpts, ParsedArgs, Diags,
|
||||
workingDirectory, LangOpts, FrontendOpts)) {
|
||||
workingDirectory, LangOpts, FrontendOpts, requiresCAS())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ void CompilerInstance::setupDependencyTrackerIfNeeded() {
|
||||
|
||||
bool CompilerInstance::setupCASIfNeeded(ArrayRef<const char *> Args) {
|
||||
const auto &Opts = getInvocation().getFrontendOptions();
|
||||
if (!Opts.EnableCaching)
|
||||
if (!getInvocation().requiresCAS())
|
||||
return false;
|
||||
|
||||
auto MaybeDB= Opts.CASOpts.getOrCreateDatabases();
|
||||
|
||||
@@ -1672,6 +1672,7 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
|
||||
std::unique_ptr<llvm::TargetMachine> TargetMachine =
|
||||
createTargetMachine(opts, Instance.getASTContext());
|
||||
|
||||
TargetMachine->Options.MCOptions.CAS = Instance.getSharedCASInstance();
|
||||
// Free up some compiler resources now that we have an IRModule.
|
||||
freeASTContextIfPossible(Instance);
|
||||
|
||||
|
||||
@@ -128,6 +128,12 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) {
|
||||
TargetOpts.DebuggerTuning = llvm::DebuggerKind::LLDB;
|
||||
TargetOpts.FunctionSections = Opts.FunctionSections;
|
||||
|
||||
// Set option to UseCASBackend if CAS was enabled on the command line.
|
||||
TargetOpts.UseCASBackend = Opts.UseCASBackend;
|
||||
|
||||
// Set option to select the CASBackendMode.
|
||||
TargetOpts.MCOptions.CASObjMode = Opts.CASObjMode;
|
||||
|
||||
auto *Clang = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
|
||||
|
||||
// WebAssembly doesn't support atomics yet, see
|
||||
@@ -605,17 +611,31 @@ bool swift::performLLVM(const IRGenOptions &Opts,
|
||||
if (OutputFilename.empty())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<raw_fd_ostream> CASIDFile;
|
||||
if (Opts.UseCASBackend && Opts.EmitCASIDFile &&
|
||||
Opts.CASObjMode != llvm::CASBackendMode::CASID &&
|
||||
Opts.OutputKind == IRGenOutputKind::ObjectFile && OutputFilename != "-") {
|
||||
std::string OutputFilenameCASID = std::string(OutputFilename);
|
||||
OutputFilenameCASID.append(".casid");
|
||||
std::error_code EC;
|
||||
CASIDFile = std::make_unique<raw_fd_ostream>(OutputFilenameCASID, EC);
|
||||
if (EC) {
|
||||
diagnoseSync(Diags, DiagMutex, SourceLoc(), diag::error_opening_output,
|
||||
OutputFilename, std::move(EC.message()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return compileAndWriteLLVM(Module, TargetMachine, Opts, Stats, Diags,
|
||||
*OutputFile, DiagMutex);
|
||||
*OutputFile, DiagMutex,
|
||||
CASIDFile ? CASIDFile.get() : nullptr);
|
||||
}
|
||||
|
||||
bool swift::compileAndWriteLLVM(llvm::Module *module,
|
||||
llvm::TargetMachine *targetMachine,
|
||||
const IRGenOptions &opts,
|
||||
UnifiedStatsReporter *stats,
|
||||
DiagnosticEngine &diags,
|
||||
llvm::raw_pwrite_stream &out,
|
||||
llvm::sys::Mutex *diagMutex) {
|
||||
bool swift::compileAndWriteLLVM(
|
||||
llvm::Module *module, llvm::TargetMachine *targetMachine,
|
||||
const IRGenOptions &opts, UnifiedStatsReporter *stats,
|
||||
DiagnosticEngine &diags, llvm::raw_pwrite_stream &out,
|
||||
llvm::sys::Mutex *diagMutex, llvm::raw_pwrite_stream *casid) {
|
||||
|
||||
// Set up the final code emission pass. Bitcode/LLVM IR is emitted as part of
|
||||
// the optimization pass pipeline.
|
||||
@@ -639,8 +659,8 @@ bool swift::compileAndWriteLLVM(llvm::Module *module,
|
||||
EmitPasses.add(createTargetTransformInfoWrapperPass(
|
||||
targetMachine->getTargetIRAnalysis()));
|
||||
|
||||
bool fail = targetMachine->addPassesToEmitFile(EmitPasses, out, nullptr,
|
||||
FileType, !opts.Verify);
|
||||
bool fail = targetMachine->addPassesToEmitFile(
|
||||
EmitPasses, out, nullptr, FileType, !opts.Verify, nullptr, casid);
|
||||
if (fail) {
|
||||
diagnoseSync(diags, diagMutex, SourceLoc(),
|
||||
diag::error_codegen_init_fail);
|
||||
|
||||
25
test/CAS/mccas.swift
Normal file
25
test/CAS/mccas.swift
Normal file
@@ -0,0 +1,25 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -c %s -target arm64-apple-darwin23.0.0 -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 -target arm64-apple-darwin23.0.0 -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 -target arm64-apple-darwin23.0.0 -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: CASID:Jllvmcas://{{.*}}
|
||||
|
||||
// RUN: %target-swift-frontend -c %s -target arm64-apple-darwin23.0.0 -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: CASID:Jllvmcas://{{.*}}
|
||||
|
||||
// RUN: %target-swift-frontend -c %s -target arm64-apple-darwin23.0.0 -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: CASID:Jllvmcas://{{.*}}
|
||||
|
||||
// RUN: %target-swift-frontend -c %s -target arm64-apple-darwin23.0.0 -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() {}
|
||||
Reference in New Issue
Block a user