r255860 - [TLS on Darwin] use CXX_FAST_TLS calling convention for access functions.

Manman Ren via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 16 16:42:36 PST 2015


Author: mren
Date: Wed Dec 16 18:42:36 2015
New Revision: 255860

URL: http://llvm.org/viewvc/llvm-project?rev=255860&view=rev
Log:
[TLS on Darwin] use CXX_FAST_TLS calling convention for access functions.

Also set nounwind attribute.

rdar://problem/9001553

Modified:
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/cxx11-thread-local-reference.cpp
    cfe/trunk/test/CodeGenCXX/cxx11-thread-local.cpp
    cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp
    cfe/trunk/test/OpenMP/parallel_copyin_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=255860&r1=255859&r2=255860&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Wed Dec 16 18:42:36 2015
@@ -2194,6 +2194,11 @@ ItaniumCXXABI::getOrCreateThreadLocalWra
       !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::EmitThreadLocalVar
   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;
 }

Modified: cfe/trunk/test/CodeGenCXX/cxx11-thread-local-reference.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-thread-local-reference.cpp?rev=255860&r1=255859&r2=255860&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx11-thread-local-reference.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx11-thread-local-reference.cpp Wed Dec 16 18:42:36 2015
@@ -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 }

Modified: cfe/trunk/test/CodeGenCXX/cxx11-thread-local.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-thread-local.cpp?rev=255860&r1=255859&r2=255860&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx11-thread-local.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx11-thread-local.cpp Wed Dec 16 18:42:36 2015
@@ -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

Modified: cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp?rev=255860&r1=255859&r2=255860&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/tls-init-funcs.cpp Wed Dec 16 18:42:36 2015
@@ -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 {

Modified: cfe/trunk/test/OpenMP/parallel_copyin_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_copyin_codegen.cpp?rev=255860&r1=255859&r2=255860&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_copyin_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_copyin_codegen.cpp Wed Dec 16 18:42:36 2015
@@ -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




More information about the cfe-commits mailing list