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