forked from OSchip/llvm-project
Add -femulated-tls flag to select the emulated TLS model.
This will be used for old targets like Android that do not support ELF TLS models. Differential Revision: http://reviews.llvm.org/D10524 llvm-svn: 243441
This commit is contained in:
parent
9938310ab3
commit
2c656c9417
|
@ -1157,6 +1157,13 @@ are listed below.
|
||||||
efficient model can be used. The TLS model can be overridden per
|
efficient model can be used. The TLS model can be overridden per
|
||||||
variable using the ``tls_model`` attribute.
|
variable using the ``tls_model`` attribute.
|
||||||
|
|
||||||
|
.. option:: -femulated-tls
|
||||||
|
|
||||||
|
Select emulated TLS model, which overrides all -ftls-model choices.
|
||||||
|
|
||||||
|
In emulated TLS mode, all access to TLS variables are converted to
|
||||||
|
calls to __emutls_get_address in the runtime library.
|
||||||
|
|
||||||
.. option:: -mhwdiv=[values]
|
.. option:: -mhwdiv=[values]
|
||||||
|
|
||||||
Select the ARM modes (arm or thumb) that support hardware division
|
Select the ARM modes (arm or thumb) that support hardware division
|
||||||
|
|
|
@ -510,6 +510,9 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
|
||||||
def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
|
def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
|
||||||
def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
|
def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
|
||||||
HelpText<"Emit all declarations, even if unused">;
|
HelpText<"Emit all declarations, even if unused">;
|
||||||
|
def femulated_tls : Flag<["-"], "femulated-tls">, Group<f_Group>, Flags<[CC1Option]>,
|
||||||
|
HelpText<"Use emutls functions to access thread_local variables">;
|
||||||
|
def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>;
|
||||||
def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
|
def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
|
||||||
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
|
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
|
||||||
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
|
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
|
||||||
|
|
|
@ -60,6 +60,7 @@ CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
|
||||||
CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
|
CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
|
||||||
CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
|
CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
|
||||||
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
|
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
|
||||||
|
CODEGENOPT(EmulatedTLS , 1, 0) ///< Set when -femulated-tls is enabled.
|
||||||
/// \brief FP_CONTRACT mode (on/off/fast).
|
/// \brief FP_CONTRACT mode (on/off/fast).
|
||||||
ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
|
ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
|
||||||
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
|
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
|
||||||
|
|
|
@ -542,6 +542,7 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
|
||||||
Options.FunctionSections = CodeGenOpts.FunctionSections;
|
Options.FunctionSections = CodeGenOpts.FunctionSections;
|
||||||
Options.DataSections = CodeGenOpts.DataSections;
|
Options.DataSections = CodeGenOpts.DataSections;
|
||||||
Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
|
Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
|
||||||
|
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
|
||||||
|
|
||||||
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
|
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
|
||||||
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
|
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
|
||||||
|
|
|
@ -4036,6 +4036,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
|
Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
|
Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
|
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
|
||||||
|
// Emulated TLS is enabled by default on Android, and can be enabled manually
|
||||||
|
// with -femulated-tls.
|
||||||
|
bool EmulatedTLSDefault = Triple.getEnvironment() == llvm::Triple::Android;
|
||||||
|
if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
|
||||||
|
EmulatedTLSDefault))
|
||||||
|
CmdArgs.push_back("-femulated-tls");
|
||||||
// AltiVec language extensions aren't relevant for assembling.
|
// AltiVec language extensions aren't relevant for assembling.
|
||||||
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
|
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
|
||||||
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
|
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
|
||||||
|
|
|
@ -593,6 +593,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Opts.EmulatedTLS =
|
||||||
|
Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
|
||||||
|
|
||||||
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
|
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
|
||||||
StringRef Name = A->getValue();
|
StringRef Name = A->getValue();
|
||||||
unsigned Model = llvm::StringSwitch<unsigned>(Name)
|
unsigned Model = llvm::StringSwitch<unsigned>(Name)
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
|
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
|
||||||
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-IE
|
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-IE
|
||||||
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LE
|
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LE
|
||||||
|
//
|
||||||
|
// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -femulated-tls -emit-llvm -o - 2>&1 | \
|
||||||
|
// RUN: FileCheck %s -check-prefix=CHECK-GD
|
||||||
|
|
||||||
|
int z1 = 0;
|
||||||
|
int z2;
|
||||||
int __thread x;
|
int __thread x;
|
||||||
int f() {
|
int f() {
|
||||||
static int __thread y;
|
static int __thread y;
|
||||||
|
@ -11,18 +16,29 @@ int f() {
|
||||||
}
|
}
|
||||||
int __thread __attribute__((tls_model("initial-exec"))) z;
|
int __thread __attribute__((tls_model("initial-exec"))) z;
|
||||||
|
|
||||||
|
// Note that unlike normal C uninitialized global variables,
|
||||||
|
// uninitialized TLS variables do NOT have COMMON linkage.
|
||||||
|
|
||||||
|
// CHECK-GD: @z1 = global i32 0
|
||||||
// CHECK-GD: @f.y = internal thread_local global i32 0
|
// CHECK-GD: @f.y = internal thread_local global i32 0
|
||||||
|
// CHECK-GD: @z2 = common global i32 0
|
||||||
// CHECK-GD: @x = thread_local global i32 0
|
// CHECK-GD: @x = thread_local global i32 0
|
||||||
// CHECK-GD: @z = thread_local(initialexec) global i32 0
|
// CHECK-GD: @z = thread_local(initialexec) global i32 0
|
||||||
|
|
||||||
|
// CHECK-LD: @z1 = global i32 0
|
||||||
// CHECK-LD: @f.y = internal thread_local(localdynamic) global i32 0
|
// CHECK-LD: @f.y = internal thread_local(localdynamic) global i32 0
|
||||||
|
// CHECK-LD: @z2 = common global i32 0
|
||||||
// CHECK-LD: @x = thread_local(localdynamic) global i32 0
|
// CHECK-LD: @x = thread_local(localdynamic) global i32 0
|
||||||
// CHECK-LD: @z = thread_local(initialexec) global i32 0
|
// CHECK-LD: @z = thread_local(initialexec) global i32 0
|
||||||
|
|
||||||
|
// CHECK-IE: @z1 = global i32 0
|
||||||
// CHECK-IE: @f.y = internal thread_local(initialexec) global i32 0
|
// CHECK-IE: @f.y = internal thread_local(initialexec) global i32 0
|
||||||
|
// CHECK-IE: @z2 = common global i32 0
|
||||||
// CHECK-IE: @x = thread_local(initialexec) global i32 0
|
// CHECK-IE: @x = thread_local(initialexec) global i32 0
|
||||||
// CHECK-IE: @z = thread_local(initialexec) global i32 0
|
// CHECK-IE: @z = thread_local(initialexec) global i32 0
|
||||||
|
|
||||||
|
// CHECK-LE: @z1 = global i32 0
|
||||||
// CHECK-LE: @f.y = internal thread_local(localexec) global i32 0
|
// CHECK-LE: @f.y = internal thread_local(localexec) global i32 0
|
||||||
|
// CHECK-LE: @z2 = common global i32 0
|
||||||
// CHECK-LE: @x = thread_local(localexec) global i32 0
|
// CHECK-LE: @x = thread_local(localexec) global i32 0
|
||||||
// CHECK-LE: @z = thread_local(initialexec) global i32 0
|
// CHECK-LE: @z = thread_local(initialexec) global i32 0
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -femulated-tls -emit-llvm %s -o - \
|
||||||
|
// RUN: -triple x86_64-linux-gnu 2>&1 | FileCheck --check-prefix=CHECK %s
|
||||||
|
|
||||||
int f();
|
int f();
|
||||||
int g();
|
int g();
|
||||||
|
|
Loading…
Reference in New Issue