diff options
Diffstat (limited to 'clang/lib/CodeGen')
-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 |
3 files changed, 51 insertions, 28 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()), |