void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { // Check our CUDA version if we're going to include the CUDA headers. if (!DriverArgs.hasArg(options::OPT_nocudainc) && !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) { StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ); assert(!Arch.empty() && "Must have an explicit GPU arch."); CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch)); } CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); }
static StringRef getHWMultLib(const ArgList &Args) { StringRef HWMult = Args.getLastArgValue(options::OPT_mhwmult_EQ, "auto"); if (HWMult == "auto") { HWMult = getSupportedHWMult(Args.getLastArg(options::OPT_mmcu_EQ)); } return llvm::StringSwitch<StringRef>(HWMult) .Case("16bit", "-lmul_16") .Case("32bit", "-lmul_32") .Case("f5series", "-lmul_f5") .Default("-lmul_none"); }
static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, const FrontendOptions &FrontendOpts, StringRef SDKPath, StringRef ResourceDir) { using namespace options; if (const Arg *A = Args.getLastArg(OPT_g_Group)) { if (A->getOption().matches(OPT_g)) Opts.DebugInfoKind = IRGenDebugInfoKind::Normal; else if (A->getOption().matches(options::OPT_gline_tables_only)) Opts.DebugInfoKind = IRGenDebugInfoKind::LineTables; else assert(A->getOption().matches(options::OPT_gnone) && "unknown -g<kind> option"); if (Opts.DebugInfoKind == IRGenDebugInfoKind::Normal) { ArgStringList RenderedArgs; for (auto A : Args) A->render(Args, RenderedArgs); CompilerInvocation::buildDWARFDebugFlags(Opts.DWARFDebugFlags, RenderedArgs, SDKPath, ResourceDir); // TODO: Should we support -fdebug-compilation-dir? llvm::SmallString<256> cwd; llvm::sys::fs::current_path(cwd); Opts.DebugCompilationDir = cwd.str(); } } for (const Arg *A : make_range(Args.filtered_begin(OPT_l, OPT_framework), Args.filtered_end())) { LibraryKind Kind; if (A->getOption().matches(OPT_l)) { Kind = LibraryKind::Library; } else if (A->getOption().matches(OPT_framework)) { Kind = LibraryKind::Framework; } else { llvm_unreachable("Unknown LinkLibrary option kind"); } Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind)); } if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names, OPT_enable_llvm_value_names)) { Opts.HasValueNamesSetting = true; Opts.ValueNames = valueNames->getOption().matches(OPT_enable_llvm_value_names); } Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts); Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer); if (Args.hasArg(OPT_disable_llvm_verify)) Opts.Verify = false; Opts.EmitStackPromotionChecks |= Args.hasArg(OPT_stack_promotion_checks); if (const Arg *A = Args.getLastArg(OPT_stack_promotion_limit)) { unsigned limit; if (StringRef(A->getValue()).getAsInteger(10, limit)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.StackPromotionSizeLimit = limit; } if (Args.hasArg(OPT_autolink_force_load)) Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name); // TODO: investigate whether these should be removed, in favor of definitions // in other classes. if (FrontendOpts.PrimaryInput && FrontendOpts.PrimaryInput->isFilename()) { unsigned Index = FrontendOpts.PrimaryInput->Index; Opts.MainInputFilename = FrontendOpts.InputFilenames[Index]; } else if (FrontendOpts.InputFilenames.size() == 1) { Opts.MainInputFilename = FrontendOpts.InputFilenames.front(); } Opts.OutputFilenames = FrontendOpts.OutputFilenames; Opts.ModuleName = FrontendOpts.ModuleName; if (Args.hasArg(OPT_use_jit)) Opts.UseJIT = true; for (const Arg *A : make_range(Args.filtered_begin(OPT_verify_type_layout), Args.filtered_end())) { Opts.VerifyTypeLayoutNames.push_back(A->getValue()); } for (const Arg *A : make_range(Args.filtered_begin( OPT_disable_autolink_framework), Args.filtered_end())) { Opts.DisableAutolinkFrameworks.push_back(A->getValue()); } Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate); Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree); if (Args.hasArg(OPT_embed_bitcode)) Opts.EmbedMode = IRGenEmbedMode::EmbedBitcode; else if (Args.hasArg(OPT_embed_bitcode_marker)) Opts.EmbedMode = IRGenEmbedMode::EmbedMarker; if (Opts.EmbedMode == IRGenEmbedMode::EmbedBitcode) { // Keep track of backend options so we can embed them in a separate data // section and use them when building from the bitcode. This can be removed // when all the backend options are recorded in the IR. for (ArgList::const_iterator A = Args.begin(), AE = Args.end(); A != AE; ++ A) { // Do not encode output and input. if ((*A)->getOption().getID() == options::OPT_o || (*A)->getOption().getID() == options::OPT_INPUT || (*A)->getOption().getID() == options::OPT_primary_file || (*A)->getOption().getID() == options::OPT_embed_bitcode) continue; ArgStringList ASL; (*A)->render(Args, ASL); for (ArgStringList::iterator it = ASL.begin(), ie = ASL.end(); it != ie; ++ it) { StringRef ArgStr(*it); Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); // using \00 to terminate to avoid problem decoding. Opts.CmdArgs.push_back('\0'); } } } if (Args.hasArg(OPT_enable_reflection_metadata)) { Opts.StripReflectionMetadata = false; Opts.StripReflectionNames = false; } if (Args.hasArg(OPT_strip_reflection_names)) { Opts.StripReflectionNames = true; } if (Args.hasArg(OPT_strip_reflection_metadata)) { Opts.StripReflectionMetadata = true; Opts.StripReflectionNames = true; } return false; }
static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, const FrontendOptions &FrontendOpts, const SILOptions &SILOpts, StringRef SDKPath, StringRef ResourceDir, const llvm::Triple &Triple) { using namespace options; if (!SILOpts.SILOutputFileNameForDebugging.empty()) { Opts.DebugInfoKind = IRGenDebugInfoKind::LineTables; } else if (const Arg *A = Args.getLastArg(OPT_g_Group)) { if (A->getOption().matches(OPT_g)) Opts.DebugInfoKind = IRGenDebugInfoKind::Normal; else if (A->getOption().matches(options::OPT_gline_tables_only)) Opts.DebugInfoKind = IRGenDebugInfoKind::LineTables; else if (A->getOption().matches(options::OPT_gdwarf_types)) Opts.DebugInfoKind = IRGenDebugInfoKind::DwarfTypes; else assert(A->getOption().matches(options::OPT_gnone) && "unknown -g<kind> option"); if (Opts.DebugInfoKind > IRGenDebugInfoKind::LineTables) { ArgStringList RenderedArgs; for (auto A : Args) A->render(Args, RenderedArgs); CompilerInvocation::buildDWARFDebugFlags(Opts.DWARFDebugFlags, RenderedArgs, SDKPath, ResourceDir); // TODO: Should we support -fdebug-compilation-dir? llvm::SmallString<256> cwd; llvm::sys::fs::current_path(cwd); Opts.DebugCompilationDir = cwd.str(); } } for (const Arg *A : Args.filtered(OPT_Xcc)) { StringRef Opt = A->getValue(); if (Opt.startswith("-D") || Opt.startswith("-U")) Opts.ClangDefines.push_back(Opt); } for (const Arg *A : Args.filtered(OPT_l, OPT_framework)) { LibraryKind Kind; if (A->getOption().matches(OPT_l)) { Kind = LibraryKind::Library; } else if (A->getOption().matches(OPT_framework)) { Kind = LibraryKind::Framework; } else { llvm_unreachable("Unknown LinkLibrary option kind"); } Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind)); } if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names, OPT_enable_llvm_value_names)) { Opts.HasValueNamesSetting = true; Opts.ValueNames = valueNames->getOption().matches(OPT_enable_llvm_value_names); } Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts); Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer); if (Args.hasArg(OPT_disable_llvm_verify)) Opts.Verify = false; Opts.EmitStackPromotionChecks |= Args.hasArg(OPT_stack_promotion_checks); if (const Arg *A = Args.getLastArg(OPT_stack_promotion_limit)) { unsigned limit; if (StringRef(A->getValue()).getAsInteger(10, limit)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.StackPromotionSizeLimit = limit; } if (Args.hasArg(OPT_autolink_force_load)) Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name); Opts.ModuleName = FrontendOpts.ModuleName; if (Args.hasArg(OPT_use_jit)) Opts.UseJIT = true; for (const Arg *A : Args.filtered(OPT_verify_type_layout)) { Opts.VerifyTypeLayoutNames.push_back(A->getValue()); } for (const Arg *A : Args.filtered(OPT_disable_autolink_framework)) { Opts.DisableAutolinkFrameworks.push_back(A->getValue()); } Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate); const Arg *ProfileUse = Args.getLastArg(OPT_profile_use); Opts.UseProfile = ProfileUse ? ProfileUse->getValue() : ""; Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree); Opts.UseSwiftCall = Args.hasArg(OPT_enable_swiftcall); // This is set to true by default. Opts.UseIncrementalLLVMCodeGen &= !Args.hasArg(OPT_disable_incremental_llvm_codegeneration); if (Args.hasArg(OPT_embed_bitcode)) Opts.EmbedMode = IRGenEmbedMode::EmbedBitcode; else if (Args.hasArg(OPT_embed_bitcode_marker)) Opts.EmbedMode = IRGenEmbedMode::EmbedMarker; if (Opts.EmbedMode == IRGenEmbedMode::EmbedBitcode) { // Keep track of backend options so we can embed them in a separate data // section and use them when building from the bitcode. This can be removed // when all the backend options are recorded in the IR. for (const Arg *A : Args) { // Do not encode output and input. if (A->getOption().getID() == options::OPT_o || A->getOption().getID() == options::OPT_INPUT || A->getOption().getID() == options::OPT_primary_file || A->getOption().getID() == options::OPT_embed_bitcode) continue; ArgStringList ASL; A->render(Args, ASL); for (ArgStringList::iterator it = ASL.begin(), ie = ASL.end(); it != ie; ++ it) { StringRef ArgStr(*it); Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); // using \00 to terminate to avoid problem decoding. Opts.CmdArgs.push_back('\0'); } } } if (const Arg *A = Args.getLastArg(options::OPT_sanitize_coverage_EQ)) { Opts.SanitizeCoverage = parseSanitizerCoverageArgValue(A, Triple, Diags, Opts.Sanitizers); } else if (Opts.Sanitizers & SanitizerKind::Fuzzer) { // Automatically set coverage flags, unless coverage type was explicitly // requested. Opts.SanitizeCoverage.IndirectCalls = true; Opts.SanitizeCoverage.TraceCmp = true; Opts.SanitizeCoverage.TracePCGuard = true; Opts.SanitizeCoverage.CoverageType = llvm::SanitizerCoverageOptions::SCK_Edge; } if (Args.hasArg(OPT_disable_reflection_metadata)) { Opts.EnableReflectionMetadata = false; Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_disable_reflection_names)) { Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_enable_class_resilience)) { Opts.EnableClassResilience = true; } if (Args.hasArg(OPT_enable_resilience_bypass)) { Opts.EnableResilienceBypass = true; } for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library)) Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library)); return false; }
void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const auto &TC = static_cast<const toolchains::CudaToolChain &>(getToolChain()); assert(TC.getTriple().isNVPTX() && "Wrong platform"); ArgStringList CmdArgs; // OpenMP uses nvlink to link cubin files. The result will be embedded in the // host binary by the host linker. assert(!JA.isHostOffloading(Action::OFK_OpenMP) && "CUDA toolchain not expected for an OpenMP host device."); if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); } else assert(Output.isNothing() && "Invalid output."); if (Args.hasArg(options::OPT_g_Flag)) CmdArgs.push_back("-g"); if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("-v"); StringRef GPUArch = Args.getLastArgValue(options::OPT_march_EQ); assert(!GPUArch.empty() && "At least one GPU Arch required for ptxas."); CmdArgs.push_back("-arch"); CmdArgs.push_back(Args.MakeArgString(GPUArch)); // Add paths specified in LIBRARY_PATH environment variable as -L options. addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); // Add paths for the default clang library path. SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(TC.getDriver().Dir); llvm::sys::path::append(DefaultLibPath, "lib" CLANG_LIBDIR_SUFFIX); CmdArgs.push_back(Args.MakeArgString(Twine("-L") + DefaultLibPath)); // Add linking against library implementing OpenMP calls on NVPTX target. CmdArgs.push_back("-lomptarget-nvptx"); for (const auto &II : Inputs) { if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR || II.getType() == types::TY_LTO_BC || II.getType() == types::TY_LLVM_BC) { C.getDriver().Diag(diag::err_drv_no_linker_llvm_support) << getToolChain().getTripleString(); continue; } // Currently, we only pass the input files to the linker, we do not pass // any libraries that may be valid only for the host. if (!II.isFilename()) continue; const char *CubinF = C.addTempFile( C.getArgs().MakeArgString(getToolChain().getInputFilename(II))); CmdArgs.push_back(CubinF); } AddOpenMPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("nvlink")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); }
void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const auto &TC = static_cast<const toolchains::CudaToolChain &>(getToolChain()); assert(TC.getTriple().isNVPTX() && "Wrong platform"); StringRef GPUArchName; // If this is an OpenMP action we need to extract the device architecture // from the -march=arch option. This option may come from -Xopenmp-target // flag or the default value. if (JA.isDeviceOffloading(Action::OFK_OpenMP)) { GPUArchName = Args.getLastArgValue(options::OPT_march_EQ); assert(!GPUArchName.empty() && "Must have an architecture passed in."); } else GPUArchName = JA.getOffloadingArch(); // Obtain architecture from the action. CudaArch gpu_arch = StringToCudaArch(GPUArchName); assert(gpu_arch != CudaArch::UNKNOWN && "Device action expected to have an architecture."); // Check that our installation's ptxas supports gpu_arch. if (!Args.hasArg(options::OPT_no_cuda_version_check)) { TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch); } ArgStringList CmdArgs; CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32"); if (Args.hasFlag(options::OPT_cuda_noopt_device_debug, options::OPT_no_cuda_noopt_device_debug, false)) { // ptxas does not accept -g option if optimization is enabled, so // we ignore the compiler's -O* options if we want debug info. CmdArgs.push_back("-g"); CmdArgs.push_back("--dont-merge-basicblocks"); CmdArgs.push_back("--return-at-end"); } else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { // Map the -O we received to -O{0,1,2,3}. // // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's // default, so it may correspond more closely to the spirit of clang -O2. // -O3 seems like the least-bad option when -Osomething is specified to // clang but it isn't handled below. StringRef OOpt = "3"; if (A->getOption().matches(options::OPT_O4) || A->getOption().matches(options::OPT_Ofast)) OOpt = "3"; else if (A->getOption().matches(options::OPT_O0)) OOpt = "0"; else if (A->getOption().matches(options::OPT_O)) { // -Os, -Oz, and -O(anything else) map to -O2, for lack of better options. OOpt = llvm::StringSwitch<const char *>(A->getValue()) .Case("1", "1") .Case("2", "2") .Case("3", "3") .Case("s", "2") .Case("z", "2") .Default("2"); } CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); } else { // If no -O was passed, pass -O0 to ptxas -- no opt flag should correspond // to no optimizations, but ptxas's default is -O3. CmdArgs.push_back("-O0"); } // Pass -v to ptxas if it was passed to the driver. if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("-v"); CmdArgs.push_back("--gpu-name"); CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch))); CmdArgs.push_back("--output-file"); CmdArgs.push_back(Args.MakeArgString(TC.getInputFilename(Output))); for (const auto& II : Inputs) CmdArgs.push_back(Args.MakeArgString(II.getFilename())); for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_ptxas)) CmdArgs.push_back(Args.MakeArgString(A)); // In OpenMP we need to generate relocatable code. if (JA.isOffloading(Action::OFK_OpenMP) && Args.hasFlag(options::OPT_fopenmp_relocatable_target, options::OPT_fnoopenmp_relocatable_target, /*Default=*/ true)) CmdArgs.push_back("-c"); const char *Exec; if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ)) Exec = A->getValue(); else Exec = Args.MakeArgString(TC.GetProgramPath("ptxas")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); }
static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, const FrontendOptions &FrontendOpts, const SILOptions &SILOpts, StringRef SDKPath, StringRef ResourceDir, const llvm::Triple &Triple) { using namespace options; if (!SILOpts.SILOutputFileNameForDebugging.empty()) { Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables; } else if (const Arg *A = Args.getLastArg(OPT_g_Group)) { if (A->getOption().matches(OPT_g)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::Normal; else if (A->getOption().matches(options::OPT_gline_tables_only)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables; else if (A->getOption().matches(options::OPT_gdwarf_types)) Opts.DebugInfoLevel = IRGenDebugInfoLevel::DwarfTypes; else assert(A->getOption().matches(options::OPT_gnone) && "unknown -g<kind> option"); if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables) { if (Args.hasArg(options::OPT_debug_info_store_invocation)) { ArgStringList RenderedArgs; for (auto A : Args) A->render(Args, RenderedArgs); CompilerInvocation::buildDebugFlags(Opts.DebugFlags, RenderedArgs, SDKPath, ResourceDir); } // TODO: Should we support -fdebug-compilation-dir? llvm::SmallString<256> cwd; llvm::sys::fs::current_path(cwd); Opts.DebugCompilationDir = cwd.str(); } } if (const Arg *A = Args.getLastArg(options::OPT_debug_info_format)) { if (A->containsValue("dwarf")) Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF; else if (A->containsValue("codeview")) Opts.DebugInfoFormat = IRGenDebugInfoFormat::CodeView; else Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); } else if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::None) { // If -g was specified but not -debug-info-format, DWARF is assumed. Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF; } if (Args.hasArg(options::OPT_debug_info_format) && !Args.hasArg(options::OPT_g_Group)) { const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format); Diags.diagnose(SourceLoc(), diag::error_option_missing_required_argument, debugFormatArg->getAsString(Args), "-g"); } if (Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView && (Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables || Opts.DebugInfoLevel == IRGenDebugInfoLevel::DwarfTypes)) { const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format); Diags.diagnose(SourceLoc(), diag::error_argument_not_allowed_with, debugFormatArg->getAsString(Args), Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables ? "-gline-tables-only" : "-gdwarf_types"); } for (auto A : Args.getAllArgValues(options::OPT_debug_prefix_map)) { auto SplitMap = StringRef(A).split('='); Opts.DebugPrefixMap.addMapping(SplitMap.first, SplitMap.second); } for (const Arg *A : Args.filtered(OPT_Xcc)) { StringRef Opt = A->getValue(); if (Opt.startswith("-D") || Opt.startswith("-U")) Opts.ClangDefines.push_back(Opt); } for (const Arg *A : Args.filtered(OPT_l, OPT_framework)) { LibraryKind Kind; if (A->getOption().matches(OPT_l)) { Kind = LibraryKind::Library; } else if (A->getOption().matches(OPT_framework)) { Kind = LibraryKind::Framework; } else { llvm_unreachable("Unknown LinkLibrary option kind"); } Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind)); } if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names, OPT_enable_llvm_value_names)) { Opts.HasValueNamesSetting = true; Opts.ValueNames = valueNames->getOption().matches(OPT_enable_llvm_value_names); } Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableSwiftSpecificLLVMOptzns |= Args.hasArg(OPT_disable_swift_specific_llvm_optzns); Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer); if (Args.hasArg(OPT_disable_llvm_verify)) Opts.Verify = false; Opts.EmitStackPromotionChecks |= Args.hasArg(OPT_stack_promotion_checks); if (const Arg *A = Args.getLastArg(OPT_stack_promotion_limit)) { unsigned limit; if (StringRef(A->getValue()).getAsInteger(10, limit)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.StackPromotionSizeLimit = limit; } if (Args.hasArg(OPT_autolink_force_load)) Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name); Opts.ModuleName = FrontendOpts.ModuleName; if (Args.hasArg(OPT_use_jit)) Opts.UseJIT = true; for (const Arg *A : Args.filtered(OPT_verify_type_layout)) { Opts.VerifyTypeLayoutNames.push_back(A->getValue()); } for (const Arg *A : Args.filtered(OPT_disable_autolink_framework)) { Opts.DisableAutolinkFrameworks.push_back(A->getValue()); } Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate); const Arg *ProfileUse = Args.getLastArg(OPT_profile_use); Opts.UseProfile = ProfileUse ? ProfileUse->getValue() : ""; Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree); Opts.EnableDynamicReplacementChaining |= Args.hasArg(OPT_enable_dynamic_replacement_chaining); Opts.UseSwiftCall = Args.hasArg(OPT_enable_swiftcall); // This is set to true by default. Opts.UseIncrementalLLVMCodeGen &= !Args.hasArg(OPT_disable_incremental_llvm_codegeneration); if (Args.hasArg(OPT_embed_bitcode)) Opts.EmbedMode = IRGenEmbedMode::EmbedBitcode; else if (Args.hasArg(OPT_embed_bitcode_marker)) Opts.EmbedMode = IRGenEmbedMode::EmbedMarker; if (Opts.EmbedMode == IRGenEmbedMode::EmbedBitcode) { // Keep track of backend options so we can embed them in a separate data // section and use them when building from the bitcode. This can be removed // when all the backend options are recorded in the IR. for (const Arg *A : Args) { // Do not encode output and input. if (A->getOption().getID() == options::OPT_o || A->getOption().getID() == options::OPT_INPUT || A->getOption().getID() == options::OPT_primary_file || A->getOption().getID() == options::OPT_embed_bitcode) continue; ArgStringList ASL; A->render(Args, ASL); for (ArgStringList::iterator it = ASL.begin(), ie = ASL.end(); it != ie; ++ it) { StringRef ArgStr(*it); Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); // using \00 to terminate to avoid problem decoding. Opts.CmdArgs.push_back('\0'); } } } if (const Arg *A = Args.getLastArg(options::OPT_sanitize_coverage_EQ)) { Opts.SanitizeCoverage = parseSanitizerCoverageArgValue(A, Triple, Diags, Opts.Sanitizers); } else if (Opts.Sanitizers & SanitizerKind::Fuzzer) { // Automatically set coverage flags, unless coverage type was explicitly // requested. Opts.SanitizeCoverage.IndirectCalls = true; Opts.SanitizeCoverage.TraceCmp = true; Opts.SanitizeCoverage.TracePCGuard = true; Opts.SanitizeCoverage.CoverageType = llvm::SanitizerCoverageOptions::SCK_Edge; } if (Args.hasArg(OPT_disable_reflection_metadata)) { Opts.EnableReflectionMetadata = false; Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_disable_reflection_names)) { Opts.EnableReflectionNames = false; } if (Args.hasArg(OPT_enable_class_resilience)) { Opts.EnableClassResilience = true; } if (Args.hasArg(OPT_enable_resilience_bypass)) { Opts.EnableResilienceBypass = true; } // PE/COFF cannot deal with the cross-module reference to the metadata parent // (e.g. NativeObject). Force the lazy initialization of the VWT always. Opts.LazyInitializeClassMetadata = Triple.isOSBinFormatCOFF(); if (const Arg *A = Args.getLastArg(OPT_read_type_info_path_EQ)) { Opts.ReadTypeInfoPath = A->getValue(); } for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library)) Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library)); if (const Arg *A = Args.getLastArg(OPT_type_info_dump_filter_EQ)) { StringRef mode(A->getValue()); if (mode == "all") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::All; else if (mode == "resilient") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::Resilient; else if (mode == "fragile") Opts.TypeInfoFilter = IRGenOptions::TypeInfoDumpFilter::Fragile; else { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); } } return false; }