forked from OSchip/llvm-project
Major bug fix: spill code for an instruction in a delay slot was
merrily being inserted before/after the instruction! llvm-svn: 4116
This commit is contained in:
parent
ffc9dd5c0d
commit
3e54d6c3be
|
@ -418,6 +418,32 @@ void PhyRegAlloc::addInterferencesForArgs() {
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
// Utility functions used below
|
// Utility functions used below
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
|
inline void
|
||||||
|
InsertBefore(MachineInstr* newMI,
|
||||||
|
MachineCodeForBasicBlock& MIVec,
|
||||||
|
MachineCodeForBasicBlock::iterator& MII)
|
||||||
|
{
|
||||||
|
MII = MIVec.insert(MII, newMI);
|
||||||
|
++MII;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
InsertAfter(MachineInstr* newMI,
|
||||||
|
MachineCodeForBasicBlock& MIVec,
|
||||||
|
MachineCodeForBasicBlock::iterator& MII)
|
||||||
|
{
|
||||||
|
++MII; // insert before the next instruction
|
||||||
|
MII = MIVec.insert(MII, newMI);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
SubstituteInPlace(MachineInstr* newMI,
|
||||||
|
MachineCodeForBasicBlock& MIVec,
|
||||||
|
MachineCodeForBasicBlock::iterator MII)
|
||||||
|
{
|
||||||
|
*MII = newMI;
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
PrependInstructions(vector<MachineInstr *> &IBef,
|
PrependInstructions(vector<MachineInstr *> &IBef,
|
||||||
MachineCodeForBasicBlock& MIVec,
|
MachineCodeForBasicBlock& MIVec,
|
||||||
|
@ -434,8 +460,7 @@ PrependInstructions(vector<MachineInstr *> &IBef,
|
||||||
if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
|
if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
|
||||||
cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n";
|
cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n";
|
||||||
}
|
}
|
||||||
MII = MIVec.insert(MII, *AdIt);
|
InsertBefore(*AdIt, MIVec, MII);
|
||||||
++MII;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,8 +481,7 @@ AppendInstructions(std::vector<MachineInstr *> &IAft,
|
||||||
if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
|
if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
|
||||||
cerr << msg << "APPENDed instr:\n " << **AdIt << "\n";
|
cerr << msg << "APPENDed instr:\n " << **AdIt << "\n";
|
||||||
}
|
}
|
||||||
++MII; // insert before the next instruction
|
InsertAfter(*AdIt, MIVec, MII);
|
||||||
MII = MIVec.insert(MII, *AdIt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,12 +563,37 @@ void PhyRegAlloc::updateMachineCode()
|
||||||
}
|
}
|
||||||
} // for each operand
|
} // for each operand
|
||||||
|
|
||||||
|
|
||||||
// Now add instructions that the register allocator inserts before/after
|
// Now add instructions that the register allocator inserts before/after
|
||||||
// this machine instructions (done only for calls/rets/incoming args)
|
// this machine instructions (done only for calls/rets/incoming args)
|
||||||
// We do this here, to ensure that spill for an instruction is inserted
|
// We do this here, to ensure that spill for an instruction is inserted
|
||||||
// closest as possible to an instruction (see above insertCode4Spill...)
|
// closest as possible to an instruction (see above insertCode4Spill...)
|
||||||
//
|
//
|
||||||
|
// First, if the instruction in the delay slot of a branch needs
|
||||||
|
// instructions inserted, move it out of the delay slot and before the
|
||||||
|
// branch because putting code before or after it would be VERY BAD!
|
||||||
|
//
|
||||||
|
unsigned bumpIteratorBy = 0;
|
||||||
|
if (MII != MIVec.begin())
|
||||||
|
if (unsigned predDelaySlots =
|
||||||
|
TM.getInstrInfo().getNumDelaySlots((*(MII-1))->getOpCode()))
|
||||||
|
{
|
||||||
|
assert(predDelaySlots==1 && "Not handling multiple delay slots!");
|
||||||
|
if (TM.getInstrInfo().isBranch((*(MII-1))->getOpCode())
|
||||||
|
&& (AddedInstrMap.count(MInst) ||
|
||||||
|
AddedInstrMap[MInst].InstrnsAfter.size() > 0))
|
||||||
|
{
|
||||||
|
// Current instruction is in the delay slot of a branch and it
|
||||||
|
// needs spill code inserted before or after it.
|
||||||
|
// Move it before the preceding branch.
|
||||||
|
InsertBefore(MInst, MIVec, --MII);
|
||||||
|
MachineInstr* nopI =
|
||||||
|
new MachineInstr(TM.getInstrInfo().getNOPOpCode());
|
||||||
|
SubstituteInPlace(nopI, MIVec, MII+1); // replace orig with NOP
|
||||||
|
--MII; // point to MInst in new location
|
||||||
|
bumpIteratorBy = 2; // later skip the branch and the NOP!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there are instructions to be added, *before* this machine
|
// If there are instructions to be added, *before* this machine
|
||||||
// instruction, add them now.
|
// instruction, add them now.
|
||||||
//
|
//
|
||||||
|
@ -561,9 +610,18 @@ void PhyRegAlloc::updateMachineCode()
|
||||||
// added after it must really go after the delayed instruction(s)
|
// added after it must really go after the delayed instruction(s)
|
||||||
// So, we move the InstrAfter of the current instruction to the
|
// So, we move the InstrAfter of the current instruction to the
|
||||||
// corresponding delayed instruction
|
// corresponding delayed instruction
|
||||||
|
if (unsigned delay =
|
||||||
|
TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) {
|
||||||
|
|
||||||
|
// Delayed instructions are typically branches or calls. Let's make
|
||||||
|
// sure this is not a branch, otherwise "insert-after" is meaningless,
|
||||||
|
// and should never happen for any reason (spill code, register
|
||||||
|
// restores, etc.).
|
||||||
|
assert(! TM.getInstrInfo().isBranch(MInst->getOpCode()) &&
|
||||||
|
! TM.getInstrInfo().isReturn(MInst->getOpCode()) &&
|
||||||
|
"INTERNAL ERROR: Register allocator should not be inserting "
|
||||||
|
"any code after a branch or return!");
|
||||||
|
|
||||||
unsigned delay;
|
|
||||||
if ((delay=TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) >0){
|
|
||||||
move2DelayedInstr(MInst, *(MII+delay) );
|
move2DelayedInstr(MInst, *(MII+delay) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -573,6 +631,10 @@ void PhyRegAlloc::updateMachineCode()
|
||||||
} // if not delay
|
} // if not delay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we mucked with the instruction order above, adjust the loop iterator
|
||||||
|
if (bumpIteratorBy)
|
||||||
|
MII = MII + bumpIteratorBy;
|
||||||
|
|
||||||
} // for each machine instruction
|
} // for each machine instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue