[llvm] r223329 - [X86] Restore X86 base pointer after call to llvm.eh.sjlj.setjmp
Michael Liao
michael.liao at intel.com
Wed Dec 3 16:56:39 PST 2014
Author: hliao
Date: Wed Dec 3 18:56:38 2014
New Revision: 223329
URL: http://llvm.org/viewvc/llvm-project?rev=223329&view=rev
Log:
[X86] Restore X86 base pointer after call to llvm.eh.sjlj.setjmp
Commit on
- This patch fixes the bug described in
http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-May/062343.html
The fix allocates an extra slot just below the GPRs and stores the base pointer
there. This is done only for functions containing llvm.eh.sjlj.setjmp that also
need a base pointer. Because code containing llvm.eh.sjlj.setjmp saves all of
the callee-save GPRs in the prologue, the offset to the extra slot can be
computed before prologue generation runs.
Impact at run-time on affected functions is::
- One extra store in the prologue, The store saves the base pointer.
- One extra load after a llvm.eh.sjlj.setjmp. The load restores the base pointer.
Because the extra slot is just above a gap between frame-pointer-relative and
base-pointer-relative chunks of memory, there is no impact on other offset
calculations other than ensuring there is room for the extra slot.
http://reviews.llvm.org/D6388
Patch by Arch Robison <arch.robison at intel.com>
Added:
llvm/trunk/test/CodeGen/X86/sjlj-baseptr.ll
Modified:
llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.cpp
llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h
Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=223329&r1=223328&r2=223329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Wed Dec 3 18:56:38 2014
@@ -448,6 +448,8 @@ void X86FrameLowering::getStackProbeFunc
[if needs base pointer]
mov %rsp, %rbx
+ [if needs to restore base pointer]
+ mov %rsp, -MMM(%rbp)
; Emit CFI info
[if needs FP]
@@ -570,6 +572,9 @@ void X86FrameLowering::emitPrologue(Mach
if (HasFP) {
// Calculate required stack adjustment.
uint64_t FrameSize = StackSize - SlotSize;
+ // If required, include space for extra hidden slot for stashing base pointer.
+ if (X86FI->getRestoreBasePointer())
+ FrameSize += SlotSize;
if (RegInfo->needsStackRealignment(MF)) {
// Callee-saved registers are pushed on stack before the stack
// is realigned.
@@ -838,6 +843,14 @@ void X86FrameLowering::emitPrologue(Mach
BuildMI(MBB, MBBI, DL, TII.get(Opc), BasePtr)
.addReg(StackPtr)
.setMIFlag(MachineInstr::FrameSetup);
+ if (X86FI->getRestoreBasePointer()) {
+ // Stash value of base pointer. Saving RSP instead of EBP shortens dependence chain.
+ unsigned Opm = Uses64BitFramePtr ? X86::MOV64mr : X86::MOV32mr;
+ addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opm)),
+ FramePtr, true, X86FI->getRestoreBasePointerOffset())
+ .addReg(StackPtr)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
}
if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=223329&r1=223328&r2=223329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 3 18:56:38 2014
@@ -20925,6 +20925,7 @@ X86TargetLowering::emitEHSjLjSetJmp(Mach
// v = phi(main, restore)
//
// restoreMBB:
+ // if base pointer being used, load it from frame
// v_restore = 1
MachineBasicBlock *thisMBB = MBB;
@@ -21008,6 +21009,18 @@ X86TargetLowering::emitEHSjLjSetJmp(Mach
.addReg(restoreDstReg).addMBB(restoreMBB);
// restoreMBB:
+ if (RegInfo->hasBasePointer(*MF)) {
+ const X86Subtarget &STI = MF->getTarget().getSubtarget<X86Subtarget>();
+ const bool Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64();
+ X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
+ X86FI->setRestoreBasePointer(MF);
+ unsigned FramePtr = RegInfo->getFrameRegister(*MF);
+ unsigned BasePtr = RegInfo->getBaseRegister();
+ unsigned Opm = Uses64BitFramePtr ? X86::MOV64rm : X86::MOV32rm;
+ addRegOffset(BuildMI(restoreMBB, DL, TII->get(Opm), BasePtr),
+ FramePtr, true, X86FI->getRestoreBasePointerOffset())
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
BuildMI(restoreMBB, DL, TII->get(X86::MOV32ri), restoreDstReg).addImm(1);
BuildMI(restoreMBB, DL, TII->get(X86::JMP_4)).addMBB(sinkMBB);
restoreMBB->addSuccessor(sinkMBB);
Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.cpp?rev=223329&r1=223328&r2=223329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.cpp Wed Dec 3 18:56:38 2014
@@ -8,7 +8,26 @@
//===----------------------------------------------------------------------===//
#include "X86MachineFunctionInfo.h"
+#include "X86RegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
void X86MachineFunctionInfo::anchor() { }
+
+void X86MachineFunctionInfo::setRestoreBasePointer(const MachineFunction *MF) {
+ if (!RestoreBasePointerOffset) {
+ const X86RegisterInfo *RegInfo = static_cast<const X86RegisterInfo *>(
+ MF->getSubtarget().getRegisterInfo());
+ unsigned SlotSize = RegInfo->getSlotSize();
+ for (const MCPhysReg *CSR =
+ RegInfo->X86RegisterInfo::getCalleeSavedRegs(MF);
+ unsigned Reg = *CSR;
+ ++CSR)
+ {
+ if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg))
+ RestoreBasePointerOffset -= SlotSize;
+ }
+ }
+}
+
Modified: llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h?rev=223329&r1=223328&r2=223329&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h Wed Dec 3 18:56:38 2014
@@ -31,6 +31,12 @@ class X86MachineFunctionInfo : public Ma
/// contains stack pointer re-alignment code which requires FP.
bool ForceFramePointer;
+ /// RestoreBasePointerOffset - Non-zero if the function has base pointer
+ /// and makes call to llvm.eh.sjlj.setjmp. When non-zero, the value is a
+ /// displacement from the frame pointer to a slot where the base pointer
+ /// is stashed.
+ signed char RestoreBasePointerOffset;
+
/// CalleeSavedFrameSize - Size of the callee-saved register portion of the
/// stack frame in bytes.
unsigned CalleeSavedFrameSize;
@@ -89,6 +95,7 @@ private:
public:
X86MachineFunctionInfo() : ForceFramePointer(false),
+ RestoreBasePointerOffset(0),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
ReturnAddrIndex(0),
@@ -104,6 +111,7 @@ public:
explicit X86MachineFunctionInfo(MachineFunction &MF)
: ForceFramePointer(false),
+ RestoreBasePointerOffset(0),
CalleeSavedFrameSize(0),
BytesToPopOnReturn(0),
ReturnAddrIndex(0),
@@ -120,6 +128,10 @@ public:
bool getForceFramePointer() const { return ForceFramePointer;}
void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; }
+ bool getRestoreBasePointer() const { return RestoreBasePointerOffset!=0; }
+ void setRestoreBasePointer(const MachineFunction *MF);
+ int getRestoreBasePointerOffset() const {return RestoreBasePointerOffset; }
+
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
Added: llvm/trunk/test/CodeGen/X86/sjlj-baseptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sjlj-baseptr.ll?rev=223329&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sjlj-baseptr.ll (added)
+++ llvm/trunk/test/CodeGen/X86/sjlj-baseptr.ll Wed Dec 3 18:56:38 2014
@@ -0,0 +1,37 @@
+; RUN: llc < %s -mtriple=i386-pc-linux -mcpu=corei7 -relocation-model=static | FileCheck --check-prefix=X86 %s
+; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7 -relocation-model=static | FileCheck --check-prefix=X64 %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%Foo = type { [125 x i8] }
+
+declare i32 @llvm.eh.sjlj.setjmp(i8*) nounwind
+
+declare void @whatever(i64, %Foo*, i8**, i8*, i8*, i32) #0
+
+attributes #0 = { nounwind uwtable "no-frame-pointer-elim"="true" }
+
+define i32 @test1(i64 %n, %Foo* byval nocapture readnone align 8 %f) #0 {
+entry:
+ %buf = alloca [5 x i8*], align 16
+ %p = alloca i8*, align 8
+ %q = alloca i8, align 64
+ %r = bitcast [5 x i8*]* %buf to i8*
+ %s = alloca i8, i64 %n, align 1
+ store i8* %s, i8** %p, align 8
+ %t = call i32 @llvm.eh.sjlj.setjmp(i8* %s)
+ call void @whatever(i64 %n, %Foo* %f, i8** %p, i8* %q, i8* %s, i32 %t) #1
+ ret i32 0
+; X86: movl %esp, %esi
+; X86: movl %esp, -16(%ebp)
+; X86: {{.LBB.*:}}
+; X86: movl -16(%ebp), %esi
+; X86: {{.LBB.*:}}
+; X64: movq %rsp, %rbx
+; X64: movq %rsp, -48(%rbp)
+; X64: {{.LBB.*:}}
+; X64: movq -48(%rbp), %rbx
+; X64: {{.LBB.*:}}
+}
+
+
More information about the llvm-commits
mailing list