forked from OSchip/llvm-project
[Driver][X86] Support branch align options with LTO
Summary: Before this patch, we use two different ways to pass options to align branch depending on whether LTO is enabled. For example, `-mbranches-within-32B-boundaries` w/o LTO and `-Wl,-plugin-opt=-x86-branches-within-32B-boundaries` w/ LTO. It's inconvenient, so this patch unifies the way: we only need to pass options like `-mbranches-within-32B-boundaries` to align branches, no matter LTO is enabled or not. Differential Revision: https://reviews.llvm.org/D80289
This commit is contained in:
parent
c1d5b831b1
commit
4954449995
|
@ -2045,57 +2045,10 @@ void Clang::AddSystemZTargetArgs(const ArgList &Args,
|
|||
}
|
||||
}
|
||||
|
||||
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) ||
|
||||
|
@ -6745,7 +6698,8 @@ void ClangAs::AddMIPSTargetArgs(const ArgList &Args,
|
|||
|
||||
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();
|
||||
|
|
|
@ -358,6 +358,7 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
|||
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 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
|||
#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 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
|||
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 @@ void tools::addLTOOptions(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));
|
||||
|
@ -492,11 +492,12 @@ void tools::addLTOOptions(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,
|
||||
|
@ -1423,3 +1424,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,6 +127,8 @@ SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue