1044eb2f6SDimitry Andric //===- LiveInterval.cpp - Live Interval Representation --------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file implements the LiveRange and LiveInterval classes. Given some
10009b1c42SEd Schouten // numbering of each the machine instructions an interval [i, j) is said to be a
11f8af5cf6SDimitry Andric // live range for register v if there is no instruction with number j' >= j
12829000e0SRoman Divacky // such that v is live at j' and there is no instruction with number i' < i such
13f8af5cf6SDimitry Andric // that v is live at i'. In this implementation ranges can have holes,
14f8af5cf6SDimitry Andric // i.e. a range might look like [1,20), [50,65), [1000,1001). Each
15f8af5cf6SDimitry Andric // individual segment is represented as an instance of LiveRange::Segment,
16f8af5cf6SDimitry Andric // and the whole range is represented as an instance of LiveRange.
17009b1c42SEd Schouten //
18009b1c42SEd Schouten //===----------------------------------------------------------------------===//
19009b1c42SEd Schouten
20009b1c42SEd Schouten #include "llvm/CodeGen/LiveInterval.h"
2101095a5dSDimitry Andric #include "LiveRangeUtils.h"
224a16efa3SDimitry Andric #include "RegisterCoalescer.h"
23044eb2f6SDimitry Andric #include "llvm/ADT/ArrayRef.h"
244a16efa3SDimitry Andric #include "llvm/ADT/STLExtras.h"
25044eb2f6SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
26044eb2f6SDimitry Andric #include "llvm/ADT/SmallVector.h"
27044eb2f6SDimitry Andric #include "llvm/ADT/iterator_range.h"
28044eb2f6SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
29044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
30044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
31044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
32b2f21fb0SEd Schouten #include "llvm/CodeGen/MachineRegisterInfo.h"
33044eb2f6SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
34044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
35eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
36044eb2f6SDimitry Andric #include "llvm/MC/LaneBitmask.h"
37044eb2f6SDimitry Andric #include "llvm/Support/Compiler.h"
38829000e0SRoman Divacky #include "llvm/Support/Debug.h"
3959850d08SRoman Divacky #include "llvm/Support/raw_ostream.h"
40009b1c42SEd Schouten #include <algorithm>
41044eb2f6SDimitry Andric #include <cassert>
42044eb2f6SDimitry Andric #include <cstddef>
43044eb2f6SDimitry Andric #include <iterator>
44044eb2f6SDimitry Andric #include <utility>
45044eb2f6SDimitry Andric
46009b1c42SEd Schouten using namespace llvm;
47009b1c42SEd Schouten
485a5ac124SDimitry Andric namespace {
49044eb2f6SDimitry Andric
505a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
515a5ac124SDimitry Andric // Implementation of various methods necessary for calculation of live ranges.
525a5ac124SDimitry Andric // The implementation of the methods abstracts from the concrete type of the
535a5ac124SDimitry Andric // segment collection.
545a5ac124SDimitry Andric //
555a5ac124SDimitry Andric // Implementation of the class follows the Template design pattern. The base
565a5ac124SDimitry Andric // class contains generic algorithms that call collection-specific methods,
575a5ac124SDimitry Andric // which are provided in concrete subclasses. In order to avoid virtual calls
585a5ac124SDimitry Andric // these methods are provided by means of C++ template instantiation.
595a5ac124SDimitry Andric // The base class calls the methods of the subclass through method impl(),
605a5ac124SDimitry Andric // which casts 'this' pointer to the type of the subclass.
615a5ac124SDimitry Andric //
625a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
635a5ac124SDimitry Andric
645a5ac124SDimitry Andric template <typename ImplT, typename IteratorT, typename CollectionT>
655a5ac124SDimitry Andric class CalcLiveRangeUtilBase {
665a5ac124SDimitry Andric protected:
675a5ac124SDimitry Andric LiveRange *LR;
685a5ac124SDimitry Andric
695a5ac124SDimitry Andric protected:
CalcLiveRangeUtilBase(LiveRange * LR)705a5ac124SDimitry Andric CalcLiveRangeUtilBase(LiveRange *LR) : LR(LR) {}
715a5ac124SDimitry Andric
725a5ac124SDimitry Andric public:
73044eb2f6SDimitry Andric using Segment = LiveRange::Segment;
74044eb2f6SDimitry Andric using iterator = IteratorT;
755a5ac124SDimitry Andric
76b915e9e0SDimitry Andric /// A counterpart of LiveRange::createDeadDef: Make sure the range has a
77b915e9e0SDimitry Andric /// value defined at @p Def.
78b915e9e0SDimitry Andric /// If @p ForVNI is null, and there is no value defined at @p Def, a new
79b915e9e0SDimitry Andric /// value will be allocated using @p VNInfoAllocator.
80b915e9e0SDimitry Andric /// If @p ForVNI is null, the return value is the value defined at @p Def,
81b915e9e0SDimitry Andric /// either a pre-existing one, or the one newly created.
82b915e9e0SDimitry Andric /// If @p ForVNI is not null, then @p Def should be the location where
83b915e9e0SDimitry Andric /// @p ForVNI is defined. If the range does not have a value defined at
84b915e9e0SDimitry Andric /// @p Def, the value @p ForVNI will be used instead of allocating a new
85b915e9e0SDimitry Andric /// one. If the range already has a value defined at @p Def, it must be
86b915e9e0SDimitry Andric /// same as @p ForVNI. In either case, @p ForVNI will be the return value.
createDeadDef(SlotIndex Def,VNInfo::Allocator * VNInfoAllocator,VNInfo * ForVNI)87b915e9e0SDimitry Andric VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator *VNInfoAllocator,
88b915e9e0SDimitry Andric VNInfo *ForVNI) {
895a5ac124SDimitry Andric assert(!Def.isDead() && "Cannot define a value at the dead slot");
90b915e9e0SDimitry Andric assert((!ForVNI || ForVNI->def == Def) &&
91b915e9e0SDimitry Andric "If ForVNI is specified, it must match Def");
925a5ac124SDimitry Andric iterator I = impl().find(Def);
935a5ac124SDimitry Andric if (I == segments().end()) {
94b915e9e0SDimitry Andric VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
955a5ac124SDimitry Andric impl().insertAtEnd(Segment(Def, Def.getDeadSlot(), VNI));
965a5ac124SDimitry Andric return VNI;
975a5ac124SDimitry Andric }
985a5ac124SDimitry Andric
995a5ac124SDimitry Andric Segment *S = segmentAt(I);
1005a5ac124SDimitry Andric if (SlotIndex::isSameInstr(Def, S->start)) {
101b915e9e0SDimitry Andric assert((!ForVNI || ForVNI == S->valno) && "Value number mismatch");
1025a5ac124SDimitry Andric assert(S->valno->def == S->start && "Inconsistent existing value def");
1035a5ac124SDimitry Andric
1045a5ac124SDimitry Andric // It is possible to have both normal and early-clobber defs of the same
1055a5ac124SDimitry Andric // register on an instruction. It doesn't make a lot of sense, but it is
1065a5ac124SDimitry Andric // possible to specify in inline assembly.
1075a5ac124SDimitry Andric //
1085a5ac124SDimitry Andric // Just convert everything to early-clobber.
1095a5ac124SDimitry Andric Def = std::min(Def, S->start);
1105a5ac124SDimitry Andric if (Def != S->start)
1115a5ac124SDimitry Andric S->start = S->valno->def = Def;
1125a5ac124SDimitry Andric return S->valno;
1135a5ac124SDimitry Andric }
1145a5ac124SDimitry Andric assert(SlotIndex::isEarlierInstr(Def, S->start) && "Already live at def");
115b915e9e0SDimitry Andric VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
1165a5ac124SDimitry Andric segments().insert(I, Segment(Def, Def.getDeadSlot(), VNI));
1175a5ac124SDimitry Andric return VNI;
1185a5ac124SDimitry Andric }
1195a5ac124SDimitry Andric
extendInBlock(SlotIndex StartIdx,SlotIndex Use)1205a5ac124SDimitry Andric VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Use) {
1215a5ac124SDimitry Andric if (segments().empty())
1225a5ac124SDimitry Andric return nullptr;
1235a5ac124SDimitry Andric iterator I =
1245a5ac124SDimitry Andric impl().findInsertPos(Segment(Use.getPrevSlot(), Use, nullptr));
1255a5ac124SDimitry Andric if (I == segments().begin())
1265a5ac124SDimitry Andric return nullptr;
1275a5ac124SDimitry Andric --I;
1285a5ac124SDimitry Andric if (I->end <= StartIdx)
1295a5ac124SDimitry Andric return nullptr;
1305a5ac124SDimitry Andric if (I->end < Use)
1315a5ac124SDimitry Andric extendSegmentEndTo(I, Use);
1325a5ac124SDimitry Andric return I->valno;
1335a5ac124SDimitry Andric }
1345a5ac124SDimitry Andric
extendInBlock(ArrayRef<SlotIndex> Undefs,SlotIndex StartIdx,SlotIndex Use)135b915e9e0SDimitry Andric std::pair<VNInfo*,bool> extendInBlock(ArrayRef<SlotIndex> Undefs,
136b915e9e0SDimitry Andric SlotIndex StartIdx, SlotIndex Use) {
137b915e9e0SDimitry Andric if (segments().empty())
138b915e9e0SDimitry Andric return std::make_pair(nullptr, false);
139b915e9e0SDimitry Andric SlotIndex BeforeUse = Use.getPrevSlot();
140b915e9e0SDimitry Andric iterator I = impl().findInsertPos(Segment(BeforeUse, Use, nullptr));
141b915e9e0SDimitry Andric if (I == segments().begin())
142b915e9e0SDimitry Andric return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
143b915e9e0SDimitry Andric --I;
144b915e9e0SDimitry Andric if (I->end <= StartIdx)
145b915e9e0SDimitry Andric return std::make_pair(nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
146b915e9e0SDimitry Andric if (I->end < Use) {
147b915e9e0SDimitry Andric if (LR->isUndefIn(Undefs, I->end, BeforeUse))
148b915e9e0SDimitry Andric return std::make_pair(nullptr, true);
149b915e9e0SDimitry Andric extendSegmentEndTo(I, Use);
150b915e9e0SDimitry Andric }
151b915e9e0SDimitry Andric return std::make_pair(I->valno, false);
152b915e9e0SDimitry Andric }
153b915e9e0SDimitry Andric
1545a5ac124SDimitry Andric /// This method is used when we want to extend the segment specified
1555a5ac124SDimitry Andric /// by I to end at the specified endpoint. To do this, we should
1565a5ac124SDimitry Andric /// merge and eliminate all segments that this will overlap
1575a5ac124SDimitry Andric /// with. The iterator is not invalidated.
extendSegmentEndTo(iterator I,SlotIndex NewEnd)1585a5ac124SDimitry Andric void extendSegmentEndTo(iterator I, SlotIndex NewEnd) {
1595a5ac124SDimitry Andric assert(I != segments().end() && "Not a valid segment!");
1605a5ac124SDimitry Andric Segment *S = segmentAt(I);
1615a5ac124SDimitry Andric VNInfo *ValNo = I->valno;
1625a5ac124SDimitry Andric
1635a5ac124SDimitry Andric // Search for the first segment that we can't merge with.
1645a5ac124SDimitry Andric iterator MergeTo = std::next(I);
1655a5ac124SDimitry Andric for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo)
1665a5ac124SDimitry Andric assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
1675a5ac124SDimitry Andric
1685a5ac124SDimitry Andric // If NewEnd was in the middle of a segment, make sure to get its endpoint.
1695a5ac124SDimitry Andric S->end = std::max(NewEnd, std::prev(MergeTo)->end);
1705a5ac124SDimitry Andric
1715a5ac124SDimitry Andric // If the newly formed segment now touches the segment after it and if they
1725a5ac124SDimitry Andric // have the same value number, merge the two segments into one segment.
1735a5ac124SDimitry Andric if (MergeTo != segments().end() && MergeTo->start <= I->end &&
1745a5ac124SDimitry Andric MergeTo->valno == ValNo) {
1755a5ac124SDimitry Andric S->end = MergeTo->end;
1765a5ac124SDimitry Andric ++MergeTo;
1775a5ac124SDimitry Andric }
1785a5ac124SDimitry Andric
1795a5ac124SDimitry Andric // Erase any dead segments.
1805a5ac124SDimitry Andric segments().erase(std::next(I), MergeTo);
1815a5ac124SDimitry Andric }
1825a5ac124SDimitry Andric
1835a5ac124SDimitry Andric /// This method is used when we want to extend the segment specified
1845a5ac124SDimitry Andric /// by I to start at the specified endpoint. To do this, we should
1855a5ac124SDimitry Andric /// merge and eliminate all segments that this will overlap with.
extendSegmentStartTo(iterator I,SlotIndex NewStart)1865a5ac124SDimitry Andric iterator extendSegmentStartTo(iterator I, SlotIndex NewStart) {
1875a5ac124SDimitry Andric assert(I != segments().end() && "Not a valid segment!");
1885a5ac124SDimitry Andric Segment *S = segmentAt(I);
1895a5ac124SDimitry Andric VNInfo *ValNo = I->valno;
1905a5ac124SDimitry Andric
1915a5ac124SDimitry Andric // Search for the first segment that we can't merge with.
1925a5ac124SDimitry Andric iterator MergeTo = I;
1935a5ac124SDimitry Andric do {
1945a5ac124SDimitry Andric if (MergeTo == segments().begin()) {
1955a5ac124SDimitry Andric S->start = NewStart;
1965a5ac124SDimitry Andric segments().erase(MergeTo, I);
1975a5ac124SDimitry Andric return I;
1985a5ac124SDimitry Andric }
1995a5ac124SDimitry Andric assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
2005a5ac124SDimitry Andric --MergeTo;
2015a5ac124SDimitry Andric } while (NewStart <= MergeTo->start);
2025a5ac124SDimitry Andric
2035a5ac124SDimitry Andric // If we start in the middle of another segment, just delete a range and
2045a5ac124SDimitry Andric // extend that segment.
2055a5ac124SDimitry Andric if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
2065a5ac124SDimitry Andric segmentAt(MergeTo)->end = S->end;
2075a5ac124SDimitry Andric } else {
2085a5ac124SDimitry Andric // Otherwise, extend the segment right after.
2095a5ac124SDimitry Andric ++MergeTo;
2105a5ac124SDimitry Andric Segment *MergeToSeg = segmentAt(MergeTo);
2115a5ac124SDimitry Andric MergeToSeg->start = NewStart;
2125a5ac124SDimitry Andric MergeToSeg->end = S->end;
2135a5ac124SDimitry Andric }
2145a5ac124SDimitry Andric
2155a5ac124SDimitry Andric segments().erase(std::next(MergeTo), std::next(I));
2165a5ac124SDimitry Andric return MergeTo;
2175a5ac124SDimitry Andric }
2185a5ac124SDimitry Andric
addSegment(Segment S)2195a5ac124SDimitry Andric iterator addSegment(Segment S) {
2205a5ac124SDimitry Andric SlotIndex Start = S.start, End = S.end;
2215a5ac124SDimitry Andric iterator I = impl().findInsertPos(S);
2225a5ac124SDimitry Andric
2235a5ac124SDimitry Andric // If the inserted segment starts in the middle or right at the end of
2245a5ac124SDimitry Andric // another segment, just extend that segment to contain the segment of S.
2255a5ac124SDimitry Andric if (I != segments().begin()) {
2265a5ac124SDimitry Andric iterator B = std::prev(I);
2275a5ac124SDimitry Andric if (S.valno == B->valno) {
2285a5ac124SDimitry Andric if (B->start <= Start && B->end >= Start) {
2295a5ac124SDimitry Andric extendSegmentEndTo(B, End);
2305a5ac124SDimitry Andric return B;
2315a5ac124SDimitry Andric }
2325a5ac124SDimitry Andric } else {
2335a5ac124SDimitry Andric // Check to make sure that we are not overlapping two live segments with
2345a5ac124SDimitry Andric // different valno's.
2355a5ac124SDimitry Andric assert(B->end <= Start &&
2365a5ac124SDimitry Andric "Cannot overlap two segments with differing ValID's"
2375a5ac124SDimitry Andric " (did you def the same reg twice in a MachineInstr?)");
2385a5ac124SDimitry Andric }
2395a5ac124SDimitry Andric }
2405a5ac124SDimitry Andric
2415a5ac124SDimitry Andric // Otherwise, if this segment ends in the middle of, or right next
2425a5ac124SDimitry Andric // to, another segment, merge it into that segment.
2435a5ac124SDimitry Andric if (I != segments().end()) {
2445a5ac124SDimitry Andric if (S.valno == I->valno) {
2455a5ac124SDimitry Andric if (I->start <= End) {
2465a5ac124SDimitry Andric I = extendSegmentStartTo(I, Start);
2475a5ac124SDimitry Andric
2485a5ac124SDimitry Andric // If S is a complete superset of a segment, we may need to grow its
2495a5ac124SDimitry Andric // endpoint as well.
2505a5ac124SDimitry Andric if (End > I->end)
2515a5ac124SDimitry Andric extendSegmentEndTo(I, End);
2525a5ac124SDimitry Andric return I;
2535a5ac124SDimitry Andric }
2545a5ac124SDimitry Andric } else {
2555a5ac124SDimitry Andric // Check to make sure that we are not overlapping two live segments with
2565a5ac124SDimitry Andric // different valno's.
2575a5ac124SDimitry Andric assert(I->start >= End &&
2585a5ac124SDimitry Andric "Cannot overlap two segments with differing ValID's");
2595a5ac124SDimitry Andric }
2605a5ac124SDimitry Andric }
2615a5ac124SDimitry Andric
2625a5ac124SDimitry Andric // Otherwise, this is just a new segment that doesn't interact with
2635a5ac124SDimitry Andric // anything.
2645a5ac124SDimitry Andric // Insert it.
2655a5ac124SDimitry Andric return segments().insert(I, S);
2665a5ac124SDimitry Andric }
2675a5ac124SDimitry Andric
2685a5ac124SDimitry Andric private:
impl()2695a5ac124SDimitry Andric ImplT &impl() { return *static_cast<ImplT *>(this); }
2705a5ac124SDimitry Andric
segments()2715a5ac124SDimitry Andric CollectionT &segments() { return impl().segmentsColl(); }
2725a5ac124SDimitry Andric
segmentAt(iterator I)2735a5ac124SDimitry Andric Segment *segmentAt(iterator I) { return const_cast<Segment *>(&(*I)); }
2745a5ac124SDimitry Andric };
2755a5ac124SDimitry Andric
2765a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
2775a5ac124SDimitry Andric // Instantiation of the methods for calculation of live ranges
2785a5ac124SDimitry Andric // based on a segment vector.
2795a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
2805a5ac124SDimitry Andric
2815a5ac124SDimitry Andric class CalcLiveRangeUtilVector;
282044eb2f6SDimitry Andric using CalcLiveRangeUtilVectorBase =
283044eb2f6SDimitry Andric CalcLiveRangeUtilBase<CalcLiveRangeUtilVector, LiveRange::iterator,
284044eb2f6SDimitry Andric LiveRange::Segments>;
2855a5ac124SDimitry Andric
2865a5ac124SDimitry Andric class CalcLiveRangeUtilVector : public CalcLiveRangeUtilVectorBase {
2875a5ac124SDimitry Andric public:
CalcLiveRangeUtilVector(LiveRange * LR)2885a5ac124SDimitry Andric CalcLiveRangeUtilVector(LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}
2895a5ac124SDimitry Andric
2905a5ac124SDimitry Andric private:
2915a5ac124SDimitry Andric friend CalcLiveRangeUtilVectorBase;
2925a5ac124SDimitry Andric
segmentsColl()2935a5ac124SDimitry Andric LiveRange::Segments &segmentsColl() { return LR->segments; }
2945a5ac124SDimitry Andric
insertAtEnd(const Segment & S)2955a5ac124SDimitry Andric void insertAtEnd(const Segment &S) { LR->segments.push_back(S); }
2965a5ac124SDimitry Andric
find(SlotIndex Pos)2975a5ac124SDimitry Andric iterator find(SlotIndex Pos) { return LR->find(Pos); }
2985a5ac124SDimitry Andric
findInsertPos(Segment S)299e6d15924SDimitry Andric iterator findInsertPos(Segment S) { return llvm::upper_bound(*LR, S.start); }
3005a5ac124SDimitry Andric };
3015a5ac124SDimitry Andric
3025a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
3035a5ac124SDimitry Andric // Instantiation of the methods for calculation of live ranges
3045a5ac124SDimitry Andric // based on a segment set.
3055a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
3065a5ac124SDimitry Andric
3075a5ac124SDimitry Andric class CalcLiveRangeUtilSet;
308044eb2f6SDimitry Andric using CalcLiveRangeUtilSetBase =
309044eb2f6SDimitry Andric CalcLiveRangeUtilBase<CalcLiveRangeUtilSet, LiveRange::SegmentSet::iterator,
310044eb2f6SDimitry Andric LiveRange::SegmentSet>;
3115a5ac124SDimitry Andric
3125a5ac124SDimitry Andric class CalcLiveRangeUtilSet : public CalcLiveRangeUtilSetBase {
3135a5ac124SDimitry Andric public:
CalcLiveRangeUtilSet(LiveRange * LR)3145a5ac124SDimitry Andric CalcLiveRangeUtilSet(LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}
3155a5ac124SDimitry Andric
3165a5ac124SDimitry Andric private:
3175a5ac124SDimitry Andric friend CalcLiveRangeUtilSetBase;
3185a5ac124SDimitry Andric
segmentsColl()3195a5ac124SDimitry Andric LiveRange::SegmentSet &segmentsColl() { return *LR->segmentSet; }
3205a5ac124SDimitry Andric
insertAtEnd(const Segment & S)3215a5ac124SDimitry Andric void insertAtEnd(const Segment &S) {
3225a5ac124SDimitry Andric LR->segmentSet->insert(LR->segmentSet->end(), S);
3235a5ac124SDimitry Andric }
3245a5ac124SDimitry Andric
find(SlotIndex Pos)3255a5ac124SDimitry Andric iterator find(SlotIndex Pos) {
3265a5ac124SDimitry Andric iterator I =
3275a5ac124SDimitry Andric LR->segmentSet->upper_bound(Segment(Pos, Pos.getNextSlot(), nullptr));
3285a5ac124SDimitry Andric if (I == LR->segmentSet->begin())
3295a5ac124SDimitry Andric return I;
3305a5ac124SDimitry Andric iterator PrevI = std::prev(I);
3315a5ac124SDimitry Andric if (Pos < (*PrevI).end)
3325a5ac124SDimitry Andric return PrevI;
3335a5ac124SDimitry Andric return I;
3345a5ac124SDimitry Andric }
3355a5ac124SDimitry Andric
findInsertPos(Segment S)3365a5ac124SDimitry Andric iterator findInsertPos(Segment S) {
3375a5ac124SDimitry Andric iterator I = LR->segmentSet->upper_bound(S);
3385a5ac124SDimitry Andric if (I != LR->segmentSet->end() && !(S.start < *I))
3395a5ac124SDimitry Andric ++I;
3405a5ac124SDimitry Andric return I;
3415a5ac124SDimitry Andric }
3425a5ac124SDimitry Andric };
343044eb2f6SDimitry Andric
344044eb2f6SDimitry Andric } // end anonymous namespace
3455a5ac124SDimitry Andric
3465a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
3475a5ac124SDimitry Andric // LiveRange methods
3485a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
3495a5ac124SDimitry Andric
find(SlotIndex Pos)350f8af5cf6SDimitry Andric LiveRange::iterator LiveRange::find(SlotIndex Pos) {
351145449b1SDimitry Andric return llvm::partition_point(*this,
352145449b1SDimitry Andric [&](const Segment &X) { return X.end <= Pos; });
35366e41e3cSRoman Divacky }
35466e41e3cSRoman Divacky
createDeadDef(SlotIndex Def,VNInfo::Allocator & VNIAlloc)355b915e9e0SDimitry Andric VNInfo *LiveRange::createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc) {
3565a5ac124SDimitry Andric // Use the segment set, if it is available.
3575a5ac124SDimitry Andric if (segmentSet != nullptr)
358b915e9e0SDimitry Andric return CalcLiveRangeUtilSet(this).createDeadDef(Def, &VNIAlloc, nullptr);
3595a5ac124SDimitry Andric // Otherwise use the segment vector.
360b915e9e0SDimitry Andric return CalcLiveRangeUtilVector(this).createDeadDef(Def, &VNIAlloc, nullptr);
361b915e9e0SDimitry Andric }
362b915e9e0SDimitry Andric
createDeadDef(VNInfo * VNI)363b915e9e0SDimitry Andric VNInfo *LiveRange::createDeadDef(VNInfo *VNI) {
364b915e9e0SDimitry Andric // Use the segment set, if it is available.
365b915e9e0SDimitry Andric if (segmentSet != nullptr)
366b915e9e0SDimitry Andric return CalcLiveRangeUtilSet(this).createDeadDef(VNI->def, nullptr, VNI);
367b915e9e0SDimitry Andric // Otherwise use the segment vector.
368b915e9e0SDimitry Andric return CalcLiveRangeUtilVector(this).createDeadDef(VNI->def, nullptr, VNI);
36958b69754SDimitry Andric }
37058b69754SDimitry Andric
371f8af5cf6SDimitry Andric // overlaps - Return true if the intersection of the two live ranges is
372009b1c42SEd Schouten // not empty.
373009b1c42SEd Schouten //
374009b1c42SEd Schouten // An example for overlaps():
375009b1c42SEd Schouten //
376009b1c42SEd Schouten // 0: A = ...
377009b1c42SEd Schouten // 4: B = ...
378009b1c42SEd Schouten // 8: C = A + B ;; last use of A
379009b1c42SEd Schouten //
380f8af5cf6SDimitry Andric // The live ranges should look like:
381009b1c42SEd Schouten //
382009b1c42SEd Schouten // A = [3, 11)
383009b1c42SEd Schouten // B = [7, x)
384009b1c42SEd Schouten // C = [11, y)
385009b1c42SEd Schouten //
386009b1c42SEd Schouten // A->overlaps(C) should return false since we want to be able to join
387009b1c42SEd Schouten // A and C.
388009b1c42SEd Schouten //
overlapsFrom(const LiveRange & other,const_iterator StartPos) const389f8af5cf6SDimitry Andric bool LiveRange::overlapsFrom(const LiveRange& other,
390009b1c42SEd Schouten const_iterator StartPos) const {
391f8af5cf6SDimitry Andric assert(!empty() && "empty range");
392009b1c42SEd Schouten const_iterator i = begin();
393009b1c42SEd Schouten const_iterator ie = end();
394009b1c42SEd Schouten const_iterator j = StartPos;
395009b1c42SEd Schouten const_iterator je = other.end();
396009b1c42SEd Schouten
397009b1c42SEd Schouten assert((StartPos->start <= i->start || StartPos == other.begin()) &&
398009b1c42SEd Schouten StartPos != other.end() && "Bogus start position hint!");
399009b1c42SEd Schouten
400009b1c42SEd Schouten if (i->start < j->start) {
401009b1c42SEd Schouten i = std::upper_bound(i, ie, j->start);
402f8af5cf6SDimitry Andric if (i != begin()) --i;
403009b1c42SEd Schouten } else if (j->start < i->start) {
404009b1c42SEd Schouten ++StartPos;
405009b1c42SEd Schouten if (StartPos != other.end() && StartPos->start <= i->start) {
406009b1c42SEd Schouten assert(StartPos < other.end() && i < end());
407009b1c42SEd Schouten j = std::upper_bound(j, je, i->start);
408f8af5cf6SDimitry Andric if (j != other.begin()) --j;
409009b1c42SEd Schouten }
410009b1c42SEd Schouten } else {
411009b1c42SEd Schouten return true;
412009b1c42SEd Schouten }
413009b1c42SEd Schouten
414009b1c42SEd Schouten if (j == je) return false;
415009b1c42SEd Schouten
416009b1c42SEd Schouten while (i != ie) {
417009b1c42SEd Schouten if (i->start > j->start) {
418009b1c42SEd Schouten std::swap(i, j);
419009b1c42SEd Schouten std::swap(ie, je);
420009b1c42SEd Schouten }
421009b1c42SEd Schouten
422009b1c42SEd Schouten if (i->end > j->start)
423009b1c42SEd Schouten return true;
424009b1c42SEd Schouten ++i;
425009b1c42SEd Schouten }
426009b1c42SEd Schouten
427009b1c42SEd Schouten return false;
428009b1c42SEd Schouten }
429009b1c42SEd Schouten
overlaps(const LiveRange & Other,const CoalescerPair & CP,const SlotIndexes & Indexes) const430f8af5cf6SDimitry Andric bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP,
431522600a2SDimitry Andric const SlotIndexes &Indexes) const {
432f8af5cf6SDimitry Andric assert(!empty() && "empty range");
433522600a2SDimitry Andric if (Other.empty())
434522600a2SDimitry Andric return false;
435522600a2SDimitry Andric
436522600a2SDimitry Andric // Use binary searches to find initial positions.
437522600a2SDimitry Andric const_iterator I = find(Other.beginIndex());
438522600a2SDimitry Andric const_iterator IE = end();
439522600a2SDimitry Andric if (I == IE)
440522600a2SDimitry Andric return false;
441522600a2SDimitry Andric const_iterator J = Other.find(I->start);
442522600a2SDimitry Andric const_iterator JE = Other.end();
443522600a2SDimitry Andric if (J == JE)
444522600a2SDimitry Andric return false;
445522600a2SDimitry Andric
446044eb2f6SDimitry Andric while (true) {
447522600a2SDimitry Andric // J has just been advanced to satisfy:
4487fa27ce4SDimitry Andric assert(J->end > I->start);
449522600a2SDimitry Andric // Check for an overlap.
450522600a2SDimitry Andric if (J->start < I->end) {
451522600a2SDimitry Andric // I and J are overlapping. Find the later start.
452522600a2SDimitry Andric SlotIndex Def = std::max(I->start, J->start);
453522600a2SDimitry Andric // Allow the overlap if Def is a coalescable copy.
454522600a2SDimitry Andric if (Def.isBlock() ||
455522600a2SDimitry Andric !CP.isCoalescable(Indexes.getInstructionFromIndex(Def)))
456522600a2SDimitry Andric return true;
457522600a2SDimitry Andric }
458522600a2SDimitry Andric // Advance the iterator that ends first to check for more overlaps.
459522600a2SDimitry Andric if (J->end > I->end) {
460522600a2SDimitry Andric std::swap(I, J);
461522600a2SDimitry Andric std::swap(IE, JE);
462522600a2SDimitry Andric }
4637fa27ce4SDimitry Andric // Advance J until J->end > I->start.
464522600a2SDimitry Andric do
465522600a2SDimitry Andric if (++J == JE)
466522600a2SDimitry Andric return false;
4677fa27ce4SDimitry Andric while (J->end <= I->start);
468522600a2SDimitry Andric }
469522600a2SDimitry Andric }
470522600a2SDimitry Andric
471f8af5cf6SDimitry Andric /// overlaps - Return true if the live range overlaps an interval specified
472009b1c42SEd Schouten /// by [Start, End).
overlaps(SlotIndex Start,SlotIndex End) const473f8af5cf6SDimitry Andric bool LiveRange::overlaps(SlotIndex Start, SlotIndex End) const {
474009b1c42SEd Schouten assert(Start < End && "Invalid range");
475344a3780SDimitry Andric const_iterator I = lower_bound(*this, End);
476f3d15b0bSRoman Divacky return I != begin() && (--I)->end > Start;
477009b1c42SEd Schouten }
478009b1c42SEd Schouten
covers(const LiveRange & Other) const47967c32a98SDimitry Andric bool LiveRange::covers(const LiveRange &Other) const {
48067c32a98SDimitry Andric if (empty())
48167c32a98SDimitry Andric return Other.empty();
48267c32a98SDimitry Andric
48367c32a98SDimitry Andric const_iterator I = begin();
48467c32a98SDimitry Andric for (const Segment &O : Other.segments) {
48567c32a98SDimitry Andric I = advanceTo(I, O.start);
48667c32a98SDimitry Andric if (I == end() || I->start > O.start)
48767c32a98SDimitry Andric return false;
48867c32a98SDimitry Andric
48967c32a98SDimitry Andric // Check adjacent live segments and see if we can get behind O.end.
49067c32a98SDimitry Andric while (I->end < O.end) {
49167c32a98SDimitry Andric const_iterator Last = I;
49267c32a98SDimitry Andric // Get next segment and abort if it was not adjacent.
49367c32a98SDimitry Andric ++I;
49467c32a98SDimitry Andric if (I == end() || Last->end != I->start)
49567c32a98SDimitry Andric return false;
49667c32a98SDimitry Andric }
49767c32a98SDimitry Andric }
49867c32a98SDimitry Andric return true;
49967c32a98SDimitry Andric }
500d39c594dSDimitry Andric
501d39c594dSDimitry Andric /// ValNo is dead, remove it. If it is the largest value number, just nuke it
502d39c594dSDimitry Andric /// (and any other deleted values neighboring it), otherwise mark it as ~1U so
503d39c594dSDimitry Andric /// it can be nuked later.
markValNoForDeletion(VNInfo * ValNo)504f8af5cf6SDimitry Andric void LiveRange::markValNoForDeletion(VNInfo *ValNo) {
505d39c594dSDimitry Andric if (ValNo->id == getNumValNums()-1) {
506d39c594dSDimitry Andric do {
507d39c594dSDimitry Andric valnos.pop_back();
508d39c594dSDimitry Andric } while (!valnos.empty() && valnos.back()->isUnused());
509d39c594dSDimitry Andric } else {
51058b69754SDimitry Andric ValNo->markUnused();
511d39c594dSDimitry Andric }
512d39c594dSDimitry Andric }
513d39c594dSDimitry Andric
514d39c594dSDimitry Andric /// RenumberValues - Renumber all values in order of appearance and delete the
515d39c594dSDimitry Andric /// remaining unused values.
RenumberValues()516f8af5cf6SDimitry Andric void LiveRange::RenumberValues() {
517d39c594dSDimitry Andric SmallPtrSet<VNInfo*, 8> Seen;
518d39c594dSDimitry Andric valnos.clear();
51967c32a98SDimitry Andric for (const Segment &S : segments) {
52067c32a98SDimitry Andric VNInfo *VNI = S.valno;
52167c32a98SDimitry Andric if (!Seen.insert(VNI).second)
522d39c594dSDimitry Andric continue;
523f8af5cf6SDimitry Andric assert(!VNI->isUnused() && "Unused valno used by live segment");
524d39c594dSDimitry Andric VNI->id = (unsigned)valnos.size();
525d39c594dSDimitry Andric valnos.push_back(VNI);
526d39c594dSDimitry Andric }
527d39c594dSDimitry Andric }
528d39c594dSDimitry Andric
addSegmentToSet(Segment S)5295a5ac124SDimitry Andric void LiveRange::addSegmentToSet(Segment S) {
5305a5ac124SDimitry Andric CalcLiveRangeUtilSet(this).addSegment(S);
531009b1c42SEd Schouten }
532009b1c42SEd Schouten
addSegment(Segment S)5335a5ac124SDimitry Andric LiveRange::iterator LiveRange::addSegment(Segment S) {
5345a5ac124SDimitry Andric // Use the segment set, if it is available.
5355a5ac124SDimitry Andric if (segmentSet != nullptr) {
5365a5ac124SDimitry Andric addSegmentToSet(S);
5375a5ac124SDimitry Andric return end();
538009b1c42SEd Schouten }
5395a5ac124SDimitry Andric // Otherwise use the segment vector.
5405a5ac124SDimitry Andric return CalcLiveRangeUtilVector(this).addSegment(S);
541009b1c42SEd Schouten }
542009b1c42SEd Schouten
append(const Segment S)54367c32a98SDimitry Andric void LiveRange::append(const Segment S) {
54467c32a98SDimitry Andric // Check that the segment belongs to the back of the list.
54567c32a98SDimitry Andric assert(segments.empty() || segments.back().end <= S.start);
54667c32a98SDimitry Andric segments.push_back(S);
54767c32a98SDimitry Andric }
54867c32a98SDimitry Andric
extendInBlock(ArrayRef<SlotIndex> Undefs,SlotIndex StartIdx,SlotIndex Kill)549b915e9e0SDimitry Andric std::pair<VNInfo*,bool> LiveRange::extendInBlock(ArrayRef<SlotIndex> Undefs,
550b915e9e0SDimitry Andric SlotIndex StartIdx, SlotIndex Kill) {
551b915e9e0SDimitry Andric // Use the segment set, if it is available.
552b915e9e0SDimitry Andric if (segmentSet != nullptr)
553b915e9e0SDimitry Andric return CalcLiveRangeUtilSet(this).extendInBlock(Undefs, StartIdx, Kill);
554b915e9e0SDimitry Andric // Otherwise use the segment vector.
555b915e9e0SDimitry Andric return CalcLiveRangeUtilVector(this).extendInBlock(Undefs, StartIdx, Kill);
556b915e9e0SDimitry Andric }
557b915e9e0SDimitry Andric
extendInBlock(SlotIndex StartIdx,SlotIndex Kill)558f8af5cf6SDimitry Andric VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
5595a5ac124SDimitry Andric // Use the segment set, if it is available.
5605a5ac124SDimitry Andric if (segmentSet != nullptr)
5615a5ac124SDimitry Andric return CalcLiveRangeUtilSet(this).extendInBlock(StartIdx, Kill);
5625a5ac124SDimitry Andric // Otherwise use the segment vector.
5635a5ac124SDimitry Andric return CalcLiveRangeUtilVector(this).extendInBlock(StartIdx, Kill);
5646b943ff3SDimitry Andric }
565009b1c42SEd Schouten
removeSegment(SlotIndex Start,SlotIndex End,bool RemoveDeadValNo)566f8af5cf6SDimitry Andric void LiveRange::removeSegment(SlotIndex Start, SlotIndex End,
567009b1c42SEd Schouten bool RemoveDeadValNo) {
568f8af5cf6SDimitry Andric // Find the Segment containing this span.
569f8af5cf6SDimitry Andric iterator I = find(Start);
570b1c73532SDimitry Andric
571b1c73532SDimitry Andric // No Segment found, so nothing to do.
572b1c73532SDimitry Andric if (I == end())
573b1c73532SDimitry Andric return;
574b1c73532SDimitry Andric
575f8af5cf6SDimitry Andric assert(I->containsInterval(Start, End)
576f8af5cf6SDimitry Andric && "Segment is not entirely in range!");
577009b1c42SEd Schouten
578f8af5cf6SDimitry Andric // If the span we are removing is at the start of the Segment, adjust it.
579009b1c42SEd Schouten VNInfo *ValNo = I->valno;
580009b1c42SEd Schouten if (I->start == Start) {
581009b1c42SEd Schouten if (I->end == End) {
582f8af5cf6SDimitry Andric segments.erase(I); // Removed the whole Segment.
583c0981da4SDimitry Andric
584c0981da4SDimitry Andric if (RemoveDeadValNo)
585c0981da4SDimitry Andric removeValNoIfDead(ValNo);
586009b1c42SEd Schouten } else
587009b1c42SEd Schouten I->start = End;
588009b1c42SEd Schouten return;
589009b1c42SEd Schouten }
590009b1c42SEd Schouten
591f8af5cf6SDimitry Andric // Otherwise if the span we are removing is at the end of the Segment,
592009b1c42SEd Schouten // adjust the other way.
593009b1c42SEd Schouten if (I->end == End) {
594009b1c42SEd Schouten I->end = Start;
595009b1c42SEd Schouten return;
596009b1c42SEd Schouten }
597009b1c42SEd Schouten
598f8af5cf6SDimitry Andric // Otherwise, we are splitting the Segment into two pieces.
59936bf506aSRoman Divacky SlotIndex OldEnd = I->end;
600f8af5cf6SDimitry Andric I->end = Start; // Trim the old segment.
601009b1c42SEd Schouten
602009b1c42SEd Schouten // Insert the new one.
6035ca98fd9SDimitry Andric segments.insert(std::next(I), Segment(End, OldEnd, ValNo));
604009b1c42SEd Schouten }
605009b1c42SEd Schouten
removeSegment(iterator I,bool RemoveDeadValNo)606c0981da4SDimitry Andric LiveRange::iterator LiveRange::removeSegment(iterator I, bool RemoveDeadValNo) {
607c0981da4SDimitry Andric VNInfo *ValNo = I->valno;
608c0981da4SDimitry Andric I = segments.erase(I);
609c0981da4SDimitry Andric if (RemoveDeadValNo)
610c0981da4SDimitry Andric removeValNoIfDead(ValNo);
611c0981da4SDimitry Andric return I;
612c0981da4SDimitry Andric }
613c0981da4SDimitry Andric
removeValNoIfDead(VNInfo * ValNo)614c0981da4SDimitry Andric void LiveRange::removeValNoIfDead(VNInfo *ValNo) {
615c0981da4SDimitry Andric if (none_of(*this, [=](const Segment &S) { return S.valno == ValNo; }))
616c0981da4SDimitry Andric markValNoForDeletion(ValNo);
617c0981da4SDimitry Andric }
618c0981da4SDimitry Andric
619f8af5cf6SDimitry Andric /// removeValNo - Remove all the segments defined by the specified value#.
620009b1c42SEd Schouten /// Also remove the value# from value# list.
removeValNo(VNInfo * ValNo)621f8af5cf6SDimitry Andric void LiveRange::removeValNo(VNInfo *ValNo) {
622009b1c42SEd Schouten if (empty()) return;
623c0981da4SDimitry Andric llvm::erase_if(segments,
624c0981da4SDimitry Andric [ValNo](const Segment &S) { return S.valno == ValNo; });
625d39c594dSDimitry Andric // Now that ValNo is dead, remove it.
626d39c594dSDimitry Andric markValNoForDeletion(ValNo);
627009b1c42SEd Schouten }
628009b1c42SEd Schouten
join(LiveRange & Other,const int * LHSValNoAssignments,const int * RHSValNoAssignments,SmallVectorImpl<VNInfo * > & NewVNInfo)629f8af5cf6SDimitry Andric void LiveRange::join(LiveRange &Other,
63036bf506aSRoman Divacky const int *LHSValNoAssignments,
631009b1c42SEd Schouten const int *RHSValNoAssignments,
632f8af5cf6SDimitry Andric SmallVectorImpl<VNInfo *> &NewVNInfo) {
63358b69754SDimitry Andric verify();
634b1c73532SDimitry Andric Other.verify();
63558b69754SDimitry Andric
636f8af5cf6SDimitry Andric // Determine if any of our values are mapped. This is uncommon, so we want
637f8af5cf6SDimitry Andric // to avoid the range scan if not.
638009b1c42SEd Schouten bool MustMapCurValNos = false;
639009b1c42SEd Schouten unsigned NumVals = getNumValNums();
640009b1c42SEd Schouten unsigned NumNewVals = NewVNInfo.size();
641009b1c42SEd Schouten for (unsigned i = 0; i != NumVals; ++i) {
642009b1c42SEd Schouten unsigned LHSValID = LHSValNoAssignments[i];
643009b1c42SEd Schouten if (i != LHSValID ||
64463faed5bSDimitry Andric (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) {
645009b1c42SEd Schouten MustMapCurValNos = true;
64663faed5bSDimitry Andric break;
64763faed5bSDimitry Andric }
648009b1c42SEd Schouten }
649009b1c42SEd Schouten
650f8af5cf6SDimitry Andric // If we have to apply a mapping to our base range assignment, rewrite it now.
651522600a2SDimitry Andric if (MustMapCurValNos && !empty()) {
652009b1c42SEd Schouten // Map the first live range.
65363faed5bSDimitry Andric
654009b1c42SEd Schouten iterator OutIt = begin();
655009b1c42SEd Schouten OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]];
6565ca98fd9SDimitry Andric for (iterator I = std::next(OutIt), E = end(); I != E; ++I) {
65763faed5bSDimitry Andric VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]];
6585ca98fd9SDimitry Andric assert(nextValNo && "Huh?");
659009b1c42SEd Schouten
660009b1c42SEd Schouten // If this live range has the same value # as its immediate predecessor,
661f8af5cf6SDimitry Andric // and if they are neighbors, remove one Segment. This happens when we
66263faed5bSDimitry Andric // have [0,4:0)[4,7:1) and map 0/1 onto the same value #.
66363faed5bSDimitry Andric if (OutIt->valno == nextValNo && OutIt->end == I->start) {
66463faed5bSDimitry Andric OutIt->end = I->end;
665009b1c42SEd Schouten } else {
666f8af5cf6SDimitry Andric // Didn't merge. Move OutIt to the next segment,
66763faed5bSDimitry Andric ++OutIt;
66863faed5bSDimitry Andric OutIt->valno = nextValNo;
66963faed5bSDimitry Andric if (OutIt != I) {
670009b1c42SEd Schouten OutIt->start = I->start;
671009b1c42SEd Schouten OutIt->end = I->end;
672009b1c42SEd Schouten }
673009b1c42SEd Schouten }
674009b1c42SEd Schouten }
675f8af5cf6SDimitry Andric // If we merge some segments, chop off the end.
67663faed5bSDimitry Andric ++OutIt;
677f8af5cf6SDimitry Andric segments.erase(OutIt, end());
678009b1c42SEd Schouten }
679009b1c42SEd Schouten
6804a16efa3SDimitry Andric // Rewrite Other values before changing the VNInfo ids.
6814a16efa3SDimitry Andric // This can leave Other in an invalid state because we're not coalescing
6824a16efa3SDimitry Andric // touching segments that now have identical values. That's OK since Other is
6834a16efa3SDimitry Andric // not supposed to be valid after calling join();
68467c32a98SDimitry Andric for (Segment &S : Other.segments)
68567c32a98SDimitry Andric S.valno = NewVNInfo[RHSValNoAssignments[S.valno->id]];
686009b1c42SEd Schouten
687009b1c42SEd Schouten // Update val# info. Renumber them and make sure they all belong to this
688f8af5cf6SDimitry Andric // LiveRange now. Also remove dead val#'s.
689009b1c42SEd Schouten unsigned NumValNos = 0;
690009b1c42SEd Schouten for (unsigned i = 0; i < NumNewVals; ++i) {
691009b1c42SEd Schouten VNInfo *VNI = NewVNInfo[i];
692009b1c42SEd Schouten if (VNI) {
693009b1c42SEd Schouten if (NumValNos >= NumVals)
694009b1c42SEd Schouten valnos.push_back(VNI);
695009b1c42SEd Schouten else
696009b1c42SEd Schouten valnos[NumValNos] = VNI;
697009b1c42SEd Schouten VNI->id = NumValNos++; // Renumber val#.
698009b1c42SEd Schouten }
699009b1c42SEd Schouten }
700009b1c42SEd Schouten if (NumNewVals < NumVals)
701009b1c42SEd Schouten valnos.resize(NumNewVals); // shrinkify
702009b1c42SEd Schouten
703f8af5cf6SDimitry Andric // Okay, now insert the RHS live segments into the LHS.
7044a16efa3SDimitry Andric LiveRangeUpdater Updater(this);
70567c32a98SDimitry Andric for (Segment &S : Other.segments)
70667c32a98SDimitry Andric Updater.add(S);
707009b1c42SEd Schouten }
708009b1c42SEd Schouten
709f8af5cf6SDimitry Andric /// Merge all of the segments in RHS into this live range as the specified
710f8af5cf6SDimitry Andric /// value number. The segments in RHS are allowed to overlap with segments in
711f8af5cf6SDimitry Andric /// the current range, but only if the overlapping segments have the
712f8af5cf6SDimitry Andric /// specified value number.
MergeSegmentsInAsValue(const LiveRange & RHS,VNInfo * LHSValNo)713f8af5cf6SDimitry Andric void LiveRange::MergeSegmentsInAsValue(const LiveRange &RHS,
714009b1c42SEd Schouten VNInfo *LHSValNo) {
7154a16efa3SDimitry Andric LiveRangeUpdater Updater(this);
71667c32a98SDimitry Andric for (const Segment &S : RHS.segments)
71767c32a98SDimitry Andric Updater.add(S.start, S.end, LHSValNo);
718009b1c42SEd Schouten }
719009b1c42SEd Schouten
720f8af5cf6SDimitry Andric /// MergeValueInAsValue - Merge all of the live segments of a specific val#
721f8af5cf6SDimitry Andric /// in RHS into this live range as the specified value number.
722f8af5cf6SDimitry Andric /// The segments in RHS are allowed to overlap with segments in the
723f8af5cf6SDimitry Andric /// current range, it will replace the value numbers of the overlaped
724f8af5cf6SDimitry Andric /// segments with the specified value number.
MergeValueInAsValue(const LiveRange & RHS,const VNInfo * RHSValNo,VNInfo * LHSValNo)725f8af5cf6SDimitry Andric void LiveRange::MergeValueInAsValue(const LiveRange &RHS,
72658b69754SDimitry Andric const VNInfo *RHSValNo,
72758b69754SDimitry Andric VNInfo *LHSValNo) {
7284a16efa3SDimitry Andric LiveRangeUpdater Updater(this);
72967c32a98SDimitry Andric for (const Segment &S : RHS.segments)
73067c32a98SDimitry Andric if (S.valno == RHSValNo)
73167c32a98SDimitry Andric Updater.add(S.start, S.end, LHSValNo);
732009b1c42SEd Schouten }
733009b1c42SEd Schouten
734009b1c42SEd Schouten /// MergeValueNumberInto - This method is called when two value nubmers
735009b1c42SEd Schouten /// are found to be equivalent. This eliminates V1, replacing all
736f8af5cf6SDimitry Andric /// segments with the V1 value number with the V2 value number. This can
737009b1c42SEd Schouten /// cause merging of V1/V2 values numbers and compaction of the value space.
MergeValueNumberInto(VNInfo * V1,VNInfo * V2)738f8af5cf6SDimitry Andric VNInfo *LiveRange::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
739009b1c42SEd Schouten assert(V1 != V2 && "Identical value#'s are always equivalent!");
740009b1c42SEd Schouten
741009b1c42SEd Schouten // This code actually merges the (numerically) larger value number into the
742009b1c42SEd Schouten // smaller value number, which is likely to allow us to compactify the value
743009b1c42SEd Schouten // space. The only thing we have to be careful of is to preserve the
744009b1c42SEd Schouten // instruction that defines the result value.
745009b1c42SEd Schouten
746009b1c42SEd Schouten // Make sure V2 is smaller than V1.
747009b1c42SEd Schouten if (V1->id < V2->id) {
74859850d08SRoman Divacky V1->copyFrom(*V2);
749009b1c42SEd Schouten std::swap(V1, V2);
750009b1c42SEd Schouten }
751009b1c42SEd Schouten
752f8af5cf6SDimitry Andric // Merge V1 segments into V2.
753009b1c42SEd Schouten for (iterator I = begin(); I != end(); ) {
754f8af5cf6SDimitry Andric iterator S = I++;
755f8af5cf6SDimitry Andric if (S->valno != V1) continue; // Not a V1 Segment.
756009b1c42SEd Schouten
757009b1c42SEd Schouten // Okay, we found a V1 live range. If it had a previous, touching, V2 live
758009b1c42SEd Schouten // range, extend it.
759f8af5cf6SDimitry Andric if (S != begin()) {
760f8af5cf6SDimitry Andric iterator Prev = S-1;
761f8af5cf6SDimitry Andric if (Prev->valno == V2 && Prev->end == S->start) {
762f8af5cf6SDimitry Andric Prev->end = S->end;
763009b1c42SEd Schouten
764009b1c42SEd Schouten // Erase this live-range.
765f8af5cf6SDimitry Andric segments.erase(S);
766009b1c42SEd Schouten I = Prev+1;
767f8af5cf6SDimitry Andric S = Prev;
768009b1c42SEd Schouten }
769009b1c42SEd Schouten }
770009b1c42SEd Schouten
771009b1c42SEd Schouten // Okay, now we have a V1 or V2 live range that is maximally merged forward.
772009b1c42SEd Schouten // Ensure that it is a V2 live-range.
773f8af5cf6SDimitry Andric S->valno = V2;
774009b1c42SEd Schouten
775f8af5cf6SDimitry Andric // If we can merge it into later V2 segments, do so now. We ignore any
776f8af5cf6SDimitry Andric // following V1 segments, as they will be merged in subsequent iterations
777009b1c42SEd Schouten // of the loop.
778009b1c42SEd Schouten if (I != end()) {
779f8af5cf6SDimitry Andric if (I->start == S->end && I->valno == V2) {
780f8af5cf6SDimitry Andric S->end = I->end;
781f8af5cf6SDimitry Andric segments.erase(I);
782f8af5cf6SDimitry Andric I = S+1;
783009b1c42SEd Schouten }
784009b1c42SEd Schouten }
785009b1c42SEd Schouten }
786009b1c42SEd Schouten
787d39c594dSDimitry Andric // Now that V1 is dead, remove it.
788d39c594dSDimitry Andric markValNoForDeletion(V1);
789009b1c42SEd Schouten
790009b1c42SEd Schouten return V2;
791009b1c42SEd Schouten }
792009b1c42SEd Schouten
flushSegmentSet()7935a5ac124SDimitry Andric void LiveRange::flushSegmentSet() {
7945a5ac124SDimitry Andric assert(segmentSet != nullptr && "segment set must have been created");
7955a5ac124SDimitry Andric assert(
7965a5ac124SDimitry Andric segments.empty() &&
7975a5ac124SDimitry Andric "segment set can be used only initially before switching to the array");
7985a5ac124SDimitry Andric segments.append(segmentSet->begin(), segmentSet->end());
7995a5ac124SDimitry Andric segmentSet = nullptr;
8005a5ac124SDimitry Andric verify();
8015a5ac124SDimitry Andric }
8025a5ac124SDimitry Andric
isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const8033f4bde29SDimitry Andric bool LiveRange::isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const {
8043f4bde29SDimitry Andric ArrayRef<SlotIndex>::iterator SlotI = Slots.begin();
8053f4bde29SDimitry Andric ArrayRef<SlotIndex>::iterator SlotE = Slots.end();
8063f4bde29SDimitry Andric
8073f4bde29SDimitry Andric // If there are no regmask slots, we have nothing to search.
8083f4bde29SDimitry Andric if (SlotI == SlotE)
8093f4bde29SDimitry Andric return false;
8103f4bde29SDimitry Andric
8113f4bde29SDimitry Andric // Start our search at the first segment that ends after the first slot.
8123f4bde29SDimitry Andric const_iterator SegmentI = find(*SlotI);
8133f4bde29SDimitry Andric const_iterator SegmentE = end();
8143f4bde29SDimitry Andric
8153f4bde29SDimitry Andric // If there are no segments that end after the first slot, we're done.
8163f4bde29SDimitry Andric if (SegmentI == SegmentE)
8173f4bde29SDimitry Andric return false;
8183f4bde29SDimitry Andric
8193f4bde29SDimitry Andric // Look for each slot in the live range.
8203f4bde29SDimitry Andric for ( ; SlotI != SlotE; ++SlotI) {
8213f4bde29SDimitry Andric // Go to the next segment that ends after the current slot.
8223f4bde29SDimitry Andric // The slot may be within a hole in the range.
8233f4bde29SDimitry Andric SegmentI = advanceTo(SegmentI, *SlotI);
8243f4bde29SDimitry Andric if (SegmentI == SegmentE)
8253f4bde29SDimitry Andric return false;
8263f4bde29SDimitry Andric
8273f4bde29SDimitry Andric // If this segment contains the slot, we're done.
8283f4bde29SDimitry Andric if (SegmentI->contains(*SlotI))
8293f4bde29SDimitry Andric return true;
8303f4bde29SDimitry Andric // Otherwise, look for the next slot.
8313f4bde29SDimitry Andric }
8323f4bde29SDimitry Andric
8333f4bde29SDimitry Andric // We didn't find a segment containing any of the slots.
8343f4bde29SDimitry Andric return false;
8353f4bde29SDimitry Andric }
8363f4bde29SDimitry Andric
freeSubRange(SubRange * S)8375a5ac124SDimitry Andric void LiveInterval::freeSubRange(SubRange *S) {
8385a5ac124SDimitry Andric S->~SubRange();
8395a5ac124SDimitry Andric // Memory was allocated with BumpPtr allocator and is not freed here.
8405a5ac124SDimitry Andric }
8415a5ac124SDimitry Andric
removeEmptySubRanges()84267c32a98SDimitry Andric void LiveInterval::removeEmptySubRanges() {
84367c32a98SDimitry Andric SubRange **NextPtr = &SubRanges;
84467c32a98SDimitry Andric SubRange *I = *NextPtr;
84567c32a98SDimitry Andric while (I != nullptr) {
84667c32a98SDimitry Andric if (!I->empty()) {
84767c32a98SDimitry Andric NextPtr = &I->Next;
84867c32a98SDimitry Andric I = *NextPtr;
84967c32a98SDimitry Andric continue;
85067c32a98SDimitry Andric }
85167c32a98SDimitry Andric // Skip empty subranges until we find the first nonempty one.
85267c32a98SDimitry Andric do {
8535a5ac124SDimitry Andric SubRange *Next = I->Next;
8545a5ac124SDimitry Andric freeSubRange(I);
8555a5ac124SDimitry Andric I = Next;
85667c32a98SDimitry Andric } while (I != nullptr && I->empty());
85767c32a98SDimitry Andric *NextPtr = I;
85867c32a98SDimitry Andric }
85967c32a98SDimitry Andric }
86067c32a98SDimitry Andric
clearSubRanges()8615a5ac124SDimitry Andric void LiveInterval::clearSubRanges() {
8625a5ac124SDimitry Andric for (SubRange *I = SubRanges, *Next; I != nullptr; I = Next) {
8635a5ac124SDimitry Andric Next = I->Next;
8645a5ac124SDimitry Andric freeSubRange(I);
8655a5ac124SDimitry Andric }
8665a5ac124SDimitry Andric SubRanges = nullptr;
8675a5ac124SDimitry Andric }
8685a5ac124SDimitry Andric
869e6d15924SDimitry Andric /// For each VNI in \p SR, check whether or not that value defines part
870e6d15924SDimitry Andric /// of the mask describe by \p LaneMask and if not, remove that value
871e6d15924SDimitry Andric /// from \p SR.
stripValuesNotDefiningMask(unsigned Reg,LiveInterval::SubRange & SR,LaneBitmask LaneMask,const SlotIndexes & Indexes,const TargetRegisterInfo & TRI,unsigned ComposeSubRegIdx)872e6d15924SDimitry Andric static void stripValuesNotDefiningMask(unsigned Reg, LiveInterval::SubRange &SR,
873e6d15924SDimitry Andric LaneBitmask LaneMask,
874e6d15924SDimitry Andric const SlotIndexes &Indexes,
875706b4fc4SDimitry Andric const TargetRegisterInfo &TRI,
876706b4fc4SDimitry Andric unsigned ComposeSubRegIdx) {
877e6d15924SDimitry Andric // Phys reg should not be tracked at subreg level.
878e6d15924SDimitry Andric // Same for noreg (Reg == 0).
8791d5ae102SDimitry Andric if (!Register::isVirtualRegister(Reg) || !Reg)
880e6d15924SDimitry Andric return;
881e6d15924SDimitry Andric // Remove the values that don't define those lanes.
882e6d15924SDimitry Andric SmallVector<VNInfo *, 8> ToBeRemoved;
883e6d15924SDimitry Andric for (VNInfo *VNI : SR.valnos) {
884e6d15924SDimitry Andric if (VNI->isUnused())
885e6d15924SDimitry Andric continue;
886e6d15924SDimitry Andric // PHI definitions don't have MI attached, so there is nothing
887e6d15924SDimitry Andric // we can use to strip the VNI.
888e6d15924SDimitry Andric if (VNI->isPHIDef())
889e6d15924SDimitry Andric continue;
890e6d15924SDimitry Andric const MachineInstr *MI = Indexes.getInstructionFromIndex(VNI->def);
891e6d15924SDimitry Andric assert(MI && "Cannot find the definition of a value");
892e6d15924SDimitry Andric bool hasDef = false;
893e6d15924SDimitry Andric for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
894e6d15924SDimitry Andric if (!MOI->isReg() || !MOI->isDef())
895e6d15924SDimitry Andric continue;
896e6d15924SDimitry Andric if (MOI->getReg() != Reg)
897e6d15924SDimitry Andric continue;
898706b4fc4SDimitry Andric LaneBitmask OrigMask = TRI.getSubRegIndexLaneMask(MOI->getSubReg());
899706b4fc4SDimitry Andric LaneBitmask ExpectedDefMask =
900706b4fc4SDimitry Andric ComposeSubRegIdx
901706b4fc4SDimitry Andric ? TRI.composeSubRegIndexLaneMask(ComposeSubRegIdx, OrigMask)
902706b4fc4SDimitry Andric : OrigMask;
903706b4fc4SDimitry Andric if ((ExpectedDefMask & LaneMask).none())
904e6d15924SDimitry Andric continue;
905e6d15924SDimitry Andric hasDef = true;
906e6d15924SDimitry Andric break;
907e6d15924SDimitry Andric }
908e6d15924SDimitry Andric
909e6d15924SDimitry Andric if (!hasDef)
910e6d15924SDimitry Andric ToBeRemoved.push_back(VNI);
911e6d15924SDimitry Andric }
912e6d15924SDimitry Andric for (VNInfo *VNI : ToBeRemoved)
913e6d15924SDimitry Andric SR.removeValNo(VNI);
914e6d15924SDimitry Andric
9151d5ae102SDimitry Andric // If the subrange is empty at this point, the MIR is invalid. Do not assert
9161d5ae102SDimitry Andric // and let the verifier catch this case.
917e6d15924SDimitry Andric }
918e6d15924SDimitry Andric
refineSubRanges(BumpPtrAllocator & Allocator,LaneBitmask LaneMask,std::function<void (LiveInterval::SubRange &)> Apply,const SlotIndexes & Indexes,const TargetRegisterInfo & TRI,unsigned ComposeSubRegIdx)919e6d15924SDimitry Andric void LiveInterval::refineSubRanges(
920e6d15924SDimitry Andric BumpPtrAllocator &Allocator, LaneBitmask LaneMask,
921e6d15924SDimitry Andric std::function<void(LiveInterval::SubRange &)> Apply,
922706b4fc4SDimitry Andric const SlotIndexes &Indexes, const TargetRegisterInfo &TRI,
923706b4fc4SDimitry Andric unsigned ComposeSubRegIdx) {
92471d5a254SDimitry Andric LaneBitmask ToApply = LaneMask;
92571d5a254SDimitry Andric for (SubRange &SR : subranges()) {
92671d5a254SDimitry Andric LaneBitmask SRMask = SR.LaneMask;
92771d5a254SDimitry Andric LaneBitmask Matching = SRMask & LaneMask;
92871d5a254SDimitry Andric if (Matching.none())
92971d5a254SDimitry Andric continue;
93071d5a254SDimitry Andric
93171d5a254SDimitry Andric SubRange *MatchingRange;
93271d5a254SDimitry Andric if (SRMask == Matching) {
93371d5a254SDimitry Andric // The subrange fits (it does not cover bits outside \p LaneMask).
93471d5a254SDimitry Andric MatchingRange = &SR;
93571d5a254SDimitry Andric } else {
93671d5a254SDimitry Andric // We have to split the subrange into a matching and non-matching part.
93771d5a254SDimitry Andric // Reduce lanemask of existing lane to non-matching part.
93871d5a254SDimitry Andric SR.LaneMask = SRMask & ~Matching;
93971d5a254SDimitry Andric // Create a new subrange for the matching part
94071d5a254SDimitry Andric MatchingRange = createSubRangeFrom(Allocator, Matching, SR);
941e6d15924SDimitry Andric // Now that the subrange is split in half, make sure we
942e6d15924SDimitry Andric // only keep in the subranges the VNIs that touch the related half.
943b60736ecSDimitry Andric stripValuesNotDefiningMask(reg(), *MatchingRange, Matching, Indexes, TRI,
944706b4fc4SDimitry Andric ComposeSubRegIdx);
945b60736ecSDimitry Andric stripValuesNotDefiningMask(reg(), SR, SR.LaneMask, Indexes, TRI,
946706b4fc4SDimitry Andric ComposeSubRegIdx);
94771d5a254SDimitry Andric }
94871d5a254SDimitry Andric Apply(*MatchingRange);
94971d5a254SDimitry Andric ToApply &= ~Matching;
95071d5a254SDimitry Andric }
95171d5a254SDimitry Andric // Create a new subrange if there are uncovered bits left.
95271d5a254SDimitry Andric if (ToApply.any()) {
95371d5a254SDimitry Andric SubRange *NewRange = createSubRange(Allocator, ToApply);
95471d5a254SDimitry Andric Apply(*NewRange);
95571d5a254SDimitry Andric }
95671d5a254SDimitry Andric }
95771d5a254SDimitry Andric
getSize() const958009b1c42SEd Schouten unsigned LiveInterval::getSize() const {
959009b1c42SEd Schouten unsigned Sum = 0;
96067c32a98SDimitry Andric for (const Segment &S : segments)
96167c32a98SDimitry Andric Sum += S.start.distance(S.end);
962009b1c42SEd Schouten return Sum;
963009b1c42SEd Schouten }
964009b1c42SEd Schouten
computeSubRangeUndefs(SmallVectorImpl<SlotIndex> & Undefs,LaneBitmask LaneMask,const MachineRegisterInfo & MRI,const SlotIndexes & Indexes) const965b915e9e0SDimitry Andric void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
966b915e9e0SDimitry Andric LaneBitmask LaneMask,
967b915e9e0SDimitry Andric const MachineRegisterInfo &MRI,
968b915e9e0SDimitry Andric const SlotIndexes &Indexes) const {
969e3b55780SDimitry Andric assert(reg().isVirtual());
970b60736ecSDimitry Andric LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg());
971b915e9e0SDimitry Andric assert((VRegMask & LaneMask).any());
972b915e9e0SDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
973b60736ecSDimitry Andric for (const MachineOperand &MO : MRI.def_operands(reg())) {
974b915e9e0SDimitry Andric if (!MO.isUndef())
975b915e9e0SDimitry Andric continue;
976b915e9e0SDimitry Andric unsigned SubReg = MO.getSubReg();
977b915e9e0SDimitry Andric assert(SubReg != 0 && "Undef should only be set on subreg defs");
978b915e9e0SDimitry Andric LaneBitmask DefMask = TRI.getSubRegIndexLaneMask(SubReg);
979b915e9e0SDimitry Andric LaneBitmask UndefMask = VRegMask & ~DefMask;
980b915e9e0SDimitry Andric if ((UndefMask & LaneMask).any()) {
981b915e9e0SDimitry Andric const MachineInstr &MI = *MO.getParent();
982b915e9e0SDimitry Andric bool EarlyClobber = MO.isEarlyClobber();
983b915e9e0SDimitry Andric SlotIndex Pos = Indexes.getInstructionIndex(MI).getRegSlot(EarlyClobber);
984b915e9e0SDimitry Andric Undefs.push_back(Pos);
985b915e9e0SDimitry Andric }
986b915e9e0SDimitry Andric }
987b915e9e0SDimitry Andric }
988b915e9e0SDimitry Andric
operator <<(raw_ostream & OS,const LiveRange::Segment & S)989044eb2f6SDimitry Andric raw_ostream& llvm::operator<<(raw_ostream& OS, const LiveRange::Segment &S) {
990044eb2f6SDimitry Andric return OS << '[' << S.start << ',' << S.end << ':' << S.valno->id << ')';
991009b1c42SEd Schouten }
992009b1c42SEd Schouten
993522600a2SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const99401095a5dSDimitry Andric LLVM_DUMP_METHOD void LiveRange::Segment::dump() const {
99501095a5dSDimitry Andric dbgs() << *this << '\n';
996009b1c42SEd Schouten }
997522600a2SDimitry Andric #endif
998009b1c42SEd Schouten
print(raw_ostream & OS) const999f8af5cf6SDimitry Andric void LiveRange::print(raw_ostream &OS) const {
1000009b1c42SEd Schouten if (empty())
1001009b1c42SEd Schouten OS << "EMPTY";
1002009b1c42SEd Schouten else {
100367c32a98SDimitry Andric for (const Segment &S : segments) {
100467c32a98SDimitry Andric OS << S;
100567c32a98SDimitry Andric assert(S.valno == getValNumInfo(S.valno->id) && "Bad VNInfo");
100666e41e3cSRoman Divacky }
1007009b1c42SEd Schouten }
1008009b1c42SEd Schouten
1009009b1c42SEd Schouten // Print value number info.
1010009b1c42SEd Schouten if (getNumValNums()) {
1011c0981da4SDimitry Andric OS << ' ';
1012009b1c42SEd Schouten unsigned vnum = 0;
1013009b1c42SEd Schouten for (const_vni_iterator i = vni_begin(), e = vni_end(); i != e;
1014009b1c42SEd Schouten ++i, ++vnum) {
1015009b1c42SEd Schouten const VNInfo *vni = *i;
101601095a5dSDimitry Andric if (vnum) OS << ' ';
101701095a5dSDimitry Andric OS << vnum << '@';
1018b2f21fb0SEd Schouten if (vni->isUnused()) {
101901095a5dSDimitry Andric OS << 'x';
1020009b1c42SEd Schouten } else {
1021009b1c42SEd Schouten OS << vni->def;
1022cf099d11SDimitry Andric if (vni->isPHIDef())
102358b69754SDimitry Andric OS << "-phi";
1024009b1c42SEd Schouten }
1025009b1c42SEd Schouten }
1026009b1c42SEd Schouten }
1027009b1c42SEd Schouten }
1028009b1c42SEd Schouten
print(raw_ostream & OS) const102901095a5dSDimitry Andric void LiveInterval::SubRange::print(raw_ostream &OS) const {
103001095a5dSDimitry Andric OS << " L" << PrintLaneMask(LaneMask) << ' '
103101095a5dSDimitry Andric << static_cast<const LiveRange &>(*this);
103201095a5dSDimitry Andric }
103301095a5dSDimitry Andric
print(raw_ostream & OS) const1034f8af5cf6SDimitry Andric void LiveInterval::print(raw_ostream &OS) const {
1035b60736ecSDimitry Andric OS << printReg(reg()) << ' ';
1036f8af5cf6SDimitry Andric super::print(OS);
103767c32a98SDimitry Andric // Print subranges
103801095a5dSDimitry Andric for (const SubRange &SR : subranges())
103901095a5dSDimitry Andric OS << SR;
1040b60736ecSDimitry Andric OS << " weight:" << Weight;
1041f8af5cf6SDimitry Andric }
1042f8af5cf6SDimitry Andric
1043522600a2SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const104401095a5dSDimitry Andric LLVM_DUMP_METHOD void LiveRange::dump() const {
104501095a5dSDimitry Andric dbgs() << *this << '\n';
1046f8af5cf6SDimitry Andric }
1047f8af5cf6SDimitry Andric
dump() const104801095a5dSDimitry Andric LLVM_DUMP_METHOD void LiveInterval::SubRange::dump() const {
104901095a5dSDimitry Andric dbgs() << *this << '\n';
105001095a5dSDimitry Andric }
105101095a5dSDimitry Andric
dump() const105201095a5dSDimitry Andric LLVM_DUMP_METHOD void LiveInterval::dump() const {
105301095a5dSDimitry Andric dbgs() << *this << '\n';
1054009b1c42SEd Schouten }
1055522600a2SDimitry Andric #endif
1056009b1c42SEd Schouten
105758b69754SDimitry Andric #ifndef NDEBUG
verify() const1058f8af5cf6SDimitry Andric void LiveRange::verify() const {
105958b69754SDimitry Andric for (const_iterator I = begin(), E = end(); I != E; ++I) {
106058b69754SDimitry Andric assert(I->start.isValid());
106158b69754SDimitry Andric assert(I->end.isValid());
106258b69754SDimitry Andric assert(I->start < I->end);
10635ca98fd9SDimitry Andric assert(I->valno != nullptr);
1064f8af5cf6SDimitry Andric assert(I->valno->id < valnos.size());
106558b69754SDimitry Andric assert(I->valno == valnos[I->valno->id]);
10665ca98fd9SDimitry Andric if (std::next(I) != E) {
10675ca98fd9SDimitry Andric assert(I->end <= std::next(I)->start);
10685ca98fd9SDimitry Andric if (I->end == std::next(I)->start)
10695ca98fd9SDimitry Andric assert(I->valno != std::next(I)->valno);
107058b69754SDimitry Andric }
107158b69754SDimitry Andric }
107258b69754SDimitry Andric }
107367c32a98SDimitry Andric
verify(const MachineRegisterInfo * MRI) const107467c32a98SDimitry Andric void LiveInterval::verify(const MachineRegisterInfo *MRI) const {
107567c32a98SDimitry Andric super::verify();
107667c32a98SDimitry Andric
107767c32a98SDimitry Andric // Make sure SubRanges are fine and LaneMasks are disjunct.
1078b915e9e0SDimitry Andric LaneBitmask Mask;
1079b60736ecSDimitry Andric LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg())
1080b915e9e0SDimitry Andric : LaneBitmask::getAll();
108167c32a98SDimitry Andric for (const SubRange &SR : subranges()) {
108267c32a98SDimitry Andric // Subrange lanemask should be disjunct to any previous subrange masks.
1083b915e9e0SDimitry Andric assert((Mask & SR.LaneMask).none());
108467c32a98SDimitry Andric Mask |= SR.LaneMask;
108567c32a98SDimitry Andric
108667c32a98SDimitry Andric // subrange mask should not contained in maximum lane mask for the vreg.
1087b915e9e0SDimitry Andric assert((Mask & ~MaxMask).none());
1088dd58ef01SDimitry Andric // empty subranges must be removed.
1089dd58ef01SDimitry Andric assert(!SR.empty());
109067c32a98SDimitry Andric
109167c32a98SDimitry Andric SR.verify();
109267c32a98SDimitry Andric // Main liverange should cover subrange.
109367c32a98SDimitry Andric assert(covers(SR));
109467c32a98SDimitry Andric }
109567c32a98SDimitry Andric }
109658b69754SDimitry Andric #endif
109758b69754SDimitry Andric
10984a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
10994a16efa3SDimitry Andric // LiveRangeUpdater class
11004a16efa3SDimitry Andric //===----------------------------------------------------------------------===//
11014a16efa3SDimitry Andric //
11024a16efa3SDimitry Andric // The LiveRangeUpdater class always maintains these invariants:
11034a16efa3SDimitry Andric //
11044a16efa3SDimitry Andric // - When LastStart is invalid, Spills is empty and the iterators are invalid.
11054a16efa3SDimitry Andric // This is the initial state, and the state created by flush().
11064a16efa3SDimitry Andric // In this state, isDirty() returns false.
11074a16efa3SDimitry Andric //
11084a16efa3SDimitry Andric // Otherwise, segments are kept in three separate areas:
11094a16efa3SDimitry Andric //
1110f8af5cf6SDimitry Andric // 1. [begin; WriteI) at the front of LR.
1111f8af5cf6SDimitry Andric // 2. [ReadI; end) at the back of LR.
11124a16efa3SDimitry Andric // 3. Spills.
11134a16efa3SDimitry Andric //
1114f8af5cf6SDimitry Andric // - LR.begin() <= WriteI <= ReadI <= LR.end().
11154a16efa3SDimitry Andric // - Segments in all three areas are fully ordered and coalesced.
11164a16efa3SDimitry Andric // - Segments in area 1 precede and can't coalesce with segments in area 2.
11174a16efa3SDimitry Andric // - Segments in Spills precede and can't coalesce with segments in area 2.
11184a16efa3SDimitry Andric // - No coalescing is possible between segments in Spills and segments in area
11194a16efa3SDimitry Andric // 1, and there are no overlapping segments.
11204a16efa3SDimitry Andric //
11214a16efa3SDimitry Andric // The segments in Spills are not ordered with respect to the segments in area
11224a16efa3SDimitry Andric // 1. They need to be merged.
11234a16efa3SDimitry Andric //
11244a16efa3SDimitry Andric // When they exist, Spills.back().start <= LastStart,
11254a16efa3SDimitry Andric // and WriteI[-1].start <= LastStart.
11264a16efa3SDimitry Andric
112771d5a254SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
print(raw_ostream & OS) const11284a16efa3SDimitry Andric void LiveRangeUpdater::print(raw_ostream &OS) const {
11294a16efa3SDimitry Andric if (!isDirty()) {
1130f8af5cf6SDimitry Andric if (LR)
1131f8af5cf6SDimitry Andric OS << "Clean updater: " << *LR << '\n';
11324a16efa3SDimitry Andric else
11334a16efa3SDimitry Andric OS << "Null updater.\n";
11344a16efa3SDimitry Andric return;
11354a16efa3SDimitry Andric }
1136f8af5cf6SDimitry Andric assert(LR && "Can't have null LR in dirty updater.");
1137f8af5cf6SDimitry Andric OS << " updater with gap = " << (ReadI - WriteI)
11384a16efa3SDimitry Andric << ", last start = " << LastStart
11394a16efa3SDimitry Andric << ":\n Area 1:";
114067c32a98SDimitry Andric for (const auto &S : make_range(LR->begin(), WriteI))
114167c32a98SDimitry Andric OS << ' ' << S;
11424a16efa3SDimitry Andric OS << "\n Spills:";
11434a16efa3SDimitry Andric for (unsigned I = 0, E = Spills.size(); I != E; ++I)
11444a16efa3SDimitry Andric OS << ' ' << Spills[I];
11454a16efa3SDimitry Andric OS << "\n Area 2:";
114667c32a98SDimitry Andric for (const auto &S : make_range(ReadI, LR->end()))
114767c32a98SDimitry Andric OS << ' ' << S;
11484a16efa3SDimitry Andric OS << '\n';
11494a16efa3SDimitry Andric }
11504a16efa3SDimitry Andric
dump() const115101095a5dSDimitry Andric LLVM_DUMP_METHOD void LiveRangeUpdater::dump() const {
11524a16efa3SDimitry Andric print(errs());
11534a16efa3SDimitry Andric }
115471d5a254SDimitry Andric #endif
11554a16efa3SDimitry Andric
11564a16efa3SDimitry Andric // Determine if A and B should be coalesced.
coalescable(const LiveRange::Segment & A,const LiveRange::Segment & B)1157f8af5cf6SDimitry Andric static inline bool coalescable(const LiveRange::Segment &A,
1158f8af5cf6SDimitry Andric const LiveRange::Segment &B) {
1159f8af5cf6SDimitry Andric assert(A.start <= B.start && "Unordered live segments.");
11604a16efa3SDimitry Andric if (A.end == B.start)
11614a16efa3SDimitry Andric return A.valno == B.valno;
11624a16efa3SDimitry Andric if (A.end < B.start)
11634a16efa3SDimitry Andric return false;
11644a16efa3SDimitry Andric assert(A.valno == B.valno && "Cannot overlap different values");
11654a16efa3SDimitry Andric return true;
11664a16efa3SDimitry Andric }
11674a16efa3SDimitry Andric
add(LiveRange::Segment Seg)1168f8af5cf6SDimitry Andric void LiveRangeUpdater::add(LiveRange::Segment Seg) {
1169f8af5cf6SDimitry Andric assert(LR && "Cannot add to a null destination");
11704a16efa3SDimitry Andric
11715a5ac124SDimitry Andric // Fall back to the regular add method if the live range
11725a5ac124SDimitry Andric // is using the segment set instead of the segment vector.
11735a5ac124SDimitry Andric if (LR->segmentSet != nullptr) {
11745a5ac124SDimitry Andric LR->addSegmentToSet(Seg);
11755a5ac124SDimitry Andric return;
11765a5ac124SDimitry Andric }
11775a5ac124SDimitry Andric
11784a16efa3SDimitry Andric // Flush the state if Start moves backwards.
11794a16efa3SDimitry Andric if (!LastStart.isValid() || LastStart > Seg.start) {
11804a16efa3SDimitry Andric if (isDirty())
11814a16efa3SDimitry Andric flush();
11824a16efa3SDimitry Andric // This brings us to an uninitialized state. Reinitialize.
11834a16efa3SDimitry Andric assert(Spills.empty() && "Leftover spilled segments");
1184f8af5cf6SDimitry Andric WriteI = ReadI = LR->begin();
11854a16efa3SDimitry Andric }
11864a16efa3SDimitry Andric
11874a16efa3SDimitry Andric // Remember start for next time.
11884a16efa3SDimitry Andric LastStart = Seg.start;
11894a16efa3SDimitry Andric
11904a16efa3SDimitry Andric // Advance ReadI until it ends after Seg.start.
1191f8af5cf6SDimitry Andric LiveRange::iterator E = LR->end();
11924a16efa3SDimitry Andric if (ReadI != E && ReadI->end <= Seg.start) {
11934a16efa3SDimitry Andric // First try to close the gap between WriteI and ReadI with spills.
11944a16efa3SDimitry Andric if (ReadI != WriteI)
11954a16efa3SDimitry Andric mergeSpills();
11964a16efa3SDimitry Andric // Then advance ReadI.
11974a16efa3SDimitry Andric if (ReadI == WriteI)
1198f8af5cf6SDimitry Andric ReadI = WriteI = LR->find(Seg.start);
11994a16efa3SDimitry Andric else
12004a16efa3SDimitry Andric while (ReadI != E && ReadI->end <= Seg.start)
12014a16efa3SDimitry Andric *WriteI++ = *ReadI++;
12024a16efa3SDimitry Andric }
12034a16efa3SDimitry Andric
12044a16efa3SDimitry Andric assert(ReadI == E || ReadI->end > Seg.start);
12054a16efa3SDimitry Andric
12064a16efa3SDimitry Andric // Check if the ReadI segment begins early.
12074a16efa3SDimitry Andric if (ReadI != E && ReadI->start <= Seg.start) {
12084a16efa3SDimitry Andric assert(ReadI->valno == Seg.valno && "Cannot overlap different values");
12094a16efa3SDimitry Andric // Bail if Seg is completely contained in ReadI.
12104a16efa3SDimitry Andric if (ReadI->end >= Seg.end)
12114a16efa3SDimitry Andric return;
12124a16efa3SDimitry Andric // Coalesce into Seg.
12134a16efa3SDimitry Andric Seg.start = ReadI->start;
12144a16efa3SDimitry Andric ++ReadI;
12154a16efa3SDimitry Andric }
12164a16efa3SDimitry Andric
12174a16efa3SDimitry Andric // Coalesce as much as possible from ReadI into Seg.
12184a16efa3SDimitry Andric while (ReadI != E && coalescable(Seg, *ReadI)) {
12194a16efa3SDimitry Andric Seg.end = std::max(Seg.end, ReadI->end);
12204a16efa3SDimitry Andric ++ReadI;
12214a16efa3SDimitry Andric }
12224a16efa3SDimitry Andric
12234a16efa3SDimitry Andric // Try coalescing Spills.back() into Seg.
12244a16efa3SDimitry Andric if (!Spills.empty() && coalescable(Spills.back(), Seg)) {
12254a16efa3SDimitry Andric Seg.start = Spills.back().start;
12264a16efa3SDimitry Andric Seg.end = std::max(Spills.back().end, Seg.end);
12274a16efa3SDimitry Andric Spills.pop_back();
12284a16efa3SDimitry Andric }
12294a16efa3SDimitry Andric
12304a16efa3SDimitry Andric // Try coalescing Seg into WriteI[-1].
1231f8af5cf6SDimitry Andric if (WriteI != LR->begin() && coalescable(WriteI[-1], Seg)) {
12324a16efa3SDimitry Andric WriteI[-1].end = std::max(WriteI[-1].end, Seg.end);
12334a16efa3SDimitry Andric return;
12344a16efa3SDimitry Andric }
12354a16efa3SDimitry Andric
12364a16efa3SDimitry Andric // Seg doesn't coalesce with anything, and needs to be inserted somewhere.
12374a16efa3SDimitry Andric if (WriteI != ReadI) {
12384a16efa3SDimitry Andric *WriteI++ = Seg;
12394a16efa3SDimitry Andric return;
12404a16efa3SDimitry Andric }
12414a16efa3SDimitry Andric
1242f8af5cf6SDimitry Andric // Finally, append to LR or Spills.
12434a16efa3SDimitry Andric if (WriteI == E) {
1244f8af5cf6SDimitry Andric LR->segments.push_back(Seg);
1245f8af5cf6SDimitry Andric WriteI = ReadI = LR->end();
12464a16efa3SDimitry Andric } else
12474a16efa3SDimitry Andric Spills.push_back(Seg);
12484a16efa3SDimitry Andric }
12494a16efa3SDimitry Andric
12504a16efa3SDimitry Andric // Merge as many spilled segments as possible into the gap between WriteI
12514a16efa3SDimitry Andric // and ReadI. Advance WriteI to reflect the inserted instructions.
mergeSpills()12524a16efa3SDimitry Andric void LiveRangeUpdater::mergeSpills() {
12534a16efa3SDimitry Andric // Perform a backwards merge of Spills and [SpillI;WriteI).
12544a16efa3SDimitry Andric size_t GapSize = ReadI - WriteI;
12554a16efa3SDimitry Andric size_t NumMoved = std::min(Spills.size(), GapSize);
1256f8af5cf6SDimitry Andric LiveRange::iterator Src = WriteI;
1257f8af5cf6SDimitry Andric LiveRange::iterator Dst = Src + NumMoved;
1258f8af5cf6SDimitry Andric LiveRange::iterator SpillSrc = Spills.end();
1259f8af5cf6SDimitry Andric LiveRange::iterator B = LR->begin();
12604a16efa3SDimitry Andric
12614a16efa3SDimitry Andric // This is the new WriteI position after merging spills.
12624a16efa3SDimitry Andric WriteI = Dst;
12634a16efa3SDimitry Andric
12644a16efa3SDimitry Andric // Now merge Src and Spills backwards.
12654a16efa3SDimitry Andric while (Src != Dst) {
12664a16efa3SDimitry Andric if (Src != B && Src[-1].start > SpillSrc[-1].start)
12674a16efa3SDimitry Andric *--Dst = *--Src;
12684a16efa3SDimitry Andric else
12694a16efa3SDimitry Andric *--Dst = *--SpillSrc;
12704a16efa3SDimitry Andric }
12714a16efa3SDimitry Andric assert(NumMoved == size_t(Spills.end() - SpillSrc));
12724a16efa3SDimitry Andric Spills.erase(SpillSrc, Spills.end());
12734a16efa3SDimitry Andric }
12744a16efa3SDimitry Andric
flush()12754a16efa3SDimitry Andric void LiveRangeUpdater::flush() {
12764a16efa3SDimitry Andric if (!isDirty())
12774a16efa3SDimitry Andric return;
12784a16efa3SDimitry Andric // Clear the dirty state.
12794a16efa3SDimitry Andric LastStart = SlotIndex();
12804a16efa3SDimitry Andric
1281f8af5cf6SDimitry Andric assert(LR && "Cannot add to a null destination");
12824a16efa3SDimitry Andric
12834a16efa3SDimitry Andric // Nothing to merge?
12844a16efa3SDimitry Andric if (Spills.empty()) {
1285f8af5cf6SDimitry Andric LR->segments.erase(WriteI, ReadI);
1286f8af5cf6SDimitry Andric LR->verify();
12874a16efa3SDimitry Andric return;
12884a16efa3SDimitry Andric }
12894a16efa3SDimitry Andric
12904a16efa3SDimitry Andric // Resize the WriteI - ReadI gap to match Spills.
12914a16efa3SDimitry Andric size_t GapSize = ReadI - WriteI;
12924a16efa3SDimitry Andric if (GapSize < Spills.size()) {
12934a16efa3SDimitry Andric // The gap is too small. Make some room.
1294f8af5cf6SDimitry Andric size_t WritePos = WriteI - LR->begin();
1295f8af5cf6SDimitry Andric LR->segments.insert(ReadI, Spills.size() - GapSize, LiveRange::Segment());
12964a16efa3SDimitry Andric // This also invalidated ReadI, but it is recomputed below.
1297f8af5cf6SDimitry Andric WriteI = LR->begin() + WritePos;
12984a16efa3SDimitry Andric } else {
12994a16efa3SDimitry Andric // Shrink the gap if necessary.
1300f8af5cf6SDimitry Andric LR->segments.erase(WriteI + Spills.size(), ReadI);
13014a16efa3SDimitry Andric }
13024a16efa3SDimitry Andric ReadI = WriteI + Spills.size();
13034a16efa3SDimitry Andric mergeSpills();
1304f8af5cf6SDimitry Andric LR->verify();
13054a16efa3SDimitry Andric }
13064a16efa3SDimitry Andric
Classify(const LiveRange & LR)1307050e163aSDimitry Andric unsigned ConnectedVNInfoEqClasses::Classify(const LiveRange &LR) {
1308cf099d11SDimitry Andric // Create initial equivalence classes.
13096b943ff3SDimitry Andric EqClass.clear();
1310050e163aSDimitry Andric EqClass.grow(LR.getNumValNums());
1311cf099d11SDimitry Andric
13125ca98fd9SDimitry Andric const VNInfo *used = nullptr, *unused = nullptr;
1313cf099d11SDimitry Andric
1314cf099d11SDimitry Andric // Determine connections.
1315050e163aSDimitry Andric for (const VNInfo *VNI : LR.valnos) {
1316cf099d11SDimitry Andric // Group all unused values into one class.
1317cf099d11SDimitry Andric if (VNI->isUnused()) {
1318cf099d11SDimitry Andric if (unused)
13196b943ff3SDimitry Andric EqClass.join(unused->id, VNI->id);
1320cf099d11SDimitry Andric unused = VNI;
1321cf099d11SDimitry Andric continue;
1322cf099d11SDimitry Andric }
1323cf099d11SDimitry Andric used = VNI;
1324cf099d11SDimitry Andric if (VNI->isPHIDef()) {
13256b943ff3SDimitry Andric const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
1326cf099d11SDimitry Andric assert(MBB && "Phi-def has no defining MBB");
1327cf099d11SDimitry Andric // Connect to values live out of predecessors.
1328344a3780SDimitry Andric for (MachineBasicBlock *Pred : MBB->predecessors())
1329344a3780SDimitry Andric if (const VNInfo *PVNI = LR.getVNInfoBefore(LIS.getMBBEndIdx(Pred)))
13306b943ff3SDimitry Andric EqClass.join(VNI->id, PVNI->id);
1331cf099d11SDimitry Andric } else {
1332cf099d11SDimitry Andric // Normal value defined by an instruction. Check for two-addr redef.
1333cf099d11SDimitry Andric // FIXME: This could be coincidental. Should we really check for a tied
1334cf099d11SDimitry Andric // operand constraint?
1335cf099d11SDimitry Andric // Note that VNI->def may be a use slot for an early clobber def.
1336050e163aSDimitry Andric if (const VNInfo *UVNI = LR.getVNInfoBefore(VNI->def))
13376b943ff3SDimitry Andric EqClass.join(VNI->id, UVNI->id);
1338cf099d11SDimitry Andric }
1339cf099d11SDimitry Andric }
1340cf099d11SDimitry Andric
1341cf099d11SDimitry Andric // Lump all the unused values in with the last used value.
1342cf099d11SDimitry Andric if (used && unused)
13436b943ff3SDimitry Andric EqClass.join(used->id, unused->id);
1344cf099d11SDimitry Andric
13456b943ff3SDimitry Andric EqClass.compress();
13466b943ff3SDimitry Andric return EqClass.getNumClasses();
1347cf099d11SDimitry Andric }
1348cf099d11SDimitry Andric
Distribute(LiveInterval & LI,LiveInterval * LIV[],MachineRegisterInfo & MRI)1349dd58ef01SDimitry Andric void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
1350dd58ef01SDimitry Andric MachineRegisterInfo &MRI) {
13516b943ff3SDimitry Andric // Rewrite instructions.
1352344a3780SDimitry Andric for (MachineOperand &MO :
1353344a3780SDimitry Andric llvm::make_early_inc_range(MRI.reg_operands(LI.reg()))) {
1354344a3780SDimitry Andric MachineInstr *MI = MO.getParent();
1355d8e91e46SDimitry Andric const VNInfo *VNI;
1356d8e91e46SDimitry Andric if (MI->isDebugValue()) {
1357d8e91e46SDimitry Andric // DBG_VALUE instructions don't have slot indexes, so get the index of
1358d8e91e46SDimitry Andric // the instruction before them. The value is defined there too.
1359d8e91e46SDimitry Andric SlotIndex Idx = LIS.getSlotIndexes()->getIndexBefore(*MI);
1360d8e91e46SDimitry Andric VNI = LI.Query(Idx).valueOut();
1361d8e91e46SDimitry Andric } else {
1362d8e91e46SDimitry Andric SlotIndex Idx = LIS.getInstructionIndex(*MI);
1363f8af5cf6SDimitry Andric LiveQueryResult LRQ = LI.Query(Idx);
1364d8e91e46SDimitry Andric VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined();
1365d8e91e46SDimitry Andric }
136658b69754SDimitry Andric // In the case of an <undef> use that isn't tied to any def, VNI will be
136758b69754SDimitry Andric // NULL. If the use is tied to a def, VNI will be the defined value.
136858b69754SDimitry Andric if (!VNI)
136958b69754SDimitry Andric continue;
1370dd58ef01SDimitry Andric if (unsigned EqClass = getEqClass(VNI))
1371b60736ecSDimitry Andric MO.setReg(LIV[EqClass - 1]->reg());
13726b943ff3SDimitry Andric }
13736b943ff3SDimitry Andric
1374dd58ef01SDimitry Andric // Distribute subregister liveranges.
1375dd58ef01SDimitry Andric if (LI.hasSubRanges()) {
1376dd58ef01SDimitry Andric unsigned NumComponents = EqClass.getNumClasses();
1377dd58ef01SDimitry Andric SmallVector<unsigned, 8> VNIMapping;
1378dd58ef01SDimitry Andric SmallVector<LiveInterval::SubRange*, 8> SubRanges;
1379dd58ef01SDimitry Andric BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator();
1380dd58ef01SDimitry Andric for (LiveInterval::SubRange &SR : LI.subranges()) {
1381dd58ef01SDimitry Andric // Create new subranges in the split intervals and construct a mapping
1382dd58ef01SDimitry Andric // for the VNInfos in the subrange.
1383dd58ef01SDimitry Andric unsigned NumValNos = SR.valnos.size();
1384dd58ef01SDimitry Andric VNIMapping.clear();
1385dd58ef01SDimitry Andric VNIMapping.reserve(NumValNos);
1386dd58ef01SDimitry Andric SubRanges.clear();
1387dd58ef01SDimitry Andric SubRanges.resize(NumComponents-1, nullptr);
1388dd58ef01SDimitry Andric for (unsigned I = 0; I < NumValNos; ++I) {
1389dd58ef01SDimitry Andric const VNInfo &VNI = *SR.valnos[I];
139001095a5dSDimitry Andric unsigned ComponentNum;
139101095a5dSDimitry Andric if (VNI.isUnused()) {
139201095a5dSDimitry Andric ComponentNum = 0;
139301095a5dSDimitry Andric } else {
1394dd58ef01SDimitry Andric const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def);
1395dd58ef01SDimitry Andric assert(MainRangeVNI != nullptr
1396dd58ef01SDimitry Andric && "SubRange def must have corresponding main range def");
139701095a5dSDimitry Andric ComponentNum = getEqClass(MainRangeVNI);
1398dd58ef01SDimitry Andric if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) {
1399dd58ef01SDimitry Andric SubRanges[ComponentNum-1]
1400dd58ef01SDimitry Andric = LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask);
1401cf099d11SDimitry Andric }
1402dd58ef01SDimitry Andric }
140301095a5dSDimitry Andric VNIMapping.push_back(ComponentNum);
140401095a5dSDimitry Andric }
1405dd58ef01SDimitry Andric DistributeRange(SR, SubRanges.data(), VNIMapping);
1406dd58ef01SDimitry Andric }
1407dd58ef01SDimitry Andric LI.removeEmptySubRanges();
1408dd58ef01SDimitry Andric }
1409cf099d11SDimitry Andric
1410dd58ef01SDimitry Andric // Distribute main liverange.
1411dd58ef01SDimitry Andric DistributeRange(LI, LIV, EqClass);
1412cf099d11SDimitry Andric }
1413