diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h --- a/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/llvm/include/llvm/CodeGen/LiveInterval.h @@ -521,11 +521,11 @@ removeSegment(S.start, S.end, RemoveDeadValNo); } - /// Remove segment pointed to by iterator @p I from this range. This does - /// not remove dead value numbers. - iterator removeSegment(iterator I) { - return segments.erase(I); - } + /// Remove segment pointed to by iterator @p I from this range. + iterator removeSegment(iterator I, bool RemoveDeadValNo = false); + + /// Mark \p ValNo for deletion if no segments in this range use it. + void removeValNoIfDead(VNInfo *ValNo); /// Query Liveness at Idx. /// The sub-instruction slot of Idx doesn't matter, only the instruction diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -592,21 +592,10 @@ VNInfo *ValNo = I->valno; if (I->start == Start) { if (I->end == End) { - if (RemoveDeadValNo) { - // Check if val# is dead. - bool isDead = true; - for (const_iterator II = begin(), EE = end(); II != EE; ++II) - if (II != I && II->valno == ValNo) { - isDead = false; - break; - } - if (isDead) { - // Now that ValNo is dead, remove it. - markValNoForDeletion(ValNo); - } - } - segments.erase(I); // Removed the whole Segment. + + if (RemoveDeadValNo) + removeValNoIfDead(ValNo); } else I->start = End; return; @@ -627,6 +616,19 @@ segments.insert(std::next(I), Segment(End, OldEnd, ValNo)); } +LiveRange::iterator LiveRange::removeSegment(iterator I, bool RemoveDeadValNo) { + VNInfo *ValNo = I->valno; + I = segments.erase(I); + if (RemoveDeadValNo) + removeValNoIfDead(ValNo); + return I; +} + +void LiveRange::removeValNoIfDead(VNInfo *ValNo) { + if (none_of(*this, [=](const Segment &S) { return S.valno == ValNo; })) + markValNoForDeletion(ValNo); +} + /// removeValNo - Remove all the segments defined by the specified value#. /// Also remove the value# from value# list. void LiveRange::removeValNo(VNInfo *ValNo) { diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -1607,17 +1607,9 @@ if (MO.isDef()) { if (!isStartValid) { if (LII->end.isDead()) { - SlotIndex prevStart; + LII = LR.removeSegment(LII, true); if (LII != LR.begin()) - prevStart = std::prev(LII)->start; - - // FIXME: This could be more efficient if there was a - // removeSegment method that returned an iterator. - LR.removeSegment(*LII, true); - if (prevStart.isValid()) - LII = LR.find(prevStart); - else - LII = LR.begin(); + --LII; } else { LII->start = instrIdx.getRegSlot(); LII->valno->def = instrIdx.getRegSlot();