[CodeGen] Attach attributes to thread local wrapper function.

This commit is a follow-up to r251734, r251476, and r249735, which fixes
a bug where function attributes were not attached to thread local
wrapper functions.

rdar://problem/20828324

llvm-svn: 257865
This commit is contained in:
Akira Hatanaka 2016-01-15 03:34:06 +00:00
parent 4769517b7b
commit 26907f9236
4 changed files with 31 additions and 12 deletions

View File

@ -2178,17 +2178,29 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
}
// FIXME: If VD is a definition, we should regenerate the function attributes
// before returning.
if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
return cast<llvm::Function>(V);
llvm::Type *RetTy = Val->getType();
if (VD->getType()->isReferenceType())
RetTy = RetTy->getPointerElementType();
QualType RetQT = VD->getType();
if (RetQT->isReferenceType())
RetQT = RetQT.getNonReferenceType();
llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
getContext().getPointerType(RetQT), FunctionArgList(),
FunctionType::ExtInfo(), false);
llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
llvm::Function *Wrapper =
llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
WrapperName.str(), &CGM.getModule());
CGM.SetLLVMFunctionAttributes(nullptr, FI, Wrapper);
if (VD->hasDefinition())
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);
// Always resolve references to the wrapper at link time.
if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) &&
!llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
@ -2264,6 +2276,10 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
Init = llvm::Function::Create(
FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
&CGM.getModule());
const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
CGM.getContext().VoidTy, FunctionArgList(), FunctionType::ExtInfo(),
false);
CGM.SetLLVMFunctionAttributes(nullptr, FI, cast<llvm::Function>(Init));
}
if (Init)

View File

@ -21,8 +21,8 @@ int &g() { return r; }
// DARWIN: call cxx_fast_tlscc i32* @_ZTW1r()
// CHECK: ret i32* %{{.*}}
// LINUX: define weak_odr hidden i32* @_ZTW1r() {
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR:#[0-9]+]] {
// LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] {
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] {
// CHECK: call void @_ZTH1r()
// CHECK: load i32*, i32** @r, align 8
// CHECK: ret i32* %{{.*}}
@ -30,4 +30,5 @@ int &g() { return r; }
// CHECK-LABEL: define internal void @__tls_init()
// CHECK: call void @[[R_INIT]]()
// DARWIN: attributes [[ATTR]] = { nounwind }
// LINUX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} }
// DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} }

View File

@ -217,7 +217,7 @@ void set_anon_i() {
// CHECK: }
// LINUX: declare extern_weak void @_ZTH1b()
// LINUX: declare extern_weak void @_ZTH1b() [[ATTR:#[0-9]+]]
// LINUX-LABEL: define internal i32* @_ZTWL1d()
@ -229,3 +229,5 @@ void set_anon_i() {
// DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE()
// CHECK: call void @_ZTHN1U1mE()
// CHECK: ret i32* @_ZN1U1mE
// LINUX: attributes [[ATTR]] = { {{.+}} }

View File

@ -617,7 +617,7 @@ int main() {
// CHECK-DEBUG: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]*
// CHECK-DEBUG: }
// CHECK-DEBUG: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}})
// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {
// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS-NEXT: call void [[GS1_TLS_INIT]]
// CHECK-TLS-NEXT: ret [[S1]]* [[GS1]]
// CHECK-TLS-NEXT: }
@ -639,15 +639,15 @@ int main() {
// CHECK-TLS: call void [[ARR_X_TLS_INIT]]
// CHECK-TLS: ret [2 x [3 x [[S1]]]]* [[ARR_X]]
// CHECK-TLS: }
// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {
// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_INT_ST_TLS_INIT]]
// CHECK-TLS: ret i32* [[ST_INT_ST]]
// CHECK-TLS: }
// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {
// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_FLOAT_ST_TLS_INIT]]
// CHECK-TLS: ret float* [[ST_FLOAT_ST]]
// CHECK-TLS: }
// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {
// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_S4_ST_TLS_INIT]]
// CHECK-TLS: ret [[S4]]* [[ST_S4_ST]]
// CHECK-TLS: }