[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,
FrameSetup = 1 << 0, // Instruction is used as a part of
// function frame setup code.
BundledPred = 1 << 1, // Instruction has bundled predecessors.
BundledSucc = 1 << 2 // Instruction has bundled successors.
FrameDestroy = 1 << 1, // Instruction is used as a part of
// function frame destruction code.
BundledPred = 1 << 2, // Instruction has bundled predecessors.
BundledSucc = 1 << 3 // Instruction has bundled successors.
};
private:
const MCInstrDesc *MCID; // Instruction descriptor.

View File

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

View File

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