mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +00:00
[Driver,CodeGen] Support -mtls-dialect= (#79256)
GCC supports -mtls-dialect= for several architectures to select TLSDESC. This patch supports the following values * x86: "gnu". "gnu2" (TLSDESC) is not supported yet. * RISC-V: "trad" (general dynamic), "desc" (TLSDESC, see #66915) AArch64 toolchains seem to support TLSDESC from the beginning, and the general dynamic model has poor support. Nobody seems to use the option -mtls-dialect= at all, so we don't bother with it. There also seems very little interest in AArch32's TLSDESC support. TLSDESC does not change IR, but affects object file generation. Without a backend option the option is a no-op for in-process ThinLTO. There seems no motivation to have fine-grained control mixing trad/desc for TLS, so we just pass -mllvm, and don't bother with a modules flag metadata or function attribute. Co-authored-by: Paul Kirth <paulkirth@google.com> (cherry picked from commit 36b4a9ccd9f7e04010476e6b2a311f2052a4ac20)
This commit is contained in:
parent
147c623a86
commit
aa4cb0e313
@ -369,6 +369,9 @@ ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibr
|
|||||||
/// The default TLS model to use.
|
/// The default TLS model to use.
|
||||||
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
|
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
|
||||||
|
|
||||||
|
/// Whether to enable TLSDESC. AArch64 enables TLSDESC regardless of this value.
|
||||||
|
CODEGENOPT(EnableTLSDESC, 1, 0)
|
||||||
|
|
||||||
/// Bit size of immediate TLS offsets (0 == use the default).
|
/// Bit size of immediate TLS offsets (0 == use the default).
|
||||||
VALUE_CODEGENOPT(TLSSize, 8, 0)
|
VALUE_CODEGENOPT(TLSSize, 8, 0)
|
||||||
|
|
||||||
|
@ -4419,6 +4419,8 @@ def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
|
|||||||
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
|
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
|
||||||
"12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">,
|
"12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">,
|
||||||
MarshallingInfoInt<CodeGenOpts<"TLSSize">>;
|
MarshallingInfoInt<CodeGenOpts<"TLSSize">>;
|
||||||
|
def mtls_dialect_EQ : Joined<["-"], "mtls-dialect=">, Group<m_Group>,
|
||||||
|
Flags<[TargetSpecific]>, HelpText<"Which thread-local storage dialect to use for dynamic accesses of TLS variables">;
|
||||||
def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
|
def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
|
||||||
def mdefault_build_attributes : Joined<["-"], "mdefault-build-attributes">, Group<m_Group>;
|
def mdefault_build_attributes : Joined<["-"], "mdefault-build-attributes">, Group<m_Group>;
|
||||||
def mno_default_build_attributes : Joined<["-"], "mno-default-build-attributes">, Group<m_Group>;
|
def mno_default_build_attributes : Joined<["-"], "mno-default-build-attributes">, Group<m_Group>;
|
||||||
@ -7066,6 +7068,9 @@ def fexperimental_assignment_tracking_EQ : Joined<["-"], "fexperimental-assignme
|
|||||||
Values<"disabled,enabled,forced">, NormalizedValues<["Disabled","Enabled","Forced"]>,
|
Values<"disabled,enabled,forced">, NormalizedValues<["Disabled","Enabled","Forced"]>,
|
||||||
MarshallingInfoEnum<CodeGenOpts<"AssignmentTrackingMode">, "Enabled">;
|
MarshallingInfoEnum<CodeGenOpts<"AssignmentTrackingMode">, "Enabled">;
|
||||||
|
|
||||||
|
def enable_tlsdesc : Flag<["-"], "enable-tlsdesc">,
|
||||||
|
MarshallingInfoFlag<CodeGenOpts<"EnableTLSDESC">>;
|
||||||
|
|
||||||
} // let Visibility = [CC1Option]
|
} // let Visibility = [CC1Option]
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -401,6 +401,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
|
|||||||
Options.UniqueBasicBlockSectionNames =
|
Options.UniqueBasicBlockSectionNames =
|
||||||
CodeGenOpts.UniqueBasicBlockSectionNames;
|
CodeGenOpts.UniqueBasicBlockSectionNames;
|
||||||
Options.TLSSize = CodeGenOpts.TLSSize;
|
Options.TLSSize = CodeGenOpts.TLSSize;
|
||||||
|
Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
|
||||||
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
|
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
|
||||||
Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
|
Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
|
||||||
Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
|
Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
|
||||||
|
@ -5822,6 +5822,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||||||
Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
|
Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isTLSDESCEnabled(TC, Args))
|
||||||
|
CmdArgs.push_back("-enable-tlsdesc");
|
||||||
|
|
||||||
// Add the target cpu
|
// Add the target cpu
|
||||||
std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false);
|
std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false);
|
||||||
if (!CPU.empty()) {
|
if (!CPU.empty()) {
|
||||||
|
@ -729,6 +729,33 @@ bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
|
|||||||
return Triple.isPS();
|
return Triple.isPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tools::isTLSDESCEnabled(const ToolChain &TC,
|
||||||
|
const llvm::opt::ArgList &Args) {
|
||||||
|
const llvm::Triple &Triple = TC.getEffectiveTriple();
|
||||||
|
Arg *A = Args.getLastArg(options::OPT_mtls_dialect_EQ);
|
||||||
|
if (!A)
|
||||||
|
return Triple.hasDefaultTLSDESC();
|
||||||
|
StringRef V = A->getValue();
|
||||||
|
bool SupportedArgument = false, EnableTLSDESC = false;
|
||||||
|
bool Unsupported = !Triple.isOSBinFormatELF();
|
||||||
|
if (Triple.isRISCV()) {
|
||||||
|
SupportedArgument = V == "desc" || V == "trad";
|
||||||
|
EnableTLSDESC = V == "desc";
|
||||||
|
} else if (Triple.isX86()) {
|
||||||
|
SupportedArgument = V == "gnu";
|
||||||
|
} else {
|
||||||
|
Unsupported = true;
|
||||||
|
}
|
||||||
|
if (Unsupported) {
|
||||||
|
TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
|
||||||
|
<< A->getSpelling() << Triple.getTriple();
|
||||||
|
} else if (!SupportedArgument) {
|
||||||
|
TC.getDriver().Diag(diag::err_drv_unsupported_option_argument_for_target)
|
||||||
|
<< A->getSpelling() << V << Triple.getTriple();
|
||||||
|
}
|
||||||
|
return EnableTLSDESC;
|
||||||
|
}
|
||||||
|
|
||||||
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
||||||
ArgStringList &CmdArgs, const InputInfo &Output,
|
ArgStringList &CmdArgs, const InputInfo &Output,
|
||||||
const InputInfo &Input, bool IsThinLTO) {
|
const InputInfo &Input, bool IsThinLTO) {
|
||||||
@ -988,6 +1015,9 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
|
|||||||
CmdArgs.push_back(
|
CmdArgs.push_back(
|
||||||
Args.MakeArgString(Twine(PluginOptPrefix) + "-emulated-tls"));
|
Args.MakeArgString(Twine(PluginOptPrefix) + "-emulated-tls"));
|
||||||
}
|
}
|
||||||
|
if (isTLSDESCEnabled(ToolChain, Args))
|
||||||
|
CmdArgs.push_back(
|
||||||
|
Args.MakeArgString(Twine(PluginOptPrefix) + "-enable-tlsdesc"));
|
||||||
|
|
||||||
if (Args.hasFlag(options::OPT_fstack_size_section,
|
if (Args.hasFlag(options::OPT_fstack_size_section,
|
||||||
options::OPT_fno_stack_size_section, false))
|
options::OPT_fno_stack_size_section, false))
|
||||||
|
@ -144,6 +144,9 @@ llvm::StringRef getLTOParallelism(const llvm::opt::ArgList &Args,
|
|||||||
bool areOptimizationsEnabled(const llvm::opt::ArgList &Args);
|
bool areOptimizationsEnabled(const llvm::opt::ArgList &Args);
|
||||||
|
|
||||||
bool isUseSeparateSections(const llvm::Triple &Triple);
|
bool isUseSeparateSections(const llvm::Triple &Triple);
|
||||||
|
// Parse -mtls-dialect=. Return true if the target supports both general-dynamic
|
||||||
|
// and TLSDESC, and TLSDESC is requested.
|
||||||
|
bool isTLSDESCEnabled(const ToolChain &TC, const llvm::opt::ArgList &Args);
|
||||||
|
|
||||||
/// \p EnvVar is split by system delimiter for environment variables.
|
/// \p EnvVar is split by system delimiter for environment variables.
|
||||||
/// If \p ArgName is "-I", "-L", or an empty string, each entry from \p EnvVar
|
/// If \p ArgName is "-I", "-L", or an empty string, each entry from \p EnvVar
|
||||||
|
14
clang/test/CodeGen/RISCV/tls-dialect.c
Normal file
14
clang/test/CodeGen/RISCV/tls-dialect.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// REQUIRES: riscv-registered-target
|
||||||
|
/// cc1 -enable-tlsdesc (due to -mtls-dialect=desc) enables TLSDESC.
|
||||||
|
// RUN: %clang_cc1 -triple riscv64 -S -mrelocation-model pic -pic-level 1 -enable-tlsdesc %s -o - | FileCheck %s --check-prefix=DESC
|
||||||
|
// RUN: %clang_cc1 -triple riscv64 -S -mrelocation-model pic -pic-level 1 %s -o - | FileCheck %s --check-prefix=NODESC
|
||||||
|
|
||||||
|
__thread int x;
|
||||||
|
|
||||||
|
// DESC: %tlsdesc_hi
|
||||||
|
// DESC-NOT: %tls_gd_pcrel_hi
|
||||||
|
// NODESC: %tls_gd_pcrel_hi
|
||||||
|
// NODESC-NOT: %tlsdesc_hi
|
||||||
|
int use() {
|
||||||
|
return x;
|
||||||
|
}
|
25
clang/test/Driver/tls-dialect.c
Normal file
25
clang/test/Driver/tls-dialect.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// RUN: %clang -### --target=riscv64-freebsd -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=DESC %s
|
||||||
|
// RUN: %clang -### --target=riscv64-linux -mtls-dialect=trad %s 2>&1 | FileCheck --check-prefix=NODESC %s
|
||||||
|
// RUN: %clang -### --target=riscv64-linux %s 2>&1 | FileCheck --check-prefix=NODESC %s
|
||||||
|
// RUN: %clang -### --target=x86_64-linux -mtls-dialect=gnu %s 2>&1 | FileCheck --check-prefix=NODESC %s
|
||||||
|
|
||||||
|
/// LTO
|
||||||
|
// RUN: %clang -### --target=riscv64-linux -flto -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=LTO-DESC %s
|
||||||
|
// RUN: %clang -### --target=riscv64-linux -flto %s 2>&1 | FileCheck --check-prefix=LTO-NODESC %s
|
||||||
|
|
||||||
|
/// Unsupported target
|
||||||
|
/// GCC supports -mtls-dialect= for AArch64, but we just unsupport it for AArch64 as it is very rarely used.
|
||||||
|
// RUN: not %clang --target=aarch64-linux -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-TARGET %s
|
||||||
|
// RUN: not %clang --target=x86_64-apple-macos -mtls-dialect=desc -flto %s 2>&1 | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
|
||||||
|
|
||||||
|
/// Unsupported argument
|
||||||
|
// RUN: not %clang -### --target=riscv64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s
|
||||||
|
// RUN: not %clang -### --target=x86_64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s
|
||||||
|
|
||||||
|
// DESC: "-cc1" {{.*}}"-enable-tlsdesc"
|
||||||
|
// NODESC-NOT: "-enable-tlsdesc"
|
||||||
|
// LTO-DESC: "-plugin-opt=-enable-tlsdesc"
|
||||||
|
// LTO-NODESC-NOT: "-plugin-opt=-enable-tlsdesc"
|
||||||
|
|
||||||
|
// UNSUPPORTED-TARGET: error: unsupported option '-mtls-dialect=' for target
|
||||||
|
// UNSUPPORTED-ARG: error: unsupported argument 'gnu2' to option '-mtls-dialect=' for target
|
@ -1033,11 +1033,11 @@ public:
|
|||||||
isWindowsCygwinEnvironment() || isOHOSFamily();
|
isWindowsCygwinEnvironment() || isOHOSFamily();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests whether the target uses TLS Descriptor by default.
|
/// True if the target supports both general-dynamic and TLSDESC, and TLSDESC
|
||||||
|
/// is enabled by default.
|
||||||
bool hasDefaultTLSDESC() const {
|
bool hasDefaultTLSDESC() const {
|
||||||
// TODO: Improve check for other platforms, like Android, and RISC-V
|
// TODO: Improve check for other platforms, like Android, and RISC-V
|
||||||
// Note: This is currently only used on RISC-V.
|
return false;
|
||||||
return isOSBinFormatELF() && isAArch64();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests whether the target uses -data-sections as default.
|
/// Tests whether the target uses -data-sections as default.
|
||||||
|
Loading…
Reference in New Issue
Block a user