diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-19 23:34:59 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-19 23:34:59 +0000 |
commit | 7ebed91fddbcd259d03c4b438719ac1ce2a4fc87 (patch) | |
tree | ad2dfa847de2a06219ea704c33e2ae5c49b11cac /lib/CodeGen/RegisterCoalescer.cpp | |
parent | 9012c57e18d76d562b1f3e60bf19cccefa7b793e (diff) | |
download | llvm-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.cpp | 24 |
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(); } |