[X86] Fix emitEpilogue() to make less assumptions about pops

This is the mirror image of r242395.
When X86FrameLowering::emitEpilogue() looks for where to insert the %esp addition that
deallocates stack space used for local allocations, it assumes that any sequence of pop
instructions from function exit backwards consists purely of restoring callee-save registers.

This may be false, since from some point backward, the pops may be clean-up of stack space
allocated for arguments to a call.

Patch by: amjad.aboud@intel.com
Differential Revision: http://reviews.llvm.org/D12688

llvm-svn: 247784
This commit is contained in:
Michael Kuperstein 2015-09-16 11:18:25 +00:00
parent 11bb848ddc
commit 098cd9fba7
3 changed files with 20 additions and 8 deletions

View File

@ -64,8 +64,10 @@ public:
NoFlags = 0, NoFlags = 0,
FrameSetup = 1 << 0, // Instruction is used as a part of FrameSetup = 1 << 0, // Instruction is used as a part of
// function frame setup code. // function frame setup code.
BundledPred = 1 << 1, // Instruction has bundled predecessors. FrameDestroy = 1 << 1, // Instruction is used as a part of
BundledSucc = 1 << 2 // Instruction has bundled successors. // function frame destruction code.
BundledPred = 1 << 2, // Instruction has bundled predecessors.
BundledSucc = 1 << 3 // Instruction has bundled successors.
}; };
private: private:
const MCInstrDesc *MCID; // Instruction descriptor. const MCInstrDesc *MCID; // Instruction descriptor.

View File

@ -1735,13 +1735,16 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
} }
bool HaveSemi = false; bool HaveSemi = false;
const unsigned PrintableFlags = FrameSetup; const unsigned PrintableFlags = FrameSetup | FrameDestroy;
if (Flags & PrintableFlags) { if (Flags & PrintableFlags) {
if (!HaveSemi) OS << ";"; HaveSemi = true; if (!HaveSemi) OS << ";"; HaveSemi = true;
OS << " flags: "; OS << " flags: ";
if (Flags & FrameSetup) if (Flags & FrameSetup)
OS << "FrameSetup"; OS << "FrameSetup";
if (Flags & FrameDestroy)
OS << "FrameDestroy";
} }
if (!memoperands_empty()) { if (!memoperands_empty()) {

View File

@ -286,6 +286,8 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
.addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub));
if (isSub) if (isSub)
MI->setFlag(MachineInstr::FrameSetup); MI->setFlag(MachineInstr::FrameSetup);
else
MI->setFlag(MachineInstr::FrameDestroy);
Offset -= ThisVal; Offset -= ThisVal;
continue; continue;
} }
@ -295,6 +297,8 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
MBB, MBBI, DL, isSub ? -ThisVal : ThisVal, InEpilogue); MBB, MBBI, DL, isSub ? -ThisVal : ThisVal, InEpilogue);
if (isSub) if (isSub)
MI.setMIFlag(MachineInstr::FrameSetup); MI.setMIFlag(MachineInstr::FrameSetup);
else
MI.setMIFlag(MachineInstr::FrameDestroy);
Offset -= ThisVal; Offset -= ThisVal;
} }
@ -1075,7 +1079,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
// Pop EBP. // Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr); MachineFramePtr).setMIFlag(MachineInstr::FrameDestroy);
} else if (hasFP(MF)) { } else if (hasFP(MF)) {
// Calculate required stack adjustment. // Calculate required stack adjustment.
uint64_t FrameSize = StackSize - SlotSize; uint64_t FrameSize = StackSize - SlotSize;
@ -1088,7 +1092,8 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
// Pop EBP. // Pop EBP.
BuildMI(MBB, MBBI, DL, BuildMI(MBB, MBBI, DL,
TII.get(Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr); TII.get(Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr)
.setMIFlag(MachineInstr::FrameDestroy);
} else { } else {
NumBytes = StackSize - CSSize; NumBytes = StackSize - CSSize;
} }
@ -1099,8 +1104,9 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock::iterator PI = std::prev(MBBI); MachineBasicBlock::iterator PI = std::prev(MBBI);
unsigned Opc = PI->getOpcode(); unsigned Opc = PI->getOpcode();
if (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::DBG_VALUE && if ((Opc != X86::POP32r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
!PI->isTerminator()) (Opc != X86::POP64r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
Opc != X86::DBG_VALUE && !PI->isTerminator())
break; break;
--MBBI; --MBBI;
@ -1463,7 +1469,8 @@ bool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
!X86::GR32RegClass.contains(Reg)) !X86::GR32RegClass.contains(Reg))
continue; continue;
BuildMI(MBB, MI, DL, TII.get(Opc), Reg); BuildMI(MBB, MI, DL, TII.get(Opc), Reg)
.setMIFlag(MachineInstr::FrameDestroy);
} }
return true; return true;
} }