Skip to content

Commit 3810f02

Browse files
committed
Merge r100559 from mainline to fix PR6696.
llvm-svn: 100851
1 parent b466918 commit 3810f02

File tree

5 files changed

+84
-14
lines changed

5 files changed

+84
-14
lines changed

llvm/lib/Target/X86/X86.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ TargetAsmBackend *createX86_64AsmBackend(const Target &, MCAssembler &);
6666
///
6767
FunctionPass *createEmitX86CodeToMemory();
6868

69+
/// createX86MaxStackAlignmentHeuristicPass - This function returns a pass
70+
/// which determines whether the frame pointer register should be
71+
/// reserved in case dynamic stack alignment is later required.
72+
///
73+
FunctionPass *createX86MaxStackAlignmentHeuristicPass();
74+
6975
extern Target TheX86_32Target, TheX86_64Target;
7076

7177
} // End llvm namespace

llvm/lib/Target/X86/X86MachineFunctionInfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
5252
/// relocation models.
5353
unsigned GlobalBaseReg;
5454

55+
/// ReserveFP - whether the function should reserve the frame pointer
56+
/// when allocating, even if there may not actually be a frame pointer used.
57+
bool ReserveFP;
58+
5559
public:
5660
X86MachineFunctionInfo() : ForceFramePointer(false),
5761
CalleeSavedFrameSize(0),
@@ -68,7 +72,8 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
6872
ReturnAddrIndex(0),
6973
TailCallReturnAddrDelta(0),
7074
SRetReturnReg(0),
71-
GlobalBaseReg(0) {}
75+
GlobalBaseReg(0),
76+
ReserveFP(false) {}
7277

7378
bool getForceFramePointer() const { return ForceFramePointer;}
7479
void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; }
@@ -90,6 +95,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
9095

9196
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
9297
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
98+
99+
bool getReserveFP() const { return ReserveFP; }
100+
void setReserveFP(bool reserveFP) { ReserveFP = reserveFP; }
93101
};
94102

95103
} // End llvm namespace

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,3 +1489,46 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
14891489
}
14901490

14911491
#include "X86GenRegisterInfo.inc"
1492+
1493+
namespace {
1494+
struct MSAH : public MachineFunctionPass {
1495+
static char ID;
1496+
MSAH() : MachineFunctionPass(&ID) {}
1497+
1498+
virtual bool runOnMachineFunction(MachineFunction &MF) {
1499+
const X86TargetMachine *TM =
1500+
static_cast<const X86TargetMachine *>(&MF.getTarget());
1501+
const X86RegisterInfo *X86RI = TM->getRegisterInfo();
1502+
MachineRegisterInfo &RI = MF.getRegInfo();
1503+
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
1504+
unsigned StackAlignment = X86RI->getStackAlignment();
1505+
1506+
// Be over-conservative: scan over all vreg defs and find whether vector
1507+
// registers are used. If yes, there is a possibility that vector register
1508+
// will be spilled and thus require dynamic stack realignment.
1509+
for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
1510+
RegNum < RI.getLastVirtReg(); ++RegNum)
1511+
if (RI.getRegClass(RegNum)->getAlignment() > StackAlignment) {
1512+
FuncInfo->setReserveFP(true);
1513+
return true;
1514+
}
1515+
1516+
// Nothing to do
1517+
return false;
1518+
}
1519+
1520+
virtual const char *getPassName() const {
1521+
return "X86 Maximal Stack Alignment Check";
1522+
}
1523+
1524+
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1525+
AU.setPreservesCFG();
1526+
MachineFunctionPass::getAnalysisUsage(AU);
1527+
}
1528+
};
1529+
1530+
char MSAH::ID = 0;
1531+
}
1532+
1533+
FunctionPass*
1534+
llvm::createX86MaxStackAlignmentHeuristicPass() { return new MSAH(); }

llvm/lib/Target/X86/X86RegisterInfo.td

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,12 @@ def GR8 : RegisterClass<"X86", [i8], 8,
352352
const TargetMachine &TM = MF.getTarget();
353353
const TargetRegisterInfo *RI = TM.getRegisterInfo();
354354
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
355+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
355356
// Does the function dedicate RBP / EBP to being a frame ptr?
356357
if (!Subtarget.is64Bit())
357358
// In 32-mode, none of the 8-bit registers aliases EBP or ESP.
358359
return begin() + 8;
359-
else if (RI->hasFP(MF))
360+
else if (RI->hasFP(MF) || MFI->getReserveFP())
360361
// If so, don't allocate SPL or BPL.
361362
return array_endof(X86_GR8_AO_64) - 1;
362363
else
@@ -396,17 +397,18 @@ def GR16 : RegisterClass<"X86", [i16], 16,
396397
const TargetMachine &TM = MF.getTarget();
397398
const TargetRegisterInfo *RI = TM.getRegisterInfo();
398399
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
400+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
399401
if (Subtarget.is64Bit()) {
400402
// Does the function dedicate RBP to being a frame ptr?
401-
if (RI->hasFP(MF))
403+
if (RI->hasFP(MF) || MFI->getReserveFP())
402404
// If so, don't allocate SP or BP.
403405
return array_endof(X86_GR16_AO_64) - 1;
404406
else
405407
// If not, just don't allocate SP.
406408
return array_endof(X86_GR16_AO_64);
407409
} else {
408410
// Does the function dedicate EBP to being a frame ptr?
409-
if (RI->hasFP(MF))
411+
if (RI->hasFP(MF) || MFI->getReserveFP())
410412
// If so, don't allocate SP or BP.
411413
return begin() + 6;
412414
else
@@ -447,17 +449,18 @@ def GR32 : RegisterClass<"X86", [i32], 32,
447449
const TargetMachine &TM = MF.getTarget();
448450
const TargetRegisterInfo *RI = TM.getRegisterInfo();
449451
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
452+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
450453
if (Subtarget.is64Bit()) {
451454
// Does the function dedicate RBP to being a frame ptr?
452-
if (RI->hasFP(MF))
455+
if (RI->hasFP(MF) || MFI->getReserveFP())
453456
// If so, don't allocate ESP or EBP.
454457
return array_endof(X86_GR32_AO_64) - 1;
455458
else
456459
// If not, just don't allocate ESP.
457460
return array_endof(X86_GR32_AO_64);
458461
} else {
459462
// Does the function dedicate EBP to being a frame ptr?
460-
if (RI->hasFP(MF))
463+
if (RI->hasFP(MF) || MFI->getReserveFP())
461464
// If so, don't allocate ESP or EBP.
462465
return begin() + 6;
463466
else
@@ -484,9 +487,11 @@ def GR64 : RegisterClass<"X86", [i64], 64,
484487
const TargetMachine &TM = MF.getTarget();
485488
const TargetRegisterInfo *RI = TM.getRegisterInfo();
486489
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
490+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
487491
if (!Subtarget.is64Bit())
488492
return begin(); // None of these are allocatable in 32-bit.
489-
if (RI->hasFP(MF)) // Does the function dedicate RBP to being a frame ptr?
493+
// Does the function dedicate RBP to being a frame ptr?
494+
if (RI->hasFP(MF) || MFI->getReserveFP())
490495
return end()-3; // If so, don't allocate RIP, RSP or RBP
491496
else
492497
return end()-2; // If not, just don't allocate RIP or RSP
@@ -582,8 +587,9 @@ def GR16_NOREX : RegisterClass<"X86", [i16], 16,
582587
GR16_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
583588
const TargetMachine &TM = MF.getTarget();
584589
const TargetRegisterInfo *RI = TM.getRegisterInfo();
590+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
585591
// Does the function dedicate RBP / EBP to being a frame ptr?
586-
if (RI->hasFP(MF))
592+
if (RI->hasFP(MF) || MFI->getReserveFP())
587593
// If so, don't allocate SP or BP.
588594
return end() - 2;
589595
else
@@ -604,8 +610,9 @@ def GR32_NOREX : RegisterClass<"X86", [i32], 32,
604610
GR32_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
605611
const TargetMachine &TM = MF.getTarget();
606612
const TargetRegisterInfo *RI = TM.getRegisterInfo();
613+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
607614
// Does the function dedicate RBP / EBP to being a frame ptr?
608-
if (RI->hasFP(MF))
615+
if (RI->hasFP(MF) || MFI->getReserveFP())
609616
// If so, don't allocate ESP or EBP.
610617
return end() - 2;
611618
else
@@ -626,8 +633,9 @@ def GR64_NOREX : RegisterClass<"X86", [i64], 64,
626633
GR64_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
627634
const TargetMachine &TM = MF.getTarget();
628635
const TargetRegisterInfo *RI = TM.getRegisterInfo();
636+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
629637
// Does the function dedicate RBP to being a frame ptr?
630-
if (RI->hasFP(MF))
638+
if (RI->hasFP(MF) || MFI->getReserveFP())
631639
// If so, don't allocate RIP, RSP or RBP.
632640
return end() - 3;
633641
else
@@ -668,17 +676,18 @@ def GR32_NOSP : RegisterClass<"X86", [i32], 32,
668676
const TargetMachine &TM = MF.getTarget();
669677
const TargetRegisterInfo *RI = TM.getRegisterInfo();
670678
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
679+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
671680
if (Subtarget.is64Bit()) {
672681
// Does the function dedicate RBP to being a frame ptr?
673-
if (RI->hasFP(MF))
682+
if (RI->hasFP(MF) || MFI->getReserveFP())
674683
// If so, don't allocate EBP.
675684
return array_endof(X86_GR32_NOSP_AO_64) - 1;
676685
else
677686
// If not, any reg in this class is ok.
678687
return array_endof(X86_GR32_NOSP_AO_64);
679688
} else {
680689
// Does the function dedicate EBP to being a frame ptr?
681-
if (RI->hasFP(MF))
690+
if (RI->hasFP(MF) || MFI->getReserveFP())
682691
// If so, don't allocate EBP.
683692
return begin() + 6;
684693
else
@@ -703,9 +712,11 @@ def GR64_NOSP : RegisterClass<"X86", [i64], 64,
703712
const TargetMachine &TM = MF.getTarget();
704713
const TargetRegisterInfo *RI = TM.getRegisterInfo();
705714
const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
715+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
706716
if (!Subtarget.is64Bit())
707717
return begin(); // None of these are allocatable in 32-bit.
708-
if (RI->hasFP(MF)) // Does the function dedicate RBP to being a frame ptr?
718+
// Does the function dedicate RBP to being a frame ptr?
719+
if (RI->hasFP(MF) || MFI->getReserveFP())
709720
return end()-1; // If so, don't allocate RBP
710721
else
711722
return end(); // If not, any reg in this class is ok.
@@ -726,8 +737,9 @@ def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
726737
{
727738
const TargetMachine &TM = MF.getTarget();
728739
const TargetRegisterInfo *RI = TM.getRegisterInfo();
740+
const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
729741
// Does the function dedicate RBP to being a frame ptr?
730-
if (RI->hasFP(MF))
742+
if (RI->hasFP(MF) || MFI->getReserveFP())
731743
// If so, don't allocate RBP.
732744
return end() - 1;
733745
else

llvm/lib/Target/X86/X86TargetMachine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
160160

161161
bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
162162
CodeGenOpt::Level OptLevel) {
163+
PM.add(createX86MaxStackAlignmentHeuristicPass());
163164
return false; // -print-machineinstr shouldn't print after this.
164165
}
165166

0 commit comments

Comments
 (0)