diff options
author | Hans Wennborg <hans@hanshq.net> | 2012-06-28 08:01:44 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2012-06-28 08:01:44 +0000 |
commit | f60f6af9e84fe7752edb6fa42464778ac8a53e99 (patch) | |
tree | 0fc46d3b32bf750669cf8ad484e64d94c8b54447 /clang/lib | |
parent | 608c0b65d78531d1713a02f34a9b876deefb4943 (diff) | |
download | bcm5719-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.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 48 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 13 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 32 |
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; } |