mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-02 04:39:35 +00: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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ec086bf087
commit
fd0832ea89
@ -448,6 +448,8 @@ void X86FrameLowering::getStackProbeFunction(const X86Subtarget &STI,
|
|||||||
|
|
||||||
[if needs base pointer]
|
[if needs base pointer]
|
||||||
mov %rsp, %rbx
|
mov %rsp, %rbx
|
||||||
|
[if needs to restore base pointer]
|
||||||
|
mov %rsp, -MMM(%rbp)
|
||||||
|
|
||||||
; Emit CFI info
|
; Emit CFI info
|
||||||
[if needs FP]
|
[if needs FP]
|
||||||
@ -570,6 +572,9 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
if (HasFP) {
|
if (HasFP) {
|
||||||
// Calculate required stack adjustment.
|
// Calculate required stack adjustment.
|
||||||
uint64_t FrameSize = StackSize - SlotSize;
|
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)) {
|
if (RegInfo->needsStackRealignment(MF)) {
|
||||||
// Callee-saved registers are pushed on stack before the stack
|
// Callee-saved registers are pushed on stack before the stack
|
||||||
// is realigned.
|
// is realigned.
|
||||||
@ -838,6 +843,14 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
BuildMI(MBB, MBBI, DL, TII.get(Opc), BasePtr)
|
BuildMI(MBB, MBBI, DL, TII.get(Opc), BasePtr)
|
||||||
.addReg(StackPtr)
|
.addReg(StackPtr)
|
||||||
.setMIFlag(MachineInstr::FrameSetup);
|
.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) {
|
if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
|
||||||
|
@ -20925,6 +20925,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
// v = phi(main, restore)
|
// v = phi(main, restore)
|
||||||
//
|
//
|
||||||
// restoreMBB:
|
// restoreMBB:
|
||||||
|
// if base pointer being used, load it from frame
|
||||||
// v_restore = 1
|
// v_restore = 1
|
||||||
|
|
||||||
MachineBasicBlock *thisMBB = MBB;
|
MachineBasicBlock *thisMBB = MBB;
|
||||||
@ -21008,6 +21009,18 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
.addReg(restoreDstReg).addMBB(restoreMBB);
|
.addReg(restoreDstReg).addMBB(restoreMBB);
|
||||||
|
|
||||||
// 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::MOV32ri), restoreDstReg).addImm(1);
|
||||||
BuildMI(restoreMBB, DL, TII->get(X86::JMP_4)).addMBB(sinkMBB);
|
BuildMI(restoreMBB, DL, TII->get(X86::JMP_4)).addMBB(sinkMBB);
|
||||||
restoreMBB->addSuccessor(sinkMBB);
|
restoreMBB->addSuccessor(sinkMBB);
|
||||||
|
@ -8,7 +8,26 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "X86MachineFunctionInfo.h"
|
#include "X86MachineFunctionInfo.h"
|
||||||
|
#include "X86RegisterInfo.h"
|
||||||
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
void X86MachineFunctionInfo::anchor() { }
|
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.
|
/// contains stack pointer re-alignment code which requires FP.
|
||||||
bool ForceFramePointer;
|
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
|
/// CalleeSavedFrameSize - Size of the callee-saved register portion of the
|
||||||
/// stack frame in bytes.
|
/// stack frame in bytes.
|
||||||
unsigned CalleeSavedFrameSize;
|
unsigned CalleeSavedFrameSize;
|
||||||
@ -89,6 +95,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
X86MachineFunctionInfo() : ForceFramePointer(false),
|
X86MachineFunctionInfo() : ForceFramePointer(false),
|
||||||
|
RestoreBasePointerOffset(0),
|
||||||
CalleeSavedFrameSize(0),
|
CalleeSavedFrameSize(0),
|
||||||
BytesToPopOnReturn(0),
|
BytesToPopOnReturn(0),
|
||||||
ReturnAddrIndex(0),
|
ReturnAddrIndex(0),
|
||||||
@ -104,6 +111,7 @@ public:
|
|||||||
|
|
||||||
explicit X86MachineFunctionInfo(MachineFunction &MF)
|
explicit X86MachineFunctionInfo(MachineFunction &MF)
|
||||||
: ForceFramePointer(false),
|
: ForceFramePointer(false),
|
||||||
|
RestoreBasePointerOffset(0),
|
||||||
CalleeSavedFrameSize(0),
|
CalleeSavedFrameSize(0),
|
||||||
BytesToPopOnReturn(0),
|
BytesToPopOnReturn(0),
|
||||||
ReturnAddrIndex(0),
|
ReturnAddrIndex(0),
|
||||||
@ -120,6 +128,10 @@ public:
|
|||||||
bool getForceFramePointer() const { return ForceFramePointer;}
|
bool getForceFramePointer() const { return ForceFramePointer;}
|
||||||
void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; }
|
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; }
|
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
|
||||||
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
|
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