diff options
author | Manman Ren <manman.ren@gmail.com> | 2016-03-18 23:35:21 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2016-03-18 23:35:21 +0000 |
commit | 5e5d046a4f677a5099d01666f1411f1c0df2a036 (patch) | |
tree | 75394b17f4cb7c7849ba90aad92fd6ab289a1515 | |
parent | c3fa1eded258aa38a30911af6602892846efd6d1 (diff) | |
download | bcm5719-llvm-5e5d046a4f677a5099d01666f1411f1c0df2a036.tar.gz bcm5719-llvm-5e5d046a4f677a5099d01666f1411f1c0df2a036.zip |
[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.
llvm-svn: 263854
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 12 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/cxx11-thread-local.cpp | 12 |
3 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5f72af83b12..ff0e972ba64 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/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/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp index 048a0bd45ad..4c1e5a70cba 100644 --- a/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/clang/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/clang/test/CodeGenCXX/cxx11-thread-local.cpp b/clang/test/CodeGenCXX/cxx11-thread-local.cpp index 40f33e0848b..f465cbdeea8 100644 --- a/clang/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/clang/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]] = { {{.+}} } |