Change eliminateCallFramePseudoInstr() to return an iterator

This will become necessary in a subsequent change to make this method
merge adjacent stack adjustments, i.e. it might erase the previous
and/or next instruction.

It also greatly simplifies the calls to this function from Prolog-
EpilogInserter. Previously, that had a bunch of logic to resume iteration
after the call; now it just continues with the returned iterator.

Note that this changes the behaviour of PEI a little. Previously,
it attempted to re-visit the new instruction created by
eliminateCallFramePseudoInstr(). That code was added in r36625,
but I can't see any reason for it: the new instructions will obviously
not be pseudo instructions, they will not have FrameIndex operands,
and we have already accounted for the stack adjustment.

Differential Revision: http://reviews.llvm.org/D18627

llvm-svn: 265036
This commit is contained in:
Hans Wennborg 2016-03-31 18:33:38 +00:00
parent 19cb9476a2
commit e1a2e90ffa
33 changed files with 85 additions and 96 deletions

View File

@ -52,6 +52,10 @@ Non-comprehensive list of changes in this release
* The C API function LLVMGetDataLayout is deprecated
in favor of LLVMGetDataLayoutStr.
* ``TargetFrameLowering::eliminateCallFramePseudoInstr`` now returns an
iterator to the next instruction instead of ``void``. Targets that previously
did ``MBB.erase(I); return;`` now probably want ``return MBB.erase(I);``.
.. NOTE
For small 1-3 sentence descriptions, just add an entry at the end of
this list. If your description won't fit comfortably in one bullet

View File

@ -273,14 +273,13 @@ public:
report_fatal_error("WinEH not implemented for this target");
}
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
/// code insertion to eliminate call frame setup and destroy pseudo
/// instructions (but only if the Target is using them). It is responsible
/// for eliminating these instructions, replacing them with concrete
/// instructions. This method need only be implemented if using call frame
/// setup/destroy pseudo instructions.
///
virtual void
/// This method is called during prolog/epilog code insertion to eliminate
/// call frame setup and destroy pseudo instructions (but only if the Target
/// is using them). It is responsible for eliminating these instructions,
/// replacing them with concrete instructions. This method need only be
/// implemented if using call frame setup/destroy pseudo instructions.
/// Returns an iterator pointing to the instruction after the replaced one.
virtual MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {

View File

@ -891,15 +891,7 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
InsideCallSequence = (I->getOpcode() == FrameSetupOpcode);
SPAdj += TII.getSPAdjust(I);
MachineBasicBlock::iterator PrevI = BB->end();
if (I != BB->begin()) PrevI = std::prev(I);
TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
// Visit the instructions created by eliminateCallFramePseudoInstr().
if (PrevI == BB->end())
I = BB->begin(); // The replaced instr was the first in the block.
else
I = std::next(PrevI);
I = TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
continue;
}

View File

@ -153,7 +153,7 @@ AArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
return !MF.getFrameInfo()->hasVarSizedObjects();
}
void AArch64FrameLowering::eliminateCallFramePseudoInstr(
MachineBasicBlock::iterator AArch64FrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const AArch64InstrInfo *TII =
@ -196,7 +196,7 @@ void AArch64FrameLowering::eliminateCallFramePseudoInstr(
emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, -CalleePopAmount,
TII);
}
MBB.erase(I);
return MBB.erase(I);
}
void AArch64FrameLowering::emitCalleeSavedFrameMoves(

View File

@ -27,9 +27,9 @@ public:
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.

View File

@ -1726,10 +1726,9 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
}
}
void ARMFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineBasicBlock::iterator ARMFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const ARMBaseInstrInfo &TII =
*static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
@ -1769,7 +1768,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
}
MBB.erase(I);
return MBB.erase(I);
}
/// Get the minimum constant for ARM that is greater than or equal to the

View File

@ -74,7 +74,7 @@ public:
bool(*Func)(unsigned, bool),
unsigned NumAlignedDPRCS2Regs) const;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;

View File

@ -49,7 +49,7 @@ emitSPUpdate(MachineBasicBlock &MBB,
}
void Thumb1FrameLowering::
MachineBasicBlock::iterator Thumb1FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const Thumb1InstrInfo &TII =
@ -80,7 +80,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
}
MBB.erase(I);
return MBB.erase(I);
}
void Thumb1FrameLowering::emitPrologue(MachineFunction &MF,

View File

@ -41,7 +41,7 @@ public:
bool hasReservedCallFrame(const MachineFunction &MF) const override;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;

View File

@ -31,10 +31,10 @@ public:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS) const override;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override {
MBB.erase(MI);
return MBB.erase(MI);
}
};
}

View File

@ -1060,15 +1060,15 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
return true;
}
void HexagonFrameLowering::eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const {
MachineBasicBlock::iterator HexagonFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineInstr &MI = *I;
unsigned Opc = MI.getOpcode();
(void)Opc; // Silence compiler warning.
assert((Opc == Hexagon::ADJCALLSTACKDOWN || Opc == Hexagon::ADJCALLSTACKUP) &&
"Cannot handle this call frame pseudo instruction");
MBB.erase(I);
return MBB.erase(I);
}

View File

@ -42,8 +42,9 @@ public:
return true;
}
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,

View File

@ -139,11 +139,11 @@ void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
replaceAdjDynAllocPseudo(MF);
}
void LanaiFrameLowering::eliminateCallFramePseudoInstr(
MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
// Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
return MBB.erase(I);
}
// The function epilogue should not depend on the current stack pointer!

View File

@ -42,7 +42,7 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;

View File

@ -224,9 +224,9 @@ MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
void MSP430FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MSP430InstrInfo &TII =
*static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
unsigned StackAlign = getStackAlignment();
@ -283,7 +283,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
MBB.erase(I);
return MBB.erase(I);
}
void

View File

@ -30,9 +30,9 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,

View File

@ -143,7 +143,7 @@ uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
}
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
void MipsFrameLowering::
MachineBasicBlock::iterator MipsFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
unsigned SP = STI.getABI().IsN64() ? Mips::SP_64 : Mips::SP;
@ -156,5 +156,5 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
STI.getInstrInfo()->adjustStackPtr(SP, Amount, MBB, I);
}
MBB.erase(I);
return MBB.erase(I);
}

View File

@ -36,7 +36,7 @@ public:
bool isFPCloseToIncomingSP() const override { return false; }
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;

View File

@ -70,10 +70,10 @@ void NVPTXFrameLowering::emitEpilogue(MachineFunction &MF,
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void NVPTXFrameLowering::eliminateCallFramePseudoInstr(
MachineBasicBlock::iterator NVPTXFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
// Simply discard ADJCALLSTACKDOWN,
// ADJCALLSTACKUP instructions.
MBB.erase(I);
return MBB.erase(I);
}

View File

@ -26,7 +26,7 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
};

View File

@ -1770,7 +1770,7 @@ restoreCRs(bool isPPC64, bool is31,
.addReg(MoveReg, getKillRegState(true)));
}
void PPCFrameLowering::
MachineBasicBlock::iterator PPCFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
@ -1807,7 +1807,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
return MBB.erase(I);
}
bool

View File

@ -93,9 +93,9 @@ public:
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,

View File

@ -183,7 +183,7 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF,
}
}
void SparcFrameLowering::
MachineBasicBlock::iterator SparcFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (!hasReservedCallFrame(MF)) {
@ -195,7 +195,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
if (Size)
emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);
}
MBB.erase(I);
return MBB.erase(I);
}

View File

@ -29,7 +29,7 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;

View File

@ -511,7 +511,7 @@ SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
return true;
}
void SystemZFrameLowering::
MachineBasicBlock::iterator SystemZFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
@ -520,7 +520,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
case SystemZ::ADJCALLSTACKUP:
assert(hasReservedCallFrame(MF) &&
"ADJSTACKDOWN and ADJSTACKUP should be no-ops");
MBB.erase(MI);
return MBB.erase(MI);
break;
default:

View File

@ -46,10 +46,9 @@ public:
int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const
override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
// Return the number of bytes in the callee-allocated part of the frame.
uint64_t getAllocatedStackSize(const MachineFunction &MF) const;

View File

@ -100,7 +100,8 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
MF.getInfo<WebAssemblyFunctionInfo>()->stackifyVReg(SPAddr);
}
void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
MachineBasicBlock::iterator
WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
assert(!I->getOperand(0).getImm() && hasFP(MF) &&
@ -111,7 +112,7 @@ void WebAssemblyFrameLowering::eliminateCallFramePseudoInstr(
DebugLoc DL = I->getDebugLoc();
writeSPToMemory(WebAssembly::SP32, MF, MBB, I, I, DL);
}
MBB.erase(I);
return MBB.erase(I);
}
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,

View File

@ -34,7 +34,7 @@ class WebAssemblyFrameLowering final : public TargetFrameLowering {
/*TransientStackAlignment=*/16,
/*StackRealignable=*/true) {}
void eliminateCallFramePseudoInstr(
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;

View File

@ -877,16 +877,7 @@ void WasmPEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
I->getOpcode() == FrameDestroyOpcode) {
InsideCallSequence = (I->getOpcode() == FrameSetupOpcode);
SPAdj += TII.getSPAdjust(I);
MachineBasicBlock::iterator PrevI = BB->end();
if (I != BB->begin()) PrevI = std::prev(I);
TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
// Visit the instructions created by eliminateCallFramePseudoInstr().
if (PrevI == BB->end())
I = BB->begin(); // The replaced instr was the first in the block.
else
I = std::next(PrevI);
I = TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
continue;
}

View File

@ -2477,7 +2477,7 @@ bool X86FrameLowering::adjustStackWithPops(MachineBasicBlock &MBB,
return true;
}
void X86FrameLowering::
MachineBasicBlock::iterator X86FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
bool reserveCallFrame = hasReservedCallFrame(MF);
@ -2521,7 +2521,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MCCFIInstruction::createGnuArgsSize(nullptr, Amount));
if (Amount == 0)
return;
return I;
// Factor out the amount that gets handled inside the sequence
// (Pushes of argument for frame setup, callee pops for frame destroy)
@ -2561,7 +2561,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
return;
return I;
}
if (isDestroy && InternalAmt) {
@ -2571,11 +2571,14 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// We are not tracking the stack pointer adjustment by the callee, so make
// sure we restore the stack pointer immediately after the call, there may
// be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
MachineBasicBlock::iterator CI = I;
MachineBasicBlock::iterator B = MBB.begin();
while (I != B && !std::prev(I)->isCall())
while (CI != B && !std::prev(I)->isCall())
--I;
BuildStackAdjustment(MBB, I, DL, -InternalAmt, /*InEpilogue=*/false);
BuildStackAdjustment(MBB, CI, DL, -InternalAmt, /*InEpilogue=*/false);
}
return I;
}
bool X86FrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {

View File

@ -103,9 +103,9 @@ public:
int getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI,
unsigned &FrameReg) const override;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;

View File

@ -482,9 +482,9 @@ restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void XCoreFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineBasicBlock::iterator XCoreFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
if (!hasReservedCallFrame(MF)) {
// Turn the adjcallstackdown instruction into 'extsp <amt>' and the
@ -528,7 +528,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
}
MBB.erase(I);
return MBB.erase(I);
}
void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF,

View File

@ -41,8 +41,8 @@ namespace llvm {
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool hasFP(const MachineFunction &MF) const override;