Also attempt trivial coalescing for live intervals that end in a copy.

The coalescer is supposed to clean these up, but when setting up parameters
for a function call, there may be copies to physregs. If the defining
instruction has been LICM'ed far away, the coalescer won't touch it.

The register allocation hint does not always work - when the register
allocator is backtracking, it clears the hints.

This patch is more conservative than r90502, and does not break
483.xalancbmk/i686. It still breaks the PowerPC bootstrap, so it is disabled
by default, and can be enabled with the -trivial-coalesce-ends option.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91049 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2009-12-10 17:48:32 +00:00
parent f05e45eb37
commit cf97036675
3 changed files with 118 additions and 78 deletions
+57 -30
View File
@@ -149,42 +149,69 @@ void LiveIntervals::dumpInstrs() const {
printInstrs(errs());
}
/// conflictsWithPhysRegDef - Returns true if the specified register
/// is defined during the duration of the specified interval.
bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
VirtRegMap &vrm, unsigned reg) {
for (LiveInterval::Ranges::const_iterator
I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
for (SlotIndex index = I->start.getBaseIndex(),
end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
index != end;
index = index.getNextIndex()) {
MachineInstr *MI = getInstructionFromIndex(index);
if (!MI)
continue; // skip deleted instructions
bool LiveIntervals::conflictsWithPhysReg(const LiveInterval &li,
VirtRegMap &vrm, unsigned reg) {
// We don't handle fancy stuff crossing basic block boundaries
if (li.ranges.size() != 1)
return true;
const LiveRange &range = li.ranges.front();
SlotIndex idx = range.start.getBaseIndex();
SlotIndex end = range.end.getPrevSlot().getBaseIndex().getNextIndex();
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
if (SrcReg == li.reg || DstReg == li.reg)
// Skip deleted instructions
MachineInstr *firstMI = getInstructionFromIndex(idx);
while (!firstMI && idx != end) {
idx = idx.getNextIndex();
firstMI = getInstructionFromIndex(idx);
}
if (!firstMI)
return false;
// Find last instruction in range
SlotIndex lastIdx = end.getPrevIndex();
MachineInstr *lastMI = getInstructionFromIndex(lastIdx);
while (!lastMI && lastIdx != idx) {
lastIdx = lastIdx.getPrevIndex();
lastMI = getInstructionFromIndex(lastIdx);
}
if (!lastMI)
return false;
// Range cannot cross basic block boundaries or terminators
MachineBasicBlock *MBB = firstMI->getParent();
if (MBB != lastMI->getParent() || lastMI->getDesc().isTerminator())
return true;
MachineBasicBlock::const_iterator E = lastMI;
++E;
for (MachineBasicBlock::const_iterator I = firstMI; I != E; ++I) {
const MachineInstr &MI = *I;
// Allow copies to and from li.reg
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
if (SrcReg == li.reg || DstReg == li.reg)
continue;
// Check for operands using reg
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand& mop = MI.getOperand(i);
if (!mop.isReg())
continue;
unsigned PhysReg = mop.getReg();
if (PhysReg == 0 || PhysReg == li.reg)
continue;
if (TargetRegisterInfo::isVirtualRegister(PhysReg)) {
if (!vrm.hasPhys(PhysReg))
continue;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
if (!mop.isReg())
continue;
unsigned PhysReg = mop.getReg();
if (PhysReg == 0 || PhysReg == li.reg)
continue;
if (TargetRegisterInfo::isVirtualRegister(PhysReg)) {
if (!vrm.hasPhys(PhysReg))
continue;
PhysReg = vrm.getPhys(PhysReg);
}
if (PhysReg && tri_->regsOverlap(PhysReg, reg))
return true;
PhysReg = vrm.getPhys(PhysReg);
}
if (PhysReg && tri_->regsOverlap(PhysReg, reg))
return true;
}
}
// No conflicts found.
return false;
}