diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2045,57 +2045,10 @@ } } -static void addX86AlignBranchArgs(const Driver &D, const ArgList &Args, - ArgStringList &CmdArgs) { - if (Args.hasArg(options::OPT_mbranches_within_32B_boundaries)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-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 { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back( - Args.MakeArgString("-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; - } - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back(Args.MakeArgString("-x86-align-branch=" + 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 { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back( - Args.MakeArgString("-x86-pad-max-prefix-size=" + Twine(PrefixSize))); - } - } -} - void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); - addX86AlignBranchArgs(D, Args, CmdArgs); + addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/false); if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || Args.hasArg(options::OPT_mkernel) || @@ -6743,7 +6696,8 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - addX86AlignBranchArgs(getToolChain().getDriver(), Args, CmdArgs); + addX86AlignBranchArgs(getToolChain().getDriver(), Args, CmdArgs, + /*IsLTO=*/false); if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) { StringRef Value = A->getValue(); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -127,6 +127,8 @@ void addMultilibFlag(bool Enabled, const char *const Flag, Multilib::flags_list &Flags); +void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, bool IsLTO); } // end namespace tools } // end namespace driver } // end namespace clang diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -358,6 +358,7 @@ ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO) { 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 @@ -374,10 +375,9 @@ #endif SmallString<1024> Plugin; - llvm::sys::path::native(Twine(ToolChain.getDriver().Dir) + - "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + - Suffix, - Plugin); + llvm::sys::path::native( + Twine(D.Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix, + Plugin); CmdArgs.push_back(Args.MakeArgString(Plugin)); } @@ -417,7 +417,7 @@ if (IsThinLTO) CmdArgs.push_back("-plugin-opt=thinlto"); - StringRef Parallelism = getLTOParallelism(Args, ToolChain.getDriver()); + StringRef Parallelism = getLTOParallelism(Args, D); if (!Parallelism.empty()) CmdArgs.push_back( Args.MakeArgString("-plugin-opt=jobs=" + Twine(Parallelism))); @@ -449,7 +449,7 @@ 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)); @@ -492,11 +492,12 @@ } // 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, @@ -1423,3 +1424,53 @@ 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)); + } + } +} diff --git a/clang/test/Driver/x86-malign-branch.c b/clang/test/Driver/x86-malign-branch.c --- a/clang/test/Driver/x86-malign-branch.c +++ b/clang/test/Driver/x86-malign-branch.c @@ -1,8 +1,10 @@ -/// Test that -malign-branch* and -mbranches-within-32B-boundaries are parsed and converted to -mllvm options. +/// Test that -malign-branch* and -mbranches-within-32B-boundaries are parsed and converted to MC options. /// Test -malign-branch-boundary= // RUN: %clang -target x86_64 -malign-branch-boundary=16 %s -c -### 2>&1 | FileCheck %s --check-prefix=BOUNDARY // BOUNDARY: "-mllvm" "-x86-align-branch-boundary=16" +// RUN: %clang -target x86_64-unknown-linux -malign-branch-boundary=16 -flto %s -### 2>&1 | FileCheck %s --check-prefix=BOUNDARY-LTO +// BOUNDARY-LTO: "-plugin-opt=-x86-align-branch-boundary=16" // RUN: %clang -target x86_64 -malign-branch-boundary=8 %s -c -### 2>&1 | FileCheck %s --check-prefix=BOUNDARY-ERR // RUN: %clang -target x86_64 -malign-branch-boundary=15 %s -c -### 2>&1 | FileCheck %s --check-prefix=BOUNDARY-ERR @@ -13,6 +15,8 @@ // TYPE0: "-mllvm" "-x86-align-branch=fused+jcc+jmp" // RUN: %clang -target x86_64 -malign-branch=fused,jcc,jmp,ret,call,indirect %s -c -### %s 2>&1 | FileCheck %s --check-prefix=TYPE1 // TYPE1: "-mllvm" "-x86-align-branch=fused+jcc+jmp+ret+call+indirect" +// RUN: %clang -target x86_64-unknown-linux -malign-branch=fused,jcc,jmp -flto %s -### %s 2>&1 | FileCheck %s --check-prefix=TYPE0-LTO +// TYPE0-LTO: "-plugin-opt=-x86-align-branch=fused+jcc+jmp" // RUN: %clang -target x86_64 -malign-branch=fused,foo,bar %s -c -### %s 2>&1 | FileCheck %s --check-prefix=TYPE-ERR // TYPE-ERR: invalid argument 'foo' to -malign-branch=; each element must be one of: fused, jcc, jmp, call, ret, indirect @@ -23,10 +27,14 @@ // PREFIX-0: "-mllvm" "-x86-pad-max-prefix-size=0" // RUN: %clang -target x86_64 -mpad-max-prefix-size=15 %s -c -### 2>&1 | FileCheck %s --check-prefix=PREFIX-15 // PREFIX-15: "-mllvm" "-x86-pad-max-prefix-size=15" +// RUN: %clang -target x86_64-unknown-linux -mpad-max-prefix-size=0 -flto %s -### 2>&1 | FileCheck %s --check-prefix=PREFIX-0-LTO +// PREFIX-0-LTO: "-plugin-opt=-x86-pad-max-prefix-size=0" /// Test -mbranches-within-32B-boundaries // RUN: %clang -target x86_64 -mbranches-within-32B-boundaries %s -c -### 2>&1 | FileCheck %s --check-prefix=32B // 32B: "-mllvm" "-x86-branches-within-32B-boundaries" +// RUN: %clang -target x86_64-unknown-linux -mbranches-within-32B-boundaries -flto %s -### 2>&1 | FileCheck %s --check-prefix=32B-LTO +// 32B-LTO: "-plugin-opt=-x86-branches-within-32B-boundaries" /// Unsupported on other targets. // RUN: %clang -target aarch64 -malign-branch=jmp %s -c -### 2>&1 | FileCheck --check-prefix=UNUSED %s