[TLS on Darwin] use a different mask for tls calls on x86-64.

Calls involved in thread-local variable lookup save more registers
than normal calls.

rdar://problem/23073171


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252837 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manman Ren 2015-11-12 00:54:04 +00:00
parent c1ad62ec03
commit 6c3ce45003
5 changed files with 44 additions and 0 deletions

View File

@ -796,6 +796,12 @@ def CSR_64EHRet : CalleeSavedRegs<(add RAX, RDX, CSR_64)>;
def CSR_Win64 : CalleeSavedRegs<(add RBX, RBP, RDI, RSI, R12, R13, R14, R15,
(sequence "XMM%u", 6, 15))>;
// The function used by Darwin to obtain the address of a thread-local variable
// uses rdi to pass a single parameter and rax for the return value. All other
// GPRs are preserved.
def CSR_64_TLS_Darwin : CalleeSavedRegs<(add CSR_64, RCX, RDX, RSI,
R8, R9, R10, R11)>;
// All GPRs - except r11
def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI,
R8, R9, R10, RSP)>;

View File

@ -21461,6 +21461,8 @@ X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
// FIXME: The 32-bit calls have non-standard calling conventions. Use a
// proper register mask.
const uint32_t *RegMask =
Subtarget->is64Bit() ?
Subtarget->getRegisterInfo()->getDarwinTLSCallPreservedMask() :
Subtarget->getRegisterInfo()->getCallPreservedMask(*F, CallingConv::C);
if (Subtarget->is64Bit()) {
MachineInstrBuilder MIB = BuildMI(*BB, MI, DL,

View File

@ -347,6 +347,10 @@ X86RegisterInfo::getNoPreservedMask() const {
return CSR_NoRegs_RegMask;
}
const uint32_t *X86RegisterInfo::getDarwinTLSCallPreservedMask() const {
return CSR_64_TLS_Darwin_RegMask;
}
BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
const X86FrameLowering *TFI = getFrameLowering(MF);

View File

@ -98,6 +98,10 @@ public:
CallingConv::ID) const override;
const uint32_t *getNoPreservedMask() const override;
// Calls involved in thread-local variable lookup save more registers than
// normal calls, so they need a different mask to represent this.
const uint32_t *getDarwinTLSCallPreservedMask() const;
/// getReservedRegs - Returns a bitset indexed by physical register number
/// indicating if a register is a special register that has particular uses and
/// should be considered unavailable at all times, e.g. SP, RA. This is used by

View File

@ -0,0 +1,28 @@
; RUN: llc < %s -mtriple x86_64-apple-darwin | FileCheck %s
@a = thread_local global i32 4, align 4
define i32 @f2(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
entry:
; Parameters are in %edi, %esi, %edx, %ecx, %r8d, there is no need to save
; these parameters except the one in %edi, before making the TLS call.
; %edi is used to pass parameter to the TLS call.
; CHECK-NOT: movl %r8d
; CHECK-NOT: movl %ecx
; CHECK-NOT: movl %edx
; CHECK-NOT: movl %esi
; CHECK: movq {{.*}}TLVP{{.*}}, %rdi
; CHECK-NEXT: callq
; CHECK-NEXT: movl (%rax),
; CHECK-NOT: movl {{.*}}, %esi
; CHECK-NOT: movl {{.*}}, %edx
; CHECK-NOT: movl {{.*}}, %ecx
; CHECK-NOT: movl {{.*}}, %r8d
; CHECK: callq
%0 = load i32, i32* @a, align 4
%call = tail call i32 @f3(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5)
%add = add nsw i32 %call, %0
ret i32 %add
}
declare i32 @f3(i32, i32, i32, i32, i32)