Bundle jump/branch instructions with the instructions in the delay slot in

delay slot filler pass of MIPS, per suggestion of Jakob Stoklund Olesen.

This change, along with the fix in r158154, enables machine verification
to be run after delay slot filling.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158426 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2012-06-13 23:25:52 +00:00
parent 14d81c416c
commit 158413930f
2 changed files with 30 additions and 19 deletions

View File

@ -58,9 +58,14 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return; return;
} }
MachineBasicBlock::const_instr_iterator I = MI;
MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
do {
MCInst TmpInst0; MCInst TmpInst0;
MCInstLowering.Lower(MI, TmpInst0); MCInstLowering.Lower(I++, TmpInst0);
OutStreamer.EmitInstruction(TmpInst0); OutStreamer.EmitInstruction(TmpInst0);
} while ((I != E) && I->isInsideBundle());
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -45,10 +45,12 @@ static cl::opt<bool> SkipDelaySlotFiller(
namespace { namespace {
struct Filler : public MachineFunctionPass { struct Filler : public MachineFunctionPass {
typedef MachineBasicBlock::instr_iterator InstrIter;
typedef MachineBasicBlock::reverse_instr_iterator ReverseInstrIter;
TargetMachine &TM; TargetMachine &TM;
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
MachineBasicBlock::iterator LastFiller; InstrIter LastFiller;
static char ID; static char ID;
Filler(TargetMachine &tm) Filler(TargetMachine &tm)
@ -71,27 +73,27 @@ namespace {
} }
bool isDelayFiller(MachineBasicBlock &MBB, bool isDelayFiller(MachineBasicBlock &MBB,
MachineBasicBlock::iterator candidate); InstrIter candidate);
void insertCallUses(MachineBasicBlock::iterator MI, void insertCallUses(InstrIter MI,
SmallSet<unsigned, 32>& RegDefs, SmallSet<unsigned, 32>& RegDefs,
SmallSet<unsigned, 32>& RegUses); SmallSet<unsigned, 32>& RegUses);
void insertDefsUses(MachineBasicBlock::iterator MI, void insertDefsUses(InstrIter MI,
SmallSet<unsigned, 32>& RegDefs, SmallSet<unsigned, 32>& RegDefs,
SmallSet<unsigned, 32>& RegUses); SmallSet<unsigned, 32>& RegUses);
bool IsRegInSet(SmallSet<unsigned, 32>& RegSet, bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
unsigned Reg); unsigned Reg);
bool delayHasHazard(MachineBasicBlock::iterator candidate, bool delayHasHazard(InstrIter candidate,
bool &sawLoad, bool &sawStore, bool &sawLoad, bool &sawStore,
SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegDefs,
SmallSet<unsigned, 32> &RegUses); SmallSet<unsigned, 32> &RegUses);
bool bool
findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot, findDelayInstr(MachineBasicBlock &MBB, InstrIter slot,
MachineBasicBlock::iterator &Filler); InstrIter &Filler);
}; };
@ -103,14 +105,14 @@ namespace {
bool Filler:: bool Filler::
runOnMachineBasicBlock(MachineBasicBlock &MBB) { runOnMachineBasicBlock(MachineBasicBlock &MBB) {
bool Changed = false; bool Changed = false;
LastFiller = MBB.end(); LastFiller = MBB.instr_end();
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) for (InstrIter I = MBB.instr_begin(); I != MBB.instr_end(); ++I)
if (I->hasDelaySlot()) { if (I->hasDelaySlot()) {
++FilledSlots; ++FilledSlots;
Changed = true; Changed = true;
MachineBasicBlock::iterator D; InstrIter D;
if (EnableDelaySlotFiller && findDelayInstr(MBB, I, D)) { if (EnableDelaySlotFiller && findDelayInstr(MBB, I, D)) {
MBB.splice(llvm::next(I), &MBB, D); MBB.splice(llvm::next(I), &MBB, D);
@ -121,6 +123,10 @@ runOnMachineBasicBlock(MachineBasicBlock &MBB) {
// Record the filler instruction that filled the delay slot. // Record the filler instruction that filled the delay slot.
// The instruction after it will be visited in the next iteration. // The instruction after it will be visited in the next iteration.
LastFiller = ++I; LastFiller = ++I;
// Set InsideBundle bit so that the machine verifier doesn't expect this
// instruction to be a terminator.
LastFiller->setIsInsideBundle();
} }
return Changed; return Changed;
@ -133,8 +139,8 @@ FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
} }
bool Filler::findDelayInstr(MachineBasicBlock &MBB, bool Filler::findDelayInstr(MachineBasicBlock &MBB,
MachineBasicBlock::iterator slot, InstrIter slot,
MachineBasicBlock::iterator &Filler) { InstrIter &Filler) {
SmallSet<unsigned, 32> RegDefs; SmallSet<unsigned, 32> RegDefs;
SmallSet<unsigned, 32> RegUses; SmallSet<unsigned, 32> RegUses;
@ -143,13 +149,13 @@ bool Filler::findDelayInstr(MachineBasicBlock &MBB,
bool sawLoad = false; bool sawLoad = false;
bool sawStore = false; bool sawStore = false;
for (MachineBasicBlock::reverse_iterator I(slot); I != MBB.rend(); ++I) { for (ReverseInstrIter I(slot); I != MBB.instr_rend(); ++I) {
// skip debug value // skip debug value
if (I->isDebugValue()) if (I->isDebugValue())
continue; continue;
// Convert to forward iterator. // Convert to forward iterator.
MachineBasicBlock::iterator FI(llvm::next(I).base()); InstrIter FI(llvm::next(I).base());
if (I->hasUnmodeledSideEffects() if (I->hasUnmodeledSideEffects()
|| I->isInlineAsm() || I->isInlineAsm()
@ -175,7 +181,7 @@ bool Filler::findDelayInstr(MachineBasicBlock &MBB,
return false; return false;
} }
bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate, bool Filler::delayHasHazard(InstrIter candidate,
bool &sawLoad, bool &sawStore, bool &sawLoad, bool &sawStore,
SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegDefs,
SmallSet<unsigned, 32> &RegUses) { SmallSet<unsigned, 32> &RegUses) {
@ -223,7 +229,7 @@ bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
} }
// Insert Defs and Uses of MI into the sets RegDefs and RegUses. // Insert Defs and Uses of MI into the sets RegDefs and RegUses.
void Filler::insertDefsUses(MachineBasicBlock::iterator MI, void Filler::insertDefsUses(InstrIter MI,
SmallSet<unsigned, 32>& RegDefs, SmallSet<unsigned, 32>& RegDefs,
SmallSet<unsigned, 32>& RegUses) { SmallSet<unsigned, 32>& RegUses) {
// If MI is a call or return, just examine the explicit non-variadic operands. // If MI is a call or return, just examine the explicit non-variadic operands.