mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-30 15:22:41 +00:00
RAFast: Generalize the logic for return operands.
This removes implicit assumption about the form of MI coming into regalloc. In particular, it should be independent of ProcessImplicitDefs which will eventually become a standard part of coming out of SSA--unless we simply can eliminate IMPLICIT_DEF completely. Current unit tests expose this once I remove incidental pass ordering restrictions. This is not a final fix. Just a temporary workaround until I figure out the right way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149360 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7f2c6dc8a0
commit
b3d58474c8
@ -167,6 +167,7 @@ namespace {
|
||||
unsigned VirtReg, unsigned Hint);
|
||||
void spillAll(MachineInstr *MI);
|
||||
bool setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg);
|
||||
void addRetOperands(MachineBasicBlock *MBB);
|
||||
};
|
||||
char RAFast::ID = 0;
|
||||
}
|
||||
@ -739,30 +740,65 @@ void RAFast::handleThroughOperands(MachineInstr *MI,
|
||||
UsedInInstr.set(PartialDefs[i]);
|
||||
}
|
||||
|
||||
/// addRetOperand - ensure that a return instruction has an operand for each
|
||||
/// value live out of the function.
|
||||
///
|
||||
/// Things marked both call and return are tail calls; do not do this for them.
|
||||
/// The tail callee need not take the same registers as input that it produces
|
||||
/// as output, and there are dependencies for its input registers elsewhere.
|
||||
///
|
||||
/// FIXME: This should be done as part of instruction selection, and this helper
|
||||
/// should be deleted. Until then, we use custom logic here to create the proper
|
||||
/// operand under all circumstances. We can't use addRegisterKilled because that
|
||||
/// doesn't make sense for undefined values. We can't simply avoid calling it
|
||||
/// for undefined values, because we must ensure that the operand always exists.
|
||||
void RAFast::addRetOperands(MachineBasicBlock *MBB) {
|
||||
if (MBB->empty() || !MBB->back().isReturn() || MBB->back().isCall())
|
||||
return;
|
||||
|
||||
MachineInstr *MI = &MBB->back();
|
||||
|
||||
for (MachineRegisterInfo::liveout_iterator
|
||||
I = MBB->getParent()->getRegInfo().liveout_begin(),
|
||||
E = MBB->getParent()->getRegInfo().liveout_end(); I != E; ++I) {
|
||||
unsigned Reg = *I;
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
|
||||
"Cannot have a live-out virtual register.");
|
||||
|
||||
bool hasDef = PhysRegState[Reg] == regReserved;
|
||||
|
||||
// Check if this register already has an operand.
|
||||
bool Found = false;
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
if (!MO.isReg() || !MO.isUse())
|
||||
continue;
|
||||
|
||||
unsigned OperReg = MO.getReg();
|
||||
for (const unsigned *AS = TRI->getOverlaps(Reg); *AS; ++AS) {
|
||||
if (OperReg != *AS)
|
||||
continue;
|
||||
if (OperReg == Reg || TRI->isSuperRegister(OperReg, Reg)) {
|
||||
// If the ret already has an operand for this physreg or a superset,
|
||||
// don't duplicate it. Set the kill flag if the value is defined.
|
||||
if (hasDef && !MO.isKill())
|
||||
MO.setIsKill();
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Found)
|
||||
MI->addOperand(MachineOperand::CreateReg(Reg,
|
||||
false /*IsDef*/,
|
||||
true /*IsImp*/,
|
||||
hasDef/*IsKill*/));
|
||||
}
|
||||
}
|
||||
|
||||
void RAFast::AllocateBasicBlock() {
|
||||
DEBUG(dbgs() << "\nAllocating " << *MBB);
|
||||
|
||||
// FIXME: This should probably be added by instruction selection instead?
|
||||
// If the last instruction in the block is a return, make sure to mark it as
|
||||
// using all of the live-out values in the function. Things marked both call
|
||||
// and return are tail calls; do not do this for them. The tail callee need
|
||||
// not take the same registers as input that it produces as output, and there
|
||||
// are dependencies for its input registers elsewhere.
|
||||
if (!MBB->empty() && MBB->back().isReturn() &&
|
||||
!MBB->back().isCall()) {
|
||||
MachineInstr *Ret = &MBB->back();
|
||||
|
||||
for (MachineRegisterInfo::liveout_iterator
|
||||
I = MF->getRegInfo().liveout_begin(),
|
||||
E = MF->getRegInfo().liveout_end(); I != E; ++I) {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(*I) &&
|
||||
"Cannot have a live-out virtual register.");
|
||||
|
||||
// Add live-out registers as implicit uses.
|
||||
Ret->addRegisterKilled(*I, TRI, true);
|
||||
}
|
||||
}
|
||||
|
||||
PhysRegState.assign(TRI->getNumRegs(), regDisabled);
|
||||
assert(LiveVirtRegs.empty() && "Mapping not cleared form last block?");
|
||||
|
||||
@ -1033,6 +1069,9 @@ void RAFast::AllocateBasicBlock() {
|
||||
MBB->erase(Coalesced[i]);
|
||||
NumCopies += Coalesced.size();
|
||||
|
||||
// addRetOperands must run after we've seen all defs in this block.
|
||||
addRetOperands(MBB);
|
||||
|
||||
DEBUG(MBB->dump());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user