mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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@intel.com> llvm-svn: 223329
This commit is contained in:
parent
84b0b8cc3b
commit
f24ea6579d
@ -448,6 +448,8 @@ void X86FrameLowering::getStackProbeFunction(const X86Subtarget &STI,
|
||||
|
||||
[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(MachineFunction &MF) const {
|
||||
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(MachineFunction &MF) const {
|
||||
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) {
|
||||
|
@ -20925,6 +20925,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
||||
// 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(MachineInstr *MI,
|
||||
.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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,12 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
|
||||
/// 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; }
|
||||
|
||||
|
37
test/CodeGen/X86/sjlj-baseptr.ll
Normal file
37
test/CodeGen/X86/sjlj-baseptr.ll
Normal file
@ -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.*:}}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user