diff options
Diffstat (limited to 'llvm/lib/CodeGen/RegisterCoalescer.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index cbb1a74049fb..7e9c992031f8 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -236,7 +236,8 @@ namespace { /// was successfully coalesced away. If it is not currently possible to /// coalesce this interval, but it may be possible if other things get /// coalesced, then it returns true by reference in 'Again'. - bool joinCopy(MachineInstr *CopyMI, bool &Again); + bool joinCopy(MachineInstr *CopyMI, bool &Again, + SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs); /// Attempt to join these two intervals. On failure, this /// returns false. The output "SrcInt" will not have been modified, so we @@ -1964,7 +1965,9 @@ void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI, LIS->shrinkToUses(&LI); } -bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { +bool RegisterCoalescer::joinCopy( + MachineInstr *CopyMI, bool &Again, + SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs) { Again = false; LLVM_DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI); @@ -2156,7 +2159,9 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { // 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); + if (ErasedInstrs.erase(CopyMI)) + // But we may encounter the instruction again in this iteration. + CurrentErasedInstrs.insert(CopyMI); // Rewrite all SrcReg operands to DstReg. // Also update DstReg operands to include DstIdx if it is set. @@ -3982,21 +3987,33 @@ void RegisterCoalescer::lateLiveIntervalUpdate() { bool RegisterCoalescer:: copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) { bool Progress = false; + SmallPtrSet<MachineInstr *, 4> CurrentErasedInstrs; for (MachineInstr *&MI : CurrList) { if (!MI) continue; // Skip instruction pointers that have already been erased, for example by // dead code elimination. - if (ErasedInstrs.count(MI)) { + if (ErasedInstrs.count(MI) || CurrentErasedInstrs.count(MI)) { MI = nullptr; continue; } bool Again = false; - bool Success = joinCopy(MI, Again); + bool Success = joinCopy(MI, Again, CurrentErasedInstrs); Progress |= Success; if (Success || !Again) MI = nullptr; } + // Clear instructions not recorded in `ErasedInstrs` but erased. + if (!CurrentErasedInstrs.empty()) { + for (MachineInstr *&MI : CurrList) { + if (MI && CurrentErasedInstrs.count(MI)) + MI = nullptr; + } + for (MachineInstr *&MI : WorkList) { + if (MI && CurrentErasedInstrs.count(MI)) + MI = nullptr; + } + } return Progress; } |
