summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterCoalescer.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-19 23:34:59 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-19 23:34:59 +0000
commit7ebed91fddbcd259d03c4b438719ac1ce2a4fc87 (patch)
treead2dfa847de2a06219ea704c33e2ae5c49b11cac /lib/CodeGen/RegisterCoalescer.cpp
parent9012c57e18d76d562b1f3e60bf19cccefa7b793e (diff)
downloadllvm-7ebed91fddbcd259d03c4b438719ac1ce2a4fc87.tar.gz
llvm-7ebed91fddbcd259d03c4b438719ac1ce2a4fc87.tar.bz2
llvm-7ebed91fddbcd259d03c4b438719ac1ce2a4fc87.tar.xz
Fix 12892.
Dead code elimination during coalescing could cause a virtual register to be split into connected components. The following rewriting would be confused about the already joined copies present in the code, but without a corresponding value number in the live range. Erase all joined copies instantly when joining intervals such that the MI and LiveInterval representations are always in sync. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157135 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterCoalescer.cpp')
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index 74d04541e0..ca5d280739 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -1081,9 +1081,10 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (!CP.isPhys() && RegClassInfo.isProperSubClass(CP.getNewRC()))
InflateRegs.push_back(CP.getDstReg());
- // Remember to delete the copy instruction.
- LIS->RemoveMachineInstrFromMaps(CopyMI);
- CopyMI->eraseFromParent();
+ // CopyMI has been erased by joinIntervals at this point. Remove it from
+ // ErasedInstrs since copyCoalesceWorkList() won't add a successful join back
+ // to the work list. This keeps ErasedInstrs from growing needlessly.
+ ErasedInstrs.erase(CopyMI);
// Rewrite all SrcReg operands to DstReg.
// Also update DstReg operands to include DstIdx if it is set.
@@ -1285,6 +1286,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
SmallVector<VNInfo*, 16> NewVNInfo;
SmallVector<MachineInstr*, 8> DupCopies;
+ SmallVector<MachineInstr*, 8> DeadCopies;
LiveInterval &LHS = LIS->getOrCreateInterval(CP.getDstReg());
DEBUG({ dbgs() << "\t\tLHS = "; LHS.print(dbgs(), TRI); dbgs() << "\n"; });
@@ -1313,6 +1315,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
continue;
LHSValsDefinedFromRHS[VNI] = lr->valno;
+ DeadCopies.push_back(MI);
}
// Loop over the value numbers of the RHS, seeing if any are defined from
@@ -1339,6 +1342,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
continue;
RHSValsDefinedFromLHS[VNI] = lr->valno;
+ DeadCopies.push_back(MI);
}
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
@@ -1438,6 +1442,17 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
if (RHSValNoAssignments.empty())
RHSValNoAssignments.push_back(-1);
+ // Now erase all the redundant copies.
+ for (unsigned i = 0, e = DeadCopies.size(); i != e; ++i) {
+ MachineInstr *MI = DeadCopies[i];
+ DEBUG(dbgs() << "\t\terased:\t" << LIS->getInstructionIndex(MI)
+ << '\t' << *MI);
+ if (!ErasedInstrs.insert(MI))
+ continue;
+ LIS->RemoveMachineInstrFromMaps(MI);
+ MI->eraseFromParent();
+ }
+
SmallVector<unsigned, 8> SourceRegisters;
for (SmallVector<MachineInstr*, 8>::iterator I = DupCopies.begin(),
E = DupCopies.end(); I != E; ++I) {
@@ -1451,7 +1466,8 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
// A = X
unsigned Src = MI->getOperand(1).getReg();
SourceRegisters.push_back(Src);
- ErasedInstrs.insert(MI);
+ if (!ErasedInstrs.insert(MI))
+ continue;
LIS->RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
}