10b57cec5SDimitry Andric //===- LiveInterval.cpp - Live Interval Representation --------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the LiveRange and LiveInterval classes. Given some 100b57cec5SDimitry Andric // numbering of each the machine instructions an interval [i, j) is said to be a 110b57cec5SDimitry Andric // live range for register v if there is no instruction with number j' >= j 120b57cec5SDimitry Andric // such that v is live at j' and there is no instruction with number i' < i such 130b57cec5SDimitry Andric // that v is live at i'. In this implementation ranges can have holes, 140b57cec5SDimitry Andric // i.e. a range might look like [1,20), [50,65), [1000,1001). Each 150b57cec5SDimitry Andric // individual segment is represented as an instance of LiveRange::Segment, 160b57cec5SDimitry Andric // and the whole range is represented as an instance of LiveRange. 170b57cec5SDimitry Andric // 180b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h" 210b57cec5SDimitry Andric #include "LiveRangeUtils.h" 220b57cec5SDimitry Andric #include "RegisterCoalescer.h" 230b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 240b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 250b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 260b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 270b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 350b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 360b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h" 370b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 380b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 390b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 400b57cec5SDimitry Andric #include <algorithm> 410b57cec5SDimitry Andric #include <cassert> 420b57cec5SDimitry Andric #include <cstddef> 430b57cec5SDimitry Andric #include <iterator> 440b57cec5SDimitry Andric #include <utility> 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric using namespace llvm; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric namespace { 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 510b57cec5SDimitry Andric // Implementation of various methods necessary for calculation of live ranges. 520b57cec5SDimitry Andric // The implementation of the methods abstracts from the concrete type of the 530b57cec5SDimitry Andric // segment collection. 540b57cec5SDimitry Andric // 550b57cec5SDimitry Andric // Implementation of the class follows the Template design pattern. The base 560b57cec5SDimitry Andric // class contains generic algorithms that call collection-specific methods, 570b57cec5SDimitry Andric // which are provided in concrete subclasses. In order to avoid virtual calls 580b57cec5SDimitry Andric // these methods are provided by means of C++ template instantiation. 590b57cec5SDimitry Andric // The base class calls the methods of the subclass through method impl(), 600b57cec5SDimitry Andric // which casts 'this' pointer to the type of the subclass. 610b57cec5SDimitry Andric // 620b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric template <typename ImplT, typename IteratorT, typename CollectionT> 650b57cec5SDimitry Andric class CalcLiveRangeUtilBase { 660b57cec5SDimitry Andric protected: 670b57cec5SDimitry Andric LiveRange *LR; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric protected: 700b57cec5SDimitry Andric CalcLiveRangeUtilBase(LiveRange *LR) : LR(LR) {} 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric public: 730b57cec5SDimitry Andric using Segment = LiveRange::Segment; 740b57cec5SDimitry Andric using iterator = IteratorT; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// A counterpart of LiveRange::createDeadDef: Make sure the range has a 770b57cec5SDimitry Andric /// value defined at @p Def. 780b57cec5SDimitry Andric /// If @p ForVNI is null, and there is no value defined at @p Def, a new 790b57cec5SDimitry Andric /// value will be allocated using @p VNInfoAllocator. 800b57cec5SDimitry Andric /// If @p ForVNI is null, the return value is the value defined at @p Def, 810b57cec5SDimitry Andric /// either a pre-existing one, or the one newly created. 820b57cec5SDimitry Andric /// If @p ForVNI is not null, then @p Def should be the location where 830b57cec5SDimitry Andric /// @p ForVNI is defined. If the range does not have a value defined at 840b57cec5SDimitry Andric /// @p Def, the value @p ForVNI will be used instead of allocating a new 850b57cec5SDimitry Andric /// one. If the range already has a value defined at @p Def, it must be 860b57cec5SDimitry Andric /// same as @p ForVNI. In either case, @p ForVNI will be the return value. 870b57cec5SDimitry Andric VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator *VNInfoAllocator, 880b57cec5SDimitry Andric VNInfo *ForVNI) { 890b57cec5SDimitry Andric assert(!Def.isDead() && "Cannot define a value at the dead slot"); 900b57cec5SDimitry Andric assert((!ForVNI || ForVNI->def == Def) && 910b57cec5SDimitry Andric "If ForVNI is specified, it must match Def"); 920b57cec5SDimitry Andric iterator I = impl().find(Def); 930b57cec5SDimitry Andric if (I == segments().end()) { 940b57cec5SDimitry Andric VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator); 950b57cec5SDimitry Andric impl().insertAtEnd(Segment(Def, Def.getDeadSlot(), VNI)); 960b57cec5SDimitry Andric return VNI; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric Segment *S = segmentAt(I); 1000b57cec5SDimitry Andric if (SlotIndex::isSameInstr(Def, S->start)) { 1010b57cec5SDimitry Andric assert((!ForVNI || ForVNI == S->valno) && "Value number mismatch"); 1020b57cec5SDimitry Andric assert(S->valno->def == S->start && "Inconsistent existing value def"); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // It is possible to have both normal and early-clobber defs of the same 1050b57cec5SDimitry Andric // register on an instruction. It doesn't make a lot of sense, but it is 1060b57cec5SDimitry Andric // possible to specify in inline assembly. 1070b57cec5SDimitry Andric // 1080b57cec5SDimitry Andric // Just convert everything to early-clobber. 1090b57cec5SDimitry Andric Def = std::min(Def, S->start); 1100b57cec5SDimitry Andric if (Def != S->start) 1110b57cec5SDimitry Andric S->start = S->valno->def = Def; 1120b57cec5SDimitry Andric return S->valno; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric assert(SlotIndex::isEarlierInstr(Def, S->start) && "Already live at def"); 1150b57cec5SDimitry Andric VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator); 1160b57cec5SDimitry Andric segments().insert(I, Segment(Def, Def.getDeadSlot(), VNI)); 1170b57cec5SDimitry Andric return VNI; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Use) { 1210b57cec5SDimitry Andric if (segments().empty()) 1220b57cec5SDimitry Andric return nullptr; 1230b57cec5SDimitry Andric iterator I = 1240b57cec5SDimitry Andric impl().findInsertPos(Segment(Use.getPrevSlot(), Use, nullptr)); 1250b57cec5SDimitry Andric if (I == segments().begin()) 1260b57cec5SDimitry Andric return nullptr; 1270b57cec5SDimitry Andric --I; 1280b57cec5SDimitry Andric if (I->end <= StartIdx) 1290b57cec5SDimitry Andric return nullptr; 1300b57cec5SDimitry Andric if (I->end < Use) 1310b57cec5SDimitry Andric extendSegmentEndTo(I, Use); 1320b57cec5SDimitry Andric return I->valno; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric std::pair<VNInfo*,bool> extendInBlock(ArrayRef<SlotIndex> Undefs, 1360b57cec5SDimitry Andric SlotIndex StartIdx, SlotIndex Use) { 1370b57cec5SDimitry Andric if (segments().empty()) 1380b57cec5SDimitry Andric return std::make_pair(nullptr, false); 1390b57cec5SDimitry Andric SlotIndex BeforeUse = Use.getPrevSlot(); 1400b57cec5SDimitry Andric iterator I = impl().findInsertPos(Segment(BeforeUse, Use, nullptr)); 1410b57cec5SDimitry Andric if (I == segments().begin()) 1420b57cec5SDimitry Andric return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse)); 1430b57cec5SDimitry Andric --I; 1440b57cec5SDimitry Andric if (I->end <= StartIdx) 1450b57cec5SDimitry Andric return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse)); 1460b57cec5SDimitry Andric if (I->end < Use) { 1470b57cec5SDimitry Andric if (LR->isUndefIn(Undefs, I->end, BeforeUse)) 1480b57cec5SDimitry Andric return std::make_pair(nullptr, true); 1490b57cec5SDimitry Andric extendSegmentEndTo(I, Use); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric return std::make_pair(I->valno, false); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric /// This method is used when we want to extend the segment specified 1550b57cec5SDimitry Andric /// by I to end at the specified endpoint. To do this, we should 1560b57cec5SDimitry Andric /// merge and eliminate all segments that this will overlap 1570b57cec5SDimitry Andric /// with. The iterator is not invalidated. 1580b57cec5SDimitry Andric void extendSegmentEndTo(iterator I, SlotIndex NewEnd) { 1590b57cec5SDimitry Andric assert(I != segments().end() && "Not a valid segment!"); 1600b57cec5SDimitry Andric Segment *S = segmentAt(I); 1610b57cec5SDimitry Andric VNInfo *ValNo = I->valno; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric // Search for the first segment that we can't merge with. 1640b57cec5SDimitry Andric iterator MergeTo = std::next(I); 1650b57cec5SDimitry Andric for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo) 1660b57cec5SDimitry Andric assert(MergeTo->valno == ValNo && "Cannot merge with differing values!"); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // If NewEnd was in the middle of a segment, make sure to get its endpoint. 1690b57cec5SDimitry Andric S->end = std::max(NewEnd, std::prev(MergeTo)->end); 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric // If the newly formed segment now touches the segment after it and if they 1720b57cec5SDimitry Andric // have the same value number, merge the two segments into one segment. 1730b57cec5SDimitry Andric if (MergeTo != segments().end() && MergeTo->start <= I->end && 1740b57cec5SDimitry Andric MergeTo->valno == ValNo) { 1750b57cec5SDimitry Andric S->end = MergeTo->end; 1760b57cec5SDimitry Andric ++MergeTo; 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric // Erase any dead segments. 1800b57cec5SDimitry Andric segments().erase(std::next(I), MergeTo); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric /// This method is used when we want to extend the segment specified 1840b57cec5SDimitry Andric /// by I to start at the specified endpoint. To do this, we should 1850b57cec5SDimitry Andric /// merge and eliminate all segments that this will overlap with. 1860b57cec5SDimitry Andric iterator extendSegmentStartTo(iterator I, SlotIndex NewStart) { 1870b57cec5SDimitry Andric assert(I != segments().end() && "Not a valid segment!"); 1880b57cec5SDimitry Andric Segment *S = segmentAt(I); 1890b57cec5SDimitry Andric VNInfo *ValNo = I->valno; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric // Search for the first segment that we can't merge with. 1920b57cec5SDimitry Andric iterator MergeTo = I; 1930b57cec5SDimitry Andric do { 1940b57cec5SDimitry Andric if (MergeTo == segments().begin()) { 1950b57cec5SDimitry Andric S->start = NewStart; 1960b57cec5SDimitry Andric segments().erase(MergeTo, I); 1970b57cec5SDimitry Andric return I; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric assert(MergeTo->valno == ValNo && "Cannot merge with differing values!"); 2000b57cec5SDimitry Andric --MergeTo; 2010b57cec5SDimitry Andric } while (NewStart <= MergeTo->start); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric // If we start in the middle of another segment, just delete a range and 2040b57cec5SDimitry Andric // extend that segment. 2050b57cec5SDimitry Andric if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) { 2060b57cec5SDimitry Andric segmentAt(MergeTo)->end = S->end; 2070b57cec5SDimitry Andric } else { 2080b57cec5SDimitry Andric // Otherwise, extend the segment right after. 2090b57cec5SDimitry Andric ++MergeTo; 2100b57cec5SDimitry Andric Segment *MergeToSeg = segmentAt(MergeTo); 2110b57cec5SDimitry Andric MergeToSeg->start = NewStart; 2120b57cec5SDimitry Andric MergeToSeg->end = S->end; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric segments().erase(std::next(MergeTo), std::next(I)); 2160b57cec5SDimitry Andric return MergeTo; 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric iterator addSegment(Segment S) { 2200b57cec5SDimitry Andric SlotIndex Start = S.start, End = S.end; 2210b57cec5SDimitry Andric iterator I = impl().findInsertPos(S); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // If the inserted segment starts in the middle or right at the end of 2240b57cec5SDimitry Andric // another segment, just extend that segment to contain the segment of S. 2250b57cec5SDimitry Andric if (I != segments().begin()) { 2260b57cec5SDimitry Andric iterator B = std::prev(I); 2270b57cec5SDimitry Andric if (S.valno == B->valno) { 2280b57cec5SDimitry Andric if (B->start <= Start && B->end >= Start) { 2290b57cec5SDimitry Andric extendSegmentEndTo(B, End); 2300b57cec5SDimitry Andric return B; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric } else { 2330b57cec5SDimitry Andric // Check to make sure that we are not overlapping two live segments with 2340b57cec5SDimitry Andric // different valno's. 2350b57cec5SDimitry Andric assert(B->end <= Start && 2360b57cec5SDimitry Andric "Cannot overlap two segments with differing ValID's" 2370b57cec5SDimitry Andric " (did you def the same reg twice in a MachineInstr?)"); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric // Otherwise, if this segment ends in the middle of, or right next 2420b57cec5SDimitry Andric // to, another segment, merge it into that segment. 2430b57cec5SDimitry Andric if (I != segments().end()) { 2440b57cec5SDimitry Andric if (S.valno == I->valno) { 2450b57cec5SDimitry Andric if (I->start <= End) { 2460b57cec5SDimitry Andric I = extendSegmentStartTo(I, Start); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // If S is a complete superset of a segment, we may need to grow its 2490b57cec5SDimitry Andric // endpoint as well. 2500b57cec5SDimitry Andric if (End > I->end) 2510b57cec5SDimitry Andric extendSegmentEndTo(I, End); 2520b57cec5SDimitry Andric return I; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric } else { 2550b57cec5SDimitry Andric // Check to make sure that we are not overlapping two live segments with 2560b57cec5SDimitry Andric // different valno's. 2570b57cec5SDimitry Andric assert(I->start >= End && 2580b57cec5SDimitry Andric "Cannot overlap two segments with differing ValID's"); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric // Otherwise, this is just a new segment that doesn't interact with 2630b57cec5SDimitry Andric // anything. 2640b57cec5SDimitry Andric // Insert it. 2650b57cec5SDimitry Andric return segments().insert(I, S); 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric private: 2690b57cec5SDimitry Andric ImplT &impl() { return *static_cast<ImplT *>(this); } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric CollectionT &segments() { return impl().segmentsColl(); } 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric Segment *segmentAt(iterator I) { return const_cast<Segment *>(&(*I)); } 2740b57cec5SDimitry Andric }; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2770b57cec5SDimitry Andric // Instantiation of the methods for calculation of live ranges 2780b57cec5SDimitry Andric // based on a segment vector. 2790b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric class CalcLiveRangeUtilVector; 2820b57cec5SDimitry Andric using CalcLiveRangeUtilVectorBase = 2830b57cec5SDimitry Andric CalcLiveRangeUtilBase<CalcLiveRangeUtilVector, LiveRange::iterator, 2840b57cec5SDimitry Andric LiveRange::Segments>; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric class CalcLiveRangeUtilVector : public CalcLiveRangeUtilVectorBase { 2870b57cec5SDimitry Andric public: 2880b57cec5SDimitry Andric CalcLiveRangeUtilVector(LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {} 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric private: 2910b57cec5SDimitry Andric friend CalcLiveRangeUtilVectorBase; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric LiveRange::Segments &segmentsColl() { return LR->segments; } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void insertAtEnd(const Segment &S) { LR->segments.push_back(S); } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric iterator find(SlotIndex Pos) { return LR->find(Pos); } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric iterator findInsertPos(Segment S) { return llvm::upper_bound(*LR, S.start); } 3000b57cec5SDimitry Andric }; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3030b57cec5SDimitry Andric // Instantiation of the methods for calculation of live ranges 3040b57cec5SDimitry Andric // based on a segment set. 3050b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric class CalcLiveRangeUtilSet; 3080b57cec5SDimitry Andric using CalcLiveRangeUtilSetBase = 3090b57cec5SDimitry Andric CalcLiveRangeUtilBase<CalcLiveRangeUtilSet, LiveRange::SegmentSet::iterator, 3100b57cec5SDimitry Andric LiveRange::SegmentSet>; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric class CalcLiveRangeUtilSet : public CalcLiveRangeUtilSetBase { 3130b57cec5SDimitry Andric public: 3140b57cec5SDimitry Andric CalcLiveRangeUtilSet(LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {} 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric private: 3170b57cec5SDimitry Andric friend CalcLiveRangeUtilSetBase; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric LiveRange::SegmentSet &segmentsColl() { return *LR->segmentSet; } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric void insertAtEnd(const Segment &S) { 3220b57cec5SDimitry Andric LR->segmentSet->insert(LR->segmentSet->end(), S); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric iterator find(SlotIndex Pos) { 3260b57cec5SDimitry Andric iterator I = 3270b57cec5SDimitry Andric LR->segmentSet->upper_bound(Segment(Pos, Pos.getNextSlot(), nullptr)); 3280b57cec5SDimitry Andric if (I == LR->segmentSet->begin()) 3290b57cec5SDimitry Andric return I; 3300b57cec5SDimitry Andric iterator PrevI = std::prev(I); 3310b57cec5SDimitry Andric if (Pos < (*PrevI).end) 3320b57cec5SDimitry Andric return PrevI; 3330b57cec5SDimitry Andric return I; 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric iterator findInsertPos(Segment S) { 3370b57cec5SDimitry Andric iterator I = LR->segmentSet->upper_bound(S); 3380b57cec5SDimitry Andric if (I != LR->segmentSet->end() && !(S.start < *I)) 3390b57cec5SDimitry Andric ++I; 3400b57cec5SDimitry Andric return I; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric }; 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric } // end anonymous namespace 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3470b57cec5SDimitry Andric // LiveRange methods 3480b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric LiveRange::iterator LiveRange::find(SlotIndex Pos) { 35181ad6265SDimitry Andric return llvm::partition_point(*this, 35281ad6265SDimitry Andric [&](const Segment &X) { return X.end <= Pos; }); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric VNInfo *LiveRange::createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc) { 3560b57cec5SDimitry Andric // Use the segment set, if it is available. 3570b57cec5SDimitry Andric if (segmentSet != nullptr) 3580b57cec5SDimitry Andric return CalcLiveRangeUtilSet(this).createDeadDef(Def, &VNIAlloc, nullptr); 3590b57cec5SDimitry Andric // Otherwise use the segment vector. 3600b57cec5SDimitry Andric return CalcLiveRangeUtilVector(this).createDeadDef(Def, &VNIAlloc, nullptr); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric VNInfo *LiveRange::createDeadDef(VNInfo *VNI) { 3640b57cec5SDimitry Andric // Use the segment set, if it is available. 3650b57cec5SDimitry Andric if (segmentSet != nullptr) 3660b57cec5SDimitry Andric return CalcLiveRangeUtilSet(this).createDeadDef(VNI->def, nullptr, VNI); 3670b57cec5SDimitry Andric // Otherwise use the segment vector. 3680b57cec5SDimitry Andric return CalcLiveRangeUtilVector(this).createDeadDef(VNI->def, nullptr, VNI); 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric // overlaps - Return true if the intersection of the two live ranges is 3720b57cec5SDimitry Andric // not empty. 3730b57cec5SDimitry Andric // 3740b57cec5SDimitry Andric // An example for overlaps(): 3750b57cec5SDimitry Andric // 3760b57cec5SDimitry Andric // 0: A = ... 3770b57cec5SDimitry Andric // 4: B = ... 3780b57cec5SDimitry Andric // 8: C = A + B ;; last use of A 3790b57cec5SDimitry Andric // 3800b57cec5SDimitry Andric // The live ranges should look like: 3810b57cec5SDimitry Andric // 3820b57cec5SDimitry Andric // A = [3, 11) 3830b57cec5SDimitry Andric // B = [7, x) 3840b57cec5SDimitry Andric // C = [11, y) 3850b57cec5SDimitry Andric // 3860b57cec5SDimitry Andric // A->overlaps(C) should return false since we want to be able to join 3870b57cec5SDimitry Andric // A and C. 3880b57cec5SDimitry Andric // 3890b57cec5SDimitry Andric bool LiveRange::overlapsFrom(const LiveRange& other, 3900b57cec5SDimitry Andric const_iterator StartPos) const { 3910b57cec5SDimitry Andric assert(!empty() && "empty range"); 3920b57cec5SDimitry Andric const_iterator i = begin(); 3930b57cec5SDimitry Andric const_iterator ie = end(); 3940b57cec5SDimitry Andric const_iterator j = StartPos; 3950b57cec5SDimitry Andric const_iterator je = other.end(); 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric assert((StartPos->start <= i->start || StartPos == other.begin()) && 3980b57cec5SDimitry Andric StartPos != other.end() && "Bogus start position hint!"); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric if (i->start < j->start) { 4010b57cec5SDimitry Andric i = std::upper_bound(i, ie, j->start); 4020b57cec5SDimitry Andric if (i != begin()) --i; 4030b57cec5SDimitry Andric } else if (j->start < i->start) { 4040b57cec5SDimitry Andric ++StartPos; 4050b57cec5SDimitry Andric if (StartPos != other.end() && StartPos->start <= i->start) { 4060b57cec5SDimitry Andric assert(StartPos < other.end() && i < end()); 4070b57cec5SDimitry Andric j = std::upper_bound(j, je, i->start); 4080b57cec5SDimitry Andric if (j != other.begin()) --j; 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric } else { 4110b57cec5SDimitry Andric return true; 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric if (j == je) return false; 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric while (i != ie) { 4170b57cec5SDimitry Andric if (i->start > j->start) { 4180b57cec5SDimitry Andric std::swap(i, j); 4190b57cec5SDimitry Andric std::swap(ie, je); 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric if (i->end > j->start) 4230b57cec5SDimitry Andric return true; 4240b57cec5SDimitry Andric ++i; 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric return false; 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP, 4310b57cec5SDimitry Andric const SlotIndexes &Indexes) const { 4320b57cec5SDimitry Andric assert(!empty() && "empty range"); 4330b57cec5SDimitry Andric if (Other.empty()) 4340b57cec5SDimitry Andric return false; 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric // Use binary searches to find initial positions. 4370b57cec5SDimitry Andric const_iterator I = find(Other.beginIndex()); 4380b57cec5SDimitry Andric const_iterator IE = end(); 4390b57cec5SDimitry Andric if (I == IE) 4400b57cec5SDimitry Andric return false; 4410b57cec5SDimitry Andric const_iterator J = Other.find(I->start); 4420b57cec5SDimitry Andric const_iterator JE = Other.end(); 4430b57cec5SDimitry Andric if (J == JE) 4440b57cec5SDimitry Andric return false; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric while (true) { 4470b57cec5SDimitry Andric // J has just been advanced to satisfy: 44806c3fb27SDimitry Andric assert(J->end > I->start); 4490b57cec5SDimitry Andric // Check for an overlap. 4500b57cec5SDimitry Andric if (J->start < I->end) { 4510b57cec5SDimitry Andric // I and J are overlapping. Find the later start. 4520b57cec5SDimitry Andric SlotIndex Def = std::max(I->start, J->start); 4530b57cec5SDimitry Andric // Allow the overlap if Def is a coalescable copy. 4540b57cec5SDimitry Andric if (Def.isBlock() || 4550b57cec5SDimitry Andric !CP.isCoalescable(Indexes.getInstructionFromIndex(Def))) 4560b57cec5SDimitry Andric return true; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric // Advance the iterator that ends first to check for more overlaps. 4590b57cec5SDimitry Andric if (J->end > I->end) { 4600b57cec5SDimitry Andric std::swap(I, J); 4610b57cec5SDimitry Andric std::swap(IE, JE); 4620b57cec5SDimitry Andric } 46306c3fb27SDimitry Andric // Advance J until J->end > I->start. 4640b57cec5SDimitry Andric do 4650b57cec5SDimitry Andric if (++J == JE) 4660b57cec5SDimitry Andric return false; 46706c3fb27SDimitry Andric while (J->end <= I->start); 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric /// overlaps - Return true if the live range overlaps an interval specified 4720b57cec5SDimitry Andric /// by [Start, End). 4730b57cec5SDimitry Andric bool LiveRange::overlaps(SlotIndex Start, SlotIndex End) const { 4740b57cec5SDimitry Andric assert(Start < End && "Invalid range"); 475fe6060f1SDimitry Andric const_iterator I = lower_bound(*this, End); 4760b57cec5SDimitry Andric return I != begin() && (--I)->end > Start; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric bool LiveRange::covers(const LiveRange &Other) const { 4800b57cec5SDimitry Andric if (empty()) 4810b57cec5SDimitry Andric return Other.empty(); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric const_iterator I = begin(); 4840b57cec5SDimitry Andric for (const Segment &O : Other.segments) { 4850b57cec5SDimitry Andric I = advanceTo(I, O.start); 4860b57cec5SDimitry Andric if (I == end() || I->start > O.start) 4870b57cec5SDimitry Andric return false; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric // Check adjacent live segments and see if we can get behind O.end. 4900b57cec5SDimitry Andric while (I->end < O.end) { 4910b57cec5SDimitry Andric const_iterator Last = I; 4920b57cec5SDimitry Andric // Get next segment and abort if it was not adjacent. 4930b57cec5SDimitry Andric ++I; 4940b57cec5SDimitry Andric if (I == end() || Last->end != I->start) 4950b57cec5SDimitry Andric return false; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric return true; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric /// ValNo is dead, remove it. If it is the largest value number, just nuke it 5020b57cec5SDimitry Andric /// (and any other deleted values neighboring it), otherwise mark it as ~1U so 5030b57cec5SDimitry Andric /// it can be nuked later. 5040b57cec5SDimitry Andric void LiveRange::markValNoForDeletion(VNInfo *ValNo) { 5050b57cec5SDimitry Andric if (ValNo->id == getNumValNums()-1) { 5060b57cec5SDimitry Andric do { 5070b57cec5SDimitry Andric valnos.pop_back(); 5080b57cec5SDimitry Andric } while (!valnos.empty() && valnos.back()->isUnused()); 5090b57cec5SDimitry Andric } else { 5100b57cec5SDimitry Andric ValNo->markUnused(); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric /// RenumberValues - Renumber all values in order of appearance and delete the 5150b57cec5SDimitry Andric /// remaining unused values. 5160b57cec5SDimitry Andric void LiveRange::RenumberValues() { 5170b57cec5SDimitry Andric SmallPtrSet<VNInfo*, 8> Seen; 5180b57cec5SDimitry Andric valnos.clear(); 5190b57cec5SDimitry Andric for (const Segment &S : segments) { 5200b57cec5SDimitry Andric VNInfo *VNI = S.valno; 5210b57cec5SDimitry Andric if (!Seen.insert(VNI).second) 5220b57cec5SDimitry Andric continue; 5230b57cec5SDimitry Andric assert(!VNI->isUnused() && "Unused valno used by live segment"); 5240b57cec5SDimitry Andric VNI->id = (unsigned)valnos.size(); 5250b57cec5SDimitry Andric valnos.push_back(VNI); 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric void LiveRange::addSegmentToSet(Segment S) { 5300b57cec5SDimitry Andric CalcLiveRangeUtilSet(this).addSegment(S); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric LiveRange::iterator LiveRange::addSegment(Segment S) { 5340b57cec5SDimitry Andric // Use the segment set, if it is available. 5350b57cec5SDimitry Andric if (segmentSet != nullptr) { 5360b57cec5SDimitry Andric addSegmentToSet(S); 5370b57cec5SDimitry Andric return end(); 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric // Otherwise use the segment vector. 5400b57cec5SDimitry Andric return CalcLiveRangeUtilVector(this).addSegment(S); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric void LiveRange::append(const Segment S) { 5440b57cec5SDimitry Andric // Check that the segment belongs to the back of the list. 5450b57cec5SDimitry Andric assert(segments.empty() || segments.back().end <= S.start); 5460b57cec5SDimitry Andric segments.push_back(S); 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric std::pair<VNInfo*,bool> LiveRange::extendInBlock(ArrayRef<SlotIndex> Undefs, 5500b57cec5SDimitry Andric SlotIndex StartIdx, SlotIndex Kill) { 5510b57cec5SDimitry Andric // Use the segment set, if it is available. 5520b57cec5SDimitry Andric if (segmentSet != nullptr) 5530b57cec5SDimitry Andric return CalcLiveRangeUtilSet(this).extendInBlock(Undefs, StartIdx, Kill); 5540b57cec5SDimitry Andric // Otherwise use the segment vector. 5550b57cec5SDimitry Andric return CalcLiveRangeUtilVector(this).extendInBlock(Undefs, StartIdx, Kill); 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) { 5590b57cec5SDimitry Andric // Use the segment set, if it is available. 5600b57cec5SDimitry Andric if (segmentSet != nullptr) 5610b57cec5SDimitry Andric return CalcLiveRangeUtilSet(this).extendInBlock(StartIdx, Kill); 5620b57cec5SDimitry Andric // Otherwise use the segment vector. 5630b57cec5SDimitry Andric return CalcLiveRangeUtilVector(this).extendInBlock(StartIdx, Kill); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric void LiveRange::removeSegment(SlotIndex Start, SlotIndex End, 5670b57cec5SDimitry Andric bool RemoveDeadValNo) { 5680b57cec5SDimitry Andric // Find the Segment containing this span. 5690b57cec5SDimitry Andric iterator I = find(Start); 570*5f757f3fSDimitry Andric 571*5f757f3fSDimitry Andric // No Segment found, so nothing to do. 572*5f757f3fSDimitry Andric if (I == end()) 573*5f757f3fSDimitry Andric return; 574*5f757f3fSDimitry Andric 5750b57cec5SDimitry Andric assert(I->containsInterval(Start, End) 5760b57cec5SDimitry Andric && "Segment is not entirely in range!"); 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric // If the span we are removing is at the start of the Segment, adjust it. 5790b57cec5SDimitry Andric VNInfo *ValNo = I->valno; 5800b57cec5SDimitry Andric if (I->start == Start) { 5810b57cec5SDimitry Andric if (I->end == End) { 5820b57cec5SDimitry Andric segments.erase(I); // Removed the whole Segment. 583349cc55cSDimitry Andric 584349cc55cSDimitry Andric if (RemoveDeadValNo) 585349cc55cSDimitry Andric removeValNoIfDead(ValNo); 5860b57cec5SDimitry Andric } else 5870b57cec5SDimitry Andric I->start = End; 5880b57cec5SDimitry Andric return; 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // Otherwise if the span we are removing is at the end of the Segment, 5920b57cec5SDimitry Andric // adjust the other way. 5930b57cec5SDimitry Andric if (I->end == End) { 5940b57cec5SDimitry Andric I->end = Start; 5950b57cec5SDimitry Andric return; 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric // Otherwise, we are splitting the Segment into two pieces. 5990b57cec5SDimitry Andric SlotIndex OldEnd = I->end; 6000b57cec5SDimitry Andric I->end = Start; // Trim the old segment. 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric // Insert the new one. 6030b57cec5SDimitry Andric segments.insert(std::next(I), Segment(End, OldEnd, ValNo)); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 606349cc55cSDimitry Andric LiveRange::iterator LiveRange::removeSegment(iterator I, bool RemoveDeadValNo) { 607349cc55cSDimitry Andric VNInfo *ValNo = I->valno; 608349cc55cSDimitry Andric I = segments.erase(I); 609349cc55cSDimitry Andric if (RemoveDeadValNo) 610349cc55cSDimitry Andric removeValNoIfDead(ValNo); 611349cc55cSDimitry Andric return I; 612349cc55cSDimitry Andric } 613349cc55cSDimitry Andric 614349cc55cSDimitry Andric void LiveRange::removeValNoIfDead(VNInfo *ValNo) { 615349cc55cSDimitry Andric if (none_of(*this, [=](const Segment &S) { return S.valno == ValNo; })) 616349cc55cSDimitry Andric markValNoForDeletion(ValNo); 617349cc55cSDimitry Andric } 618349cc55cSDimitry Andric 6190b57cec5SDimitry Andric /// removeValNo - Remove all the segments defined by the specified value#. 6200b57cec5SDimitry Andric /// Also remove the value# from value# list. 6210b57cec5SDimitry Andric void LiveRange::removeValNo(VNInfo *ValNo) { 6220b57cec5SDimitry Andric if (empty()) return; 623349cc55cSDimitry Andric llvm::erase_if(segments, 624349cc55cSDimitry Andric [ValNo](const Segment &S) { return S.valno == ValNo; }); 6250b57cec5SDimitry Andric // Now that ValNo is dead, remove it. 6260b57cec5SDimitry Andric markValNoForDeletion(ValNo); 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric void LiveRange::join(LiveRange &Other, 6300b57cec5SDimitry Andric const int *LHSValNoAssignments, 6310b57cec5SDimitry Andric const int *RHSValNoAssignments, 6320b57cec5SDimitry Andric SmallVectorImpl<VNInfo *> &NewVNInfo) { 6330b57cec5SDimitry Andric verify(); 634*5f757f3fSDimitry Andric Other.verify(); 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric // Determine if any of our values are mapped. This is uncommon, so we want 6370b57cec5SDimitry Andric // to avoid the range scan if not. 6380b57cec5SDimitry Andric bool MustMapCurValNos = false; 6390b57cec5SDimitry Andric unsigned NumVals = getNumValNums(); 6400b57cec5SDimitry Andric unsigned NumNewVals = NewVNInfo.size(); 6410b57cec5SDimitry Andric for (unsigned i = 0; i != NumVals; ++i) { 6420b57cec5SDimitry Andric unsigned LHSValID = LHSValNoAssignments[i]; 6430b57cec5SDimitry Andric if (i != LHSValID || 6440b57cec5SDimitry Andric (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) { 6450b57cec5SDimitry Andric MustMapCurValNos = true; 6460b57cec5SDimitry Andric break; 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric } 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric // If we have to apply a mapping to our base range assignment, rewrite it now. 6510b57cec5SDimitry Andric if (MustMapCurValNos && !empty()) { 6520b57cec5SDimitry Andric // Map the first live range. 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric iterator OutIt = begin(); 6550b57cec5SDimitry Andric OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]]; 6560b57cec5SDimitry Andric for (iterator I = std::next(OutIt), E = end(); I != E; ++I) { 6570b57cec5SDimitry Andric VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]]; 6580b57cec5SDimitry Andric assert(nextValNo && "Huh?"); 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric // If this live range has the same value # as its immediate predecessor, 6610b57cec5SDimitry Andric // and if they are neighbors, remove one Segment. This happens when we 6620b57cec5SDimitry Andric // have [0,4:0)[4,7:1) and map 0/1 onto the same value #. 6630b57cec5SDimitry Andric if (OutIt->valno == nextValNo && OutIt->end == I->start) { 6640b57cec5SDimitry Andric OutIt->end = I->end; 6650b57cec5SDimitry Andric } else { 6660b57cec5SDimitry Andric // Didn't merge. Move OutIt to the next segment, 6670b57cec5SDimitry Andric ++OutIt; 6680b57cec5SDimitry Andric OutIt->valno = nextValNo; 6690b57cec5SDimitry Andric if (OutIt != I) { 6700b57cec5SDimitry Andric OutIt->start = I->start; 6710b57cec5SDimitry Andric OutIt->end = I->end; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric // If we merge some segments, chop off the end. 6760b57cec5SDimitry Andric ++OutIt; 6770b57cec5SDimitry Andric segments.erase(OutIt, end()); 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric // Rewrite Other values before changing the VNInfo ids. 6810b57cec5SDimitry Andric // This can leave Other in an invalid state because we're not coalescing 6820b57cec5SDimitry Andric // touching segments that now have identical values. That's OK since Other is 6830b57cec5SDimitry Andric // not supposed to be valid after calling join(); 6840b57cec5SDimitry Andric for (Segment &S : Other.segments) 6850b57cec5SDimitry Andric S.valno = NewVNInfo[RHSValNoAssignments[S.valno->id]]; 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric // Update val# info. Renumber them and make sure they all belong to this 6880b57cec5SDimitry Andric // LiveRange now. Also remove dead val#'s. 6890b57cec5SDimitry Andric unsigned NumValNos = 0; 6900b57cec5SDimitry Andric for (unsigned i = 0; i < NumNewVals; ++i) { 6910b57cec5SDimitry Andric VNInfo *VNI = NewVNInfo[i]; 6920b57cec5SDimitry Andric if (VNI) { 6930b57cec5SDimitry Andric if (NumValNos >= NumVals) 6940b57cec5SDimitry Andric valnos.push_back(VNI); 6950b57cec5SDimitry Andric else 6960b57cec5SDimitry Andric valnos[NumValNos] = VNI; 6970b57cec5SDimitry Andric VNI->id = NumValNos++; // Renumber val#. 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric if (NumNewVals < NumVals) 7010b57cec5SDimitry Andric valnos.resize(NumNewVals); // shrinkify 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric // Okay, now insert the RHS live segments into the LHS. 7040b57cec5SDimitry Andric LiveRangeUpdater Updater(this); 7050b57cec5SDimitry Andric for (Segment &S : Other.segments) 7060b57cec5SDimitry Andric Updater.add(S); 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric /// Merge all of the segments in RHS into this live range as the specified 7100b57cec5SDimitry Andric /// value number. The segments in RHS are allowed to overlap with segments in 7110b57cec5SDimitry Andric /// the current range, but only if the overlapping segments have the 7120b57cec5SDimitry Andric /// specified value number. 7130b57cec5SDimitry Andric void LiveRange::MergeSegmentsInAsValue(const LiveRange &RHS, 7140b57cec5SDimitry Andric VNInfo *LHSValNo) { 7150b57cec5SDimitry Andric LiveRangeUpdater Updater(this); 7160b57cec5SDimitry Andric for (const Segment &S : RHS.segments) 7170b57cec5SDimitry Andric Updater.add(S.start, S.end, LHSValNo); 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric /// MergeValueInAsValue - Merge all of the live segments of a specific val# 7210b57cec5SDimitry Andric /// in RHS into this live range as the specified value number. 7220b57cec5SDimitry Andric /// The segments in RHS are allowed to overlap with segments in the 7230b57cec5SDimitry Andric /// current range, it will replace the value numbers of the overlaped 7240b57cec5SDimitry Andric /// segments with the specified value number. 7250b57cec5SDimitry Andric void LiveRange::MergeValueInAsValue(const LiveRange &RHS, 7260b57cec5SDimitry Andric const VNInfo *RHSValNo, 7270b57cec5SDimitry Andric VNInfo *LHSValNo) { 7280b57cec5SDimitry Andric LiveRangeUpdater Updater(this); 7290b57cec5SDimitry Andric for (const Segment &S : RHS.segments) 7300b57cec5SDimitry Andric if (S.valno == RHSValNo) 7310b57cec5SDimitry Andric Updater.add(S.start, S.end, LHSValNo); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric /// MergeValueNumberInto - This method is called when two value nubmers 7350b57cec5SDimitry Andric /// are found to be equivalent. This eliminates V1, replacing all 7360b57cec5SDimitry Andric /// segments with the V1 value number with the V2 value number. This can 7370b57cec5SDimitry Andric /// cause merging of V1/V2 values numbers and compaction of the value space. 7380b57cec5SDimitry Andric VNInfo *LiveRange::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { 7390b57cec5SDimitry Andric assert(V1 != V2 && "Identical value#'s are always equivalent!"); 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric // This code actually merges the (numerically) larger value number into the 7420b57cec5SDimitry Andric // smaller value number, which is likely to allow us to compactify the value 7430b57cec5SDimitry Andric // space. The only thing we have to be careful of is to preserve the 7440b57cec5SDimitry Andric // instruction that defines the result value. 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric // Make sure V2 is smaller than V1. 7470b57cec5SDimitry Andric if (V1->id < V2->id) { 7480b57cec5SDimitry Andric V1->copyFrom(*V2); 7490b57cec5SDimitry Andric std::swap(V1, V2); 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric // Merge V1 segments into V2. 7530b57cec5SDimitry Andric for (iterator I = begin(); I != end(); ) { 7540b57cec5SDimitry Andric iterator S = I++; 7550b57cec5SDimitry Andric if (S->valno != V1) continue; // Not a V1 Segment. 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric // Okay, we found a V1 live range. If it had a previous, touching, V2 live 7580b57cec5SDimitry Andric // range, extend it. 7590b57cec5SDimitry Andric if (S != begin()) { 7600b57cec5SDimitry Andric iterator Prev = S-1; 7610b57cec5SDimitry Andric if (Prev->valno == V2 && Prev->end == S->start) { 7620b57cec5SDimitry Andric Prev->end = S->end; 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric // Erase this live-range. 7650b57cec5SDimitry Andric segments.erase(S); 7660b57cec5SDimitry Andric I = Prev+1; 7670b57cec5SDimitry Andric S = Prev; 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric // Okay, now we have a V1 or V2 live range that is maximally merged forward. 7720b57cec5SDimitry Andric // Ensure that it is a V2 live-range. 7730b57cec5SDimitry Andric S->valno = V2; 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric // If we can merge it into later V2 segments, do so now. We ignore any 7760b57cec5SDimitry Andric // following V1 segments, as they will be merged in subsequent iterations 7770b57cec5SDimitry Andric // of the loop. 7780b57cec5SDimitry Andric if (I != end()) { 7790b57cec5SDimitry Andric if (I->start == S->end && I->valno == V2) { 7800b57cec5SDimitry Andric S->end = I->end; 7810b57cec5SDimitry Andric segments.erase(I); 7820b57cec5SDimitry Andric I = S+1; 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric // Now that V1 is dead, remove it. 7880b57cec5SDimitry Andric markValNoForDeletion(V1); 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric return V2; 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric void LiveRange::flushSegmentSet() { 7940b57cec5SDimitry Andric assert(segmentSet != nullptr && "segment set must have been created"); 7950b57cec5SDimitry Andric assert( 7960b57cec5SDimitry Andric segments.empty() && 7970b57cec5SDimitry Andric "segment set can be used only initially before switching to the array"); 7980b57cec5SDimitry Andric segments.append(segmentSet->begin(), segmentSet->end()); 7990b57cec5SDimitry Andric segmentSet = nullptr; 8000b57cec5SDimitry Andric verify(); 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric bool LiveRange::isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const { 8040b57cec5SDimitry Andric ArrayRef<SlotIndex>::iterator SlotI = Slots.begin(); 8050b57cec5SDimitry Andric ArrayRef<SlotIndex>::iterator SlotE = Slots.end(); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // If there are no regmask slots, we have nothing to search. 8080b57cec5SDimitry Andric if (SlotI == SlotE) 8090b57cec5SDimitry Andric return false; 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // Start our search at the first segment that ends after the first slot. 8120b57cec5SDimitry Andric const_iterator SegmentI = find(*SlotI); 8130b57cec5SDimitry Andric const_iterator SegmentE = end(); 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric // If there are no segments that end after the first slot, we're done. 8160b57cec5SDimitry Andric if (SegmentI == SegmentE) 8170b57cec5SDimitry Andric return false; 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Look for each slot in the live range. 8200b57cec5SDimitry Andric for ( ; SlotI != SlotE; ++SlotI) { 8210b57cec5SDimitry Andric // Go to the next segment that ends after the current slot. 8220b57cec5SDimitry Andric // The slot may be within a hole in the range. 8230b57cec5SDimitry Andric SegmentI = advanceTo(SegmentI, *SlotI); 8240b57cec5SDimitry Andric if (SegmentI == SegmentE) 8250b57cec5SDimitry Andric return false; 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // If this segment contains the slot, we're done. 8280b57cec5SDimitry Andric if (SegmentI->contains(*SlotI)) 8290b57cec5SDimitry Andric return true; 8300b57cec5SDimitry Andric // Otherwise, look for the next slot. 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric // We didn't find a segment containing any of the slots. 8340b57cec5SDimitry Andric return false; 8350b57cec5SDimitry Andric } 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric void LiveInterval::freeSubRange(SubRange *S) { 8380b57cec5SDimitry Andric S->~SubRange(); 8390b57cec5SDimitry Andric // Memory was allocated with BumpPtr allocator and is not freed here. 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric void LiveInterval::removeEmptySubRanges() { 8430b57cec5SDimitry Andric SubRange **NextPtr = &SubRanges; 8440b57cec5SDimitry Andric SubRange *I = *NextPtr; 8450b57cec5SDimitry Andric while (I != nullptr) { 8460b57cec5SDimitry Andric if (!I->empty()) { 8470b57cec5SDimitry Andric NextPtr = &I->Next; 8480b57cec5SDimitry Andric I = *NextPtr; 8490b57cec5SDimitry Andric continue; 8500b57cec5SDimitry Andric } 8510b57cec5SDimitry Andric // Skip empty subranges until we find the first nonempty one. 8520b57cec5SDimitry Andric do { 8530b57cec5SDimitry Andric SubRange *Next = I->Next; 8540b57cec5SDimitry Andric freeSubRange(I); 8550b57cec5SDimitry Andric I = Next; 8560b57cec5SDimitry Andric } while (I != nullptr && I->empty()); 8570b57cec5SDimitry Andric *NextPtr = I; 8580b57cec5SDimitry Andric } 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric void LiveInterval::clearSubRanges() { 8620b57cec5SDimitry Andric for (SubRange *I = SubRanges, *Next; I != nullptr; I = Next) { 8630b57cec5SDimitry Andric Next = I->Next; 8640b57cec5SDimitry Andric freeSubRange(I); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric SubRanges = nullptr; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric /// For each VNI in \p SR, check whether or not that value defines part 8700b57cec5SDimitry Andric /// of the mask describe by \p LaneMask and if not, remove that value 8710b57cec5SDimitry Andric /// from \p SR. 8720b57cec5SDimitry Andric static void stripValuesNotDefiningMask(unsigned Reg, LiveInterval::SubRange &SR, 8730b57cec5SDimitry Andric LaneBitmask LaneMask, 8740b57cec5SDimitry Andric const SlotIndexes &Indexes, 875480093f4SDimitry Andric const TargetRegisterInfo &TRI, 876480093f4SDimitry Andric unsigned ComposeSubRegIdx) { 8770b57cec5SDimitry Andric // Phys reg should not be tracked at subreg level. 8780b57cec5SDimitry Andric // Same for noreg (Reg == 0). 8798bcb0991SDimitry Andric if (!Register::isVirtualRegister(Reg) || !Reg) 8800b57cec5SDimitry Andric return; 8810b57cec5SDimitry Andric // Remove the values that don't define those lanes. 8820b57cec5SDimitry Andric SmallVector<VNInfo *, 8> ToBeRemoved; 8830b57cec5SDimitry Andric for (VNInfo *VNI : SR.valnos) { 8840b57cec5SDimitry Andric if (VNI->isUnused()) 8850b57cec5SDimitry Andric continue; 8860b57cec5SDimitry Andric // PHI definitions don't have MI attached, so there is nothing 8870b57cec5SDimitry Andric // we can use to strip the VNI. 8880b57cec5SDimitry Andric if (VNI->isPHIDef()) 8890b57cec5SDimitry Andric continue; 8900b57cec5SDimitry Andric const MachineInstr *MI = Indexes.getInstructionFromIndex(VNI->def); 8910b57cec5SDimitry Andric assert(MI && "Cannot find the definition of a value"); 8920b57cec5SDimitry Andric bool hasDef = false; 8930b57cec5SDimitry Andric for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) { 8940b57cec5SDimitry Andric if (!MOI->isReg() || !MOI->isDef()) 8950b57cec5SDimitry Andric continue; 8960b57cec5SDimitry Andric if (MOI->getReg() != Reg) 8970b57cec5SDimitry Andric continue; 898480093f4SDimitry Andric LaneBitmask OrigMask = TRI.getSubRegIndexLaneMask(MOI->getSubReg()); 899480093f4SDimitry Andric LaneBitmask ExpectedDefMask = 900480093f4SDimitry Andric ComposeSubRegIdx 901480093f4SDimitry Andric ? TRI.composeSubRegIndexLaneMask(ComposeSubRegIdx, OrigMask) 902480093f4SDimitry Andric : OrigMask; 903480093f4SDimitry Andric if ((ExpectedDefMask & LaneMask).none()) 9040b57cec5SDimitry Andric continue; 9050b57cec5SDimitry Andric hasDef = true; 9060b57cec5SDimitry Andric break; 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric if (!hasDef) 9100b57cec5SDimitry Andric ToBeRemoved.push_back(VNI); 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric for (VNInfo *VNI : ToBeRemoved) 9130b57cec5SDimitry Andric SR.removeValNo(VNI); 9140b57cec5SDimitry Andric 9158bcb0991SDimitry Andric // If the subrange is empty at this point, the MIR is invalid. Do not assert 9168bcb0991SDimitry Andric // and let the verifier catch this case. 9170b57cec5SDimitry Andric } 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric void LiveInterval::refineSubRanges( 9200b57cec5SDimitry Andric BumpPtrAllocator &Allocator, LaneBitmask LaneMask, 9210b57cec5SDimitry Andric std::function<void(LiveInterval::SubRange &)> Apply, 922480093f4SDimitry Andric const SlotIndexes &Indexes, const TargetRegisterInfo &TRI, 923480093f4SDimitry Andric unsigned ComposeSubRegIdx) { 9240b57cec5SDimitry Andric LaneBitmask ToApply = LaneMask; 9250b57cec5SDimitry Andric for (SubRange &SR : subranges()) { 9260b57cec5SDimitry Andric LaneBitmask SRMask = SR.LaneMask; 9270b57cec5SDimitry Andric LaneBitmask Matching = SRMask & LaneMask; 9280b57cec5SDimitry Andric if (Matching.none()) 9290b57cec5SDimitry Andric continue; 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric SubRange *MatchingRange; 9320b57cec5SDimitry Andric if (SRMask == Matching) { 9330b57cec5SDimitry Andric // The subrange fits (it does not cover bits outside \p LaneMask). 9340b57cec5SDimitry Andric MatchingRange = &SR; 9350b57cec5SDimitry Andric } else { 9360b57cec5SDimitry Andric // We have to split the subrange into a matching and non-matching part. 9370b57cec5SDimitry Andric // Reduce lanemask of existing lane to non-matching part. 9380b57cec5SDimitry Andric SR.LaneMask = SRMask & ~Matching; 9390b57cec5SDimitry Andric // Create a new subrange for the matching part 9400b57cec5SDimitry Andric MatchingRange = createSubRangeFrom(Allocator, Matching, SR); 9410b57cec5SDimitry Andric // Now that the subrange is split in half, make sure we 9420b57cec5SDimitry Andric // only keep in the subranges the VNIs that touch the related half. 943e8d8bef9SDimitry Andric stripValuesNotDefiningMask(reg(), *MatchingRange, Matching, Indexes, TRI, 944480093f4SDimitry Andric ComposeSubRegIdx); 945e8d8bef9SDimitry Andric stripValuesNotDefiningMask(reg(), SR, SR.LaneMask, Indexes, TRI, 946480093f4SDimitry Andric ComposeSubRegIdx); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric Apply(*MatchingRange); 9490b57cec5SDimitry Andric ToApply &= ~Matching; 9500b57cec5SDimitry Andric } 9510b57cec5SDimitry Andric // Create a new subrange if there are uncovered bits left. 9520b57cec5SDimitry Andric if (ToApply.any()) { 9530b57cec5SDimitry Andric SubRange *NewRange = createSubRange(Allocator, ToApply); 9540b57cec5SDimitry Andric Apply(*NewRange); 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric unsigned LiveInterval::getSize() const { 9590b57cec5SDimitry Andric unsigned Sum = 0; 9600b57cec5SDimitry Andric for (const Segment &S : segments) 9610b57cec5SDimitry Andric Sum += S.start.distance(S.end); 9620b57cec5SDimitry Andric return Sum; 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs, 9660b57cec5SDimitry Andric LaneBitmask LaneMask, 9670b57cec5SDimitry Andric const MachineRegisterInfo &MRI, 9680b57cec5SDimitry Andric const SlotIndexes &Indexes) const { 969bdd1243dSDimitry Andric assert(reg().isVirtual()); 970e8d8bef9SDimitry Andric LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg()); 9710b57cec5SDimitry Andric assert((VRegMask & LaneMask).any()); 9720b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 973e8d8bef9SDimitry Andric for (const MachineOperand &MO : MRI.def_operands(reg())) { 9740b57cec5SDimitry Andric if (!MO.isUndef()) 9750b57cec5SDimitry Andric continue; 9760b57cec5SDimitry Andric unsigned SubReg = MO.getSubReg(); 9770b57cec5SDimitry Andric assert(SubReg != 0 && "Undef should only be set on subreg defs"); 9780b57cec5SDimitry Andric LaneBitmask DefMask = TRI.getSubRegIndexLaneMask(SubReg); 9790b57cec5SDimitry Andric LaneBitmask UndefMask = VRegMask & ~DefMask; 9800b57cec5SDimitry Andric if ((UndefMask & LaneMask).any()) { 9810b57cec5SDimitry Andric const MachineInstr &MI = *MO.getParent(); 9820b57cec5SDimitry Andric bool EarlyClobber = MO.isEarlyClobber(); 9830b57cec5SDimitry Andric SlotIndex Pos = Indexes.getInstructionIndex(MI).getRegSlot(EarlyClobber); 9840b57cec5SDimitry Andric Undefs.push_back(Pos); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric } 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric raw_ostream& llvm::operator<<(raw_ostream& OS, const LiveRange::Segment &S) { 9900b57cec5SDimitry Andric return OS << '[' << S.start << ',' << S.end << ':' << S.valno->id << ')'; 9910b57cec5SDimitry Andric } 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 9940b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveRange::Segment::dump() const { 9950b57cec5SDimitry Andric dbgs() << *this << '\n'; 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric #endif 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric void LiveRange::print(raw_ostream &OS) const { 10000b57cec5SDimitry Andric if (empty()) 10010b57cec5SDimitry Andric OS << "EMPTY"; 10020b57cec5SDimitry Andric else { 10030b57cec5SDimitry Andric for (const Segment &S : segments) { 10040b57cec5SDimitry Andric OS << S; 10050b57cec5SDimitry Andric assert(S.valno == getValNumInfo(S.valno->id) && "Bad VNInfo"); 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric // Print value number info. 10100b57cec5SDimitry Andric if (getNumValNums()) { 1011349cc55cSDimitry Andric OS << ' '; 10120b57cec5SDimitry Andric unsigned vnum = 0; 10130b57cec5SDimitry Andric for (const_vni_iterator i = vni_begin(), e = vni_end(); i != e; 10140b57cec5SDimitry Andric ++i, ++vnum) { 10150b57cec5SDimitry Andric const VNInfo *vni = *i; 10160b57cec5SDimitry Andric if (vnum) OS << ' '; 10170b57cec5SDimitry Andric OS << vnum << '@'; 10180b57cec5SDimitry Andric if (vni->isUnused()) { 10190b57cec5SDimitry Andric OS << 'x'; 10200b57cec5SDimitry Andric } else { 10210b57cec5SDimitry Andric OS << vni->def; 10220b57cec5SDimitry Andric if (vni->isPHIDef()) 10230b57cec5SDimitry Andric OS << "-phi"; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric } 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric void LiveInterval::SubRange::print(raw_ostream &OS) const { 10300b57cec5SDimitry Andric OS << " L" << PrintLaneMask(LaneMask) << ' ' 10310b57cec5SDimitry Andric << static_cast<const LiveRange &>(*this); 10320b57cec5SDimitry Andric } 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric void LiveInterval::print(raw_ostream &OS) const { 1035e8d8bef9SDimitry Andric OS << printReg(reg()) << ' '; 10360b57cec5SDimitry Andric super::print(OS); 10370b57cec5SDimitry Andric // Print subranges 10380b57cec5SDimitry Andric for (const SubRange &SR : subranges()) 10390b57cec5SDimitry Andric OS << SR; 1040e8d8bef9SDimitry Andric OS << " weight:" << Weight; 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 10440b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveRange::dump() const { 10450b57cec5SDimitry Andric dbgs() << *this << '\n'; 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveInterval::SubRange::dump() const { 10490b57cec5SDimitry Andric dbgs() << *this << '\n'; 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveInterval::dump() const { 10530b57cec5SDimitry Andric dbgs() << *this << '\n'; 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric #endif 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric #ifndef NDEBUG 10580b57cec5SDimitry Andric void LiveRange::verify() const { 10590b57cec5SDimitry Andric for (const_iterator I = begin(), E = end(); I != E; ++I) { 10600b57cec5SDimitry Andric assert(I->start.isValid()); 10610b57cec5SDimitry Andric assert(I->end.isValid()); 10620b57cec5SDimitry Andric assert(I->start < I->end); 10630b57cec5SDimitry Andric assert(I->valno != nullptr); 10640b57cec5SDimitry Andric assert(I->valno->id < valnos.size()); 10650b57cec5SDimitry Andric assert(I->valno == valnos[I->valno->id]); 10660b57cec5SDimitry Andric if (std::next(I) != E) { 10670b57cec5SDimitry Andric assert(I->end <= std::next(I)->start); 10680b57cec5SDimitry Andric if (I->end == std::next(I)->start) 10690b57cec5SDimitry Andric assert(I->valno != std::next(I)->valno); 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric void LiveInterval::verify(const MachineRegisterInfo *MRI) const { 10750b57cec5SDimitry Andric super::verify(); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric // Make sure SubRanges are fine and LaneMasks are disjunct. 10780b57cec5SDimitry Andric LaneBitmask Mask; 1079e8d8bef9SDimitry Andric LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg()) 10800b57cec5SDimitry Andric : LaneBitmask::getAll(); 10810b57cec5SDimitry Andric for (const SubRange &SR : subranges()) { 10820b57cec5SDimitry Andric // Subrange lanemask should be disjunct to any previous subrange masks. 10830b57cec5SDimitry Andric assert((Mask & SR.LaneMask).none()); 10840b57cec5SDimitry Andric Mask |= SR.LaneMask; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric // subrange mask should not contained in maximum lane mask for the vreg. 10870b57cec5SDimitry Andric assert((Mask & ~MaxMask).none()); 10880b57cec5SDimitry Andric // empty subranges must be removed. 10890b57cec5SDimitry Andric assert(!SR.empty()); 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric SR.verify(); 10920b57cec5SDimitry Andric // Main liverange should cover subrange. 10930b57cec5SDimitry Andric assert(covers(SR)); 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric #endif 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10990b57cec5SDimitry Andric // LiveRangeUpdater class 11000b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11010b57cec5SDimitry Andric // 11020b57cec5SDimitry Andric // The LiveRangeUpdater class always maintains these invariants: 11030b57cec5SDimitry Andric // 11040b57cec5SDimitry Andric // - When LastStart is invalid, Spills is empty and the iterators are invalid. 11050b57cec5SDimitry Andric // This is the initial state, and the state created by flush(). 11060b57cec5SDimitry Andric // In this state, isDirty() returns false. 11070b57cec5SDimitry Andric // 11080b57cec5SDimitry Andric // Otherwise, segments are kept in three separate areas: 11090b57cec5SDimitry Andric // 11100b57cec5SDimitry Andric // 1. [begin; WriteI) at the front of LR. 11110b57cec5SDimitry Andric // 2. [ReadI; end) at the back of LR. 11120b57cec5SDimitry Andric // 3. Spills. 11130b57cec5SDimitry Andric // 11140b57cec5SDimitry Andric // - LR.begin() <= WriteI <= ReadI <= LR.end(). 11150b57cec5SDimitry Andric // - Segments in all three areas are fully ordered and coalesced. 11160b57cec5SDimitry Andric // - Segments in area 1 precede and can't coalesce with segments in area 2. 11170b57cec5SDimitry Andric // - Segments in Spills precede and can't coalesce with segments in area 2. 11180b57cec5SDimitry Andric // - No coalescing is possible between segments in Spills and segments in area 11190b57cec5SDimitry Andric // 1, and there are no overlapping segments. 11200b57cec5SDimitry Andric // 11210b57cec5SDimitry Andric // The segments in Spills are not ordered with respect to the segments in area 11220b57cec5SDimitry Andric // 1. They need to be merged. 11230b57cec5SDimitry Andric // 11240b57cec5SDimitry Andric // When they exist, Spills.back().start <= LastStart, 11250b57cec5SDimitry Andric // and WriteI[-1].start <= LastStart. 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 11280b57cec5SDimitry Andric void LiveRangeUpdater::print(raw_ostream &OS) const { 11290b57cec5SDimitry Andric if (!isDirty()) { 11300b57cec5SDimitry Andric if (LR) 11310b57cec5SDimitry Andric OS << "Clean updater: " << *LR << '\n'; 11320b57cec5SDimitry Andric else 11330b57cec5SDimitry Andric OS << "Null updater.\n"; 11340b57cec5SDimitry Andric return; 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric assert(LR && "Can't have null LR in dirty updater."); 11370b57cec5SDimitry Andric OS << " updater with gap = " << (ReadI - WriteI) 11380b57cec5SDimitry Andric << ", last start = " << LastStart 11390b57cec5SDimitry Andric << ":\n Area 1:"; 11400b57cec5SDimitry Andric for (const auto &S : make_range(LR->begin(), WriteI)) 11410b57cec5SDimitry Andric OS << ' ' << S; 11420b57cec5SDimitry Andric OS << "\n Spills:"; 11430b57cec5SDimitry Andric for (unsigned I = 0, E = Spills.size(); I != E; ++I) 11440b57cec5SDimitry Andric OS << ' ' << Spills[I]; 11450b57cec5SDimitry Andric OS << "\n Area 2:"; 11460b57cec5SDimitry Andric for (const auto &S : make_range(ReadI, LR->end())) 11470b57cec5SDimitry Andric OS << ' ' << S; 11480b57cec5SDimitry Andric OS << '\n'; 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveRangeUpdater::dump() const { 11520b57cec5SDimitry Andric print(errs()); 11530b57cec5SDimitry Andric } 11540b57cec5SDimitry Andric #endif 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric // Determine if A and B should be coalesced. 11570b57cec5SDimitry Andric static inline bool coalescable(const LiveRange::Segment &A, 11580b57cec5SDimitry Andric const LiveRange::Segment &B) { 11590b57cec5SDimitry Andric assert(A.start <= B.start && "Unordered live segments."); 11600b57cec5SDimitry Andric if (A.end == B.start) 11610b57cec5SDimitry Andric return A.valno == B.valno; 11620b57cec5SDimitry Andric if (A.end < B.start) 11630b57cec5SDimitry Andric return false; 11640b57cec5SDimitry Andric assert(A.valno == B.valno && "Cannot overlap different values"); 11650b57cec5SDimitry Andric return true; 11660b57cec5SDimitry Andric } 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric void LiveRangeUpdater::add(LiveRange::Segment Seg) { 11690b57cec5SDimitry Andric assert(LR && "Cannot add to a null destination"); 11700b57cec5SDimitry Andric 11710b57cec5SDimitry Andric // Fall back to the regular add method if the live range 11720b57cec5SDimitry Andric // is using the segment set instead of the segment vector. 11730b57cec5SDimitry Andric if (LR->segmentSet != nullptr) { 11740b57cec5SDimitry Andric LR->addSegmentToSet(Seg); 11750b57cec5SDimitry Andric return; 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric // Flush the state if Start moves backwards. 11790b57cec5SDimitry Andric if (!LastStart.isValid() || LastStart > Seg.start) { 11800b57cec5SDimitry Andric if (isDirty()) 11810b57cec5SDimitry Andric flush(); 11820b57cec5SDimitry Andric // This brings us to an uninitialized state. Reinitialize. 11830b57cec5SDimitry Andric assert(Spills.empty() && "Leftover spilled segments"); 11840b57cec5SDimitry Andric WriteI = ReadI = LR->begin(); 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric // Remember start for next time. 11880b57cec5SDimitry Andric LastStart = Seg.start; 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric // Advance ReadI until it ends after Seg.start. 11910b57cec5SDimitry Andric LiveRange::iterator E = LR->end(); 11920b57cec5SDimitry Andric if (ReadI != E && ReadI->end <= Seg.start) { 11930b57cec5SDimitry Andric // First try to close the gap between WriteI and ReadI with spills. 11940b57cec5SDimitry Andric if (ReadI != WriteI) 11950b57cec5SDimitry Andric mergeSpills(); 11960b57cec5SDimitry Andric // Then advance ReadI. 11970b57cec5SDimitry Andric if (ReadI == WriteI) 11980b57cec5SDimitry Andric ReadI = WriteI = LR->find(Seg.start); 11990b57cec5SDimitry Andric else 12000b57cec5SDimitry Andric while (ReadI != E && ReadI->end <= Seg.start) 12010b57cec5SDimitry Andric *WriteI++ = *ReadI++; 12020b57cec5SDimitry Andric } 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric assert(ReadI == E || ReadI->end > Seg.start); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric // Check if the ReadI segment begins early. 12070b57cec5SDimitry Andric if (ReadI != E && ReadI->start <= Seg.start) { 12080b57cec5SDimitry Andric assert(ReadI->valno == Seg.valno && "Cannot overlap different values"); 12090b57cec5SDimitry Andric // Bail if Seg is completely contained in ReadI. 12100b57cec5SDimitry Andric if (ReadI->end >= Seg.end) 12110b57cec5SDimitry Andric return; 12120b57cec5SDimitry Andric // Coalesce into Seg. 12130b57cec5SDimitry Andric Seg.start = ReadI->start; 12140b57cec5SDimitry Andric ++ReadI; 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric // Coalesce as much as possible from ReadI into Seg. 12180b57cec5SDimitry Andric while (ReadI != E && coalescable(Seg, *ReadI)) { 12190b57cec5SDimitry Andric Seg.end = std::max(Seg.end, ReadI->end); 12200b57cec5SDimitry Andric ++ReadI; 12210b57cec5SDimitry Andric } 12220b57cec5SDimitry Andric 12230b57cec5SDimitry Andric // Try coalescing Spills.back() into Seg. 12240b57cec5SDimitry Andric if (!Spills.empty() && coalescable(Spills.back(), Seg)) { 12250b57cec5SDimitry Andric Seg.start = Spills.back().start; 12260b57cec5SDimitry Andric Seg.end = std::max(Spills.back().end, Seg.end); 12270b57cec5SDimitry Andric Spills.pop_back(); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // Try coalescing Seg into WriteI[-1]. 12310b57cec5SDimitry Andric if (WriteI != LR->begin() && coalescable(WriteI[-1], Seg)) { 12320b57cec5SDimitry Andric WriteI[-1].end = std::max(WriteI[-1].end, Seg.end); 12330b57cec5SDimitry Andric return; 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric // Seg doesn't coalesce with anything, and needs to be inserted somewhere. 12370b57cec5SDimitry Andric if (WriteI != ReadI) { 12380b57cec5SDimitry Andric *WriteI++ = Seg; 12390b57cec5SDimitry Andric return; 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric // Finally, append to LR or Spills. 12430b57cec5SDimitry Andric if (WriteI == E) { 12440b57cec5SDimitry Andric LR->segments.push_back(Seg); 12450b57cec5SDimitry Andric WriteI = ReadI = LR->end(); 12460b57cec5SDimitry Andric } else 12470b57cec5SDimitry Andric Spills.push_back(Seg); 12480b57cec5SDimitry Andric } 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // Merge as many spilled segments as possible into the gap between WriteI 12510b57cec5SDimitry Andric // and ReadI. Advance WriteI to reflect the inserted instructions. 12520b57cec5SDimitry Andric void LiveRangeUpdater::mergeSpills() { 12530b57cec5SDimitry Andric // Perform a backwards merge of Spills and [SpillI;WriteI). 12540b57cec5SDimitry Andric size_t GapSize = ReadI - WriteI; 12550b57cec5SDimitry Andric size_t NumMoved = std::min(Spills.size(), GapSize); 12560b57cec5SDimitry Andric LiveRange::iterator Src = WriteI; 12570b57cec5SDimitry Andric LiveRange::iterator Dst = Src + NumMoved; 12580b57cec5SDimitry Andric LiveRange::iterator SpillSrc = Spills.end(); 12590b57cec5SDimitry Andric LiveRange::iterator B = LR->begin(); 12600b57cec5SDimitry Andric 12610b57cec5SDimitry Andric // This is the new WriteI position after merging spills. 12620b57cec5SDimitry Andric WriteI = Dst; 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric // Now merge Src and Spills backwards. 12650b57cec5SDimitry Andric while (Src != Dst) { 12660b57cec5SDimitry Andric if (Src != B && Src[-1].start > SpillSrc[-1].start) 12670b57cec5SDimitry Andric *--Dst = *--Src; 12680b57cec5SDimitry Andric else 12690b57cec5SDimitry Andric *--Dst = *--SpillSrc; 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric assert(NumMoved == size_t(Spills.end() - SpillSrc)); 12720b57cec5SDimitry Andric Spills.erase(SpillSrc, Spills.end()); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric void LiveRangeUpdater::flush() { 12760b57cec5SDimitry Andric if (!isDirty()) 12770b57cec5SDimitry Andric return; 12780b57cec5SDimitry Andric // Clear the dirty state. 12790b57cec5SDimitry Andric LastStart = SlotIndex(); 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric assert(LR && "Cannot add to a null destination"); 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andric // Nothing to merge? 12840b57cec5SDimitry Andric if (Spills.empty()) { 12850b57cec5SDimitry Andric LR->segments.erase(WriteI, ReadI); 12860b57cec5SDimitry Andric LR->verify(); 12870b57cec5SDimitry Andric return; 12880b57cec5SDimitry Andric } 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andric // Resize the WriteI - ReadI gap to match Spills. 12910b57cec5SDimitry Andric size_t GapSize = ReadI - WriteI; 12920b57cec5SDimitry Andric if (GapSize < Spills.size()) { 12930b57cec5SDimitry Andric // The gap is too small. Make some room. 12940b57cec5SDimitry Andric size_t WritePos = WriteI - LR->begin(); 12950b57cec5SDimitry Andric LR->segments.insert(ReadI, Spills.size() - GapSize, LiveRange::Segment()); 12960b57cec5SDimitry Andric // This also invalidated ReadI, but it is recomputed below. 12970b57cec5SDimitry Andric WriteI = LR->begin() + WritePos; 12980b57cec5SDimitry Andric } else { 12990b57cec5SDimitry Andric // Shrink the gap if necessary. 13000b57cec5SDimitry Andric LR->segments.erase(WriteI + Spills.size(), ReadI); 13010b57cec5SDimitry Andric } 13020b57cec5SDimitry Andric ReadI = WriteI + Spills.size(); 13030b57cec5SDimitry Andric mergeSpills(); 13040b57cec5SDimitry Andric LR->verify(); 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric 13070b57cec5SDimitry Andric unsigned ConnectedVNInfoEqClasses::Classify(const LiveRange &LR) { 13080b57cec5SDimitry Andric // Create initial equivalence classes. 13090b57cec5SDimitry Andric EqClass.clear(); 13100b57cec5SDimitry Andric EqClass.grow(LR.getNumValNums()); 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric const VNInfo *used = nullptr, *unused = nullptr; 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric // Determine connections. 13150b57cec5SDimitry Andric for (const VNInfo *VNI : LR.valnos) { 13160b57cec5SDimitry Andric // Group all unused values into one class. 13170b57cec5SDimitry Andric if (VNI->isUnused()) { 13180b57cec5SDimitry Andric if (unused) 13190b57cec5SDimitry Andric EqClass.join(unused->id, VNI->id); 13200b57cec5SDimitry Andric unused = VNI; 13210b57cec5SDimitry Andric continue; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric used = VNI; 13240b57cec5SDimitry Andric if (VNI->isPHIDef()) { 13250b57cec5SDimitry Andric const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); 13260b57cec5SDimitry Andric assert(MBB && "Phi-def has no defining MBB"); 13270b57cec5SDimitry Andric // Connect to values live out of predecessors. 1328fe6060f1SDimitry Andric for (MachineBasicBlock *Pred : MBB->predecessors()) 1329fe6060f1SDimitry Andric if (const VNInfo *PVNI = LR.getVNInfoBefore(LIS.getMBBEndIdx(Pred))) 13300b57cec5SDimitry Andric EqClass.join(VNI->id, PVNI->id); 13310b57cec5SDimitry Andric } else { 13320b57cec5SDimitry Andric // Normal value defined by an instruction. Check for two-addr redef. 13330b57cec5SDimitry Andric // FIXME: This could be coincidental. Should we really check for a tied 13340b57cec5SDimitry Andric // operand constraint? 13350b57cec5SDimitry Andric // Note that VNI->def may be a use slot for an early clobber def. 13360b57cec5SDimitry Andric if (const VNInfo *UVNI = LR.getVNInfoBefore(VNI->def)) 13370b57cec5SDimitry Andric EqClass.join(VNI->id, UVNI->id); 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric } 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric // Lump all the unused values in with the last used value. 13420b57cec5SDimitry Andric if (used && unused) 13430b57cec5SDimitry Andric EqClass.join(used->id, unused->id); 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric EqClass.compress(); 13460b57cec5SDimitry Andric return EqClass.getNumClasses(); 13470b57cec5SDimitry Andric } 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andric void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[], 13500b57cec5SDimitry Andric MachineRegisterInfo &MRI) { 13510b57cec5SDimitry Andric // Rewrite instructions. 1352fe6060f1SDimitry Andric for (MachineOperand &MO : 1353fe6060f1SDimitry Andric llvm::make_early_inc_range(MRI.reg_operands(LI.reg()))) { 1354fe6060f1SDimitry Andric MachineInstr *MI = MO.getParent(); 13550b57cec5SDimitry Andric const VNInfo *VNI; 13560b57cec5SDimitry Andric if (MI->isDebugValue()) { 13570b57cec5SDimitry Andric // DBG_VALUE instructions don't have slot indexes, so get the index of 13580b57cec5SDimitry Andric // the instruction before them. The value is defined there too. 13590b57cec5SDimitry Andric SlotIndex Idx = LIS.getSlotIndexes()->getIndexBefore(*MI); 13600b57cec5SDimitry Andric VNI = LI.Query(Idx).valueOut(); 13610b57cec5SDimitry Andric } else { 13620b57cec5SDimitry Andric SlotIndex Idx = LIS.getInstructionIndex(*MI); 13630b57cec5SDimitry Andric LiveQueryResult LRQ = LI.Query(Idx); 13640b57cec5SDimitry Andric VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined(); 13650b57cec5SDimitry Andric } 13660b57cec5SDimitry Andric // In the case of an <undef> use that isn't tied to any def, VNI will be 13670b57cec5SDimitry Andric // NULL. If the use is tied to a def, VNI will be the defined value. 13680b57cec5SDimitry Andric if (!VNI) 13690b57cec5SDimitry Andric continue; 13700b57cec5SDimitry Andric if (unsigned EqClass = getEqClass(VNI)) 1371e8d8bef9SDimitry Andric MO.setReg(LIV[EqClass - 1]->reg()); 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric // Distribute subregister liveranges. 13750b57cec5SDimitry Andric if (LI.hasSubRanges()) { 13760b57cec5SDimitry Andric unsigned NumComponents = EqClass.getNumClasses(); 13770b57cec5SDimitry Andric SmallVector<unsigned, 8> VNIMapping; 13780b57cec5SDimitry Andric SmallVector<LiveInterval::SubRange*, 8> SubRanges; 13790b57cec5SDimitry Andric BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator(); 13800b57cec5SDimitry Andric for (LiveInterval::SubRange &SR : LI.subranges()) { 13810b57cec5SDimitry Andric // Create new subranges in the split intervals and construct a mapping 13820b57cec5SDimitry Andric // for the VNInfos in the subrange. 13830b57cec5SDimitry Andric unsigned NumValNos = SR.valnos.size(); 13840b57cec5SDimitry Andric VNIMapping.clear(); 13850b57cec5SDimitry Andric VNIMapping.reserve(NumValNos); 13860b57cec5SDimitry Andric SubRanges.clear(); 13870b57cec5SDimitry Andric SubRanges.resize(NumComponents-1, nullptr); 13880b57cec5SDimitry Andric for (unsigned I = 0; I < NumValNos; ++I) { 13890b57cec5SDimitry Andric const VNInfo &VNI = *SR.valnos[I]; 13900b57cec5SDimitry Andric unsigned ComponentNum; 13910b57cec5SDimitry Andric if (VNI.isUnused()) { 13920b57cec5SDimitry Andric ComponentNum = 0; 13930b57cec5SDimitry Andric } else { 13940b57cec5SDimitry Andric const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def); 13950b57cec5SDimitry Andric assert(MainRangeVNI != nullptr 13960b57cec5SDimitry Andric && "SubRange def must have corresponding main range def"); 13970b57cec5SDimitry Andric ComponentNum = getEqClass(MainRangeVNI); 13980b57cec5SDimitry Andric if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) { 13990b57cec5SDimitry Andric SubRanges[ComponentNum-1] 14000b57cec5SDimitry Andric = LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask); 14010b57cec5SDimitry Andric } 14020b57cec5SDimitry Andric } 14030b57cec5SDimitry Andric VNIMapping.push_back(ComponentNum); 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric DistributeRange(SR, SubRanges.data(), VNIMapping); 14060b57cec5SDimitry Andric } 14070b57cec5SDimitry Andric LI.removeEmptySubRanges(); 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric // Distribute main liverange. 14110b57cec5SDimitry Andric DistributeRange(LI, LIV, EqClass); 14120b57cec5SDimitry Andric } 1413