[RegisterCoalescer] Remove copies to reserved registers

This allows the RegisterCoalescer to join "non-flipped" range pairs with a
physical destination register -- which allows the RegisterCoalescer to remove
copies like this:

<vreg> = something (maybe a load, for example)
... (things that don't use PHYSREG)
PHYSREG = COPY <vreg>

(with all of the restrictions normally applied by the RegisterCoalescer: having
compatible register classes, etc. )

Previously, the RegisterCoalescer handled only the opposite case (copying
*from* a physical register). I don't handle the problem fully here, but try to
get the common case where there is only one use of <vreg> (the COPY).

An upcoming commit to the PowerPC backend will make this pattern much more
common on PPC64/ELF systems.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226071 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel
2015-01-15 01:25:28 +00:00
parent 4572a0a0a2
commit 47ab8c106f
3 changed files with 39 additions and 7 deletions

View File

@@ -1209,10 +1209,10 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) {
}
LiveInterval &JoinVInt = LIS->getInterval(CP.getSrcReg());
if (CP.isFlipped() && JoinVInt.containsOneValue())
if (JoinVInt.containsOneValue())
return true;
DEBUG(dbgs() << "\tCannot join defs into reserved register.\n");
DEBUG(dbgs() << "\tCannot join complex intervals into reserved register.\n");
return false;
}
@@ -1431,8 +1431,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
DEBUG(dbgs() << "\t\tRHS = " << RHS << '\n');
assert(CP.isFlipped() && RHS.containsOneValue() &&
"Invalid join with reserved register");
assert(RHS.containsOneValue() && "Invalid join with reserved register");
// Optimization for reserved registers like ESP. We can only merge with a
// reserved physreg if RHS has a single value that is a copy of CP.DstReg().
@@ -1453,7 +1452,18 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// defs are there.
// Delete the identity copy.
MachineInstr *CopyMI = MRI->getVRegDef(RHS.reg);
MachineInstr *CopyMI;
if (CP.isFlipped()) {
CopyMI = MRI->getVRegDef(RHS.reg);
} else {
if (!MRI->hasOneNonDBGUse(RHS.reg)) {
DEBUG(dbgs() << "\t\tMultiple vreg uses\n");
return false;
}
CopyMI = &*MRI->use_instr_nodbg_begin(RHS.reg);
}
LIS->RemoveMachineInstrFromMaps(CopyMI);
CopyMI->eraseFromParent();