//===-- LiveInterval.cpp - Live Interval Representation -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveRange and LiveInterval classes.  Given some
// numbering of each the machine instructions an interval [i, j) is said to be a
// live range for register v if there is no instruction with number j' >= j
// such that v is live at j' and there is no instruction with number i' < i such
// that v is live at i'. In this implementation ranges can have holes,
// i.e. a range might look like [1,20), [50,65), [1000,1001).  Each
// individual segment is represented as an instance of LiveRange::Segment,
// and the whole range is represented as an instance of LiveRange.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/LiveInterval.h"

#include "LiveRangeUtils.h"
#include "RegisterCoalescer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm>
using namespace llvm;

namespace {
//===----------------------------------------------------------------------===//
// Implementation of various methods necessary for calculation of live ranges.
// The implementation of the methods abstracts from the concrete type of the
// segment collection.
//
// Implementation of the class follows the Template design pattern. The base
// class contains generic algorithms that call collection-specific methods,
// which are provided in concrete subclasses. In order to avoid virtual calls
// these methods are provided by means of C++ template instantiation.
// The base class calls the methods of the subclass through method impl(),
// which casts 'this' pointer to the type of the subclass.
//
//===----------------------------------------------------------------------===//

template <typename ImplT, typename IteratorT, typename CollectionT>
class CalcLiveRangeUtilBase {
protected:
  LiveRange *LR;

protected:
  CalcLiveRangeUtilBase(LiveRange *LR) : LR(LR) {}

public:
  typedef LiveRange::Segment Segment;
  typedef IteratorT iterator;

  /// A counterpart of LiveRange::createDeadDef: Make sure the range has a
  /// value defined at @p Def.
  /// If @p ForVNI is null, and there is no value defined at @p Def, a new
  /// value will be allocated using @p VNInfoAllocator.
  /// If @p ForVNI is null, the return value is the value defined at @p Def,
  /// either a pre-existing one, or the one newly created.
  /// If @p ForVNI is not null, then @p Def should be the location where
  /// @p ForVNI is defined. If the range does not have a value defined at
  /// @p Def, the value @p ForVNI will be used instead of allocating a new
  /// one. If the range already has a value defined at @p Def, it must be
  /// same as @p ForVNI. In either case, @p ForVNI will be the return value.
  VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator *VNInfoAllocator,
                        VNInfo *ForVNI) {
    assert(!Def.isDead() && "Cannot define a value at the dead slot");
    assert((!ForVNI || ForVNI->def == Def) &&
           "If ForVNI is specified, it must match Def");
    iterator I = impl().find(Def);
    if (I == segments().end()) {
      VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
      impl().insertAtEnd(Segment(Def, Def.getDeadSlot(), VNI));
      return VNI;
    }

    Segment *S = segmentAt(I);
    if (SlotIndex::isSameInstr(Def, S->start)) {
      assert((!ForVNI || ForVNI == S->valno) && "Value number mismatch");
      assert(S->valno->def == S->start && "Inconsistent existing value def");

      // It is possible to have both normal and early-clobber defs of the same
      // register on an instruction. It doesn't make a lot of sense, but it is
      // possible to specify in inline assembly.
      //
      // Just convert everything to early-clobber.
      Def = std::min(Def, S->start);
      if (Def != S->start)
        S->start = S->valno->def = Def;
      return S->valno;
    }
    assert(SlotIndex::isEarlierInstr(Def, S->start) && "Already live at def");
    VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
    segments().insert(I, Segment(Def, Def.getDeadSlot(), VNI));
    return VNI;
  }

  VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Use) {
    if (segments().empty())
      return nullptr;
    iterator I =
      impl().findInsertPos(Segment(Use.getPrevSlot(), Use, nullptr));
    if (I == segments().begin())
      return nullptr;
    --I;
    if (I->end <= StartIdx)
      return nullptr;
    if (I->end < Use)
      extendSegmentEndTo(I, Use);
    return I->valno;
  }

  std::pair<VNInfo*,bool> extendInBlock(ArrayRef<SlotIndex> Undefs,
      SlotIndex StartIdx, SlotIndex Use) {
    if (segments().empty())
      return std::make_pair(nullptr, false);
    SlotIndex BeforeUse = Use.getPrevSlot();
    iterator I = impl().findInsertPos(Segment(BeforeUse, Use, nullptr));
    if (I == segments().begin())
      return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
    --I;
    if (I->end <= StartIdx)
      return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
    if (I->end < Use) {
      if (LR->isUndefIn(Undefs, I->end, BeforeUse))
        return std::make_pair(nullptr, true);
      extendSegmentEndTo(I, Use);
    }
    return std::make_pair(I->valno, false);
  }

  /// This method is used when we want to extend the segment specified
  /// by I to end at the specified endpoint. To do this, we should
  /// merge and eliminate all segments that this will overlap
  /// with. The iterator is not invalidated.
  void extendSegmentEndTo(iterator I, SlotIndex NewEnd) {
    assert(I != segments().end() && "Not a valid segment!");
    Segment *S = segmentAt(I);
    VNInfo *ValNo = I->valno;

    // Search for the first segment that we can't merge with.
    iterator MergeTo = std::next(I);
    for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo)
      assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");

    // If NewEnd was in the middle of a segment, make sure to get its endpoint.
    S->end = std::max(NewEnd, std::prev(MergeTo)->end);

    // If the newly formed segment now touches the segment after it and if they
    // have the same value number, merge the two segments into one segment.
    if (MergeTo != segments().end() && MergeTo->start <= I->end &&
        MergeTo->valno == ValNo) {
      S->end = MergeTo->end;
      ++MergeTo;
    }

    // Erase any dead segments.
    segments().erase(std::next(I), MergeTo);
  }

  /// This method is used when we want to extend the segment specified
  /// by I to start at the specified endpoint.  To do this, we should
  /// merge and eliminate all segments that this will overlap with.
  iterator extendSegmentStartTo(iterator I, SlotIndex NewStart) {
    assert(I != segments().end() && "Not a valid segment!");
    Segment *S = segmentAt(I);
    VNInfo *ValNo = I->valno;

    // Search for the first segment that we can't merge with.
    iterator MergeTo = I;
    do {
      if (MergeTo == segments().begin()) {
        S->start = NewStart;
        segments().erase(MergeTo, I);
        return I;
      }
      assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
      --MergeTo;
    } while (NewStart <= MergeTo->start);

    // If we start in the middle of another segment, just delete a range and
    // extend that segment.
    if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
      segmentAt(MergeTo)->end = S->end;
    } else {
      // Otherwise, extend the segment right after.
      ++MergeTo;
      Segment *MergeToSeg = segmentAt(MergeTo);
      MergeToSeg->start = NewStart;
      MergeToSeg->end = S->end;
    }

    segments().erase(std::next(MergeTo), std::next(I));
    return MergeTo;
  }

  iterator addSegment(Segment S) {
    SlotIndex Start = S.start, End = S.end;
    iterator I = impl().findInsertPos(S);

    // If the inserted segment starts in the middle or right at the end of
    // another segment, just extend that segment to contain the segment of S.
    if (I != segments().begin()) {
      iterator B = std::prev(I);
      if (S.valno == B->valno) {
        if (B->start <= Start && B->end >= Start) {
          extendSegmentEndTo(B, End);
          return B;
        }
      } else {
        // Check to make sure that we are not overlapping two live segments with
        // different valno's.
        assert(B->end <= Start &&
               "Cannot overlap two segments with differing ValID's"
               " (did you def the same reg twice in a MachineInstr?)");
      }
    }

    // Otherwise, if this segment ends in the middle of, or right next
    // to, another segment, merge it into that segment.
    if (I != segments().end()) {
      if (S.valno == I->valno) {
        if (I->start <= End) {
          I = extendSegmentStartTo(I, Start);

          // If S is a complete superset of a segment, we may need to grow its
          // endpoint as well.
          if (End > I->end)
            extendSegmentEndTo(I, End);
          return I;
        }
      } else {
        // Check to make sure that we are not overlapping two live segments with
        // different valno's.
        assert(I->start >= End &&
               "Cannot overlap two segments with differing ValID's");
      }
    }

    // Otherwise, this is just a new segment that doesn't interact with
    // anything.
    // Insert it.
    return segments().insert(I, S);
  }

private:
  ImplT &impl() { return *static_cast<ImplT *>(this); }

  CollectionT &segments() { return impl().segmentsColl(); }

  Segment *segmentAt(iterator I) { return const_cast<Segment *>(&(*I)); }
};

//===----------------------------------------------------------------------===//
//   Instantiation of the methods for calculation of live ranges
//   based on a segment vector.
//===----------------------------------------------------------------------===//

class CalcLiveRangeUtilVector;
typedef CalcLiveRangeUtilBase<CalcLiveRangeUtilVector, LiveRange::iterator,
                              LiveRange::Segments> CalcLiveRangeUtilVectorBase;

class CalcLiveRangeUtilVector : public CalcLiveRangeUtilVectorBase {
public:
  CalcLiveRangeUtilVector(LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}

private:
  friend CalcLiveRangeUtilVectorBase;

  LiveRange::Segments &segmentsColl() { return LR->segments; }

  void insertAtEnd(const Segment &S) { LR->segments.push_back(S); }

  iterator find(SlotIndex Pos) { return LR->find(Pos); }

  iterator findInsertPos(Segment S) {
    return std::upper_bound(LR->begin(), LR->end(), S.start);
  }
};

//===----------------------------------------------------------------------===//
//   Instantiation of the methods for calculation of live ranges
//   based on a segment set.
//===----------------------------------------------------------------------===//

class CalcLiveRangeUtilSet;
typedef CalcLiveRangeUtilBase<CalcLiveRangeUtilSet,
                              LiveRange::SegmentSet::iterator,
                              LiveRange::SegmentSet> CalcLiveRangeUtilSetBase;

class CalcLiveRangeUtilSet : public CalcLiveRangeUtilSetBase {
public:
  CalcLiveRangeUtilSet(LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}

private:
  friend CalcLiveRangeUtilSetBase;

  LiveRange::SegmentSet &segmentsColl() { return *LR->segmentSet; }

  void insertAtEnd(const Segment &S) {
    LR->segmentSet->insert(LR->segmentSet->end(), S);
  }

  iterator find(SlotIndex Pos) {
    iterator I =
        LR->segmentSet->upper_bound(Segment(Pos, Pos.getNextSlot(), nullptr));
    if (I == LR->segmentSet->begin())
      return I;
    iterator PrevI = std::prev(I);
    if (Pos < (*PrevI).end)
      return PrevI;
    return I;
  }

  iterator findInsertPos(Segment S) {
    iterator I = LR->segmentSet->upper_bound(S);
    if (I != LR->segmentSet->end() && !(S.start < *I))
      ++I;
    return I;
  }
};
} // namespace

//===----------------------------------------------------------------------===//
//   LiveRange methods
//===----------------------------------------------------------------------===//

LiveRange::iterator LiveRange::find(SlotIndex Pos) {
  // This algorithm is basically std::upper_bound.
  // Unfortunately, std::upper_bound cannot be used with mixed types until we
  // adopt C++0x. Many libraries can do it, but not all.
  if (empty() || Pos >= endIndex())
    return end();
  iterator I = begin();
  size_t Len = size();
  do {
    size_t Mid = Len >> 1;
    if (Pos < I[Mid].end) {
      Len = Mid;
    } else {
      I += Mid + 1;
      Len -= Mid + 1;
    }
  } while (Len);
  return I;
}

VNInfo *LiveRange::createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc) {
  // Use the segment set, if it is available.
  if (segmentSet != nullptr)
    return CalcLiveRangeUtilSet(this).createDeadDef(Def, &VNIAlloc, nullptr);
  // Otherwise use the segment vector.
  return CalcLiveRangeUtilVector(this).createDeadDef(Def, &VNIAlloc, nullptr);
}

VNInfo *LiveRange::createDeadDef(VNInfo *VNI) {
  // Use the segment set, if it is available.
  if (segmentSet != nullptr)
    return CalcLiveRangeUtilSet(this).createDeadDef(VNI->def, nullptr, VNI);
  // Otherwise use the segment vector.
  return CalcLiveRangeUtilVector(this).createDeadDef(VNI->def, nullptr, VNI);
}

// overlaps - Return true if the intersection of the two live ranges is
// not empty.
//
// An example for overlaps():
//
// 0: A = ...
// 4: B = ...
// 8: C = A + B ;; last use of A
//
// The live ranges should look like:
//
// A = [3, 11)
// B = [7, x)
// C = [11, y)
//
// A->overlaps(C) should return false since we want to be able to join
// A and C.
//
bool LiveRange::overlapsFrom(const LiveRange& other,
                             const_iterator StartPos) const {
  assert(!empty() && "empty range");
  const_iterator i = begin();
  const_iterator ie = end();
  const_iterator j = StartPos;
  const_iterator je = other.end();

  assert((StartPos->start <= i->start || StartPos == other.begin()) &&
         StartPos != other.end() && "Bogus start position hint!");

  if (i->start < j->start) {
    i = std::upper_bound(i, ie, j->start);
    if (i != begin()) --i;
  } else if (j->start < i->start) {
    ++StartPos;
    if (StartPos != other.end() && StartPos->start <= i->start) {
      assert(StartPos < other.end() && i < end());
      j = std::upper_bound(j, je, i->start);
      if (j != other.begin()) --j;
    }
  } else {
    return true;
  }

  if (j == je) return false;

  while (i != ie) {
    if (i->start > j->start) {
      std::swap(i, j);
      std::swap(ie, je);
    }

    if (i->end > j->start)
      return true;
    ++i;
  }

  return false;
}

bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP,
                         const SlotIndexes &Indexes) const {
  assert(!empty() && "empty range");
  if (Other.empty())
    return false;

  // Use binary searches to find initial positions.
  const_iterator I = find(Other.beginIndex());
  const_iterator IE = end();
  if (I == IE)
    return false;
  const_iterator J = Other.find(I->start);
  const_iterator JE = Other.end();
  if (J == JE)
    return false;

  for (;;) {
    // J has just been advanced to satisfy:
    assert(J->end >= I->start);
    // Check for an overlap.
    if (J->start < I->end) {
      // I and J are overlapping. Find the later start.
      SlotIndex Def = std::max(I->start, J->start);
      // Allow the overlap if Def is a coalescable copy.
      if (Def.isBlock() ||
          !CP.isCoalescable(Indexes.getInstructionFromIndex(Def)))
        return true;
    }
    // Advance the iterator that ends first to check for more overlaps.
    if (J->end > I->end) {
      std::swap(I, J);
      std::swap(IE, JE);
    }
    // Advance J until J->end >= I->start.
    do
      if (++J == JE)
        return false;
    while (J->end < I->start);
  }
}

/// overlaps - Return true if the live range overlaps an interval specified
/// by [Start, End).
bool LiveRange::overlaps(SlotIndex Start, SlotIndex End) const {
  assert(Start < End && "Invalid range");
  const_iterator I = std::lower_bound(begin(), end(), End);
  return I != begin() && (--I)->end > Start;
}

bool LiveRange::covers(const LiveRange &Other) const {
  if (empty())
    return Other.empty();

  const_iterator I = begin();
  for (const Segment &O : Other.segments) {
    I = advanceTo(I, O.start);
    if (I == end() || I->start > O.start)
      return false;

    // Check adjacent live segments and see if we can get behind O.end.
    while (I->end < O.end) {
      const_iterator Last = I;
      // Get next segment and abort if it was not adjacent.
      ++I;
      if (I == end() || Last->end != I->start)
        return false;
    }
  }
  return true;
}

/// ValNo is dead, remove it.  If it is the largest value number, just nuke it
/// (and any other deleted values neighboring it), otherwise mark it as ~1U so
/// it can be nuked later.
void LiveRange::markValNoForDeletion(VNInfo *ValNo) {
  if (ValNo->id == getNumValNums()-1) {
    do {
      valnos.pop_back();
    } while (!valnos.empty() && valnos.back()->isUnused());
  } else {
    ValNo->markUnused();
  }
}

/// RenumberValues - Renumber all values in order of appearance and delete the
/// remaining unused values.
void LiveRange::RenumberValues() {
  SmallPtrSet<VNInfo*, 8> Seen;
  valnos.clear();
  for (const Segment &S : segments) {
    VNInfo *VNI = S.valno;
    if (!Seen.insert(VNI).second)
      continue;
    assert(!VNI->isUnused() && "Unused valno used by live segment");
    VNI->id = (unsigned)valnos.size();
    valnos.push_back(VNI);
  }
}

void LiveRange::addSegmentToSet(Segment S) {
  CalcLiveRangeUtilSet(this).addSegment(S);
}

LiveRange::iterator LiveRange::addSegment(Segment S) {
  // Use the segment set, if it is available.
  if (segmentSet != nullptr) {
    addSegmentToSet(S);
    return end();
  }
  // Otherwise use the segment vector.
  return CalcLiveRangeUtilVector(this).addSegment(S);
}

void LiveRange::append(const Segment S) {
  // Check that the segment belongs to the back of the list.
  assert(segments.empty() || segments.back().end <= S.start);
  segments.push_back(S);
}

std::pair<VNInfo*,bool> LiveRange::extendInBlock(ArrayRef<SlotIndex> Undefs,
    SlotIndex StartIdx, SlotIndex Kill) {
  // Use the segment set, if it is available.
  if (segmentSet != nullptr)
    return CalcLiveRangeUtilSet(this).extendInBlock(Undefs, StartIdx, Kill);
  // Otherwise use the segment vector.
  return CalcLiveRangeUtilVector(this).extendInBlock(Undefs, StartIdx, Kill);
}

VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
  // Use the segment set, if it is available.
  if (segmentSet != nullptr)
    return CalcLiveRangeUtilSet(this).extendInBlock(StartIdx, Kill);
  // Otherwise use the segment vector.
  return CalcLiveRangeUtilVector(this).extendInBlock(StartIdx, Kill);
}

/// Remove the specified segment from this range.  Note that the segment must
/// be in a single Segment in its entirety.
void LiveRange::removeSegment(SlotIndex Start, SlotIndex End,
                              bool RemoveDeadValNo) {
  // Find the Segment containing this span.
  iterator I = find(Start);
  assert(I != end() && "Segment is not in range!");
  assert(I->containsInterval(Start, End)
         && "Segment is not entirely in range!");

  // If the span we are removing is at the start of the Segment, adjust it.
  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.
    } else
      I->start = End;
    return;
  }

  // Otherwise if the span we are removing is at the end of the Segment,
  // adjust the other way.
  if (I->end == End) {
    I->end = Start;
    return;
  }

  // Otherwise, we are splitting the Segment into two pieces.
  SlotIndex OldEnd = I->end;
  I->end = Start;   // Trim the old segment.

  // Insert the new one.
  segments.insert(std::next(I), Segment(End, OldEnd, ValNo));
}

/// removeValNo - Remove all the segments defined by the specified value#.
/// Also remove the value# from value# list.
void LiveRange::removeValNo(VNInfo *ValNo) {
  if (empty()) return;
  segments.erase(remove_if(*this, [ValNo](const Segment &S) {
    return S.valno == ValNo;
  }), end());
  // Now that ValNo is dead, remove it.
  markValNoForDeletion(ValNo);
}

void LiveRange::join(LiveRange &Other,
                     const int *LHSValNoAssignments,
                     const int *RHSValNoAssignments,
                     SmallVectorImpl<VNInfo *> &NewVNInfo) {
  verify();

  // Determine if any of our values are mapped.  This is uncommon, so we want
  // to avoid the range scan if not.
  bool MustMapCurValNos = false;
  unsigned NumVals = getNumValNums();
  unsigned NumNewVals = NewVNInfo.size();
  for (unsigned i = 0; i != NumVals; ++i) {
    unsigned LHSValID = LHSValNoAssignments[i];
    if (i != LHSValID ||
        (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) {
      MustMapCurValNos = true;
      break;
    }
  }

  // If we have to apply a mapping to our base range assignment, rewrite it now.
  if (MustMapCurValNos && !empty()) {
    // Map the first live range.

    iterator OutIt = begin();
    OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]];
    for (iterator I = std::next(OutIt), E = end(); I != E; ++I) {
      VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]];
      assert(nextValNo && "Huh?");

      // If this live range has the same value # as its immediate predecessor,
      // and if they are neighbors, remove one Segment.  This happens when we
      // have [0,4:0)[4,7:1) and map 0/1 onto the same value #.
      if (OutIt->valno == nextValNo && OutIt->end == I->start) {
        OutIt->end = I->end;
      } else {
        // Didn't merge. Move OutIt to the next segment,
        ++OutIt;
        OutIt->valno = nextValNo;
        if (OutIt != I) {
          OutIt->start = I->start;
          OutIt->end = I->end;
        }
      }
    }
    // If we merge some segments, chop off the end.
    ++OutIt;
    segments.erase(OutIt, end());
  }

  // Rewrite Other values before changing the VNInfo ids.
  // This can leave Other in an invalid state because we're not coalescing
  // touching segments that now have identical values. That's OK since Other is
  // not supposed to be valid after calling join();
  for (Segment &S : Other.segments)
    S.valno = NewVNInfo[RHSValNoAssignments[S.valno->id]];

  // Update val# info. Renumber them and make sure they all belong to this
  // LiveRange now. Also remove dead val#'s.
  unsigned NumValNos = 0;
  for (unsigned i = 0; i < NumNewVals; ++i) {
    VNInfo *VNI = NewVNInfo[i];
    if (VNI) {
      if (NumValNos >= NumVals)
        valnos.push_back(VNI);
      else
        valnos[NumValNos] = VNI;
      VNI->id = NumValNos++;  // Renumber val#.
    }
  }
  if (NumNewVals < NumVals)
    valnos.resize(NumNewVals);  // shrinkify

  // Okay, now insert the RHS live segments into the LHS.
  LiveRangeUpdater Updater(this);
  for (Segment &S : Other.segments)
    Updater.add(S);
}

/// Merge all of the segments in RHS into this live range as the specified
/// value number.  The segments in RHS are allowed to overlap with segments in
/// the current range, but only if the overlapping segments have the
/// specified value number.
void LiveRange::MergeSegmentsInAsValue(const LiveRange &RHS,
                                       VNInfo *LHSValNo) {
  LiveRangeUpdater Updater(this);
  for (const Segment &S : RHS.segments)
    Updater.add(S.start, S.end, LHSValNo);
}

/// MergeValueInAsValue - Merge all of the live segments of a specific val#
/// in RHS into this live range as the specified value number.
/// The segments in RHS are allowed to overlap with segments in the
/// current range, it will replace the value numbers of the overlaped
/// segments with the specified value number.
void LiveRange::MergeValueInAsValue(const LiveRange &RHS,
                                    const VNInfo *RHSValNo,
                                    VNInfo *LHSValNo) {
  LiveRangeUpdater Updater(this);
  for (const Segment &S : RHS.segments)
    if (S.valno == RHSValNo)
      Updater.add(S.start, S.end, LHSValNo);
}

/// MergeValueNumberInto - This method is called when two value nubmers
/// are found to be equivalent.  This eliminates V1, replacing all
/// segments with the V1 value number with the V2 value number.  This can
/// cause merging of V1/V2 values numbers and compaction of the value space.
VNInfo *LiveRange::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
  assert(V1 != V2 && "Identical value#'s are always equivalent!");

  // This code actually merges the (numerically) larger value number into the
  // smaller value number, which is likely to allow us to compactify the value
  // space.  The only thing we have to be careful of is to preserve the
  // instruction that defines the result value.

  // Make sure V2 is smaller than V1.
  if (V1->id < V2->id) {
    V1->copyFrom(*V2);
    std::swap(V1, V2);
  }

  // Merge V1 segments into V2.
  for (iterator I = begin(); I != end(); ) {
    iterator S = I++;
    if (S->valno != V1) continue;  // Not a V1 Segment.

    // Okay, we found a V1 live range.  If it had a previous, touching, V2 live
    // range, extend it.
    if (S != begin()) {
      iterator Prev = S-1;
      if (Prev->valno == V2 && Prev->end == S->start) {
        Prev->end = S->end;

        // Erase this live-range.
        segments.erase(S);
        I = Prev+1;
        S = Prev;
      }
    }

    // Okay, now we have a V1 or V2 live range that is maximally merged forward.
    // Ensure that it is a V2 live-range.
    S->valno = V2;

    // If we can merge it into later V2 segments, do so now.  We ignore any
    // following V1 segments, as they will be merged in subsequent iterations
    // of the loop.
    if (I != end()) {
      if (I->start == S->end && I->valno == V2) {
        S->end = I->end;
        segments.erase(I);
        I = S+1;
      }
    }
  }

  // Now that V1 is dead, remove it.
  markValNoForDeletion(V1);

  return V2;
}

void LiveRange::flushSegmentSet() {
  assert(segmentSet != nullptr && "segment set must have been created");
  assert(
      segments.empty() &&
      "segment set can be used only initially before switching to the array");
  segments.append(segmentSet->begin(), segmentSet->end());
  segmentSet = nullptr;
  verify();
}

bool LiveRange::isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const {
  ArrayRef<SlotIndex>::iterator SlotI = Slots.begin();
  ArrayRef<SlotIndex>::iterator SlotE = Slots.end();

  // If there are no regmask slots, we have nothing to search.
  if (SlotI == SlotE)
    return false;

  // Start our search at the first segment that ends after the first slot.
  const_iterator SegmentI = find(*SlotI);
  const_iterator SegmentE = end();

  // If there are no segments that end after the first slot, we're done.
  if (SegmentI == SegmentE)
    return false;

  // Look for each slot in the live range.
  for ( ; SlotI != SlotE; ++SlotI) {
    // Go to the next segment that ends after the current slot.
    // The slot may be within a hole in the range.
    SegmentI = advanceTo(SegmentI, *SlotI);
    if (SegmentI == SegmentE)
      return false;

    // If this segment contains the slot, we're done.
    if (SegmentI->contains(*SlotI))
      return true;
    // Otherwise, look for the next slot.
  }

  // We didn't find a segment containing any of the slots.
  return false;
}

void LiveInterval::freeSubRange(SubRange *S) {
  S->~SubRange();
  // Memory was allocated with BumpPtr allocator and is not freed here.
}

void LiveInterval::removeEmptySubRanges() {
  SubRange **NextPtr = &SubRanges;
  SubRange *I = *NextPtr;
  while (I != nullptr) {
    if (!I->empty()) {
      NextPtr = &I->Next;
      I = *NextPtr;
      continue;
    }
    // Skip empty subranges until we find the first nonempty one.
    do {
      SubRange *Next = I->Next;
      freeSubRange(I);
      I = Next;
    } while (I != nullptr && I->empty());
    *NextPtr = I;
  }
}

void LiveInterval::clearSubRanges() {
  for (SubRange *I = SubRanges, *Next; I != nullptr; I = Next) {
    Next = I->Next;
    freeSubRange(I);
  }
  SubRanges = nullptr;
}

unsigned LiveInterval::getSize() const {
  unsigned Sum = 0;
  for (const Segment &S : segments)
    Sum += S.start.distance(S.end);
  return Sum;
}

void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
                                         LaneBitmask LaneMask,
                                         const MachineRegisterInfo &MRI,
                                         const SlotIndexes &Indexes) const {
  assert(TargetRegisterInfo::isVirtualRegister(reg));
  LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg);
  assert((VRegMask & LaneMask) != 0);
  const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
  for (const MachineOperand &MO : MRI.def_operands(reg)) {
    if (!MO.isUndef())
      continue;
    unsigned SubReg = MO.getSubReg();
    assert(SubReg != 0 && "Undef should only be set on subreg defs");
    LaneBitmask DefMask = TRI.getSubRegIndexLaneMask(SubReg);
    LaneBitmask UndefMask = VRegMask & ~DefMask;
    if ((UndefMask & LaneMask) != 0) {
      const MachineInstr &MI = *MO.getParent();
      bool EarlyClobber = MO.isEarlyClobber();
      SlotIndex Pos = Indexes.getInstructionIndex(MI).getRegSlot(EarlyClobber);
      Undefs.push_back(Pos);
    }
  }
}

raw_ostream& llvm::operator<<(raw_ostream& os, const LiveRange::Segment &S) {
  return os << '[' << S.start << ',' << S.end << ':' << S.valno->id << ')';
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveRange::Segment::dump() const {
  dbgs() << *this << '\n';
}
#endif

void LiveRange::print(raw_ostream &OS) const {
  if (empty())
    OS << "EMPTY";
  else {
    for (const Segment &S : segments) {
      OS << S;
      assert(S.valno == getValNumInfo(S.valno->id) && "Bad VNInfo");
    }
  }

  // Print value number info.
  if (getNumValNums()) {
    OS << "  ";
    unsigned vnum = 0;
    for (const_vni_iterator i = vni_begin(), e = vni_end(); i != e;
         ++i, ++vnum) {
      const VNInfo *vni = *i;
      if (vnum) OS << ' ';
      OS << vnum << '@';
      if (vni->isUnused()) {
        OS << 'x';
      } else {
        OS << vni->def;
        if (vni->isPHIDef())
          OS << "-phi";
      }
    }
  }
}

void LiveInterval::SubRange::print(raw_ostream &OS) const {
  OS << " L" << PrintLaneMask(LaneMask) << ' '
     << static_cast<const LiveRange&>(*this);
}

void LiveInterval::print(raw_ostream &OS) const {
  OS << PrintReg(reg) << ' ';
  super::print(OS);
  // Print subranges
  for (const SubRange &SR : subranges())
    OS << SR;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveRange::dump() const {
  dbgs() << *this << '\n';
}

LLVM_DUMP_METHOD void LiveInterval::SubRange::dump() const {
  dbgs() << *this << '\n';
}

LLVM_DUMP_METHOD void LiveInterval::dump() const {
  dbgs() << *this << '\n';
}
#endif

#ifndef NDEBUG
void LiveRange::verify() const {
  for (const_iterator I = begin(), E = end(); I != E; ++I) {
    assert(I->start.isValid());
    assert(I->end.isValid());
    assert(I->start < I->end);
    assert(I->valno != nullptr);
    assert(I->valno->id < valnos.size());
    assert(I->valno == valnos[I->valno->id]);
    if (std::next(I) != E) {
      assert(I->end <= std::next(I)->start);
      if (I->end == std::next(I)->start)
        assert(I->valno != std::next(I)->valno);
    }
  }
}

void LiveInterval::verify(const MachineRegisterInfo *MRI) const {
  super::verify();

  // Make sure SubRanges are fine and LaneMasks are disjunct.
  LaneBitmask Mask = 0;
  LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg) : ~0u;
  for (const SubRange &SR : subranges()) {
    // Subrange lanemask should be disjunct to any previous subrange masks.
    assert((Mask & SR.LaneMask) == 0);
    Mask |= SR.LaneMask;

    // subrange mask should not contained in maximum lane mask for the vreg.
    assert((Mask & ~MaxMask) == 0);
    // empty subranges must be removed.
    assert(!SR.empty());

    SR.verify();
    // Main liverange should cover subrange.
    assert(covers(SR));
  }
}
#endif


//===----------------------------------------------------------------------===//
//                           LiveRangeUpdater class
//===----------------------------------------------------------------------===//
//
// The LiveRangeUpdater class always maintains these invariants:
//
// - When LastStart is invalid, Spills is empty and the iterators are invalid.
//   This is the initial state, and the state created by flush().
//   In this state, isDirty() returns false.
//
// Otherwise, segments are kept in three separate areas:
//
// 1. [begin; WriteI) at the front of LR.
// 2. [ReadI; end) at the back of LR.
// 3. Spills.
//
// - LR.begin() <= WriteI <= ReadI <= LR.end().
// - Segments in all three areas are fully ordered and coalesced.
// - Segments in area 1 precede and can't coalesce with segments in area 2.
// - Segments in Spills precede and can't coalesce with segments in area 2.
// - No coalescing is possible between segments in Spills and segments in area
//   1, and there are no overlapping segments.
//
// The segments in Spills are not ordered with respect to the segments in area
// 1. They need to be merged.
//
// When they exist, Spills.back().start <= LastStart,
//                 and WriteI[-1].start <= LastStart.

void LiveRangeUpdater::print(raw_ostream &OS) const {
  if (!isDirty()) {
    if (LR)
      OS << "Clean updater: " << *LR << '\n';
    else
      OS << "Null updater.\n";
    return;
  }
  assert(LR && "Can't have null LR in dirty updater.");
  OS << " updater with gap = " << (ReadI - WriteI)
     << ", last start = " << LastStart
     << ":\n  Area 1:";
  for (const auto &S : make_range(LR->begin(), WriteI))
    OS << ' ' << S;
  OS << "\n  Spills:";
  for (unsigned I = 0, E = Spills.size(); I != E; ++I)
    OS << ' ' << Spills[I];
  OS << "\n  Area 2:";
  for (const auto &S : make_range(ReadI, LR->end()))
    OS << ' ' << S;
  OS << '\n';
}

LLVM_DUMP_METHOD void LiveRangeUpdater::dump() const {
  print(errs());
}

// Determine if A and B should be coalesced.
static inline bool coalescable(const LiveRange::Segment &A,
                               const LiveRange::Segment &B) {
  assert(A.start <= B.start && "Unordered live segments.");
  if (A.end == B.start)
    return A.valno == B.valno;
  if (A.end < B.start)
    return false;
  assert(A.valno == B.valno && "Cannot overlap different values");
  return true;
}

void LiveRangeUpdater::add(LiveRange::Segment Seg) {
  assert(LR && "Cannot add to a null destination");

  // Fall back to the regular add method if the live range
  // is using the segment set instead of the segment vector.
  if (LR->segmentSet != nullptr) {
    LR->addSegmentToSet(Seg);
    return;
  }

  // Flush the state if Start moves backwards.
  if (!LastStart.isValid() || LastStart > Seg.start) {
    if (isDirty())
      flush();
    // This brings us to an uninitialized state. Reinitialize.
    assert(Spills.empty() && "Leftover spilled segments");
    WriteI = ReadI = LR->begin();
  }

  // Remember start for next time.
  LastStart = Seg.start;

  // Advance ReadI until it ends after Seg.start.
  LiveRange::iterator E = LR->end();
  if (ReadI != E && ReadI->end <= Seg.start) {
    // First try to close the gap between WriteI and ReadI with spills.
    if (ReadI != WriteI)
      mergeSpills();
    // Then advance ReadI.
    if (ReadI == WriteI)
      ReadI = WriteI = LR->find(Seg.start);
    else
      while (ReadI != E && ReadI->end <= Seg.start)
        *WriteI++ = *ReadI++;
  }

  assert(ReadI == E || ReadI->end > Seg.start);

  // Check if the ReadI segment begins early.
  if (ReadI != E && ReadI->start <= Seg.start) {
    assert(ReadI->valno == Seg.valno && "Cannot overlap different values");
    // Bail if Seg is completely contained in ReadI.
    if (ReadI->end >= Seg.end)
      return;
    // Coalesce into Seg.
    Seg.start = ReadI->start;
    ++ReadI;
  }

  // Coalesce as much as possible from ReadI into Seg.
  while (ReadI != E && coalescable(Seg, *ReadI)) {
    Seg.end = std::max(Seg.end, ReadI->end);
    ++ReadI;
  }

  // Try coalescing Spills.back() into Seg.
  if (!Spills.empty() && coalescable(Spills.back(), Seg)) {
    Seg.start = Spills.back().start;
    Seg.end = std::max(Spills.back().end, Seg.end);
    Spills.pop_back();
  }

  // Try coalescing Seg into WriteI[-1].
  if (WriteI != LR->begin() && coalescable(WriteI[-1], Seg)) {
    WriteI[-1].end = std::max(WriteI[-1].end, Seg.end);
    return;
  }

  // Seg doesn't coalesce with anything, and needs to be inserted somewhere.
  if (WriteI != ReadI) {
    *WriteI++ = Seg;
    return;
  }

  // Finally, append to LR or Spills.
  if (WriteI == E) {
    LR->segments.push_back(Seg);
    WriteI = ReadI = LR->end();
  } else
    Spills.push_back(Seg);
}

// Merge as many spilled segments as possible into the gap between WriteI
// and ReadI. Advance WriteI to reflect the inserted instructions.
void LiveRangeUpdater::mergeSpills() {
  // Perform a backwards merge of Spills and [SpillI;WriteI).
  size_t GapSize = ReadI - WriteI;
  size_t NumMoved = std::min(Spills.size(), GapSize);
  LiveRange::iterator Src = WriteI;
  LiveRange::iterator Dst = Src + NumMoved;
  LiveRange::iterator SpillSrc = Spills.end();
  LiveRange::iterator B = LR->begin();

  // This is the new WriteI position after merging spills.
  WriteI = Dst;

  // Now merge Src and Spills backwards.
  while (Src != Dst) {
    if (Src != B && Src[-1].start > SpillSrc[-1].start)
      *--Dst = *--Src;
    else
      *--Dst = *--SpillSrc;
  }
  assert(NumMoved == size_t(Spills.end() - SpillSrc));
  Spills.erase(SpillSrc, Spills.end());
}

void LiveRangeUpdater::flush() {
  if (!isDirty())
    return;
  // Clear the dirty state.
  LastStart = SlotIndex();

  assert(LR && "Cannot add to a null destination");

  // Nothing to merge?
  if (Spills.empty()) {
    LR->segments.erase(WriteI, ReadI);
    LR->verify();
    return;
  }

  // Resize the WriteI - ReadI gap to match Spills.
  size_t GapSize = ReadI - WriteI;
  if (GapSize < Spills.size()) {
    // The gap is too small. Make some room.
    size_t WritePos = WriteI - LR->begin();
    LR->segments.insert(ReadI, Spills.size() - GapSize, LiveRange::Segment());
    // This also invalidated ReadI, but it is recomputed below.
    WriteI = LR->begin() + WritePos;
  } else {
    // Shrink the gap if necessary.
    LR->segments.erase(WriteI + Spills.size(), ReadI);
  }
  ReadI = WriteI + Spills.size();
  mergeSpills();
  LR->verify();
}

unsigned ConnectedVNInfoEqClasses::Classify(const LiveRange &LR) {
  // Create initial equivalence classes.
  EqClass.clear();
  EqClass.grow(LR.getNumValNums());

  const VNInfo *used = nullptr, *unused = nullptr;

  // Determine connections.
  for (const VNInfo *VNI : LR.valnos) {
    // Group all unused values into one class.
    if (VNI->isUnused()) {
      if (unused)
        EqClass.join(unused->id, VNI->id);
      unused = VNI;
      continue;
    }
    used = VNI;
    if (VNI->isPHIDef()) {
      const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
      assert(MBB && "Phi-def has no defining MBB");
      // Connect to values live out of predecessors.
      for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
           PE = MBB->pred_end(); PI != PE; ++PI)
        if (const VNInfo *PVNI = LR.getVNInfoBefore(LIS.getMBBEndIdx(*PI)))
          EqClass.join(VNI->id, PVNI->id);
    } else {
      // Normal value defined by an instruction. Check for two-addr redef.
      // FIXME: This could be coincidental. Should we really check for a tied
      // operand constraint?
      // Note that VNI->def may be a use slot for an early clobber def.
      if (const VNInfo *UVNI = LR.getVNInfoBefore(VNI->def))
        EqClass.join(VNI->id, UVNI->id);
    }
  }

  // Lump all the unused values in with the last used value.
  if (used && unused)
    EqClass.join(used->id, unused->id);

  EqClass.compress();
  return EqClass.getNumClasses();
}

void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
                                          MachineRegisterInfo &MRI) {
  // Rewrite instructions.
  for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg),
       RE = MRI.reg_end(); RI != RE;) {
    MachineOperand &MO = *RI;
    MachineInstr *MI = RI->getParent();
    ++RI;
    // DBG_VALUE instructions don't have slot indexes, so get the index of the
    // instruction before them.
    // Normally, DBG_VALUE instructions are removed before this function is
    // called, but it is not a requirement.
    SlotIndex Idx;
    if (MI->isDebugValue())
      Idx = LIS.getSlotIndexes()->getIndexBefore(*MI);
    else
      Idx = LIS.getInstructionIndex(*MI);
    LiveQueryResult LRQ = LI.Query(Idx);
    const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined();
    // In the case of an <undef> use that isn't tied to any def, VNI will be
    // NULL. If the use is tied to a def, VNI will be the defined value.
    if (!VNI)
      continue;
    if (unsigned EqClass = getEqClass(VNI))
      MO.setReg(LIV[EqClass-1]->reg);
  }

  // Distribute subregister liveranges.
  if (LI.hasSubRanges()) {
    unsigned NumComponents = EqClass.getNumClasses();
    SmallVector<unsigned, 8> VNIMapping;
    SmallVector<LiveInterval::SubRange*, 8> SubRanges;
    BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator();
    for (LiveInterval::SubRange &SR : LI.subranges()) {
      // Create new subranges in the split intervals and construct a mapping
      // for the VNInfos in the subrange.
      unsigned NumValNos = SR.valnos.size();
      VNIMapping.clear();
      VNIMapping.reserve(NumValNos);
      SubRanges.clear();
      SubRanges.resize(NumComponents-1, nullptr);
      for (unsigned I = 0; I < NumValNos; ++I) {
        const VNInfo &VNI = *SR.valnos[I];
        unsigned ComponentNum;
        if (VNI.isUnused()) {
          ComponentNum = 0;
        } else {
          const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def);
          assert(MainRangeVNI != nullptr
                 && "SubRange def must have corresponding main range def");
          ComponentNum = getEqClass(MainRangeVNI);
          if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) {
            SubRanges[ComponentNum-1]
              = LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask);
          }
        }
        VNIMapping.push_back(ComponentNum);
      }
      DistributeRange(SR, SubRanges.data(), VNIMapping);
    }
    LI.removeEmptySubRanges();
  }

  // Distribute main liverange.
  DistributeRange(LI, LIV, EqClass);
}
