The coalescer does not coalesce a virtual register to a physical register if any of the physical register's sub-register live intervals overlaps with the virtual register. This is overly conservative. It prevents a extract_subreg from being coalesced away:

v1024 = EDI  // not killed
      =
      = EDI

One possible solution is for the coalescer to examine the sub-register live intervals in the same manner as the physical register. Another possibility is to examine defs and uses (when needed) of sub-registers. Both solutions are too expensive. For now, look for "short virtual intervals" and scan instructions to look for conflict instead.

This is a small win on x86-64. e.g. It shaves 403.gcc by ~80 instructions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61847 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2009-01-07 02:08:57 +00:00
parent d37eaa3b97
commit 8f90b6eb2f
4 changed files with 115 additions and 20 deletions

View File

@@ -323,6 +323,47 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
return false;
}
/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
/// it can check use as well.
bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
unsigned Reg, bool CheckUse,
SmallPtrSet<MachineInstr*,32> &JoinedCopies) {
for (LiveInterval::Ranges::const_iterator
I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
for (unsigned index = getBaseIndex(I->start),
end = getBaseIndex(I->end-1) + InstrSlots::NUM; index != end;
index += InstrSlots::NUM) {
// Skip deleted instructions.
MachineInstr *MI = 0;
while (index != end) {
MI = getInstructionFromIndex(index);
if (MI)
break;
index += InstrSlots::NUM;
}
if (index == end) break;
if (JoinedCopies.count(MI))
continue;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand& MO = MI->getOperand(i);
if (!MO.isReg())
continue;
if (MO.isUse() && !CheckUse)
continue;
unsigned PhysReg = MO.getReg();
if (PhysReg == 0 || TargetRegisterInfo::isVirtualRegister(PhysReg))
continue;
if (tri_->isSubRegister(Reg, PhysReg))
return true;
}
}
}
return false;
}
void LiveIntervals::printRegName(unsigned reg) const {
if (TargetRegisterInfo::isPhysicalRegister(reg))
cerr << tri_->getName(reg);
@@ -794,10 +835,15 @@ unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
if (!VNI->copy)
return 0;
if (VNI->copy->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)
return VNI->copy->getOperand(1).getReg();
if (VNI->copy->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
if (VNI->copy->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
// If it's extracting out of a physical register, return the sub-register.
unsigned Reg = VNI->copy->getOperand(1).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
Reg = tri_->getSubReg(Reg, VNI->copy->getOperand(2).getImm());
return Reg;
} else if (VNI->copy->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
return VNI->copy->getOperand(2).getReg();
unsigned SrcReg, DstReg;
if (tii_->isMoveInstr(*VNI->copy, SrcReg, DstReg))
return SrcReg;