diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Driver/ToolChains/CommonArgs.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-cfca06d7963fa0909f90483b42a6d7d194d01e08.tar.gz src-cfca06d7963fa0909f90483b42a6d7d194d01e08.zip |
Vendor import of llvm-project master 2e10b7a39b9, the last commit beforevendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9vendor/llvm-project/master
the llvmorg-12-init tag, from which release/11.x was branched.
Notes
Notes:
svn path=/vendor/llvm-project/master/; revision=363578
svn path=/vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9/; revision=363579; tag=vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9
Diffstat (limited to 'clang/lib/Driver/ToolChains/CommonArgs.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/CommonArgs.cpp | 344 |
1 files changed, 175 insertions, 169 deletions
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 37ec73468570..1cac5a0822a4 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -12,6 +12,7 @@ #include "Arch/Mips.h" #include "Arch/PPC.h" #include "Arch/SystemZ.h" +#include "Arch/VE.h" #include "Arch/X86.h" #include "HIP.h" #include "Hexagon.h" @@ -50,6 +51,7 @@ #include "llvm/Support/Program.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/Threading.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" @@ -82,6 +84,31 @@ void tools::handleTargetFeaturesGroup(const ArgList &Args, } } +std::vector<StringRef> +tools::unifyTargetFeatures(const std::vector<StringRef> &Features) { + std::vector<StringRef> UnifiedFeatures; + // Find the last of each feature. + llvm::StringMap<unsigned> LastOpt; + for (unsigned I = 0, N = Features.size(); I < N; ++I) { + StringRef Name = Features[I]; + assert(Name[0] == '-' || Name[0] == '+'); + LastOpt[Name.drop_front(1)] = I; + } + + for (unsigned I = 0, N = Features.size(); I < N; ++I) { + // If this feature was overridden, ignore it. + StringRef Name = Features[I]; + llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name.drop_front(1)); + assert(LastI != LastOpt.end()); + unsigned Last = LastI->second; + if (Last != I) + continue; + + UnifiedFeatures.push_back(Name); + } + return UnifiedFeatures; +} + void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs, const char *ArgName, const char *EnvVar) { const char *DirList = ::getenv(EnvVar); @@ -91,7 +118,7 @@ void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs, return; // Nothing to do. StringRef Name(ArgName); - if (Name.equals("-I") || Name.equals("-L")) + if (Name.equals("-I") || Name.equals("-L") || Name.empty()) CombinedArg = true; StringRef Dirs(DirList); @@ -151,14 +178,12 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); for (const auto &II : Inputs) { - // If the current tool chain refers to an OpenMP or HIP offloading host, we - // should ignore inputs that refer to OpenMP or HIP offloading devices - + // If the current tool chain refers to an OpenMP offloading host, we + // should ignore inputs that refer to OpenMP offloading devices - // they will be embedded according to a proper linker script. if (auto *IA = II.getAction()) if ((JA.isHostOffloading(Action::OFK_OpenMP) && - IA->isDeviceOffloading(Action::OFK_OpenMP)) || - (JA.isHostOffloading(Action::OFK_HIP) && - IA->isDeviceOffloading(Action::OFK_HIP))) + IA->isDeviceOffloading(Action::OFK_OpenMP))) continue; if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType())) @@ -278,7 +303,7 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, StringRef CPUName; StringRef ABIName; mips::getMipsCPUAndABI(Args, T, CPUName, ABIName); - return CPUName; + return std::string(CPUName); } case llvm::Triple::nvptx: @@ -293,15 +318,19 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, std::string TargetCPUName = ppc::getPPCTargetCPU(Args); // LLVM may default to generating code for the native CPU, // but, like gcc, we default to a more generic option for - // each architecture. (except on Darwin) - if (TargetCPUName.empty() && !T.isOSDarwin()) { - if (T.getArch() == llvm::Triple::ppc64) - TargetCPUName = "ppc64"; - else if (T.getArch() == llvm::Triple::ppc64le) - TargetCPUName = "ppc64le"; - else - TargetCPUName = "ppc"; - } + // each architecture. (except on AIX) + if (!TargetCPUName.empty()) + return TargetCPUName; + + if (T.isOSAIX()) + TargetCPUName = "pwr4"; + else if (T.getArch() == llvm::Triple::ppc64le) + TargetCPUName = "ppc64le"; + else if (T.getArch() == llvm::Triple::ppc64) + TargetCPUName = "ppc64"; + else + TargetCPUName = "ppc"; + return TargetCPUName; } @@ -334,18 +363,18 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T, case llvm::Triple::wasm32: case llvm::Triple::wasm64: - return getWebAssemblyTargetCPU(Args); + return std::string(getWebAssemblyTargetCPU(Args)); } } -unsigned tools::getLTOParallelism(const ArgList &Args, const Driver &D) { - unsigned Parallelism = 0; +llvm::StringRef tools::getLTOParallelism(const ArgList &Args, const Driver &D) { Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ); - if (LtoJobsArg && - StringRef(LtoJobsArg->getValue()).getAsInteger(10, Parallelism)) - D.Diag(diag::err_drv_invalid_int_value) << LtoJobsArg->getAsString(Args) - << LtoJobsArg->getValue(); - return Parallelism; + if (!LtoJobsArg) + return {}; + if (!llvm::get_threadpool_strategy(LtoJobsArg->getValue())) + D.Diag(diag::err_drv_invalid_int_value) + << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue(); + return LtoJobsArg->getValue(); } // CloudABI uses -ffunction-sections and -fdata-sections by default. @@ -353,28 +382,32 @@ bool tools::isUseSeparateSections(const llvm::Triple &Triple) { return Triple.getOS() == llvm::Triple::CloudABI; } -void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, +void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO) { - // Tell the linker to load the plugin. This has to come before AddLinkerInputs - // as gold requires -plugin to come before any -plugin-opt that -Wl might - // forward. - CmdArgs.push_back("-plugin"); + const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath()); + const Driver &D = ToolChain.getDriver(); + if (llvm::sys::path::filename(Linker) != "ld.lld" && + llvm::sys::path::stem(Linker) != "ld.lld") { + // Tell the linker to load the plugin. This has to come before + // AddLinkerInputs as gold requires -plugin to come before any -plugin-opt + // that -Wl might forward. + CmdArgs.push_back("-plugin"); #if defined(_WIN32) - const char *Suffix = ".dll"; + const char *Suffix = ".dll"; #elif defined(__APPLE__) - const char *Suffix = ".dylib"; + const char *Suffix = ".dylib"; #else - const char *Suffix = ".so"; + const char *Suffix = ".so"; #endif - SmallString<1024> Plugin; - llvm::sys::path::native(Twine(ToolChain.getDriver().Dir) + - "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + - Suffix, - Plugin); - CmdArgs.push_back(Args.MakeArgString(Plugin)); + SmallString<1024> Plugin; + llvm::sys::path::native( + Twine(D.Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix, + Plugin); + CmdArgs.push_back(Args.MakeArgString(Plugin)); + } // Try to pass driver level flags relevant to LTO code generation down to // the plugin. @@ -385,13 +418,19 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU)); if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { + // The optimization level matches + // CompilerInvocation.cpp:getOptimizationLevel(). StringRef OOpt; if (A->getOption().matches(options::OPT_O4) || A->getOption().matches(options::OPT_Ofast)) OOpt = "3"; - else if (A->getOption().matches(options::OPT_O)) + else if (A->getOption().matches(options::OPT_O)) { OOpt = A->getValue(); - else if (A->getOption().matches(options::OPT_O0)) + if (OOpt == "g") + OOpt = "1"; + else if (OOpt == "s" || OOpt == "z") + OOpt = "2"; + } else if (A->getOption().matches(options::OPT_O0)) OOpt = "0"; if (!OOpt.empty()) CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt)); @@ -406,7 +445,8 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, if (IsThinLTO) CmdArgs.push_back("-plugin-opt=thinlto"); - if (unsigned Parallelism = getLTOParallelism(Args, ToolChain.getDriver())) + StringRef Parallelism = getLTOParallelism(Args, D); + if (!Parallelism.empty()) CmdArgs.push_back( Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism))); @@ -437,7 +477,7 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, if (Arg *A = getLastProfileSampleUseArg(Args)) { StringRef FName = A->getValue(); if (!llvm::sys::fs::exists(FName)) - ToolChain.getDriver().Diag(diag::err_drv_no_such_file) << FName; + D.Diag(diag::err_drv_no_such_file) << FName; else CmdArgs.push_back( Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName)); @@ -480,17 +520,21 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, } // Setup statistics file output. - SmallString<128> StatsFile = - getStatsFileName(Args, Output, Input, ToolChain.getDriver()); + SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D); if (!StatsFile.empty()) CmdArgs.push_back( Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile)); + + addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true); } void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { + // Enable -frtlib-add-rpath by default for the case of VE. + const bool IsVE = TC.getTriple().isVE(); + bool DefaultValue = IsVE; if (!Args.hasFlag(options::OPT_frtlib_add_rpath, - options::OPT_fno_rtlib_add_rpath, false)) + options::OPT_fno_rtlib_add_rpath, DefaultValue)) return; std::string CandidateRPath = TC.getArchSpecificLibPath(); @@ -583,6 +627,11 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { + // Fuchsia never needs these. Any sanitizer runtimes with system + // dependencies use the `.deplibs` feature instead. + if (TC.getTriple().isOSFuchsia()) + return; + // Force linking against the system libraries sanitizers depends on // (see PR15823 why this is necessary). CmdArgs.push_back("--no-as-needed"); @@ -642,17 +691,21 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("stats_client"); // Collect static runtimes. - if (Args.hasArg(options::OPT_shared) || SanArgs.needsSharedRt()) { - // Don't link static runtimes into DSOs or if -shared-libasan. + if (Args.hasArg(options::OPT_shared)) { + // Don't link static runtimes into DSOs. return; } - if (SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { + + // Each static runtime that has a DSO counterpart above is excluded below, + // but runtimes that exist only as static are not affected by needsSharedRt. + + if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { StaticRuntimes.push_back("asan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("asan_cxx"); } - if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { StaticRuntimes.push_back("hwasan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("hwasan_cxx"); @@ -671,7 +724,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); } - if (SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("ubsan_minimal"); } else { @@ -684,18 +737,20 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("safestack"); RequiredSymbols.push_back("__safestack_init"); } - if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes()) - StaticRuntimes.push_back("cfi"); - if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) { - StaticRuntimes.push_back("cfi_diag"); - if (SanArgs.linkCXXRuntimes()) - StaticRuntimes.push_back("ubsan_standalone_cxx"); + if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) { + if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes()) + StaticRuntimes.push_back("cfi"); + if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) { + StaticRuntimes.push_back("cfi_diag"); + if (SanArgs.linkCXXRuntimes()) + StaticRuntimes.push_back("ubsan_standalone_cxx"); + } } if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes()) { NonWholeStaticRuntimes.push_back("stats"); RequiredSymbols.push_back("__sanitizer_stats_register"); } - if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("scudo_minimal"); if (SanArgs.linkCXXRuntimes()) @@ -751,7 +806,7 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("--export-dynamic"); if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic) - CmdArgs.push_back("-export-dynamic-symbol=__cfi_check"); + CmdArgs.push_back("--export-dynamic-symbol=__cfi_check"); return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty(); } @@ -834,10 +889,12 @@ void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename()); // First extract the dwo sections. - C.addCommand(std::make_unique<Command>(JA, T, Exec, ExtractArgs, II)); + C.addCommand(std::make_unique<Command>( + JA, T, ResponseFileSupport::AtFileCurCP(), Exec, ExtractArgs, II)); // Then remove them from the original .o file. - C.addCommand(std::make_unique<Command>(JA, T, Exec, StripArgs, II)); + C.addCommand(std::make_unique<Command>( + JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II)); } // Claim options we don't want to warn if they are unused. We do this for @@ -1211,7 +1268,14 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, case ToolChain::UNW_CompilerRT: if (LGT == LibGccType::StaticLibGcc) CmdArgs.push_back("-l:libunwind.a"); - else + else if (TC.getTriple().isOSCygMing()) { + if (LGT == LibGccType::SharedLibGcc) + CmdArgs.push_back("-l:libunwind.dll.a"); + else + // Let the linker choose between libunwind.dll.a and libunwind.a + // depending on what's available, and depending on the -static flag + CmdArgs.push_back("-lunwind"); + } else CmdArgs.push_back("-l:libunwind.so"); break; } @@ -1263,114 +1327,6 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D, } } -/// Add HIP linker script arguments at the end of the argument list so that -/// the fat binary is built by embedding the device images into the host. The -/// linker script also defines a symbol required by the code generation so that -/// the image can be retrieved at runtime. This should be used only in tool -/// chains that support linker scripts. -void tools::AddHIPLinkerScript(const ToolChain &TC, Compilation &C, - const InputInfo &Output, - const InputInfoList &Inputs, const ArgList &Args, - ArgStringList &CmdArgs, const JobAction &JA, - const Tool &T) { - - // If this is not a HIP host toolchain, we don't need to do anything. - if (!JA.isHostOffloading(Action::OFK_HIP)) - return; - - InputInfoList DeviceInputs; - for (const auto &II : Inputs) { - const Action *A = II.getAction(); - // Is this a device linking action? - if (A && isa<LinkJobAction>(A) && A->isDeviceOffloading(Action::OFK_HIP)) { - DeviceInputs.push_back(II); - } - } - - if (DeviceInputs.empty()) - return; - - // Create temporary linker script. Keep it if save-temps is enabled. - const char *LKS; - std::string Name = llvm::sys::path::filename(Output.getFilename()); - if (C.getDriver().isSaveTempsEnabled()) { - LKS = C.getArgs().MakeArgString(Name + ".lk"); - } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "lk"); - LKS = C.addTempFile(C.getArgs().MakeArgString(TmpName)); - } - - // Add linker script option to the command. - CmdArgs.push_back("-T"); - CmdArgs.push_back(LKS); - - // Create a buffer to write the contents of the linker script. - std::string LksBuffer; - llvm::raw_string_ostream LksStream(LksBuffer); - - // Get the HIP offload tool chain. - auto *HIPTC = static_cast<const toolchains::CudaToolChain *>( - C.getSingleOffloadToolChain<Action::OFK_HIP>()); - assert(HIPTC->getTriple().getArch() == llvm::Triple::amdgcn && - "Wrong platform"); - (void)HIPTC; - - const char *BundleFile; - if (C.getDriver().isSaveTempsEnabled()) { - BundleFile = C.getArgs().MakeArgString(Name + ".hipfb"); - } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "hipfb"); - BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpName)); - } - AMDGCN::constructHIPFatbinCommand(C, JA, BundleFile, DeviceInputs, Args, T); - - // Add commands to embed target binaries. We ensure that each section and - // image is 16-byte aligned. This is not mandatory, but increases the - // likelihood of data to be aligned with a cache block in several main host - // machines. - LksStream << "/*\n"; - LksStream << " HIP Offload Linker Script\n"; - LksStream << " *** Automatically generated by Clang ***\n"; - LksStream << "*/\n"; - LksStream << "TARGET(binary)\n"; - LksStream << "INPUT(" << BundleFile << ")\n"; - LksStream << "SECTIONS\n"; - LksStream << "{\n"; - LksStream << " .hip_fatbin :\n"; - LksStream << " ALIGN(0x10)\n"; - LksStream << " {\n"; - LksStream << " PROVIDE_HIDDEN(__hip_fatbin = .);\n"; - LksStream << " " << BundleFile << "\n"; - LksStream << " }\n"; - LksStream << " /DISCARD/ :\n"; - LksStream << " {\n"; - LksStream << " * ( __CLANG_OFFLOAD_BUNDLE__* )\n"; - LksStream << " }\n"; - LksStream << "}\n"; - LksStream << "INSERT BEFORE .data\n"; - LksStream.flush(); - - // Dump the contents of the linker script if the user requested that. We - // support this option to enable testing of behavior with -###. - if (C.getArgs().hasArg(options::OPT_fhip_dump_offload_linker_script)) - llvm::errs() << LksBuffer; - - // If this is a dry run, do not create the linker script file. - if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) - return; - - // Open script file and write the contents. - std::error_code EC; - llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::OF_None); - - if (EC) { - C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); - return; - } - - Lksf << LksBuffer; -} - SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args, const InputInfo &Output, const InputInfo &Input, @@ -1399,3 +1355,53 @@ void tools::addMultilibFlag(bool Enabled, const char *const Flag, Multilib::flags_list &Flags) { Flags.push_back(std::string(Enabled ? "+" : "-") + Flag); } + +void tools::addX86AlignBranchArgs(const Driver &D, const ArgList &Args, + ArgStringList &CmdArgs, bool IsLTO) { + auto addArg = [&, IsLTO](const Twine &Arg) { + if (IsLTO) { + CmdArgs.push_back(Args.MakeArgString("-plugin-opt=" + Arg)); + } else { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(Arg)); + } + }; + + if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) { + addArg(Twine("-x86-branches-within-32B-boundaries")); + } + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) { + StringRef Value = A->getValue(); + unsigned Boundary; + if (Value.getAsInteger(10, Boundary) || Boundary < 16 || + !llvm::isPowerOf2_64(Boundary)) { + D.Diag(diag::err_drv_invalid_argument_to_option) + << Value << A->getOption().getName(); + } else { + addArg("-x86-align-branch-boundary=" + Twine(Boundary)); + } + } + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) { + std::string AlignBranch; + for (StringRef T : A->getValues()) { + if (T != "fused" && T != "jcc" && T != "jmp" && T != "call" && + T != "ret" && T != "indirect") + D.Diag(diag::err_drv_invalid_malign_branch_EQ) + << T << "fused, jcc, jmp, call, ret, indirect"; + if (!AlignBranch.empty()) + AlignBranch += '+'; + AlignBranch += T; + } + addArg("-x86-align-branch=" + Twine(AlignBranch)); + } + if (const Arg *A = Args.getLastArg(options::OPT_mpad_max_prefix_size_EQ)) { + StringRef Value = A->getValue(); + unsigned PrefixSize; + if (Value.getAsInteger(10, PrefixSize)) { + D.Diag(diag::err_drv_invalid_argument_to_option) + << Value << A->getOption().getName(); + } else { + addArg("-x86-pad-max-prefix-size=" + Twine(PrefixSize)); + } + } +} |