[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
This commit is contained in:
parent
c3fa1eded2
commit
5e5d046a4f
|
@ -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);
|
||||
|
|
|
@ -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"{{.*}} }
|
||||
|
|
|
@ -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]] = { {{.+}} }
|
||||
|
|
Loading…
Reference in New Issue