LiveInterval.cpp revision f542649f1b374b1bae845e4e4f6d1e82f90a9e31
12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===-- LiveInterval.cpp - Live Interval Representation -------------------===//
22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
32228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//                     The LLVM Compiler Infrastructure
42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi// This file was developed by the LLVM research group and is distributed under
62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// the University of Illinois Open Source License. See LICENSE.TXT for details.
72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===----------------------------------------------------------------------===//
92228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// This file implements the LiveRange and LiveInterval classes.  Given some
112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// numbering of each the machine instructions an interval [i, j) is said to be a
122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// live interval for register v if there is no instruction with number j' > j
132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// such that v is live at j' abd there is no instruction with number i' < i such
142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// that v is live at i'. In this implementation intervals can have holes,
152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// i.e. an interval might look like [1,20), [50,65), [1000,1001).  Each
162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// individual range is represented as an instance of LiveRange, and the whole
172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// interval is represented as an instance of LiveInterval.
182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===----------------------------------------------------------------------===//
202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "LiveInterval.h"
222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "Support/STLExtras.h"
232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <iostream>
242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <map>
252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectusing namespace llvm;
262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// An example for liveAt():
282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// this = [1,4), liveAt(0) will return false. The instruction defining this
302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// spans slots [0,3]. The interval belongs to an spilled definition of the
312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// variable it represents. This is because slot 1 is used (def slot) and spans
322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// up to slot 3 (store slot).
332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbool LiveInterval::liveAt(unsigned I) const {
352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I);
362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (r == ranges.begin())
382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return false;
392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  --r;
412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return r->contains(I);
422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// An example for overlaps():
452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 0: A = ...
472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 4: B = ...
482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 8: C = A + B ;; last use of A
492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// The live intervals should look like:
512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// A = [3, 11)
532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// B = [7, x)
542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// C = [11, y)
552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//
562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// A->overlaps(C) should return false since we want to be able to join
572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// A and C.
582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbool LiveInterval::overlaps(const LiveInterval& other) const {
592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator i = ranges.begin();
602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator ie = ranges.end();
612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator j = other.ranges.begin();
622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator je = other.ranges.end();
632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (i->start < j->start) {
652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    i = std::upper_bound(i, ie, j->start);
662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i != ranges.begin()) --i;
672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else if (j->start < i->start) {
682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    j = std::upper_bound(j, je, i->start);
692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (j != other.ranges.begin()) --j;
702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return true;
722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  while (i != ie && j != je) {
752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i->start == j->start)
762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return true;
772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i->start > j->start) {
792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      std::swap(i, j);
802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      std::swap(ie, je);
812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    assert(i->start < j->start);
832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i->end > j->start)
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return true;
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ++i;
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return false;
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// joinable - Two intervals are joinable if the either don't overlap at all
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// or if the destination of the copy is a single assignment value, and it
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// only overlaps with one value in the source interval.
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const {
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const LiveRange *SourceLR = other.getLiveRangeContaining(CopyIdx-1);
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  assert(SourceLR && DestLR && "Not joining due to a copy?");
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned OtherValIdx = SourceLR->ValId;
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned ThisValIdx = DestLR->ValId;
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator i = ranges.begin();
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator ie = ranges.end();
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator j = other.ranges.begin();
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::const_iterator je = other.ranges.end();
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (i->start < j->start) {
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    i = std::upper_bound(i, ie, j->start);
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i != ranges.begin()) --i;
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else if (j->start < i->start) {
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    j = std::upper_bound(j, je, i->start);
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (j != other.ranges.begin()) --j;
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
114577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi
115577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi  while (i != ie && j != je) {
116577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    if (i->start == j->start) {
117577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      // If this is not the allowed value merge, we cannot join.
118577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
119577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi        return true;
120577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    } else if (i->start < j->start) {
121577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      if (i->end > j->start) {
122577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
123577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi          return true;
124577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      }
125577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    } else {
126577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      if (j->end > i->start) {
127577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
128577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi          return true;
129577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      }
130577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    }
131577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    if (i->end < j->end)
132577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi      ++i;
133577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi    else
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      ++j;
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return false;
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
140577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// extendIntervalEndTo - This method is used when we want to extend the range
142577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi/// specified by I to end at the specified endpoint.  To do this, we should
143577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi/// merge and eliminate all ranges that this will overlap with.  The iterator is
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// not invalidated.
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) {
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  assert(I != ranges.end() && "Not a valid interval!");
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned ValId = I->ValId;
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // Search for the first interval that we can't merge with.
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::iterator MergeTo = next(I);
151577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi  for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) {
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    assert(MergeTo->ValId == ValId && "Cannot merge with differing values!");
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // If NewEnd was in the middle of an interval, make sure to get its endpoint.
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  I->end = std::max(NewEnd, prior(MergeTo)->end);
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // Erase any dead ranges
159577fcbb570d023be4cea9564292dd2bd95f40c3bJean-Michel Trivi  ranges.erase(next(I), MergeTo);
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// extendIntervalStartTo - This method is used when we want to extend the range
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// specified by I to start at the specified endpoint.  To do this, we should
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// merge and eliminate all ranges that this will overlap with.
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLiveInterval::Ranges::iterator
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) {
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  assert(I != ranges.end() && "Not a valid interval!");
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned ValId = I->ValId;
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // Search for the first interval that we can't merge with.
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::iterator MergeTo = I;
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  do {
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (MergeTo == ranges.begin()) {
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      I->start = NewStart;
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      ranges.erase(MergeTo, I);
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return I;
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    assert(MergeTo->ValId == ValId && "Cannot merge with differing values!");
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    --MergeTo;
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } while (NewStart <= MergeTo->start);
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // If we start in the middle of another interval, just delete a range and
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // extend that interval.
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (MergeTo->end >= NewStart && MergeTo->ValId == ValId) {
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    MergeTo->end = I->end;
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    // Otherwise, extend the interval right after.
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ++MergeTo;
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    MergeTo->start = NewStart;
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    MergeTo->end = I->end;
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ranges.erase(next(MergeTo), next(I));
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return MergeTo;
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLiveInterval::Ranges::iterator
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLiveInterval::addRangeFrom(LiveRange LR, Ranges::iterator From) {
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned Start = LR.start, End = LR.end;
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Ranges::iterator it = std::upper_bound(From, ranges.end(), Start);
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // If the inserted interval starts in the middle or right at the end of
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // another interval, just extend that interval to contain the range of LR.
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (it != ranges.begin()) {
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    Ranges::iterator B = prior(it);
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (LR.ValId == B->ValId) {
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (B->start <= Start && B->end >= Start) {
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        extendIntervalEndTo(B, End);
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return B;
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      // Check to make sure that we are not overlapping two live ranges with
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      // different ValId's.
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      assert(B->end <= Start &&
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project             "Cannot overlap two LiveRanges with differing ValID's");
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // Otherwise, if this range ends in the middle of, or right next to, another
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  // interval, merge it into that interval.
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (it != ranges.end())
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (LR.ValId == it->ValId) {
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (it->start <= End) {
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        it = extendIntervalStartTo(it, Start);
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        // If LR is a complete superset of an interval, we may need to grow its
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        // endpoint as well.
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (End > it->end)
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          extendIntervalEndTo(it, End);
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return it;
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
234      // Check to make sure that we are not overlapping two live ranges with
235      // different ValId's.
236      assert(it->start >= End &&
237             "Cannot overlap two LiveRanges with differing ValID's");
238    }
239
240  // Otherwise, this is just a new range that doesn't interact with anything.
241  // Insert it.
242  return ranges.insert(it, LR);
243}
244
245
246/// removeRange - Remove the specified range from this interval.  Note that
247/// the range must already be in this interval in its entirety.
248void LiveInterval::removeRange(unsigned Start, unsigned End) {
249  // Find the LiveRange containing this span.
250  Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start);
251  assert(I != ranges.begin() && "Range is not in interval!");
252  --I;
253  assert(I->contains(Start) && I->contains(End-1) &&
254         "Range is not entirely in interval!");
255
256  // If the span we are removing is at the start of the LiveRange, adjust it.
257  if (I->start == Start) {
258    if (I->end == End)
259      ranges.erase(I);  // Removed the whole LiveRange.
260    else
261      I->start = End;
262    return;
263  }
264
265  // Otherwise if the span we are removing is at the end of the LiveRange,
266  // adjust the other way.
267  if (I->end == End) {
268    I->end = Start;
269    return;
270  }
271
272  // Otherwise, we are splitting the LiveRange into two pieces.
273  unsigned OldEnd = I->end;
274  I->end = Start;   // Trim the old interval.
275
276  // Insert the new one.
277  ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId));
278}
279
280/// getLiveRangeContaining - Return the live range that contains the
281/// specified index, or null if there is none.
282const LiveRange *LiveInterval::getLiveRangeContaining(unsigned Idx) const {
283  Ranges::const_iterator It = std::upper_bound(ranges.begin(),ranges.end(),Idx);
284  if (It != ranges.begin()) {
285    const LiveRange &LR = *prior(It);
286    if (LR.contains(Idx))
287      return &LR;
288  }
289
290  return 0;
291}
292
293
294
295/// join - Join two live intervals (this, and other) together.  This operation
296/// is the result of a copy instruction in the source program, that occurs at
297/// index 'CopyIdx' that copies from 'Other' to 'this'.
298void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
299  const LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1);
300  const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
301  assert(SourceLR && DestLR && "Not joining due to a copy?");
302  unsigned MergedSrcValIdx = SourceLR->ValId;
303  unsigned MergedDstValIdx = DestLR->ValId;
304
305  // Try to do the least amount of work possible.  In particular, if there are
306  // more liverange chunks in the other set than there are in the 'this' set,
307  // swap sets to merge the fewest chunks in possible.
308  if (Other.ranges.size() > ranges.size()) {
309    std::swap(MergedSrcValIdx, MergedDstValIdx);
310    std::swap(ranges, Other.ranges);
311    std::swap(NumValues, Other.NumValues);
312  }
313
314  // Join the ranges of other into the ranges of this interval.
315  Ranges::iterator InsertPos = ranges.begin();
316  std::map<unsigned, unsigned> Dst2SrcIdxMap;
317  for (Ranges::iterator I = Other.ranges.begin(),
318         E = Other.ranges.end(); I != E; ++I) {
319    // Map the ValId in the other live range to the current live range.
320    if (I->ValId == MergedSrcValIdx)
321      I->ValId = MergedDstValIdx;
322    else {
323      unsigned &NV = Dst2SrcIdxMap[I->ValId];
324      if (NV == 0) NV = getNextValue();
325      I->ValId = NV;
326    }
327
328    InsertPos = addRangeFrom(*I, InsertPos);
329  }
330
331  weight += Other.weight;
332}
333
334std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
335  return os << '[' << LR.start << ',' << LR.end << ':' << LR.ValId << ")";
336}
337
338void LiveRange::dump() const {
339  std::cerr << *this << "\n";
340}
341
342
343std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li) {
344  os << "%reg" << li.reg << ',' << li.weight;
345  if (li.empty())
346    return os << "EMPTY";
347
348  os << " = ";
349  for (LiveInterval::Ranges::const_iterator i = li.ranges.begin(),
350         e = li.ranges.end(); i != e; ++i)
351    os << *i;
352  return os;
353}
354
355void LiveInterval::dump() const {
356  std::cerr << *this << "\n";
357}
358