From: Manman Ren Date: Fri, 18 Mar 2016 23:35:21 +0000 (+0000) Subject: [TLS on Darwin] use CXX_FAST_TLS calling convention for tls_init. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a795333934bec106f2dde66447c58f3bf33556c0;p=clang [TLS on Darwin] use CXX_FAST_TLS calling convention for tls_init. This makes sure we don't generate a lot of code to spill/reload CSRs when calling tls_init from the access functions. This helps performance when tls_init is not inlined into the access functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@263854 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 5f72af83b1..ff0e972ba6 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2237,6 +2237,11 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs( CodeGenFunction(CGM) .GenerateCXXGlobalInitFunc(InitFunc, CXXThreadLocalInits, Address(Guard, GuardAlign)); + // On Darwin platforms, use CXX_FAST_TLS calling convention. + if (CGM.getTarget().getTriple().isOSDarwin()) { + InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); + InitFunc->addFnAttr(llvm::Attribute::NoUnwind); + } } for (const VarDecl *VD : CXXThreadLocals) { llvm::GlobalVariable *Var = @@ -2286,8 +2291,11 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs( llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper); CGBuilderTy Builder(CGM, Entry); if (InitIsInitFunc) { - if (Init) - Builder.CreateCall(Init); + if (Init) { + llvm::CallInst *CallVal = Builder.CreateCall(Init); + if (isThreadWrapperReplaceable(VD, CGM)) + CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); + } } else { // Don't know whether we have an init function. Call it if it exists. llvm::Value *Have = Builder.CreateIsNotNull(Init); diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp index 048a0bd45a..4c1e5a70cb 100644 --- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -23,11 +23,13 @@ int &g() { return r; } // LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] { // DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] { -// CHECK: call void @_ZTH1r() +// LINUX: call void @_ZTH1r() +// DARWIN: call cxx_fast_tlscc void @_ZTH1r() // CHECK: load i32*, i32** @r, align 8 // CHECK: ret i32* %{{.*}} -// CHECK-LABEL: define internal void @__tls_init() +// LINUX-LABEL: define internal void @__tls_init() +// DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init() // CHECK: call void @[[R_INIT]]() // LINUX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} } diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp index 40f33e0848..f465cbdeea 100644 --- a/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/test/CodeGenCXX/cxx11-thread-local.cpp @@ -122,7 +122,8 @@ int f() { // LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE() // DARWIN-LABEL: define weak_odr hidden cxx_fast_tlscc i32* @_ZTWN1VIiE1mE() -// CHECK: call void @_ZTHN1VIiE1mE() +// LINUX: call void @_ZTHN1VIiE1mE() +// DARWIN: call cxx_fast_tlscc void @_ZTHN1VIiE1mE() // CHECK: ret i32* @_ZN1VIiE1mE @@ -212,7 +213,8 @@ void set_anon_i() { // LIUNX: define weak_odr hidden i32* @_ZTW1a() { // DARWIN: define cxx_fast_tlscc i32* @_ZTW1a() -// CHECK: call void @_ZTH1a() +// LINUX: call void @_ZTH1a() +// DARWIN: call cxx_fast_tlscc void @_ZTH1a() // CHECK: ret i32* @a // CHECK: } @@ -222,12 +224,14 @@ void set_anon_i() { // LINUX-LABEL: define internal i32* @_ZTWL1d() // DARWIN-LABEL: define internal cxx_fast_tlscc i32* @_ZTWL1d() -// CHECK: call void @_ZTHL1d() +// LINUX: call void @_ZTHL1d() +// DARWIN: call cxx_fast_tlscc void @_ZTHL1d() // CHECK: ret i32* @_ZL1d // LINUX-LABEL: define weak_odr hidden i32* @_ZTWN1U1mE() // DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE() -// CHECK: call void @_ZTHN1U1mE() +// LINUX: call void @_ZTHN1U1mE() +// DARWIN: call cxx_fast_tlscc void @_ZTHN1U1mE() // CHECK: ret i32* @_ZN1U1mE // LINUX: attributes [[ATTR]] = { {{.+}} }