diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2015-01-15 01:25:28 +0000 |
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2015-01-15 01:25:28 +0000 |
| commit | 8299646236a11df360b3d6c7e9c53babbb785e02 (patch) | |
| tree | 88fe2dfb0a07bbf1740bd0dabbc29adaf5f26dca /llvm/lib/CodeGen | |
| parent | 64202167c59c95ebec033f7ed6e3ef0e8f420c91 (diff) | |
| download | bcm5719-llvm-8299646236a11df360b3d6c7e9c53babbb785e02.tar.gz bcm5719-llvm-8299646236a11df360b3d6c7e9c53babbb785e02.zip | |
[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.
llvm-svn: 226071
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index b8cae4a59ed..517bc2dbe12 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -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(); |

