LiveInterval.cpp revision a1613db62fec94845aa8306232fb665273615bad
1//===-- LiveInterval.cpp - Live Interval Representation -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the LiveRange and LiveInterval classes. Given some 11// numbering of each the machine instructions an interval [i, j) is said to be a 12// live interval for register v if there is no instruction with number j' > j 13// such that v is live at j' abd there is no instruction with number i' < i such 14// that v is live at i'. In this implementation intervals can have holes, 15// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each 16// individual range is represented as an instance of LiveRange, and the whole 17// interval is represented as an instance of LiveInterval. 18// 19//===----------------------------------------------------------------------===// 20 21#include "LiveInterval.h" 22#include "Support/STLExtras.h" 23#include <iostream> 24#include <map> 25using namespace llvm; 26 27// An example for liveAt(): 28// 29// this = [1,4), liveAt(0) will return false. The instruction defining this 30// spans slots [0,3]. The interval belongs to an spilled definition of the 31// variable it represents. This is because slot 1 is used (def slot) and spans 32// up to slot 3 (store slot). 33// 34bool LiveInterval::liveAt(unsigned I) const { 35 Ranges::const_iterator r = std::upper_bound(ranges.begin(), ranges.end(), I); 36 37 if (r == ranges.begin()) 38 return false; 39 40 --r; 41 return r->contains(I); 42} 43 44// An example for overlaps(): 45// 46// 0: A = ... 47// 4: B = ... 48// 8: C = A + B ;; last use of A 49// 50// The live intervals should look like: 51// 52// A = [3, 11) 53// B = [7, x) 54// C = [11, y) 55// 56// A->overlaps(C) should return false since we want to be able to join 57// A and C. 58bool LiveInterval::overlaps(const LiveInterval& other) const { 59 Ranges::const_iterator i = ranges.begin(); 60 Ranges::const_iterator ie = ranges.end(); 61 Ranges::const_iterator j = other.ranges.begin(); 62 Ranges::const_iterator je = other.ranges.end(); 63 if (i->start < j->start) { 64 i = std::upper_bound(i, ie, j->start); 65 if (i != ranges.begin()) --i; 66 } else if (j->start < i->start) { 67 j = std::upper_bound(j, je, i->start); 68 if (j != other.ranges.begin()) --j; 69 } else { 70 return true; 71 } 72 73 while (i != ie && j != je) { 74 if (i->start == j->start) 75 return true; 76 77 if (i->start > j->start) { 78 std::swap(i, j); 79 std::swap(ie, je); 80 } 81 assert(i->start < j->start); 82 83 if (i->end > j->start) 84 return true; 85 ++i; 86 } 87 88 return false; 89} 90 91/// joinable - Two intervals are joinable if the either don't overlap at all 92/// or if the destination of the copy is a single assignment value, and it 93/// only overlaps with one value in the source interval. 94bool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const { 95 return overlaps(other); 96} 97 98 99/// extendIntervalEndTo - This method is used when we want to extend the range 100/// specified by I to end at the specified endpoint. To do this, we should 101/// merge and eliminate all ranges that this will overlap with. The iterator is 102/// not invalidated. 103void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) { 104 assert(I != ranges.end() && "Not a valid interval!"); 105 unsigned ValId = I->ValId; 106 107 // Search for the first interval that we can't merge with. 108 Ranges::iterator MergeTo = next(I); 109 for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) { 110 assert(MergeTo->ValId == ValId && "Cannot merge with differing values!"); 111 } 112 113 // If NewEnd was in the middle of an interval, make sure to get its endpoint. 114 I->end = std::max(NewEnd, prior(MergeTo)->end); 115 116 // Erase any dead ranges 117 ranges.erase(next(I), MergeTo); 118} 119 120 121/// extendIntervalStartTo - This method is used when we want to extend the range 122/// specified by I to start at the specified endpoint. To do this, we should 123/// merge and eliminate all ranges that this will overlap with. 124LiveInterval::Ranges::iterator 125LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) { 126 assert(I != ranges.end() && "Not a valid interval!"); 127 unsigned ValId = I->ValId; 128 129 // Search for the first interval that we can't merge with. 130 Ranges::iterator MergeTo = I; 131 do { 132 if (MergeTo == ranges.begin()) { 133 I->start = NewStart; 134 ranges.erase(MergeTo, I); 135 return I; 136 } 137 assert(MergeTo->ValId == ValId && "Cannot merge with differing values!"); 138 --MergeTo; 139 } while (NewStart <= MergeTo->start); 140 141 // If we start in the middle of another interval, just delete a range and 142 // extend that interval. 143 if (MergeTo->end >= NewStart && MergeTo->ValId == ValId) { 144 MergeTo->end = I->end; 145 } else { 146 // Otherwise, extend the interval right after. 147 ++MergeTo; 148 MergeTo->start = NewStart; 149 MergeTo->end = I->end; 150 } 151 152 ranges.erase(next(MergeTo), next(I)); 153 return MergeTo; 154} 155 156LiveInterval::Ranges::iterator 157LiveInterval::addRangeFrom(LiveRange LR, Ranges::iterator From) { 158 unsigned Start = LR.start, End = LR.end; 159 Ranges::iterator it = std::upper_bound(From, ranges.end(), Start); 160 161 // If the inserted interval starts in the middle or right at the end of 162 // another interval, just extend that interval to contain the range of LR. 163 if (it != ranges.begin()) { 164 Ranges::iterator B = prior(it); 165 if (LR.ValId == B->ValId) { 166 if (B->start <= Start && B->end >= Start) { 167 extendIntervalEndTo(B, End); 168 return B; 169 } 170 } else { 171 // Check to make sure that we are not overlapping two live ranges with 172 // different ValId's. 173 assert(B->end <= Start && 174 "Cannot overlap two LiveRanges with differing ValID's"); 175 } 176 } 177 178 // Otherwise, if this range ends in the middle of, or right next to, another 179 // interval, merge it into that interval. 180 if (it != ranges.end()) 181 if (LR.ValId == it->ValId) { 182 if (it->start <= End) { 183 it = extendIntervalStartTo(it, Start); 184 185 // If LR is a complete superset of an interval, we may need to grow its 186 // endpoint as well. 187 if (End > it->end) 188 extendIntervalEndTo(it, End); 189 return it; 190 } 191 } else { 192 // Check to make sure that we are not overlapping two live ranges with 193 // different ValId's. 194 assert(it->start >= End && 195 "Cannot overlap two LiveRanges with differing ValID's"); 196 } 197 198 // Otherwise, this is just a new range that doesn't interact with anything. 199 // Insert it. 200 return ranges.insert(it, LR); 201} 202 203 204/// removeRange - Remove the specified range from this interval. Note that 205/// the range must already be in this interval in its entirety. 206void LiveInterval::removeRange(unsigned Start, unsigned End) { 207 // Find the LiveRange containing this span. 208 Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); 209 assert(I != ranges.begin() && "Range is not in interval!"); 210 --I; 211 assert(I->contains(Start) && I->contains(End-1) && 212 "Range is not entirely in interval!"); 213 214 // If the span we are removing is at the start of the LiveRange, adjust it. 215 if (I->start == Start) { 216 if (I->end == End) 217 ranges.erase(I); // Removed the whole LiveRange. 218 else 219 I->start = End; 220 return; 221 } 222 223 // Otherwise if the span we are removing is at the end of the LiveRange, 224 // adjust the other way. 225 if (I->end == End) { 226 I->start = Start; 227 return; 228 } 229 230 // Otherwise, we are splitting the LiveRange into two pieces. 231 unsigned OldEnd = I->end; 232 I->end = Start; // Trim the old interval. 233 234 // Insert the new one. 235 ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId)); 236} 237 238/// getLiveRangeContaining - Return the live range that contains the 239/// specified index, or null if there is none. 240LiveRange *LiveInterval::getLiveRangeContaining(unsigned Idx) { 241 Ranges::iterator It = std::upper_bound(ranges.begin(), ranges.end(), Idx); 242 if (It != ranges.begin()) { 243 LiveRange &LR = *prior(It); 244 if (LR.contains(Idx)) 245 return &LR; 246 } 247 248 return 0; 249} 250 251 252 253/// join - Join two live intervals (this, and other) together. This operation 254/// is the result of a copy instruction in the source program, that occurs at 255/// index 'CopyIdx' that copies from 'Other' to 'this'. 256void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) { 257 LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1); 258 LiveRange *DestLR = getLiveRangeContaining(CopyIdx); 259 assert(SourceLR && DestLR && "Not joining due to a copy?"); 260 unsigned MergedSrcValIdx = SourceLR->ValId; 261 unsigned MergedDstValIdx = DestLR->ValId; 262 263 // Try to do the least amount of work possible. In particular, if there are 264 // more liverange chunks in the other set than there are in the 'this' set, 265 // swap sets to merge the fewest chunks in possible. 266 if (Other.ranges.size() > ranges.size()) { 267 std::swap(MergedSrcValIdx, MergedDstValIdx); 268 std::swap(ranges, Other.ranges); 269 std::swap(NumValues, Other.NumValues); 270 } 271 272 // Join the ranges of other into the ranges of this interval. 273 Ranges::iterator InsertPos = ranges.begin(); 274 std::map<unsigned, unsigned> Dst2SrcIdxMap; 275 for (Ranges::iterator I = Other.ranges.begin(), 276 E = Other.ranges.end(); I != E; ++I) { 277 // Map the ValId in the other live range to the current live range. 278 if (I->ValId == MergedSrcValIdx) 279 I->ValId = MergedDstValIdx; 280 else { 281 unsigned &NV = Dst2SrcIdxMap[I->ValId]; 282 if (NV == 0) NV = getNextValue(); 283 I->ValId = NV; 284 } 285 286 InsertPos = addRangeFrom(*I, InsertPos); 287 } 288 289 weight += Other.weight; 290} 291 292std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) { 293 return os << '[' << LR.start << ',' << LR.end << ':' << LR.ValId << ")"; 294} 295 296void LiveRange::dump() const { 297 std::cerr << *this << "\n"; 298} 299 300 301std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li) { 302 os << "%reg" << li.reg << ',' << li.weight; 303 if (li.empty()) 304 return os << "EMPTY"; 305 306 os << " = "; 307 for (LiveInterval::Ranges::const_iterator i = li.ranges.begin(), 308 e = li.ranges.end(); i != e; ++i) 309 os << *i; 310 return os; 311} 312 313void LiveInterval::dump() const { 314 std::cerr << *this << "\n"; 315} 316