From 8592a9a7beccdf2ac2aa37eb2e8cf6bf6e6a38a6 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Thu, 17 Dec 2015 00:42:36 +0000 Subject: [PATCH] [TLS on Darwin] use CXX_FAST_TLS calling convention for access functions. Also set nounwind attribute. rdar://problem/9001553 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255860 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/ItaniumCXXABI.cpp | 14 ++++++++--- .../cxx11-thread-local-reference.cpp | 7 ++++-- test/CodeGenCXX/cxx11-thread-local.cpp | 23 +++++++++++-------- test/CodeGenCXX/tls-init-funcs.cpp | 8 +++---- test/OpenMP/parallel_copyin_codegen.cpp | 18 +++++++-------- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 44f64569e2..0c4008f8ee 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2194,6 +2194,11 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) && !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()))) Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); + + if (isThreadWrapperReplaceable(VD, CGM)) { + Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); + Wrapper->addFnAttr(llvm::Attribute::NoUnwind); + } return Wrapper; } @@ -2305,13 +2310,16 @@ LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD); llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val); - Val = CGF.Builder.CreateCall(Wrapper); + llvm::CallInst *CallVal = CGF.Builder.CreateCall(Wrapper); + if (isThreadWrapperReplaceable(VD, CGF.CGM)) + CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); LValue LV; if (VD->getType()->isReferenceType()) - LV = CGF.MakeNaturalAlignAddrLValue(Val, LValType); + LV = CGF.MakeNaturalAlignAddrLValue(CallVal, LValType); else - LV = CGF.MakeAddrLValue(Val, LValType, CGF.getContext().getDeclAlign(VD)); + LV = CGF.MakeAddrLValue(CallVal, LValType, + CGF.getContext().getDeclAlign(VD)); // FIXME: need setObjCGCLValueClass? return LV; } diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp index a1efd1adb3..8b2ac5eed8 100644 --- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -17,14 +17,17 @@ int &g() { return r; } // CHECK: store i32* %{{.*}}, i32** @r, align 8 // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z1gv() -// CHECK: call i32* @_ZTW1r() +// LINUX: call i32* @_ZTW1r() +// DARWIN: call cxx_fast_tlscc i32* @_ZTW1r() // CHECK: ret i32* %{{.*}} // LINUX: define weak_odr hidden i32* @_ZTW1r() { -// DARWIN: define i32* @_ZTW1r() { +// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR:#[0-9]+]] { // CHECK: call void @_ZTH1r() // CHECK: load i32*, i32** @r, align 8 // CHECK: ret i32* %{{.*}} // CHECK-LABEL: define internal void @__tls_init() // CHECK: call void @[[R_INIT]]() + +// DARWIN: attributes [[ATTR]] = { nounwind } diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp index e00a881a66..b5bcc5e23e 100644 --- a/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/test/CodeGenCXX/cxx11-thread-local.cpp @@ -91,7 +91,8 @@ int f() { } // CHECK: define {{.*}} @[[C_INIT:.*]]() -// CHECK: call i32* @_ZTW1b() +// LINUX: call i32* @_ZTW1b() +// DARWIN: call cxx_fast_tlscc i32* @_ZTW1b() // CHECK-NEXT: load i32, i32* %{{.*}}, align 4 // CHECK-NEXT: store i32 %{{.*}}, i32* @c, align 4 @@ -102,7 +103,7 @@ int f() { // LINUX: br label // finally: // LINUX: ret i32* @b -// DARWIN-LABEL: declare i32* @_ZTW1b() +// DARWIN-LABEL: declare cxx_fast_tlscc i32* @_ZTW1b() // There is no definition of the thread wrapper on Darwin for external TLV. // CHECK: define {{.*}} @[[D_INIT:.*]]() @@ -114,11 +115,13 @@ int f() { // CHECK-NEXT: store i32 %{{.*}}, i32* @_ZN1U1mE, align 4 // CHECK: define {{.*}} @[[E_INIT:.*]]() -// CHECK: call i32* @_ZTWN1VIiE1mE() +// LINUX: call i32* @_ZTWN1VIiE1mE() +// DARWIN: call cxx_fast_tlscc i32* @_ZTWN1VIiE1mE() // CHECK-NEXT: load i32, i32* %{{.*}}, align 4 // CHECK-NEXT: store i32 %{{.*}}, i32* @e, align 4 -// CHECK-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE() +// LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE() +// DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE() // CHECK: call void @_ZTHN1VIiE1mE() // CHECK: ret i32* @_ZN1VIiE1mE @@ -167,7 +170,7 @@ struct PR19254 { // CHECK: define {{.*}} @_ZN7PR192541fEv( int PR19254::f() { // LINUX: call void @_ZTHN7PR192541nE( - // DARWIN: call i32* @_ZTWN7PR192541nE( + // DARWIN: call cxx_fast_tlscc i32* @_ZTWN7PR192541nE( return this->n; } @@ -177,7 +180,8 @@ thread_local int anon_i{1}; void set_anon_i() { anon_i = 2; } -// CHECK-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE() +// LINUX-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE() +// DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWN12_GLOBAL__N_16anon_iE() // CHECK: define {{.*}} @[[V_M_INIT:.*]]() // CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) @@ -207,7 +211,7 @@ void set_anon_i() { // LIUNX: define weak_odr hidden i32* @_ZTW1a() { -// DARWIN: define i32* @_ZTW1a() { +// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a() // CHECK: call void @_ZTH1a() // CHECK: ret i32* @a // CHECK: } @@ -216,11 +220,12 @@ void set_anon_i() { // LINUX: declare extern_weak void @_ZTH1b() -// CHECK-LABEL: define internal i32* @_ZTWL1d() +// LINUX-LABEL: define internal i32* @_ZTWL1d() +// DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWL1d() // CHECK: call void @_ZTHL1d() // CHECK: ret i32* @_ZL1d // LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1U1mE() -// DARWIN-LABEL: define i32* @_ZTWN1U1mE() +// DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE() // CHECK: call void @_ZTHN1U1mE() // CHECK: ret i32* @_ZN1U1mE diff --git a/test/CodeGenCXX/tls-init-funcs.cpp b/test/CodeGenCXX/tls-init-funcs.cpp index 8188f214df..a2a563b84f 100644 --- a/test/CodeGenCXX/tls-init-funcs.cpp +++ b/test/CodeGenCXX/tls-init-funcs.cpp @@ -4,10 +4,10 @@ // CHECK: @_Z2vtIiE = linkonce_odr thread_local global i32 5 // CHECK: @_ZZ3inlvE3loc = linkonce_odr thread_local global i32 0 // CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev -// CHECK: call i32* @_ZTW3ext() -// CHECK: declare i32* @_ZTW3ext() -// CHECK: define weak_odr hidden i32* @_ZTW2vtIiE() -// CHECK: define weak_odr hidden i32* @_ZTW2vtIvE() +// CHECK: call cxx_fast_tlscc i32* @_ZTW3ext() +// CHECK: declare cxx_fast_tlscc i32* @_ZTW3ext() +// CHECK: define weak_odr hidden cxx_fast_tlscc i32* @_ZTW2vtIiE() +// CHECK: define weak_odr hidden cxx_fast_tlscc i32* @_ZTW2vtIvE() // CHECK: define {{.*}} @_ZTW1a struct A { diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp index 9a7449ded0..1ae8a16124 100644 --- a/test/OpenMP/parallel_copyin_codegen.cpp +++ b/test/OpenMP/parallel_copyin_codegen.cpp @@ -85,10 +85,10 @@ int main() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) - // TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call i{{[0-9]+}}* [[G_CTOR:@.+]]() + // TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) - // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() { + // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() // TLS-LAMBDA: ret i{{[0-9]+}}* [[G]] // TLS-LAMBDA: } @@ -108,7 +108,7 @@ int main() { // LAMBDA: [[DONE]] // TLS-LAMBDA-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % - // TLS-LAMBDA-DAG: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-LAMBDA-DAG: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-LAMBDA-DAG: [[G_CAPTURE_SRCC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_SRC]] to i{{[0-9]+}} // TLS-LAMBDA-DAG: [[G_CAPTURE_DSTC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_DST]] to i{{[0-9]+}} // TLS-LAMBDA: icmp ne i{{[0-9]+}} {{%.+}}, {{%.+}} @@ -129,7 +129,7 @@ int main() { g = 2; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] - // TLS-LAMBDA: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-LAMBDA: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 }(); } @@ -147,10 +147,10 @@ int main() { // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}) - // TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call i{{[0-9]+}}* [[G_CTOR:@.+]]() + // TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]() // TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]]) - // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() { + // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS: ret i{{[0-9]+}}* [[G]] // TLS-BLOCKS: } #pragma omp parallel copyin(g) @@ -169,7 +169,7 @@ int main() { // BLOCKS: [[DONE]] // TLS-BLOCKS-DAG: [[G_CAPTURE_SRC:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % - // TLS-BLOCKS-DAG: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS-DAG: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS-DAG: [[G_CAPTURE_SRCC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_SRC]] to i{{[0-9]+}} // TLS-BLOCKS-DAG: [[G_CAPTURE_DSTC:%.+]] = ptrtoint i{{[0-9]+}}* [[G_CAPTURE_DST]] to i{{[0-9]+}} // TLS-BLOCKS: icmp ne i{{[0-9]+}} {{%.+}}, {{%.+}} @@ -186,7 +186,7 @@ int main() { // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 - // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS: call {{.*}}void {{%.+}}(i8 @@ -201,7 +201,7 @@ int main() { // BLOCKS: ret // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} - // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call i{{[0-9]+}}* [[G_CTOR]]() + // TLS-BLOCKS: [[G_CAPTURE_DST:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR]]() // TLS-BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_CAPTURE_DST]] // TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}} // TLS-BLOCKS: ret -- 2.40.0