36 #include "llvm/Config/llvm-config.h" 65 template <
typename ImplT,
typename IteratorT,
typename CollectionT>
66 class CalcLiveRangeUtilBase {
71 CalcLiveRangeUtilBase(
LiveRange *LR) : LR(LR) {}
75 using iterator = IteratorT;
90 assert(!Def.
isDead() &&
"Cannot define a value at the dead slot");
92 "If ForVNI is specified, it must match Def");
93 iterator
I =
impl().find(Def);
94 if (I == segments().
end()) {
100 Segment *S = segmentAt(I);
102 assert((!ForVNI || ForVNI == S->valno) &&
"Value number mismatch");
103 assert(S->valno->def == S->start &&
"Inconsistent existing value def");
110 Def = std::min(Def, S->start);
112 S->start = S->valno->def =
Def;
117 segments().insert(I, Segment(Def, Def.
getDeadSlot(), VNI));
122 if (segments().
empty())
126 if (I == segments().begin())
129 if (I->end <= StartIdx)
132 extendSegmentEndTo(I, Use);
138 if (segments().
empty())
139 return std::make_pair(
nullptr,
false);
141 iterator I =
impl().findInsertPos(Segment(BeforeUse, Use,
nullptr));
142 if (I == segments().
begin())
143 return std::make_pair(
nullptr, LR->
isUndefIn(Undefs, StartIdx, BeforeUse));
145 if (I->end <= StartIdx)
146 return std::make_pair(
nullptr, LR->
isUndefIn(Undefs, StartIdx, BeforeUse));
149 return std::make_pair(
nullptr,
true);
150 extendSegmentEndTo(I, Use);
152 return std::make_pair(I->valno,
false);
159 void extendSegmentEndTo(iterator I,
SlotIndex NewEnd) {
160 assert(I != segments().
end() &&
"Not a valid segment!");
161 Segment *S = segmentAt(I);
165 iterator MergeTo = std::next(I);
166 for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo)
167 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
170 S->end =
std::max(NewEnd, std::prev(MergeTo)->
end);
174 if (MergeTo != segments().
end() && MergeTo->start <= I->
end &&
175 MergeTo->valno == ValNo) {
176 S->end = MergeTo->end;
181 segments().erase(std::next(I), MergeTo);
187 iterator extendSegmentStartTo(iterator I,
SlotIndex NewStart) {
188 assert(I != segments().
end() &&
"Not a valid segment!");
189 Segment *S = segmentAt(I);
193 iterator MergeTo =
I;
195 if (MergeTo == segments().
begin()) {
197 segments().erase(MergeTo, I);
200 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
202 }
while (NewStart <= MergeTo->start);
206 if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
207 segmentAt(MergeTo)->end = S->end;
211 Segment *MergeToSeg = segmentAt(MergeTo);
212 MergeToSeg->start = NewStart;
213 MergeToSeg->end = S->end;
216 segments().erase(std::next(MergeTo), std::next(I));
220 iterator addSegment(Segment S) {
222 iterator I =
impl().findInsertPos(S);
226 if (I != segments().
begin()) {
227 iterator
B = std::prev(I);
228 if (S.valno == B->valno) {
229 if (B->start <= Start && B->end >= Start) {
230 extendSegmentEndTo(B, End);
237 "Cannot overlap two segments with differing ValID's" 238 " (did you def the same reg twice in a MachineInstr?)");
244 if (I != segments().
end()) {
245 if (S.valno == I->valno) {
246 if (I->start <= End) {
247 I = extendSegmentStartTo(I, Start);
252 extendSegmentEndTo(I, End);
259 "Cannot overlap two segments with differing ValID's");
266 return segments().insert(I, S);
270 ImplT &
impl() {
return *
static_cast<ImplT *
>(
this); }
272 CollectionT &segments() {
return impl().segmentsColl(); }
274 Segment *segmentAt(iterator I) {
return const_cast<Segment *
>(&(*I)); }
282 class CalcLiveRangeUtilVector;
283 using CalcLiveRangeUtilVectorBase =
287 class CalcLiveRangeUtilVector :
public CalcLiveRangeUtilVectorBase {
289 CalcLiveRangeUtilVector(
LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}
292 friend CalcLiveRangeUtilVectorBase;
294 LiveRange::Segments &segmentsColl() {
return LR->
segments; }
300 iterator findInsertPos(Segment S) {
310 class CalcLiveRangeUtilSet;
311 using CalcLiveRangeUtilSetBase =
312 CalcLiveRangeUtilBase<CalcLiveRangeUtilSet, LiveRange::SegmentSet::iterator,
315 class CalcLiveRangeUtilSet :
public CalcLiveRangeUtilSetBase {
317 CalcLiveRangeUtilSet(
LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}
320 friend CalcLiveRangeUtilSetBase;
322 LiveRange::SegmentSet &segmentsColl() {
return *LR->
segmentSet; }
324 void insertAtEnd(
const Segment &S) {
333 iterator PrevI = std::prev(I);
334 if (Pos < (*PrevI).end)
339 iterator findInsertPos(Segment S) {
357 if (
empty() || Pos >= endIndex())
362 size_t Mid = Len >> 1;
363 if (Pos < I[Mid].
end) {
375 if (segmentSet !=
nullptr)
376 return CalcLiveRangeUtilSet(
this).createDeadDef(Def, &VNIAlloc,
nullptr);
378 return CalcLiveRangeUtilVector(
this).createDeadDef(Def, &VNIAlloc,
nullptr);
383 if (segmentSet !=
nullptr)
384 return CalcLiveRangeUtilSet(
this).createDeadDef(VNI->
def,
nullptr, VNI);
386 return CalcLiveRangeUtilVector(
this).createDeadDef(VNI->
def,
nullptr, VNI);
415 assert((StartPos->start <= i->start || StartPos == other.
begin()) &&
416 StartPos != other.
end() &&
"Bogus start position hint!");
418 if (i->start < j->start) {
420 if (i !=
begin()) --i;
421 }
else if (j->start < i->start) {
423 if (StartPos != other.
end() && StartPos->start <= i->start) {
426 if (j != other.
begin()) --j;
432 if (j == je)
return false;
435 if (i->start > j->start) {
440 if (i->end > j->start)
466 assert(J->end >= I->start);
468 if (J->start < I->end) {
477 if (J->end > I->end) {
485 while (J->end < I->start);
492 assert(Start < End &&
"Invalid range");
494 return I !=
begin() && (--
I)->
end > Start;
499 return Other.
empty();
503 I = advanceTo(I, O.
start);
504 if (I ==
end() || I->start > O.
start)
508 while (I->end < O.
end) {
512 if (I ==
end() || Last->
end != I->start)
522 void LiveRange::markValNoForDeletion(
VNInfo *ValNo) {
523 if (ValNo->
id == getNumValNums()-1) {
526 }
while (!valnos.empty() && valnos.back()->isUnused());
537 for (
const Segment &S : segments) {
539 if (!Seen.
insert(VNI).second)
543 valnos.push_back(VNI);
547 void LiveRange::addSegmentToSet(
Segment S) {
548 CalcLiveRangeUtilSet(
this).addSegment(S);
553 if (segmentSet !=
nullptr) {
558 return CalcLiveRangeUtilVector(
this).addSegment(S);
563 assert(segments.empty() || segments.back().end <= S.
start);
564 segments.push_back(S);
570 if (segmentSet !=
nullptr)
571 return CalcLiveRangeUtilSet(
this).extendInBlock(Undefs, StartIdx, Kill);
573 return CalcLiveRangeUtilVector(
this).extendInBlock(Undefs, StartIdx, Kill);
578 if (segmentSet !=
nullptr)
579 return CalcLiveRangeUtilSet(
this).extendInBlock(StartIdx, Kill);
581 return CalcLiveRangeUtilVector(
this).extendInBlock(StartIdx, Kill);
587 bool RemoveDeadValNo) {
590 assert(I !=
end() &&
"Segment is not in range!");
591 assert(I->containsInterval(Start, End)
592 &&
"Segment is not entirely in range!");
596 if (I->start == Start) {
598 if (RemoveDeadValNo) {
602 if (II != I && II->valno == ValNo) {
608 markValNoForDeletion(ValNo);
630 segments.insert(std::next(I),
Segment(End, OldEnd, ValNo));
638 return S.
valno == ValNo;
641 markValNoForDeletion(ValNo);
645 const int *LHSValNoAssignments,
646 const int *RHSValNoAssignments,
652 bool MustMapCurValNos =
false;
653 unsigned NumVals = getNumValNums();
654 unsigned NumNewVals = NewVNInfo.
size();
655 for (
unsigned i = 0; i != NumVals; ++i) {
656 unsigned LHSValID = LHSValNoAssignments[i];
658 (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) {
659 MustMapCurValNos =
true;
665 if (MustMapCurValNos && !
empty()) {
669 OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]];
671 VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]];
672 assert(nextValNo &&
"Huh?");
677 if (OutIt->valno == nextValNo && OutIt->end == I->start) {
682 OutIt->valno = nextValNo;
684 OutIt->start = I->start;
691 segments.erase(OutIt,
end());
703 unsigned NumValNos = 0;
704 for (
unsigned i = 0; i < NumNewVals; ++i) {
705 VNInfo *VNI = NewVNInfo[i];
707 if (NumValNos >= NumVals)
710 valnos[NumValNos] = VNI;
711 VNI->
id = NumValNos++;
714 if (NumNewVals < NumVals)
715 valnos.resize(NumNewVals);
744 if (S.
valno == RHSValNo)
753 assert(V1 != V2 &&
"Identical value#'s are always equivalent!");
761 if (V1->
id < V2->
id) {
769 if (S->valno != V1)
continue;
775 if (Prev->valno == V2 && Prev->end == S->start) {
793 if (I->start == S->end && I->valno == V2) {
802 markValNoForDeletion(V1);
808 assert(segmentSet !=
nullptr &&
"segment set must have been created");
811 "segment set can be used only initially before switching to the array");
812 segments.append(segmentSet->begin(), segmentSet->end());
813 segmentSet =
nullptr;
830 if (SegmentI == SegmentE)
834 for ( ; SlotI != SlotE; ++SlotI) {
837 SegmentI = advanceTo(SegmentI, *SlotI);
838 if (SegmentI == SegmentE)
842 if (SegmentI->contains(*SlotI))
851 void LiveInterval::freeSubRange(SubRange *S) {
859 while (I !=
nullptr) {
870 }
while (I !=
nullptr && I->
empty());
876 for (
SubRange *I = SubRanges, *Next; I !=
nullptr; I = Next) {
893 if (SRMask == Matching) {
901 MatchingRange = createSubRangeFrom(Allocator, Matching, SR);
903 Apply(*MatchingRange);
904 ToApply &= ~Matching;
908 SubRange *NewRange = createSubRange(Allocator, ToApply);
915 for (
const Segment &S : segments)
916 Sum += S.start.distance(S.end);
926 assert((VRegMask & LaneMask).any());
931 unsigned SubReg = MO.getSubReg();
932 assert(SubReg != 0 &&
"Undef should only be set on subreg defs");
935 if ((UndefMask & LaneMask).any()) {
945 return OS <<
'[' << S.
start <<
',' << S.
end <<
':' << S.
valno->
id <<
')';
948 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 950 dbgs() << *
this <<
'\n';
958 for (
const Segment &S : segments) {
960 assert(S.valno == getValNumInfo(S.valno->id) &&
"Bad VNInfo");
965 if (getNumValNums()) {
993 for (
const SubRange &SR : subranges())
995 OS <<
" weight:" << weight;
998 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1000 dbgs() << *
this <<
'\n';
1004 dbgs() << *
this <<
'\n';
1008 dbgs() << *
this <<
'\n';
1015 assert(I->start.isValid());
1016 assert(I->end.isValid());
1017 assert(I->start < I->end);
1018 assert(I->valno !=
nullptr);
1019 assert(I->valno->id < valnos.size());
1020 assert(I->valno == valnos[I->valno->id]);
1021 if (std::next(I) !=
E) {
1022 assert(I->end <= std::next(I)->start);
1023 if (I->end == std::next(I)->start)
1024 assert(I->valno != std::next(I)->valno);
1036 for (
const SubRange &SR : subranges()) {
1038 assert((Mask & SR.LaneMask).none());
1039 Mask |= SR.LaneMask;
1042 assert((Mask & ~MaxMask).none());
1082 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1086 OS <<
"Clean updater: " << *LR <<
'\n';
1088 OS <<
"Null updater.\n";
1091 assert(LR &&
"Can't have null LR in dirty updater.");
1092 OS <<
" updater with gap = " << (ReadI - WriteI)
1093 <<
", last start = " << LastStart
1098 for (
unsigned I = 0,
E = Spills.size(); I !=
E; ++
I)
1099 OS <<
' ' << Spills[I];
1124 assert(LR &&
"Cannot add to a null destination");
1129 LR->addSegmentToSet(Seg);
1134 if (!LastStart.isValid() || LastStart > Seg.
start) {
1138 assert(Spills.empty() &&
"Leftover spilled segments");
1139 WriteI = ReadI = LR->
begin();
1143 LastStart = Seg.
start;
1146 LiveRange::iterator
E = LR->
end();
1147 if (ReadI != E && ReadI->end <= Seg.
start) {
1149 if (ReadI != WriteI)
1152 if (ReadI == WriteI)
1155 while (ReadI != E && ReadI->end <= Seg.
start)
1156 *WriteI++ = *ReadI++;
1162 if (ReadI != E && ReadI->start <= Seg.
start) {
1163 assert(ReadI->valno == Seg.
valno &&
"Cannot overlap different values");
1165 if (ReadI->end >= Seg.
end)
1168 Seg.
start = ReadI->start;
1179 if (!Spills.empty() &&
coalescable(Spills.back(), Seg)) {
1180 Seg.
start = Spills.back().start;
1192 if (WriteI != ReadI) {
1200 WriteI = ReadI = LR->
end();
1202 Spills.push_back(Seg);
1207 void LiveRangeUpdater::mergeSpills() {
1209 size_t GapSize = ReadI - WriteI;
1210 size_t NumMoved = std::min(Spills.size(), GapSize);
1211 LiveRange::iterator Src = WriteI;
1212 LiveRange::iterator Dst = Src + NumMoved;
1213 LiveRange::iterator SpillSrc = Spills.end();
1214 LiveRange::iterator B = LR->
begin();
1220 while (Src != Dst) {
1221 if (Src != B && Src[-1].start > SpillSrc[-1].start)
1224 *--Dst = *--SpillSrc;
1226 assert(NumMoved ==
size_t(Spills.end() - SpillSrc));
1227 Spills.erase(SpillSrc, Spills.end());
1236 assert(LR &&
"Cannot add to a null destination");
1239 if (Spills.empty()) {
1246 size_t GapSize = ReadI - WriteI;
1247 if (GapSize < Spills.size()) {
1249 size_t WritePos = WriteI - LR->
begin();
1252 WriteI = LR->
begin() + WritePos;
1257 ReadI = WriteI + Spills.size();
1267 const VNInfo *used =
nullptr, *unused =
nullptr;
1274 EqClass.join(unused->id, VNI->
id);
1281 assert(MBB &&
"Phi-def has no defining MBB");
1284 PE = MBB->
pred_end(); PI != PE; ++PI)
1286 EqClass.join(VNI->
id, PVNI->id);
1293 EqClass.join(VNI->
id, UVNI->id);
1299 EqClass.join(used->
id, unused->id);
1302 return EqClass.getNumClasses();
1309 RE = MRI.
reg_end(); RI != RE;) {
1317 SlotIndex Idx = LIS.getSlotIndexes()->getIndexBefore(*MI);
1320 SlotIndex Idx = LIS.getInstructionIndex(*MI);
1328 if (
unsigned EqClass = getEqClass(VNI))
1329 MO.
setReg(LIV[EqClass-1]->reg);
1334 unsigned NumComponents = EqClass.getNumClasses();
1341 unsigned NumValNos = SR.valnos.size();
1343 VNIMapping.
reserve(NumValNos);
1345 SubRanges.
resize(NumComponents-1,
nullptr);
1346 for (
unsigned I = 0; I < NumValNos; ++
I) {
1347 const VNInfo &VNI = *SR.valnos[
I];
1348 unsigned ComponentNum;
1353 assert(MainRangeVNI !=
nullptr 1354 &&
"SubRange def must have corresponding main range def");
1355 ComponentNum = getEqClass(MainRangeVNI);
1356 if (ComponentNum > 0 && SubRanges[ComponentNum-1] ==
nullptr) {
1357 SubRanges[ComponentNum-1]
void add(LiveRange::Segment)
Add a segment to LR and coalesce when possible, just like LR.addSegment().
std::set< Segment > SegmentSet
void RenumberValues()
RenumberValues - Renumber all values in order of appearance and remove unused values.
bool overlapsFrom(const LiveRange &Other, const_iterator StartPos) const
overlapsFrom - Return true if the intersection of the two live ranges is not empty.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
const_iterator end(StringRef path)
Get end iterator over path.
A common definition of LaneBitmask for use in TableGen and CodeGen.
void flush()
Flush the updater state to LR so it is valid and contains all added segments.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
SlotIndex def
The index of the defining instruction.
LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
This class represents lattice values for constants.
static bool coalescable(const LiveRange::Segment &A, const LiveRange::Segment &B)
bool isCoalescable(const MachineInstr *) const
Return true if MI is a copy instruction that will become an identity copy after coalescing.
void MergeValueInAsValue(const LiveRange &RHS, const VNInfo *RHSValNo, VNInfo *LHSValNo)
MergeValueInAsValue - Merge all of the segments of a specific val# in RHS into this live range as the...
Segments::iterator iterator
void push_back(const T &Elt)
bool isUndefIn(ArrayRef< SlotIndex > Undefs, SlotIndex Begin, SlotIndex End) const
Returns true if there is an explicit "undef" between Begin End.
LiveInterval - This class represents the liveness of a register, or stack slot.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool isDead() const
isDead - Returns true if this is a dead def kill slot.
bool isLiveAtIndexes(ArrayRef< SlotIndex > Slots) const
A live range for subregisters.
This represents a simple continuous liveness interval for a value.
unsigned const TargetRegisterInfo * TRI
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
void markUnused()
Mark this value as unused.
std::vector< MachineBasicBlock * >::const_iterator const_pred_iterator
void reserve(size_type N)
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
VNInfo - Value Number Information.
void flushSegmentSet()
Flush segment set into the regular segment vector.
void Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI)
Distribute values in LI into a separate LiveIntervals for each connected component.
This class represents the liveness of a register, stack slot, etc.
bool isUnused() const
Returns true if this value is unused.
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
bool isBlock() const
isBlock - Returns true if this is a block boundary slot.
void verify() const
Walk the range and assert if any invariants fail to hold.
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A Use represents the edge between a Value definition and its users.
A helper class for register coalescers.
iterator_range< subrange_iterator > subranges()
Result of a LiveRange query.
static constexpr LaneBitmask getAll()
SlotIndex getInstructionIndex(const MachineInstr &MI) const
Returns the base index for the given instruction.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
void MergeSegmentsInAsValue(const LiveRange &RHS, VNInfo *LHSValNo)
Merge all of the live segments of a specific val# in RHS into this live range as the specified value ...
place backedge safepoints impl
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
iterator_range< def_iterator > def_operands(unsigned Reg) const
VNInfo * MergeValueNumberInto(VNInfo *V1, VNInfo *V2)
MergeValueNumberInto - This method is called when two value numbers are found to be equivalent...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
SlotIndex getNextSlot() const
Returns the next slot in the index list.
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
void print(raw_ostream &OS) const
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)
Helper function that distributes live range value numbers and the corresponding segments of a master ...
void copyFrom(VNInfo &src)
Copy from the parameter into this VNInfo.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
friend const_iterator end(StringRef path)
Get end iterator over path.
const TargetRegisterInfo * getTargetRegisterInfo() const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
unsigned const MachineRegisterInfo * MRI
VNInfoList::const_iterator const_vni_iterator
void print(raw_ostream &OS) const
Allocate memory in an ever growing pool, as if by bump-pointer.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned Classify(const LiveRange &LR)
Classify the values in LR into connected components.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
constexpr bool none() const
void append(const LiveRange::Segment S)
Append a segment to the list of segments.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
void join(LiveRange &Other, const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVectorImpl< VNInfo *> &NewVNInfo)
join - Join two live ranges (this, and other) together.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, std::function< void(LiveInterval::SubRange &)> Apply)
Refines the subranges to support LaneMask.
iterator erase(const_iterator CI)
void print(raw_ostream &) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
unsigned id
The ID number of this value.
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified segment from this range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool covers(const LiveRange &Other) const
Returns true if all segments of the Other live range are completely covered by this live range...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
Segments::const_iterator const_iterator
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
reg_iterator reg_begin(unsigned RegNo) const
std::unique_ptr< SegmentSet > segmentSet
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void clearSubRanges()
Removes all subregister liveness information.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx...
void computeSubRangeUndefs(SmallVectorImpl< SlotIndex > &Undefs, LaneBitmask LaneMask, const MachineRegisterInfo &MRI, const SlotIndexes &Indexes) const
For a given lane mask LaneMask, compute indexes at which the lane is marked undefined by subregister ...
iterator insert(iterator I, T &&Elt)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
unsigned getNumValNums() const
Representation of each machine instruction.
pointer data()
Return a pointer to the vector's buffer, even if empty().
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
constexpr bool any() const
static void createDeadDef(SlotIndexes &Indexes, VNInfo::Allocator &Alloc, LiveRange &LR, const MachineOperand &MO)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Helper class for performant LiveRange bulk updates.
VNInfo * getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
std::pair< VNInfo *, bool > extendInBlock(ArrayRef< SlotIndex > Undefs, SlotIndex StartIdx, SlotIndex Kill)
Attempt to extend a value defined after StartIdx to include Use.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
print Print MemDeps of function
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
static reg_iterator reg_end()
void print(raw_ostream &OS) const
SlotIndex - An opaque wrapper around machine indexes.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...