//===-- 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) {
    if ((++StartPos)->start <= i->start) {
      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";
}
