STATISTIC(FilledSlots, "Number of delay slots filled");
STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
- "are not NOP.");
+ " are not NOP.");
static cl::opt<bool> EnableDelaySlotFiller(
"enable-mips-delay-filler",
LastFiller = MBB.end();
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
- if (I->getDesc().hasDelaySlot()) {
+ if (I->hasDelaySlot()) {
++FilledSlots;
Changed = true;
if (EnableDelaySlotFiller && findDelayInstr(MBB, I, D)) {
MBB.splice(llvm::next(I), &MBB, D);
++UsefulSlots;
- }
- else
+ } else
BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
// Record the filler instruction that filled the delay slot.
continue;
// Convert to forward iterator.
- MachineBasicBlock::iterator FI(next(I).base());
+ MachineBasicBlock::iterator FI(llvm::next(I).base());
if (I->hasUnmodeledSideEffects()
|| I->isInlineAsm()
|| I->isLabel()
|| FI == LastFiller
- || I->getDesc().isPseudo()
+ || I->isPseudo()
//
// Should not allow:
// ERET, DERET or WAIT, PAUSE. Need to add these to instruction
}
bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
- bool &sawLoad,
- bool &sawStore,
+ bool &sawLoad, bool &sawStore,
SmallSet<unsigned, 32> &RegDefs,
SmallSet<unsigned, 32> &RegUses) {
if (candidate->isImplicitDef() || candidate->isKill())
// Loads or stores cannot be moved past a store to the delay slot
// and stores cannot be moved past a load.
- if (candidate->getDesc().mayLoad()) {
+ if (candidate->mayLoad()) {
if (sawStore)
return true;
sawLoad = true;
}
- if (candidate->getDesc().mayStore()) {
+ if (candidate->mayStore()) {
if (sawStore)
return true;
sawStore = true;
return true;
}
- assert(!candidate->getDesc().isCall() && "Cannot put calls in delay slot.");
+ assert((!candidate->isCall() && !candidate->isReturn()) &&
+ "Cannot put calls or returns in delay slot.");
for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
const MachineOperand &MO = candidate->getOperand(i);
SmallSet<unsigned, 32>& RegDefs,
SmallSet<unsigned, 32>& RegUses) {
// If MI is a call or return, just examine the explicit non-variadic operands.
- // NOTE: $ra is not added to RegDefs, since currently $ra is reserved and
- // no instruction that can possibly be put in a delay slot can read or
- // write it.
-
- unsigned e = MI->getDesc().isCall() ? MI->getDesc().getNumOperands() :
- MI->getNumOperands();
+ MCInstrDesc MCID = MI->getDesc();
+ unsigned e = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() :
+ MI->getNumOperands();
+
+ // Add RA to RegDefs to prevent users of RA from going into delay slot.
+ if (MI->isCall())
+ RegDefs.insert(Mips::RA);
for (unsigned i = 0; i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);