//===-- LiveInterval.cpp - Live Interval Representation -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and 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 interval for register v if there is no instruction with number j' > j
// such that v is live at j' abd there is no instruction with number i' < i such
// that v is live at i'. In this implementation intervals can have holes,
// i.e. an interval might look like [1,20), [50,65), [1000,1001).  Each
// individual range is represented as an instance of LiveRange, and the whole
// interval is represented as an instance of LiveInterval.
//
//===----------------------------------------------------------------------===//

#include "LiveInterval.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
#include <iostream>
#include <map>
using namespace llvm;

// An example for liveAt():
//
// this = [1,4), liveAt(0) will return false. The instruction defining this
// spans slots [0,3]. The interval belongs to an spilled definition of the
// variable it represents. This is because slot 1 is used (def slot) and spans
// up to slot 3 (store slot).
//
bool LiveInterval::liveAt(unsigned I) const {
  Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I);

  if (r == ranges.begin())
    return false;

  --r;
  return r->contains(I);
}

// overlaps - Return true if the intersection of the two live intervals is
// not empty.
//
// An example for overlaps():
//
// 0: A = ...
// 4: B = ...
// 8: C = A + B ;; last use of A
//
// The live intervals 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 LiveInterval::overlapsFrom(const LiveInterval& other,
                                const_iterator StartPos) const {
  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 != ranges.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.ranges.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;
}

/// joinable - Two intervals are joinable if the either don't overlap at all
/// or if the destination of the copy is a single assignment value, and it
/// only overlaps with one value in the source interval.
bool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const {
  const LiveRange *SourceLR = other.getLiveRangeContaining(CopyIdx-1);
  const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
  assert(SourceLR && DestLR && "Not joining due to a copy?");
  unsigned OtherValIdx = SourceLR->ValId;
  unsigned ThisValIdx = DestLR->ValId;

  Ranges::const_iterator i = ranges.begin();
  Ranges::const_iterator ie = ranges.end();
  Ranges::const_iterator j = other.ranges.begin();
  Ranges::const_iterator je = other.ranges.end();

  if (i->start < j->start) {
    i = std::upper_bound(i, ie, j->start);
    if (i != ranges.begin()) --i;
  } else if (j->start < i->start) {
    j = std::upper_bound(j, je, i->start);
    if (j != other.ranges.begin()) --j;
  }

  while (i != ie && j != je) {
    if (i->start == j->start) {
      // If this is not the allowed value merge, we cannot join.
      if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
        return false;
    } else if (i->start < j->start) {
      if (i->end > j->start) {
        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
          return false;
      }
    } else {
      if (j->end > i->start) {
        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
          return false;
      }
    }
    if (i->end < j->end)
      ++i;
    else
      ++j;
  }

  return true;
}


/// extendIntervalEndTo - This method is used when we want to extend the range
/// specified by I to end at the specified endpoint.  To do this, we should
/// merge and eliminate all ranges that this will overlap with.  The iterator is
/// not invalidated.
void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) {
  assert(I != ranges.end() && "Not a valid interval!");
  unsigned ValId = I->ValId;

  // Search for the first interval that we can't merge with.
  Ranges::iterator MergeTo = next(I);
  for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) {
    assert(MergeTo->ValId == ValId && "Cannot merge with differing values!");
  }

  // If NewEnd was in the middle of an interval, make sure to get its endpoint.
  I->end = std::max(NewEnd, prior(MergeTo)->end);

  // Erase any dead ranges
  ranges.erase(next(I), MergeTo);
}


/// extendIntervalStartTo - This method is used when we want to extend the range
/// specified by I to start at the specified endpoint.  To do this, we should
/// merge and eliminate all ranges that this will overlap with.
LiveInterval::Ranges::iterator
LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) {
  assert(I != ranges.end() && "Not a valid interval!");
  unsigned ValId = I->ValId;

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

  // If we start in the middle of another interval, just delete a range and
  // extend that interval.
  if (MergeTo->end >= NewStart && MergeTo->ValId == ValId) {
    MergeTo->end = I->end;
  } else {
    // Otherwise, extend the interval right after.
    ++MergeTo;
    MergeTo->start = NewStart;
    MergeTo->end = I->end;
  }

  ranges.erase(next(MergeTo), next(I));
  return MergeTo;
}

LiveInterval::Ranges::iterator
LiveInterval::addRangeFrom(LiveRange LR, Ranges::iterator From) {
  unsigned Start = LR.start, End = LR.end;
  Ranges::iterator it = std::upper_bound(From, ranges.end(), Start);

  // If the inserted interval starts in the middle or right at the end of
  // another interval, just extend that interval to contain the range of LR.
  if (it != ranges.begin()) {
    Ranges::iterator B = prior(it);
    if (LR.ValId == B->ValId) {
      if (B->start <= Start && B->end >= Start) {
        extendIntervalEndTo(B, End);
        return B;
      }
    } else {
      // Check to make sure that we are not overlapping two live ranges with
      // different ValId's.
      assert(B->end <= Start &&
             "Cannot overlap two LiveRanges with differing ValID's"
             " (did you def the same reg twice in a MachineInstr?)");
    }
  }

  // Otherwise, if this range ends in the middle of, or right next to, another
  // interval, merge it into that interval.
  if (it != ranges.end())
    if (LR.ValId == it->ValId) {
      if (it->start <= End) {
        it = extendIntervalStartTo(it, Start);

        // If LR is a complete superset of an interval, we may need to grow its
        // endpoint as well.
        if (End > it->end)
          extendIntervalEndTo(it, End);
        return it;
      }
    } else {
      // Check to make sure that we are not overlapping two live ranges with
      // different ValId's.
      assert(it->start >= End &&
             "Cannot overlap two LiveRanges with differing ValID's");
    }

  // Otherwise, this is just a new range that doesn't interact with anything.
  // Insert it.
  return ranges.insert(it, LR);
}


/// removeRange - Remove the specified range from this interval.  Note that
/// the range must already be in this interval in its entirety.
void LiveInterval::removeRange(unsigned Start, unsigned End) {
  // Find the LiveRange containing this span.
  Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start);
  assert(I != ranges.begin() && "Range is not in interval!");
  --I;
  assert(I->contains(Start) && I->contains(End-1) &&
         "Range is not entirely in interval!");

  // If the span we are removing is at the start of the LiveRange, adjust it.
  if (I->start == Start) {
    if (I->end == End)
      ranges.erase(I);  // Removed the whole LiveRange.
    else
      I->start = End;
    return;
  }

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

  // Otherwise, we are splitting the LiveRange into two pieces.
  unsigned OldEnd = I->end;
  I->end = Start;   // Trim the old interval.

  // Insert the new one.
  ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId));
}

/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
const LiveRange *LiveInterval::getLiveRangeContaining(unsigned Idx) const {
  Ranges::const_iterator It = std::upper_bound(ranges.begin(),ranges.end(),Idx);
  if (It != ranges.begin()) {
    const LiveRange &LR = *prior(It);
    if (LR.contains(Idx))
      return &LR;
  }

  return 0;
}



/// join - Join two live intervals (this, and other) together.  This operation
/// is the result of a copy instruction in the source program, that occurs at
/// index 'CopyIdx' that copies from 'Other' to 'this'.
void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
  const LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1);
  const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
  assert(SourceLR && DestLR && "Not joining due to a copy?");
  unsigned MergedSrcValIdx = SourceLR->ValId;
  unsigned MergedDstValIdx = DestLR->ValId;

  // Try to do the least amount of work possible.  In particular, if there are
  // more liverange chunks in the other set than there are in the 'this' set,
  // swap sets to merge the fewest chunks in possible.
  if (Other.ranges.size() > ranges.size()) {
    std::swap(MergedSrcValIdx, MergedDstValIdx);
    std::swap(ranges, Other.ranges);
    std::swap(NumValues, Other.NumValues);
  }

  // Join the ranges of other into the ranges of this interval.
  Ranges::iterator InsertPos = ranges.begin();
  std::map<unsigned, unsigned> Dst2SrcIdxMap;
  for (Ranges::iterator I = Other.ranges.begin(),
         E = Other.ranges.end(); I != E; ++I) {
    // Map the ValId in the other live range to the current live range.
    if (I->ValId == MergedSrcValIdx)
      I->ValId = MergedDstValIdx;
    else {
      unsigned &NV = Dst2SrcIdxMap[I->ValId];
      if (NV == 0) NV = getNextValue();
      I->ValId = NV;
    }

    InsertPos = addRangeFrom(*I, InsertPos);
  }

  weight += Other.weight;
}

std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
  return os << '[' << LR.start << ',' << LR.end << ':' << LR.ValId << ")";
}

void LiveRange::dump() const {
  std::cerr << *this << "\n";
}


std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li) {
  os << "%reg" << li.reg << ',' << li.weight;
  if (li.empty())
    return os << "EMPTY";

  os << " = ";
  for (LiveInterval::Ranges::const_iterator i = li.ranges.begin(),
         e = li.ranges.end(); i != e; ++i)
    os << *i;
  return os;
}

void LiveInterval::dump() const {
  std::cerr << *this << "\n";
}
