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 takes care of a few more cases that r90163 missed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90502 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2009-12-04 00:16:04 +00:00
parent 2e65c29ac6
commit 6b74e505be
5 changed files with 103 additions and 53 deletions

View File

@ -157,19 +157,15 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
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()) {
index != end;
index = index.getNextIndex()) {
MachineInstr *MI = getInstructionFromIndex(index);
if (!MI)
continue; // skip deleted instructions
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
if (SrcReg == li.reg || DstReg == li.reg)
continue;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
if (!mop.isReg())
if (!mop.isReg() || mop.isUse())
continue;
unsigned PhysReg = mop.getReg();
if (PhysReg == 0 || PhysReg == li.reg)
@ -188,6 +184,50 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
return false;
}
/// conflictsWithPhysRegUse - Returns true if the specified register is used or
/// defined during the duration of the specified interval. Copies to and from
/// li.reg are allowed.
bool LiveIntervals::conflictsWithPhysRegUse(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
// Terminators are considered conflicts since reg may be used at the
// destination.
if (MI->getDesc().isTerminator())
return true;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand& mop = MI->getOperand(i);
if (!mop.isReg() || mop.isUndef())
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)) {
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) ||
(SrcReg != li.reg && DstReg != li.reg))
return true;
}
}
}
}
return false;
}
/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
/// it can check use as well.
bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,