summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2015-01-15 01:25:28 +0000
committerHal Finkel <hfinkel@anl.gov>2015-01-15 01:25:28 +0000
commit8299646236a11df360b3d6c7e9c53babbb785e02 (patch)
tree88fe2dfb0a07bbf1740bd0dabbc29adaf5f26dca /llvm/lib/CodeGen
parent64202167c59c95ebec033f7ed6e3ef0e8f420c91 (diff)
downloadbcm5719-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.cpp20
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();
OpenPOWER on IntegriCloud