summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2012-06-28 08:01:44 +0000
committerHans Wennborg <hans@hanshq.net>2012-06-28 08:01:44 +0000
commitf60f6af9e84fe7752edb6fa42464778ac8a53e99 (patch)
tree0fc46d3b32bf750669cf8ad484e64d94c8b54447 /clang/lib
parent608c0b65d78531d1713a02f34a9b876deefb4943 (diff)
downloadbcm5719-llvm-f60f6af9e84fe7752edb6fa42464778ac8a53e99.tar.gz
bcm5719-llvm-f60f6af9e84fe7752edb6fa42464778ac8a53e99.zip
Add -ftls-model command-line flag.
This allows for setting the default TLS model. (PR9788) llvm-svn: 159336
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp18
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp48
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h13
-rw-r--r--clang/lib/Driver/Tools.cpp2
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp32
5 files changed, 84 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 08a938254ba..be6638e0e57 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -183,26 +183,20 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
else
Name = GetStaticDeclName(*this, D, Separator);
- llvm::GlobalVariable::ThreadLocalMode TLM;
- TLM = D.isThreadSpecified() ? llvm::GlobalVariable::GeneralDynamicTLSModel
- : llvm::GlobalVariable::NotThreadLocal;
-
- // Set the TLS mode if it it's explicitly specified.
- if (D.hasAttr<TLSModelAttr>()) {
- assert(D.isThreadSpecified() && "Can't have TLS model on non-tls var.");
- const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
- TLM = CodeGenModule::GetLLVMTLSModel(Attr->getModel());
- }
-
llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(CGM.getModule(), LTy,
Ty.isConstant(getContext()), Linkage,
- CGM.EmitNullConstant(D.getType()), Name, 0, TLM,
+ CGM.EmitNullConstant(D.getType()), Name, 0,
+ llvm::GlobalVariable::NotThreadLocal,
CGM.getContext().getTargetAddressSpace(Ty));
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
if (Linkage != llvm::GlobalValue::InternalLinkage)
GV->setVisibility(CurFn->getVisibility());
+
+ if (D.isThreadSpecified())
+ CGM.setTLSMode(GV, D);
+
return GV;
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8f769d90204..25053b91a4c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -258,6 +258,45 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
+ return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
+ .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
+ .Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
+ .Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
+ .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel);
+}
+
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
+ CodeGenOptions::TLSModel M) {
+ switch (M) {
+ case CodeGenOptions::GeneralDynamicTLSModel:
+ return llvm::GlobalVariable::GeneralDynamicTLSModel;
+ case CodeGenOptions::LocalDynamicTLSModel:
+ return llvm::GlobalVariable::LocalDynamicTLSModel;
+ case CodeGenOptions::InitialExecTLSModel:
+ return llvm::GlobalVariable::InitialExecTLSModel;
+ case CodeGenOptions::LocalExecTLSModel:
+ return llvm::GlobalVariable::LocalExecTLSModel;
+ }
+ llvm_unreachable("Invalid TLS model!");
+}
+
+void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,
+ const VarDecl &D) const {
+ assert(D.isThreadSpecified() && "setting TLS mode on non-TLS var!");
+
+ llvm::GlobalVariable::ThreadLocalMode TLM;
+ TLM = GetLLVMTLSModel(CodeGenOpts.DefaultTLSModel);
+
+ // Override the TLS model if it is explicitly specified.
+ if (D.hasAttr<TLSModelAttr>()) {
+ const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
+ TLM = GetLLVMTLSModel(Attr->getModel());
+ }
+
+ GV->setThreadLocalMode(TLM);
+}
+
/// Set the symbol visibility of type information (vtable and RTTI)
/// associated with the given type.
void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
@@ -1212,13 +1251,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
- GV->setThreadLocal(D->isThreadSpecified());
-
- // Set the TLS model if it it's explicitly specified.
- if (D->hasAttr<TLSModelAttr>()) {
- const TLSModelAttr *Attr = D->getAttr<TLSModelAttr>();
- GV->setThreadLocalMode(GetLLVMTLSModel(Attr->getModel()));
- }
+ if (D->isThreadSpecified())
+ setTLSMode(GV, *D);
}
if (AddrSpace != Ty->getAddressSpace())
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a742d846c19..d6ff50d5ad7 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -474,6 +474,10 @@ public:
/// GlobalValue.
void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
+ /// setTLSMode - Set the TLS mode for the given LLVM GlobalVariable
+ /// for the thread-local variable declaration D.
+ void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const;
+
/// TypeVisibilityKind - The kind of global variable that is passed to
/// setTypeVisibility
enum TypeVisibilityKind {
@@ -498,15 +502,6 @@ public:
llvm_unreachable("unknown visibility!");
}
- static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
- return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
- .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
- .Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
- .Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
- .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel)
- .Default(llvm::GlobalVariable::NotThreadLocal);
- }
-
llvm::Constant *GetAddrOfGlobal(GlobalDecl GD) {
if (isa<CXXConstructorDecl>(GD.getDecl()))
return GetAddrOfCXXConstructor(cast<CXXConstructorDecl>(GD.getDecl()),
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index c3ea22f888a..c5a837f3d1e 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -2209,6 +2209,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
+ Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
+
// -fhosted is default.
if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
KernelOrKext)
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 40328d42009..4100deacbd1 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -307,6 +307,20 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) {
Res.push_back("-disable-llvm-verifier");
for (unsigned i = 0, e = Opts.BackendOptions.size(); i != e; ++i)
Res.push_back("-backend-option", Opts.BackendOptions[i]);
+
+ switch (Opts.DefaultTLSModel) {
+ case CodeGenOptions::GeneralDynamicTLSModel:
+ break;
+ case CodeGenOptions::LocalDynamicTLSModel:
+ Res.push_back("-ftls-model=local-dynamic");
+ break;
+ case CodeGenOptions::InitialExecTLSModel:
+ Res.push_back("-ftls-model=initial-exec");
+ break;
+ case CodeGenOptions::LocalExecTLSModel:
+ Res.push_back("-ftls-model=local-exec");
+ break;
+ }
}
static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
@@ -788,7 +802,7 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) {
if (Opts.AppleKext)
Res.push_back("-fapple-kext");
-
+
if (Opts.getVisibilityMode() != DefaultVisibility) {
Res.push_back("-fvisibility");
if (Opts.getVisibilityMode() == HiddenVisibility) {
@@ -1256,6 +1270,22 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
+ if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
+ StringRef Name = A->getValue(Args);
+ unsigned Model = llvm::StringSwitch<unsigned>(Name)
+ .Case("global-dynamic", CodeGenOptions::GeneralDynamicTLSModel)
+ .Case("local-dynamic", CodeGenOptions::LocalDynamicTLSModel)
+ .Case("initial-exec", CodeGenOptions::InitialExecTLSModel)
+ .Case("local-exec", CodeGenOptions::LocalExecTLSModel)
+ .Default(~0U);
+ if (Model == ~0U) {
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+ Success = false;
+ } else {
+ Opts.DefaultTLSModel = static_cast<CodeGenOptions::TLSModel>(Model);
+ }
+ }
+
return Success;
}
OpenPOWER on IntegriCloud