summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-23 20:21:06 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-23 20:21:06 +0000
commit5b8f476037f38b91263f693b83bfce740622f0d2 (patch)
treee57fb6730b55a1d9c20216f72e8e47bcd36b2ff2 /llvm/lib/CodeGen
parent4ab452d061a185a527a7cc09d2dc47ec77d9bcd8 (diff)
downloadbcm5719-llvm-5b8f476037f38b91263f693b83bfce740622f0d2.tar.gz
bcm5719-llvm-5b8f476037f38b91263f693b83bfce740622f0d2.zip
Correctly deal with identity copies in RegisterCoalescer.
Now that the coalescer keeps live intervals and machine code in sync at all times, it needs to deal with identity copies differently. When merging two virtual registers, all identity copies are removed right away. This means that other identity copies must come from somewhere else, and they are going to have a value number. Deal with such copies by merging the value numbers before erasing the copy instruction. Otherwise, we leave dangling value numbers in the live interval. This fixes PR12927. llvm-svn: 157340
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 30997c24bab..db117ed1a09 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -988,20 +988,31 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
return true;
}
- // If they are already joined we continue.
- if (CP.getSrcReg() == CP.getDstReg()) {
- DEBUG(dbgs() << "\tCopy already coalesced.\n");
+ // Eliminate undefs.
+ if (!CP.isPhys() && eliminateUndefCopy(CopyMI, CP)) {
+ DEBUG(dbgs() << "\tEliminated copy of <undef> value.\n");
LIS->RemoveMachineInstrFromMaps(CopyMI);
CopyMI->eraseFromParent();
return false; // Not coalescable.
}
- // Eliminate undefs.
- if (!CP.isPhys() && eliminateUndefCopy(CopyMI, CP)) {
- DEBUG(dbgs() << "\tEliminated copy of <undef> value.\n");
+ // Coalesced copies are normally removed immediately, but transformations
+ // like removeCopyByCommutingDef() can inadvertently create identity copies.
+ // When that happens, just join the values and remove the copy.
+ if (CP.getSrcReg() == CP.getDstReg()) {
+ LiveInterval &LI = LIS->getInterval(CP.getSrcReg());
+ DEBUG(dbgs() << "\tCopy already coalesced: " << LI << '\n');
+ LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(CopyMI));
+ if (VNInfo *DefVNI = LRQ.valueDefined()) {
+ VNInfo *ReadVNI = LRQ.valueIn();
+ assert(ReadVNI && "No value before copy and no <undef> flag.");
+ assert(ReadVNI != DefVNI && "Cannot read and define the same value.");
+ LI.MergeValueNumberInto(DefVNI, ReadVNI);
+ DEBUG(dbgs() << "\tMerged values: " << LI << '\n');
+ }
LIS->RemoveMachineInstrFromMaps(CopyMI);
CopyMI->eraseFromParent();
- return false; // Not coalescable.
+ return true;
}
// Enforce policies.
OpenPOWER on IntegriCloud