diff options
| author | Manman Ren <manman.ren@gmail.com> | 2015-11-12 00:54:04 +0000 |
|---|---|---|
| committer | Manman Ren <manman.ren@gmail.com> | 2015-11-12 00:54:04 +0000 |
| commit | 3f2b9c18e2384247d9592e8e618c01d16dcc9168 (patch) | |
| tree | 44a2767beeb06b302b0dd7f77167a74287a96f90 | |
| parent | e053d443097f8d9374e5bbbd988eff9bdb575c12 (diff) | |
| download | bcm5719-llvm-3f2b9c18e2384247d9592e8e618c01d16dcc9168.tar.gz bcm5719-llvm-3f2b9c18e2384247d9592e8e618c01d16dcc9168.zip | |
[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
llvm-svn: 252837
| -rw-r--r-- | llvm/lib/Target/X86/X86CallingConv.td | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.h | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/darwin-tls.ll | 28 |
5 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index aaabf7a59f5..76256f3c704 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -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)>; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a0ffa12bb36..46b2b5e669f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -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, diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index b1147877753..8b4bbac7007 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -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); diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h index c20842b25de..1b1a1ccfc1a 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -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 diff --git a/llvm/test/CodeGen/X86/darwin-tls.ll b/llvm/test/CodeGen/X86/darwin-tls.ll new file mode 100644 index 00000000000..ca9a998ccc7 --- /dev/null +++ b/llvm/test/CodeGen/X86/darwin-tls.ll @@ -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) |

