50 template <
typename ImplT,
typename IteratorT,
typename CollectionT>
51 class CalcLiveRangeUtilBase {
56 CalcLiveRangeUtilBase(
LiveRange *LR) : LR(LR) {}
60 typedef IteratorT iterator;
75 assert(!Def.
isDead() &&
"Cannot define a value at the dead slot");
77 "If ForVNI is specified, it must match Def");
78 iterator
I =
impl().find(Def);
79 if (I == segments().
end()) {
80 VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
85 Segment *S = segmentAt(I);
87 assert((!ForVNI || ForVNI == S->valno) &&
"Value number mismatch");
88 assert(S->valno->def == S->start &&
"Inconsistent existing value def");
97 S->start = S->valno->def =
Def;
101 VNInfo *VNI = ForVNI ? ForVNI : LR->getNextValue(Def, *VNInfoAllocator);
102 segments().insert(I, Segment(Def, Def.
getDeadSlot(), VNI));
107 if (segments().empty())
111 if (I == segments().begin())
114 if (I->end <= StartIdx)
117 extendSegmentEndTo(I, Use);
123 if (segments().empty())
124 return std::make_pair(
nullptr,
false);
126 iterator I =
impl().findInsertPos(Segment(BeforeUse, Use,
nullptr));
127 if (I == segments().
begin())
128 return std::make_pair(
nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
130 if (I->end <= StartIdx)
131 return std::make_pair(
nullptr, LR->isUndefIn(Undefs, StartIdx, BeforeUse));
133 if (LR->isUndefIn(Undefs, I->
end, BeforeUse))
134 return std::make_pair(
nullptr,
true);
135 extendSegmentEndTo(I, Use);
137 return std::make_pair(I->valno,
false);
144 void extendSegmentEndTo(iterator I,
SlotIndex NewEnd) {
145 assert(I != segments().
end() &&
"Not a valid segment!");
146 Segment *S = segmentAt(I);
150 iterator MergeTo = std::next(I);
151 for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo)
152 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
155 S->end = std::max(NewEnd, std::prev(MergeTo)->
end);
159 if (MergeTo != segments().
end() && MergeTo->start <= I->
end &&
160 MergeTo->valno == ValNo) {
161 S->end = MergeTo->end;
166 segments().erase(std::next(I), MergeTo);
172 iterator extendSegmentStartTo(iterator I,
SlotIndex NewStart) {
173 assert(I != segments().
end() &&
"Not a valid segment!");
174 Segment *S = segmentAt(I);
178 iterator MergeTo =
I;
180 if (MergeTo == segments().
begin()) {
182 segments().erase(MergeTo, I);
185 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
187 }
while (NewStart <= MergeTo->start);
191 if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
192 segmentAt(MergeTo)->end = S->end;
196 Segment *MergeToSeg = segmentAt(MergeTo);
197 MergeToSeg->start = NewStart;
198 MergeToSeg->end = S->end;
201 segments().erase(std::next(MergeTo), std::next(I));
205 iterator addSegment(Segment S) {
207 iterator I =
impl().findInsertPos(S);
211 if (I != segments().
begin()) {
212 iterator
B = std::prev(I);
213 if (S.valno == B->valno) {
214 if (B->start <= Start && B->end >= Start) {
215 extendSegmentEndTo(B,
End);
222 "Cannot overlap two segments with differing ValID's"
223 " (did you def the same reg twice in a MachineInstr?)");
229 if (I != segments().
end()) {
230 if (S.valno == I->valno) {
231 if (I->start <=
End) {
232 I = extendSegmentStartTo(I, Start);
237 extendSegmentEndTo(I,
End);
244 "Cannot overlap two segments with differing ValID's");
251 return segments().insert(I, S);
255 ImplT &
impl() {
return *
static_cast<ImplT *
>(
this); }
257 CollectionT &segments() {
return impl().segmentsColl(); }
259 Segment *segmentAt(iterator I) {
return const_cast<Segment *
>(&(*I)); }
267 class CalcLiveRangeUtilVector;
271 class CalcLiveRangeUtilVector :
public CalcLiveRangeUtilVectorBase {
273 CalcLiveRangeUtilVector(
LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}
276 friend CalcLiveRangeUtilVectorBase;
280 void insertAtEnd(
const Segment &S) { LR->segments.
push_back(S); }
284 iterator findInsertPos(Segment S) {
285 return std::upper_bound(LR->begin(), LR->end(), S.start);
294 class CalcLiveRangeUtilSet;
295 typedef CalcLiveRangeUtilBase<CalcLiveRangeUtilSet,
296 LiveRange::SegmentSet::iterator,
299 class CalcLiveRangeUtilSet :
public CalcLiveRangeUtilSetBase {
301 CalcLiveRangeUtilSet(
LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}
304 friend CalcLiveRangeUtilSetBase;
308 void insertAtEnd(
const Segment &S) {
309 LR->segmentSet->insert(LR->segmentSet->end(), S);
314 LR->segmentSet->upper_bound(Segment(Pos, Pos.
getNextSlot(),
nullptr));
315 if (I == LR->segmentSet->begin())
317 iterator PrevI = std::prev(I);
318 if (Pos < (*PrevI).end)
323 iterator findInsertPos(Segment S) {
324 iterator I = LR->segmentSet->upper_bound(S);
325 if (I != LR->segmentSet->end() && !(S.start < *
I))
345 size_t Mid = Len >> 1;
346 if (Pos < I[Mid].
end) {
359 return CalcLiveRangeUtilSet(
this).createDeadDef(Def, &VNIAlloc,
nullptr);
361 return CalcLiveRangeUtilVector(
this).createDeadDef(Def, &VNIAlloc,
nullptr);
367 return CalcLiveRangeUtilSet(
this).createDeadDef(VNI->
def,
nullptr, VNI);
369 return CalcLiveRangeUtilVector(
this).createDeadDef(VNI->
def,
nullptr, VNI);
398 assert((StartPos->start <= i->start || StartPos == other.
begin()) &&
399 StartPos != other.
end() &&
"Bogus start position hint!");
401 if (i->start < j->start) {
402 i = std::upper_bound(i, ie, j->start);
404 }
else if (j->start < i->start) {
406 if (StartPos != other.
end() && StartPos->start <= i->start) {
408 j = std::upper_bound(j, je, i->start);
409 if (j != other.
begin()) --j;
415 if (j == je)
return false;
418 if (i->start > j->start) {
423 if (i->end > j->start)
449 assert(J->end >= I->start);
451 if (J->start < I->end) {
453 SlotIndex Def = std::max(I->start, J->start);
460 if (J->end > I->end) {
468 while (J->end < I->start);
475 assert(Start < End &&
"Invalid range");
477 return I !=
begin() && (--
I)->
end > Start;
482 return Other.
empty();
487 if (I ==
end() || I->start > O.
start)
491 while (I->end < O.
end) {
495 if (I ==
end() || Last->end != I->start)
505 void LiveRange::markValNoForDeletion(
VNInfo *ValNo) {
522 if (!Seen.
insert(VNI).second)
530 void LiveRange::addSegmentToSet(Segment S) {
531 CalcLiveRangeUtilSet(
this).addSegment(S);
541 return CalcLiveRangeUtilVector(
this).addSegment(S);
554 return CalcLiveRangeUtilSet(
this).extendInBlock(Undefs, StartIdx, Kill);
556 return CalcLiveRangeUtilVector(
this).extendInBlock(Undefs, StartIdx, Kill);
562 return CalcLiveRangeUtilSet(
this).extendInBlock(StartIdx, Kill);
564 return CalcLiveRangeUtilVector(
this).extendInBlock(StartIdx, Kill);
570 bool RemoveDeadValNo) {
573 assert(I !=
end() &&
"Segment is not in range!");
574 assert(I->containsInterval(Start, End)
575 &&
"Segment is not entirely in range!");
579 if (I->start == Start) {
581 if (RemoveDeadValNo) {
585 if (II != I && II->valno == ValNo) {
591 markValNoForDeletion(ValNo);
621 return S.
valno == ValNo;
624 markValNoForDeletion(ValNo);
628 const int *LHSValNoAssignments,
629 const int *RHSValNoAssignments,
635 bool MustMapCurValNos =
false;
637 unsigned NumNewVals = NewVNInfo.
size();
638 for (
unsigned i = 0;
i != NumVals; ++
i) {
639 unsigned LHSValID = LHSValNoAssignments[
i];
641 (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] !=
getValNumInfo(
i))) {
642 MustMapCurValNos =
true;
648 if (MustMapCurValNos && !
empty()) {
652 OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]];
654 VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]];
655 assert(nextValNo &&
"Huh?");
660 if (OutIt->valno == nextValNo && OutIt->end == I->start) {
665 OutIt->valno = nextValNo;
667 OutIt->start = I->start;
686 unsigned NumValNos = 0;
687 for (
unsigned i = 0;
i < NumNewVals; ++
i) {
690 if (NumValNos >= NumVals)
694 VNI->
id = NumValNos++;
697 if (NumNewVals < NumVals)
727 if (S.
valno == RHSValNo)
736 assert(V1 != V2 &&
"Identical value#'s are always equivalent!");
744 if (V1->
id < V2->
id) {
752 if (S->valno != V1)
continue;
758 if (Prev->valno == V2 && Prev->end == S->start) {
776 if (I->start == S->end && I->valno == V2) {
785 markValNoForDeletion(V1);
794 "segment set can be used only initially before switching to the array");
813 if (SegmentI == SegmentE)
817 for ( ; SlotI != SlotE; ++SlotI) {
821 if (SegmentI == SegmentE)
825 if (SegmentI->contains(*SlotI))
834 void LiveInterval::freeSubRange(SubRange *S) {
842 while (I !=
nullptr) {
853 }
while (I !=
nullptr && I->
empty());
859 for (
SubRange *I = SubRanges, *Next; I !=
nullptr; I = Next) {
869 Sum += S.start.distance(S.end);
879 assert((VRegMask & LaneMask).any());
884 unsigned SubReg = MO.getSubReg();
885 assert(SubReg != 0 &&
"Undef should only be set on subreg defs");
888 if ((UndefMask & LaneMask).any()) {
898 return os <<
'[' << S.
start <<
',' << S.
end <<
':' << S.
valno->
id <<
')';
901 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
903 dbgs() << *
this <<
'\n';
946 for (
const SubRange &SR : subranges())
950 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
952 dbgs() << *
this <<
'\n';
956 dbgs() << *
this <<
'\n';
960 dbgs() << *
this <<
'\n';
967 assert(I->start.isValid());
969 assert(I->start < I->end);
970 assert(I->valno !=
nullptr);
973 if (std::next(I) !=
E) {
974 assert(I->end <= std::next(I)->start);
975 if (I->end == std::next(I)->start)
976 assert(I->valno != std::next(I)->valno);
988 for (
const SubRange &SR : subranges()) {
990 assert((Mask & SR.LaneMask).none());
994 assert((Mask & ~MaxMask).none());
1038 OS <<
"Clean updater: " << *LR <<
'\n';
1040 OS <<
"Null updater.\n";
1043 assert(LR &&
"Can't have null LR in dirty updater.");
1044 OS <<
" updater with gap = " << (ReadI - WriteI)
1045 <<
", last start = " << LastStart
1047 for (
const auto &S :
make_range(LR->begin(), WriteI))
1050 for (
unsigned I = 0,
E = Spills.size(); I !=
E; ++
I)
1051 OS <<
' ' << Spills[I];
1053 for (
const auto &S :
make_range(ReadI, LR->end()))
1075 assert(LR &&
"Cannot add to a null destination");
1079 if (LR->segmentSet !=
nullptr) {
1080 LR->addSegmentToSet(Seg);
1085 if (!LastStart.isValid() || LastStart > Seg.
start) {
1089 assert(Spills.empty() &&
"Leftover spilled segments");
1090 WriteI = ReadI = LR->begin();
1094 LastStart = Seg.
start;
1097 LiveRange::iterator
E = LR->end();
1098 if (ReadI != E && ReadI->end <= Seg.
start) {
1100 if (ReadI != WriteI)
1103 if (ReadI == WriteI)
1104 ReadI = WriteI = LR->find(Seg.
start);
1106 while (ReadI != E && ReadI->end <= Seg.
start)
1107 *WriteI++ = *ReadI++;
1113 if (ReadI != E && ReadI->start <= Seg.
start) {
1114 assert(ReadI->valno == Seg.
valno &&
"Cannot overlap different values");
1116 if (ReadI->end >= Seg.
end)
1119 Seg.
start = ReadI->start;
1125 Seg.
end = std::max(Seg.
end, ReadI->end);
1130 if (!Spills.empty() &&
coalescable(Spills.back(), Seg)) {
1131 Seg.
start = Spills.back().start;
1132 Seg.
end = std::max(Spills.back().end, Seg.
end);
1137 if (WriteI != LR->begin() &&
coalescable(WriteI[-1], Seg)) {
1138 WriteI[-1].end = std::max(WriteI[-1].
end, Seg.
end);
1143 if (WriteI != ReadI) {
1150 LR->segments.push_back(Seg);
1151 WriteI = ReadI = LR->
end();
1153 Spills.push_back(Seg);
1158 void LiveRangeUpdater::mergeSpills() {
1160 size_t GapSize = ReadI - WriteI;
1161 size_t NumMoved =
std::min(Spills.size(), GapSize);
1162 LiveRange::iterator Src = WriteI;
1163 LiveRange::iterator Dst = Src + NumMoved;
1164 LiveRange::iterator SpillSrc = Spills.end();
1165 LiveRange::iterator B = LR->begin();
1171 while (Src != Dst) {
1172 if (Src != B && Src[-1].start > SpillSrc[-1].start)
1175 *--Dst = *--SpillSrc;
1177 assert(NumMoved ==
size_t(Spills.end() - SpillSrc));
1178 Spills.erase(SpillSrc, Spills.end());
1187 assert(LR &&
"Cannot add to a null destination");
1190 if (Spills.empty()) {
1191 LR->segments.erase(WriteI, ReadI);
1197 size_t GapSize = ReadI - WriteI;
1198 if (GapSize < Spills.size()) {
1200 size_t WritePos = WriteI - LR->begin();
1203 WriteI = LR->begin() + WritePos;
1206 LR->segments.erase(WriteI + Spills.size(), ReadI);
1208 ReadI = WriteI + Spills.size();
1218 const VNInfo *used =
nullptr, *unused =
nullptr;
1225 EqClass.join(unused->id, VNI->
id);
1232 assert(MBB &&
"Phi-def has no defining MBB");
1235 PE = MBB->
pred_end(); PI != PE; ++PI)
1237 EqClass.join(VNI->
id, PVNI->id);
1244 EqClass.join(VNI->
id, UVNI->id);
1250 EqClass.join(used->
id, unused->id);
1253 return EqClass.getNumClasses();
1260 RE = MRI.
reg_end(); RI != RE;) {
1270 Idx = LIS.getSlotIndexes()->getIndexBefore(*MI);
1272 Idx = LIS.getInstructionIndex(*MI);
1279 if (
unsigned EqClass = getEqClass(VNI))
1280 MO.
setReg(LIV[EqClass-1]->reg);
1285 unsigned NumComponents = EqClass.getNumClasses();
1292 unsigned NumValNos = SR.valnos.size();
1294 VNIMapping.
reserve(NumValNos);
1296 SubRanges.
resize(NumComponents-1,
nullptr);
1297 for (
unsigned I = 0; I < NumValNos; ++
I) {
1298 const VNInfo &VNI = *SR.valnos[
I];
1299 unsigned ComponentNum;
1304 assert(MainRangeVNI !=
nullptr
1305 &&
"SubRange def must have corresponding main range def");
1306 ComponentNum = getEqClass(MainRangeVNI);
1307 if (ComponentNum > 0 && SubRanges[ComponentNum-1] ==
nullptr) {
1308 SubRanges[ComponentNum-1]
void add(LiveRange::Segment)
Add a segment to LR and coalesce when possible, just like LR.addSegment().
void RenumberValues()
RenumberValues - Renumber all values in order of appearance and remove unused values.
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
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.
Segments::iterator iterator
SlotIndex getInstructionIndex(const MachineInstr &MI) const
Returns the base index for the given instruction.
SlotIndex def
The index of the defining instruction.
static bool coalescable(const LiveRange::Segment &A, const LiveRange::Segment &B)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
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...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
static LaneBitmask getAll()
LiveInterval - This class represents the liveness of a register, or stack slot.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position...
bool isLiveAtIndexes(ArrayRef< SlotIndex > Slots) const
const_iterator begin(StringRef path)
Get begin iterator over path.
A live range for subregisters.
This represents a simple continuous liveness interval for a value.
void markUnused()
Mark this value as unused.
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
void reserve(size_type N)
VNInfo - Value Number Information.
unsigned getNumValNums() const
void flushSegmentSet()
Flush segment set into the regular segment vector.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
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.
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...
const TargetRegisterInfo * getTargetRegisterInfo() const
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.
bool isBlock() const
isBlock - Returns true if this is a block boundary slot.
unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
LLVM_NODISCARD bool empty() const
void print(raw_ostream &OS) const
bool isUnused() const
Returns true if this value is unused.
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 isDead() const
isDead - Returns true if this is a dead def kill slot.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
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)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)
Helper function that distributes live range value numbers and the corresponding segments of a master ...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void copyFrom(VNInfo &src)
Copy from the parameter into this VNInfo.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
iterator_range< def_iterator > def_operands(unsigned Reg) const
bool isDebugValue() const
void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
friend const_iterator end(StringRef path)
Get end iterator over path.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
unsigned const MachineRegisterInfo * MRI
Allocate memory in an ever growing pool, as if by bump-pointer.
std::pair< VNInfo *, bool > extendInBlock(ArrayRef< SlotIndex > Undefs, SlotIndex StartIdx, SlotIndex Use)
Attempt to extend a value defined after StartIdx to include Use.
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.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
Greedy Register Allocator
static const unsigned End
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
void append(const LiveRange::Segment S)
Append a segment to the list of segments.
void verify() const
Walk the range and assert if any invariants fail to hold.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
iterator erase(const_iterator CI)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
std::vector< MachineBasicBlock * >::const_iterator const_pred_iterator
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
MachineOperand class - Representation of each machine instruction operand.
std::unique_ptr< SegmentSet > segmentSet
bool isCoalescable(const MachineInstr *) const
Return true if MI is a copy instruction that will become an identity copy after coalescing.
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.
void print(raw_ostream &OS) const
iterator insert(iterator I, T &&Elt)
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
Representation of each machine instruction.
void print(raw_ostream &OS) const
void print(raw_ostream &) const
LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
pointer data()
Return a pointer to the vector's buffer, even if empty().
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
createDeadDef - Make sure the range has a value defined at Def.
SlotIndex endIndex() const
endNumber - return the maximum point of the range of the whole, exclusive.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static void createDeadDef(SlotIndexes &Indexes, VNInfo::Allocator &Alloc, LiveRange &LR, const MachineOperand &MO)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
Helper class for performant LiveRange bulk updates.
std::set< Segment > SegmentSet
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLVM_ATTRIBUTE_UNUSED Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
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...
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 ...
void join(LiveRange &Other, const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVectorImpl< VNInfo * > &NewVNInfo)
join - Join two live ranges (this, and other) together.
reg_iterator reg_begin(unsigned RegNo) const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
SlotIndex getNextSlot() const
Returns the next slot in the index list.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
static reg_iterator reg_end()
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...
bool overlapsFrom(const LiveRange &Other, const_iterator I) const
overlapsFrom - Return true if the intersection of the two live ranges is not empty.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
bool covers(const LiveRange &Other) const
Returns true if all segments of the Other live range are completely covered by this live range...
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx...