1 //===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // 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 range for register v if there is no instruction with number j' >= j 13 // such that v is live at j' and there is no instruction with number i' < i such 14 // that v is live at i'. In this implementation ranges can have holes, 15 // i.e. a range might look like [1,20), [50,65), [1000,1001). Each 16 // individual segment is represented as an instance of LiveRange::Segment, 17 // and the whole range is represented as an instance of LiveRange. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #ifndef LLVM_CODEGEN_LIVEINTERVAL_H 22 #define LLVM_CODEGEN_LIVEINTERVAL_H 23 24 #include "llvm/ADT/IntEqClasses.h" 25 #include "llvm/CodeGen/SlotIndexes.h" 26 #include "llvm/Support/AlignOf.h" 27 #include "llvm/Support/Allocator.h" 28 #include <cassert> 29 #include <climits> 30 31 namespace llvm { 32 class CoalescerPair; 33 class LiveIntervals; 34 class MachineInstr; 35 class MachineRegisterInfo; 36 class TargetRegisterInfo; 37 class raw_ostream; 38 template <typename T, unsigned Small> class SmallPtrSet; 39 40 /// VNInfo - Value Number Information. 41 /// This class holds information about a machine level values, including 42 /// definition and use points. 43 /// 44 class VNInfo { 45 public: 46 typedef BumpPtrAllocator Allocator; 47 48 /// The ID number of this value. 49 unsigned id; 50 51 /// The index of the defining instruction. 52 SlotIndex def; 53 54 /// VNInfo constructor. VNInfo(unsigned i,SlotIndex d)55 VNInfo(unsigned i, SlotIndex d) 56 : id(i), def(d) 57 { } 58 59 /// VNInfo construtor, copies values from orig, except for the value number. VNInfo(unsigned i,const VNInfo & orig)60 VNInfo(unsigned i, const VNInfo &orig) 61 : id(i), def(orig.def) 62 { } 63 64 /// Copy from the parameter into this VNInfo. copyFrom(VNInfo & src)65 void copyFrom(VNInfo &src) { 66 def = src.def; 67 } 68 69 /// Returns true if this value is defined by a PHI instruction (or was, 70 /// PHI instructions may have been eliminated). 71 /// PHI-defs begin at a block boundary, all other defs begin at register or 72 /// EC slots. isPHIDef()73 bool isPHIDef() const { return def.isBlock(); } 74 75 /// Returns true if this value is unused. isUnused()76 bool isUnused() const { return !def.isValid(); } 77 78 /// Mark this value as unused. markUnused()79 void markUnused() { def = SlotIndex(); } 80 }; 81 82 /// Result of a LiveRange query. This class hides the implementation details 83 /// of live ranges, and it should be used as the primary interface for 84 /// examining live ranges around instructions. 85 class LiveQueryResult { 86 VNInfo *const EarlyVal; 87 VNInfo *const LateVal; 88 const SlotIndex EndPoint; 89 const bool Kill; 90 91 public: LiveQueryResult(VNInfo * EarlyVal,VNInfo * LateVal,SlotIndex EndPoint,bool Kill)92 LiveQueryResult(VNInfo *EarlyVal, VNInfo *LateVal, SlotIndex EndPoint, 93 bool Kill) 94 : EarlyVal(EarlyVal), LateVal(LateVal), EndPoint(EndPoint), Kill(Kill) 95 {} 96 97 /// Return the value that is live-in to the instruction. This is the value 98 /// that will be read by the instruction's use operands. Return NULL if no 99 /// value is live-in. valueIn()100 VNInfo *valueIn() const { 101 return EarlyVal; 102 } 103 104 /// Return true if the live-in value is killed by this instruction. This 105 /// means that either the live range ends at the instruction, or it changes 106 /// value. isKill()107 bool isKill() const { 108 return Kill; 109 } 110 111 /// Return true if this instruction has a dead def. isDeadDef()112 bool isDeadDef() const { 113 return EndPoint.isDead(); 114 } 115 116 /// Return the value leaving the instruction, if any. This can be a 117 /// live-through value, or a live def. A dead def returns NULL. valueOut()118 VNInfo *valueOut() const { 119 return isDeadDef() ? nullptr : LateVal; 120 } 121 122 /// Return the value defined by this instruction, if any. This includes 123 /// dead defs, it is the value created by the instruction's def operands. valueDefined()124 VNInfo *valueDefined() const { 125 return EarlyVal == LateVal ? nullptr : LateVal; 126 } 127 128 /// Return the end point of the last live range segment to interact with 129 /// the instruction, if any. 130 /// 131 /// The end point is an invalid SlotIndex only if the live range doesn't 132 /// intersect the instruction at all. 133 /// 134 /// The end point may be at or past the end of the instruction's basic 135 /// block. That means the value was live out of the block. endPoint()136 SlotIndex endPoint() const { 137 return EndPoint; 138 } 139 }; 140 141 /// This class represents the liveness of a register, stack slot, etc. 142 /// It manages an ordered list of Segment objects. 143 /// The Segments are organized in a static single assignment form: At places 144 /// where a new value is defined or different values reach a CFG join a new 145 /// segment with a new value number is used. 146 class LiveRange { 147 public: 148 149 /// This represents a simple continuous liveness interval for a value. 150 /// The start point is inclusive, the end point exclusive. These intervals 151 /// are rendered as [start,end). 152 struct Segment { 153 SlotIndex start; // Start point of the interval (inclusive) 154 SlotIndex end; // End point of the interval (exclusive) 155 VNInfo *valno; // identifier for the value contained in this segment. 156 SegmentSegment157 Segment() : valno(nullptr) {} 158 SegmentSegment159 Segment(SlotIndex S, SlotIndex E, VNInfo *V) 160 : start(S), end(E), valno(V) { 161 assert(S < E && "Cannot create empty or backwards segment"); 162 } 163 164 /// Return true if the index is covered by this segment. containsSegment165 bool contains(SlotIndex I) const { 166 return start <= I && I < end; 167 } 168 169 /// Return true if the given interval, [S, E), is covered by this segment. containsIntervalSegment170 bool containsInterval(SlotIndex S, SlotIndex E) const { 171 assert((S < E) && "Backwards interval?"); 172 return (start <= S && S < end) && (start < E && E <= end); 173 } 174 175 bool operator<(const Segment &Other) const { 176 return std::tie(start, end) < std::tie(Other.start, Other.end); 177 } 178 bool operator==(const Segment &Other) const { 179 return start == Other.start && end == Other.end; 180 } 181 182 void dump() const; 183 }; 184 185 typedef SmallVector<Segment,4> Segments; 186 typedef SmallVector<VNInfo*,4> VNInfoList; 187 188 Segments segments; // the liveness segments 189 VNInfoList valnos; // value#'s 190 191 typedef Segments::iterator iterator; begin()192 iterator begin() { return segments.begin(); } end()193 iterator end() { return segments.end(); } 194 195 typedef Segments::const_iterator const_iterator; begin()196 const_iterator begin() const { return segments.begin(); } end()197 const_iterator end() const { return segments.end(); } 198 199 typedef VNInfoList::iterator vni_iterator; vni_begin()200 vni_iterator vni_begin() { return valnos.begin(); } vni_end()201 vni_iterator vni_end() { return valnos.end(); } 202 203 typedef VNInfoList::const_iterator const_vni_iterator; vni_begin()204 const_vni_iterator vni_begin() const { return valnos.begin(); } vni_end()205 const_vni_iterator vni_end() const { return valnos.end(); } 206 207 /// advanceTo - Advance the specified iterator to point to the Segment 208 /// containing the specified position, or end() if the position is past the 209 /// end of the range. If no Segment contains this position, but the 210 /// position is in a hole, this method returns an iterator pointing to the 211 /// Segment immediately after the hole. advanceTo(iterator I,SlotIndex Pos)212 iterator advanceTo(iterator I, SlotIndex Pos) { 213 assert(I != end()); 214 if (Pos >= endIndex()) 215 return end(); 216 while (I->end <= Pos) ++I; 217 return I; 218 } 219 220 /// find - Return an iterator pointing to the first segment that ends after 221 /// Pos, or end(). This is the same as advanceTo(begin(), Pos), but faster 222 /// when searching large ranges. 223 /// 224 /// If Pos is contained in a Segment, that segment is returned. 225 /// If Pos is in a hole, the following Segment is returned. 226 /// If Pos is beyond endIndex, end() is returned. 227 iterator find(SlotIndex Pos); 228 find(SlotIndex Pos)229 const_iterator find(SlotIndex Pos) const { 230 return const_cast<LiveRange*>(this)->find(Pos); 231 } 232 clear()233 void clear() { 234 valnos.clear(); 235 segments.clear(); 236 } 237 size()238 size_t size() const { 239 return segments.size(); 240 } 241 hasAtLeastOneValue()242 bool hasAtLeastOneValue() const { return !valnos.empty(); } 243 containsOneValue()244 bool containsOneValue() const { return valnos.size() == 1; } 245 getNumValNums()246 unsigned getNumValNums() const { return (unsigned)valnos.size(); } 247 248 /// getValNumInfo - Returns pointer to the specified val#. 249 /// getValNumInfo(unsigned ValNo)250 inline VNInfo *getValNumInfo(unsigned ValNo) { 251 return valnos[ValNo]; 252 } getValNumInfo(unsigned ValNo)253 inline const VNInfo *getValNumInfo(unsigned ValNo) const { 254 return valnos[ValNo]; 255 } 256 257 /// containsValue - Returns true if VNI belongs to this range. containsValue(const VNInfo * VNI)258 bool containsValue(const VNInfo *VNI) const { 259 return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id); 260 } 261 262 /// getNextValue - Create a new value number and return it. MIIdx specifies 263 /// the instruction that defines the value number. getNextValue(SlotIndex def,VNInfo::Allocator & VNInfoAllocator)264 VNInfo *getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator) { 265 VNInfo *VNI = 266 new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def); 267 valnos.push_back(VNI); 268 return VNI; 269 } 270 271 /// createDeadDef - Make sure the range has a value defined at Def. 272 /// If one already exists, return it. Otherwise allocate a new value and 273 /// add liveness for a dead def. 274 VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator); 275 276 /// Create a copy of the given value. The new value will be identical except 277 /// for the Value number. createValueCopy(const VNInfo * orig,VNInfo::Allocator & VNInfoAllocator)278 VNInfo *createValueCopy(const VNInfo *orig, 279 VNInfo::Allocator &VNInfoAllocator) { 280 VNInfo *VNI = 281 new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig); 282 valnos.push_back(VNI); 283 return VNI; 284 } 285 286 /// RenumberValues - Renumber all values in order of appearance and remove 287 /// unused values. 288 void RenumberValues(); 289 290 /// MergeValueNumberInto - This method is called when two value numbers 291 /// are found to be equivalent. This eliminates V1, replacing all 292 /// segments with the V1 value number with the V2 value number. This can 293 /// cause merging of V1/V2 values numbers and compaction of the value space. 294 VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2); 295 296 /// Merge all of the live segments of a specific val# in RHS into this live 297 /// range as the specified value number. The segments in RHS are allowed 298 /// to overlap with segments in the current range, it will replace the 299 /// value numbers of the overlaped live segments with the specified value 300 /// number. 301 void MergeSegmentsInAsValue(const LiveRange &RHS, VNInfo *LHSValNo); 302 303 /// MergeValueInAsValue - Merge all of the segments of a specific val# 304 /// in RHS into this live range as the specified value number. 305 /// The segments in RHS are allowed to overlap with segments in the 306 /// current range, but only if the overlapping segments have the 307 /// specified value number. 308 void MergeValueInAsValue(const LiveRange &RHS, 309 const VNInfo *RHSValNo, VNInfo *LHSValNo); 310 empty()311 bool empty() const { return segments.empty(); } 312 313 /// beginIndex - Return the lowest numbered slot covered. beginIndex()314 SlotIndex beginIndex() const { 315 assert(!empty() && "Call to beginIndex() on empty range."); 316 return segments.front().start; 317 } 318 319 /// endNumber - return the maximum point of the range of the whole, 320 /// exclusive. endIndex()321 SlotIndex endIndex() const { 322 assert(!empty() && "Call to endIndex() on empty range."); 323 return segments.back().end; 324 } 325 expiredAt(SlotIndex index)326 bool expiredAt(SlotIndex index) const { 327 return index >= endIndex(); 328 } 329 liveAt(SlotIndex index)330 bool liveAt(SlotIndex index) const { 331 const_iterator r = find(index); 332 return r != end() && r->start <= index; 333 } 334 335 /// Return the segment that contains the specified index, or null if there 336 /// is none. getSegmentContaining(SlotIndex Idx)337 const Segment *getSegmentContaining(SlotIndex Idx) const { 338 const_iterator I = FindSegmentContaining(Idx); 339 return I == end() ? nullptr : &*I; 340 } 341 342 /// Return the live segment that contains the specified index, or null if 343 /// there is none. getSegmentContaining(SlotIndex Idx)344 Segment *getSegmentContaining(SlotIndex Idx) { 345 iterator I = FindSegmentContaining(Idx); 346 return I == end() ? nullptr : &*I; 347 } 348 349 /// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL. getVNInfoAt(SlotIndex Idx)350 VNInfo *getVNInfoAt(SlotIndex Idx) const { 351 const_iterator I = FindSegmentContaining(Idx); 352 return I == end() ? nullptr : I->valno; 353 } 354 355 /// getVNInfoBefore - Return the VNInfo that is live up to but not 356 /// necessarilly including Idx, or NULL. Use this to find the reaching def 357 /// used by an instruction at this SlotIndex position. getVNInfoBefore(SlotIndex Idx)358 VNInfo *getVNInfoBefore(SlotIndex Idx) const { 359 const_iterator I = FindSegmentContaining(Idx.getPrevSlot()); 360 return I == end() ? nullptr : I->valno; 361 } 362 363 /// Return an iterator to the segment that contains the specified index, or 364 /// end() if there is none. FindSegmentContaining(SlotIndex Idx)365 iterator FindSegmentContaining(SlotIndex Idx) { 366 iterator I = find(Idx); 367 return I != end() && I->start <= Idx ? I : end(); 368 } 369 FindSegmentContaining(SlotIndex Idx)370 const_iterator FindSegmentContaining(SlotIndex Idx) const { 371 const_iterator I = find(Idx); 372 return I != end() && I->start <= Idx ? I : end(); 373 } 374 375 /// overlaps - Return true if the intersection of the two live ranges is 376 /// not empty. overlaps(const LiveRange & other)377 bool overlaps(const LiveRange &other) const { 378 if (other.empty()) 379 return false; 380 return overlapsFrom(other, other.begin()); 381 } 382 383 /// overlaps - Return true if the two ranges have overlapping segments 384 /// that are not coalescable according to CP. 385 /// 386 /// Overlapping segments where one range is defined by a coalescable 387 /// copy are allowed. 388 bool overlaps(const LiveRange &Other, const CoalescerPair &CP, 389 const SlotIndexes&) const; 390 391 /// overlaps - Return true if the live range overlaps an interval specified 392 /// by [Start, End). 393 bool overlaps(SlotIndex Start, SlotIndex End) const; 394 395 /// overlapsFrom - Return true if the intersection of the two live ranges 396 /// is not empty. The specified iterator is a hint that we can begin 397 /// scanning the Other range starting at I. 398 bool overlapsFrom(const LiveRange &Other, const_iterator I) const; 399 400 /// Add the specified Segment to this range, merging segments as 401 /// appropriate. This returns an iterator to the inserted segment (which 402 /// may have grown since it was inserted). addSegment(Segment S)403 iterator addSegment(Segment S) { 404 return addSegmentFrom(S, segments.begin()); 405 } 406 407 /// extendInBlock - If this range is live before Kill in the basic block 408 /// that starts at StartIdx, extend it to be live up to Kill, and return 409 /// the value. If there is no segment before Kill, return NULL. 410 VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); 411 412 /// join - Join two live ranges (this, and other) together. This applies 413 /// mappings to the value numbers in the LHS/RHS ranges as specified. If 414 /// the ranges are not joinable, this aborts. 415 void join(LiveRange &Other, 416 const int *ValNoAssignments, 417 const int *RHSValNoAssignments, 418 SmallVectorImpl<VNInfo *> &NewVNInfo); 419 420 /// True iff this segment is a single segment that lies between the 421 /// specified boundaries, exclusively. Vregs live across a backedge are not 422 /// considered local. The boundaries are expected to lie within an extended 423 /// basic block, so vregs that are not live out should contain no holes. isLocal(SlotIndex Start,SlotIndex End)424 bool isLocal(SlotIndex Start, SlotIndex End) const { 425 return beginIndex() > Start.getBaseIndex() && 426 endIndex() < End.getBoundaryIndex(); 427 } 428 429 /// Remove the specified segment from this range. Note that the segment 430 /// must be a single Segment in its entirety. 431 void removeSegment(SlotIndex Start, SlotIndex End, 432 bool RemoveDeadValNo = false); 433 434 void removeSegment(Segment S, bool RemoveDeadValNo = false) { 435 removeSegment(S.start, S.end, RemoveDeadValNo); 436 } 437 438 /// Query Liveness at Idx. 439 /// The sub-instruction slot of Idx doesn't matter, only the instruction 440 /// it refers to is considered. Query(SlotIndex Idx)441 LiveQueryResult Query(SlotIndex Idx) const { 442 // Find the segment that enters the instruction. 443 const_iterator I = find(Idx.getBaseIndex()); 444 const_iterator E = end(); 445 if (I == E) 446 return LiveQueryResult(nullptr, nullptr, SlotIndex(), false); 447 448 // Is this an instruction live-in segment? 449 // If Idx is the start index of a basic block, include live-in segments 450 // that start at Idx.getBaseIndex(). 451 VNInfo *EarlyVal = nullptr; 452 VNInfo *LateVal = nullptr; 453 SlotIndex EndPoint; 454 bool Kill = false; 455 if (I->start <= Idx.getBaseIndex()) { 456 EarlyVal = I->valno; 457 EndPoint = I->end; 458 // Move to the potentially live-out segment. 459 if (SlotIndex::isSameInstr(Idx, I->end)) { 460 Kill = true; 461 if (++I == E) 462 return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill); 463 } 464 // Special case: A PHIDef value can have its def in the middle of a 465 // segment if the value happens to be live out of the layout 466 // predecessor. 467 // Such a value is not live-in. 468 if (EarlyVal->def == Idx.getBaseIndex()) 469 EarlyVal = nullptr; 470 } 471 // I now points to the segment that may be live-through, or defined by 472 // this instr. Ignore segments starting after the current instr. 473 if (!SlotIndex::isEarlierInstr(Idx, I->start)) { 474 LateVal = I->valno; 475 EndPoint = I->end; 476 } 477 return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill); 478 } 479 480 /// removeValNo - Remove all the segments defined by the specified value#. 481 /// Also remove the value# from value# list. 482 void removeValNo(VNInfo *ValNo); 483 484 /// Returns true if the live range is zero length, i.e. no live segments 485 /// span instructions. It doesn't pay to spill such a range. isZeroLength(SlotIndexes * Indexes)486 bool isZeroLength(SlotIndexes *Indexes) const { 487 for (const_iterator i = begin(), e = end(); i != e; ++i) 488 if (Indexes->getNextNonNullIndex(i->start).getBaseIndex() < 489 i->end.getBaseIndex()) 490 return false; 491 return true; 492 } 493 494 bool operator<(const LiveRange& other) const { 495 const SlotIndex &thisIndex = beginIndex(); 496 const SlotIndex &otherIndex = other.beginIndex(); 497 return thisIndex < otherIndex; 498 } 499 500 void print(raw_ostream &OS) const; 501 void dump() const; 502 503 /// \brief Walk the range and assert if any invariants fail to hold. 504 /// 505 /// Note that this is a no-op when asserts are disabled. 506 #ifdef NDEBUG verify()507 void verify() const {} 508 #else 509 void verify() const; 510 #endif 511 512 private: 513 514 iterator addSegmentFrom(Segment S, iterator From); 515 void extendSegmentEndTo(iterator I, SlotIndex NewEnd); 516 iterator extendSegmentStartTo(iterator I, SlotIndex NewStr); 517 void markValNoForDeletion(VNInfo *V); 518 519 }; 520 521 inline raw_ostream &operator<<(raw_ostream &OS, const LiveRange &LR) { 522 LR.print(OS); 523 return OS; 524 } 525 526 /// LiveInterval - This class represents the liveness of a register, 527 /// or stack slot. 528 class LiveInterval : public LiveRange { 529 public: 530 typedef LiveRange super; 531 532 const unsigned reg; // the register or stack slot of this interval. 533 float weight; // weight of this interval 534 LiveInterval(unsigned Reg,float Weight)535 LiveInterval(unsigned Reg, float Weight) 536 : reg(Reg), weight(Weight) {} 537 538 /// getSize - Returns the sum of sizes of all the LiveRange's. 539 /// 540 unsigned getSize() const; 541 542 /// isSpillable - Can this interval be spilled? isSpillable()543 bool isSpillable() const { 544 return weight != llvm::huge_valf; 545 } 546 547 /// markNotSpillable - Mark interval as not spillable markNotSpillable()548 void markNotSpillable() { 549 weight = llvm::huge_valf; 550 } 551 552 bool operator<(const LiveInterval& other) const { 553 const SlotIndex &thisIndex = beginIndex(); 554 const SlotIndex &otherIndex = other.beginIndex(); 555 return std::tie(thisIndex, reg) < std::tie(otherIndex, other.reg); 556 } 557 558 void print(raw_ostream &OS) const; 559 void dump() const; 560 561 private: 562 LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION; 563 564 }; 565 566 inline raw_ostream &operator<<(raw_ostream &OS, const LiveInterval &LI) { 567 LI.print(OS); 568 return OS; 569 } 570 571 raw_ostream &operator<<(raw_ostream &OS, const LiveRange::Segment &S); 572 573 inline bool operator<(SlotIndex V, const LiveRange::Segment &S) { 574 return V < S.start; 575 } 576 577 inline bool operator<(const LiveRange::Segment &S, SlotIndex V) { 578 return S.start < V; 579 } 580 581 /// Helper class for performant LiveRange bulk updates. 582 /// 583 /// Calling LiveRange::addSegment() repeatedly can be expensive on large 584 /// live ranges because segments after the insertion point may need to be 585 /// shifted. The LiveRangeUpdater class can defer the shifting when adding 586 /// many segments in order. 587 /// 588 /// The LiveRange will be in an invalid state until flush() is called. 589 class LiveRangeUpdater { 590 LiveRange *LR; 591 SlotIndex LastStart; 592 LiveRange::iterator WriteI; 593 LiveRange::iterator ReadI; 594 SmallVector<LiveRange::Segment, 16> Spills; 595 void mergeSpills(); 596 597 public: 598 /// Create a LiveRangeUpdater for adding segments to LR. 599 /// LR will temporarily be in an invalid state until flush() is called. LR(lr)600 LiveRangeUpdater(LiveRange *lr = nullptr) : LR(lr) {} 601 ~LiveRangeUpdater()602 ~LiveRangeUpdater() { flush(); } 603 604 /// Add a segment to LR and coalesce when possible, just like 605 /// LR.addSegment(). Segments should be added in increasing start order for 606 /// best performance. 607 void add(LiveRange::Segment); 608 add(SlotIndex Start,SlotIndex End,VNInfo * VNI)609 void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) { 610 add(LiveRange::Segment(Start, End, VNI)); 611 } 612 613 /// Return true if the LR is currently in an invalid state, and flush() 614 /// needs to be called. isDirty()615 bool isDirty() const { return LastStart.isValid(); } 616 617 /// Flush the updater state to LR so it is valid and contains all added 618 /// segments. 619 void flush(); 620 621 /// Select a different destination live range. setDest(LiveRange * lr)622 void setDest(LiveRange *lr) { 623 if (LR != lr && isDirty()) 624 flush(); 625 LR = lr; 626 } 627 628 /// Get the current destination live range. getDest()629 LiveRange *getDest() const { return LR; } 630 631 void dump() const; 632 void print(raw_ostream&) const; 633 }; 634 635 inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) { 636 X.print(OS); 637 return OS; 638 } 639 640 /// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a 641 /// LiveInterval into equivalence clases of connected components. A 642 /// LiveInterval that has multiple connected components can be broken into 643 /// multiple LiveIntervals. 644 /// 645 /// Given a LiveInterval that may have multiple connected components, run: 646 /// 647 /// unsigned numComps = ConEQ.Classify(LI); 648 /// if (numComps > 1) { 649 /// // allocate numComps-1 new LiveIntervals into LIS[1..] 650 /// ConEQ.Distribute(LIS); 651 /// } 652 653 class ConnectedVNInfoEqClasses { 654 LiveIntervals &LIS; 655 IntEqClasses EqClass; 656 657 // Note that values a and b are connected. 658 void Connect(unsigned a, unsigned b); 659 660 unsigned Renumber(); 661 662 public: ConnectedVNInfoEqClasses(LiveIntervals & lis)663 explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} 664 665 /// Classify - Classify the values in LI into connected components. 666 /// Return the number of connected components. 667 unsigned Classify(const LiveInterval *LI); 668 669 /// getEqClass - Classify creates equivalence classes numbered 0..N. Return 670 /// the equivalence class assigned the VNI. getEqClass(const VNInfo * VNI)671 unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } 672 673 /// Distribute - Distribute values in LIV[0] into a separate LiveInterval 674 /// for each connected component. LIV must have a LiveInterval for each 675 /// connected component. The LiveIntervals in Liv[1..] must be empty. 676 /// Instructions using LIV[0] are rewritten. 677 void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); 678 679 }; 680 681 } 682 #endif 683