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:
CalcLiveRangeUtilBase(LiveRange * LR)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.
createDeadDef(SlotIndex Def,VNInfo::Allocator * VNInfoAllocator,VNInfo * ForVNI)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
extendInBlock(SlotIndex StartIdx,SlotIndex Use)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
extendInBlock(ArrayRef<SlotIndex> Undefs,SlotIndex StartIdx,SlotIndex Use)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.
extendSegmentEndTo(iterator I,SlotIndex NewEnd)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.
extendSegmentStartTo(iterator I,SlotIndex NewStart)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
addSegment(Segment S)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:
impl()2690b57cec5SDimitry Andric ImplT &impl() { return *static_cast<ImplT *>(this); }
2700b57cec5SDimitry Andric
segments()2710b57cec5SDimitry Andric CollectionT &segments() { return impl().segmentsColl(); }
2720b57cec5SDimitry Andric
segmentAt(iterator I)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:
CalcLiveRangeUtilVector(LiveRange * LR)2880b57cec5SDimitry Andric CalcLiveRangeUtilVector(LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andric private:
2910b57cec5SDimitry Andric friend CalcLiveRangeUtilVectorBase;
2920b57cec5SDimitry Andric
segmentsColl()2930b57cec5SDimitry Andric LiveRange::Segments &segmentsColl() { return LR->segments; }
2940b57cec5SDimitry Andric
insertAtEnd(const Segment & S)2950b57cec5SDimitry Andric void insertAtEnd(const Segment &S) { LR->segments.push_back(S); }
2960b57cec5SDimitry Andric
find(SlotIndex Pos)2970b57cec5SDimitry Andric iterator find(SlotIndex Pos) { return LR->find(Pos); }
2980b57cec5SDimitry Andric
findInsertPos(Segment S)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:
CalcLiveRangeUtilSet(LiveRange * LR)3140b57cec5SDimitry Andric CalcLiveRangeUtilSet(LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric private:
3170b57cec5SDimitry Andric friend CalcLiveRangeUtilSetBase;
3180b57cec5SDimitry Andric
segmentsColl()3190b57cec5SDimitry Andric LiveRange::SegmentSet &segmentsColl() { return *LR->segmentSet; }
3200b57cec5SDimitry Andric
insertAtEnd(const Segment & S)3210b57cec5SDimitry Andric void insertAtEnd(const Segment &S) {
3220b57cec5SDimitry Andric LR->segmentSet->insert(LR->segmentSet->end(), S);
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric
find(SlotIndex Pos)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
findInsertPos(Segment S)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
find(SlotIndex Pos)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
createDeadDef(SlotIndex Def,VNInfo::Allocator & VNIAlloc)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
createDeadDef(VNInfo * VNI)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 //
overlapsFrom(const LiveRange & other,const_iterator StartPos) const3890b57cec5SDimitry 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
overlaps(const LiveRange & Other,const CoalescerPair & CP,const SlotIndexes & Indexes) const4300b57cec5SDimitry 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).
overlaps(SlotIndex Start,SlotIndex End) const4730b57cec5SDimitry 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
covers(const LiveRange & Other) const4790b57cec5SDimitry 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.
markValNoForDeletion(VNInfo * ValNo)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.
RenumberValues()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
addSegmentToSet(Segment S)5290b57cec5SDimitry Andric void LiveRange::addSegmentToSet(Segment S) {
5300b57cec5SDimitry Andric CalcLiveRangeUtilSet(this).addSegment(S);
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric
addSegment(Segment S)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
append(const Segment S)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
extendInBlock(ArrayRef<SlotIndex> Undefs,SlotIndex StartIdx,SlotIndex Kill)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
extendInBlock(SlotIndex StartIdx,SlotIndex Kill)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
removeSegment(SlotIndex Start,SlotIndex End,bool RemoveDeadValNo)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
removeSegment(iterator I,bool RemoveDeadValNo)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
removeValNoIfDead(VNInfo * ValNo)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.
removeValNo(VNInfo * ValNo)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
join(LiveRange & Other,const int * LHSValNoAssignments,const int * RHSValNoAssignments,SmallVectorImpl<VNInfo * > & NewVNInfo)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.
MergeSegmentsInAsValue(const LiveRange & RHS,VNInfo * LHSValNo)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.
MergeValueInAsValue(const LiveRange & RHS,const VNInfo * RHSValNo,VNInfo * LHSValNo)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.
MergeValueNumberInto(VNInfo * V1,VNInfo * V2)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
flushSegmentSet()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
isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const8030b57cec5SDimitry 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
freeSubRange(SubRange * S)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
removeEmptySubRanges()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
clearSubRanges()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.
stripValuesNotDefiningMask(unsigned Reg,LiveInterval::SubRange & SR,LaneBitmask LaneMask,const SlotIndexes & Indexes,const TargetRegisterInfo & TRI,unsigned ComposeSubRegIdx)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
refineSubRanges(BumpPtrAllocator & Allocator,LaneBitmask LaneMask,std::function<void (LiveInterval::SubRange &)> Apply,const SlotIndexes & Indexes,const TargetRegisterInfo & TRI,unsigned ComposeSubRegIdx)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
getSize() const9580b57cec5SDimitry 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
computeSubRangeUndefs(SmallVectorImpl<SlotIndex> & Undefs,LaneBitmask LaneMask,const MachineRegisterInfo & MRI,const SlotIndexes & Indexes) const9650b57cec5SDimitry 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
operator <<(raw_ostream & OS,const LiveRange::Segment & S)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)
dump() const9940b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveRange::Segment::dump() const {
9950b57cec5SDimitry Andric dbgs() << *this << '\n';
9960b57cec5SDimitry Andric }
9970b57cec5SDimitry Andric #endif
9980b57cec5SDimitry Andric
print(raw_ostream & OS) const9990b57cec5SDimitry 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
print(raw_ostream & OS) const10290b57cec5SDimitry 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
print(raw_ostream & OS) const10340b57cec5SDimitry 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)
dump() const10440b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveRange::dump() const {
10450b57cec5SDimitry Andric dbgs() << *this << '\n';
10460b57cec5SDimitry Andric }
10470b57cec5SDimitry Andric
dump() const10480b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveInterval::SubRange::dump() const {
10490b57cec5SDimitry Andric dbgs() << *this << '\n';
10500b57cec5SDimitry Andric }
10510b57cec5SDimitry Andric
dump() const10520b57cec5SDimitry Andric LLVM_DUMP_METHOD void LiveInterval::dump() const {
10530b57cec5SDimitry Andric dbgs() << *this << '\n';
10540b57cec5SDimitry Andric }
10550b57cec5SDimitry Andric #endif
10560b57cec5SDimitry Andric
10570b57cec5SDimitry Andric #ifndef NDEBUG
verify() const10580b57cec5SDimitry 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
verify(const MachineRegisterInfo * MRI) const10740b57cec5SDimitry 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)
print(raw_ostream & OS) const11280b57cec5SDimitry 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
dump() const11510b57cec5SDimitry 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.
coalescable(const LiveRange::Segment & A,const LiveRange::Segment & B)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
add(LiveRange::Segment Seg)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.
mergeSpills()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
flush()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
Classify(const LiveRange & LR)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
Distribute(LiveInterval & LI,LiveInterval * LIV[],MachineRegisterInfo & MRI)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