Go to the documentation of this file.
35 #include "llvm/Config/llvm-config.h"
64 template <
typename ImplT,
typename IteratorT,
typename CollectionT>
65 class CalcLiveRangeUtilBase {
70 CalcLiveRangeUtilBase(
LiveRange *LR) : LR(LR) {}
74 using iterator = IteratorT;
89 assert(!
Def.isDead() &&
"Cannot define a value at the dead slot");
91 "If ForVNI is specified, it must match Def");
93 if (
I == segments().
end()) {
95 impl().insertAtEnd(Segment(
Def,
Def.getDeadSlot(), VNI));
99 Segment *
S = segmentAt(
I);
101 assert((!ForVNI || ForVNI ==
S->valno) &&
"Value number mismatch");
102 assert(
S->valno->def ==
S->start &&
"Inconsistent existing value def");
111 S->start =
S->valno->def =
Def;
116 segments().insert(
I, Segment(
Def,
Def.getDeadSlot(), VNI));
121 if (segments().empty())
124 impl().findInsertPos(Segment(
Use.getPrevSlot(),
Use,
nullptr));
125 if (
I == segments().
begin())
128 if (
I->end <= StartIdx)
131 extendSegmentEndTo(
I,
Use);
137 if (segments().empty())
138 return std::make_pair(
nullptr,
false);
140 iterator
I =
impl().findInsertPos(Segment(BeforeUse,
Use,
nullptr));
141 if (
I == segments().
begin())
142 return std::make_pair(
nullptr, LR->
isUndefIn(Undefs, StartIdx, BeforeUse));
144 if (
I->end <= StartIdx)
145 return std::make_pair(
nullptr, LR->
isUndefIn(Undefs, StartIdx, BeforeUse));
148 return std::make_pair(
nullptr,
true);
149 extendSegmentEndTo(
I,
Use);
151 return std::make_pair(
I->valno,
false);
158 void extendSegmentEndTo(iterator
I,
SlotIndex NewEnd) {
159 assert(
I != segments().
end() &&
"Not a valid segment!");
160 Segment *
S = segmentAt(
I);
164 iterator MergeTo = std::next(
I);
165 for (; MergeTo != segments().end() && NewEnd >= MergeTo->end; ++MergeTo)
166 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
173 if (MergeTo != segments().
end() && MergeTo->start <=
I->end &&
174 MergeTo->valno == ValNo) {
175 S->end = MergeTo->end;
180 segments().erase(std::next(
I), MergeTo);
186 iterator extendSegmentStartTo(iterator
I,
SlotIndex NewStart) {
187 assert(
I != segments().
end() &&
"Not a valid segment!");
188 Segment *
S = segmentAt(
I);
192 iterator MergeTo =
I;
194 if (MergeTo == segments().
begin()) {
196 segments().erase(MergeTo,
I);
199 assert(MergeTo->valno == ValNo &&
"Cannot merge with differing values!");
201 }
while (NewStart <= MergeTo->start);
205 if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
206 segmentAt(MergeTo)->end =
S->end;
210 Segment *MergeToSeg = segmentAt(MergeTo);
211 MergeToSeg->start = NewStart;
212 MergeToSeg->end =
S->end;
215 segments().erase(std::next(MergeTo), std::next(
I));
219 iterator addSegment(Segment
S) {
221 iterator
I =
impl().findInsertPos(
S);
225 if (
I != segments().
begin()) {
226 iterator
B = std::prev(
I);
227 if (
S.valno ==
B->valno) {
228 if (
B->start <= Start &&
B->end >= Start) {
229 extendSegmentEndTo(
B, End);
236 "Cannot overlap two segments with differing ValID's"
237 " (did you def the same reg twice in a MachineInstr?)");
243 if (
I != segments().
end()) {
244 if (
S.valno ==
I->valno) {
245 if (
I->start <= End) {
246 I = extendSegmentStartTo(
I, Start);
251 extendSegmentEndTo(
I, End);
258 "Cannot overlap two segments with differing ValID's");
265 return segments().insert(
I,
S);
269 ImplT &
impl() {
return *
static_cast<ImplT *
>(
this); }
271 CollectionT &segments() {
return impl().segmentsColl(); }
273 Segment *segmentAt(iterator
I) {
return const_cast<Segment *
>(&(*I)); }
281 class CalcLiveRangeUtilVector;
282 using CalcLiveRangeUtilVectorBase =
286 class CalcLiveRangeUtilVector :
public CalcLiveRangeUtilVectorBase {
288 CalcLiveRangeUtilVector(
LiveRange *LR) : CalcLiveRangeUtilVectorBase(LR) {}
291 friend CalcLiveRangeUtilVectorBase;
295 void insertAtEnd(
const Segment &
S) { LR->
segments.push_back(
S); }
307 class CalcLiveRangeUtilSet;
308 using CalcLiveRangeUtilSetBase =
309 CalcLiveRangeUtilBase<CalcLiveRangeUtilSet, LiveRange::SegmentSet::iterator,
312 class CalcLiveRangeUtilSet :
public CalcLiveRangeUtilSetBase {
314 CalcLiveRangeUtilSet(
LiveRange *LR) : CalcLiveRangeUtilSetBase(LR) {}
317 friend CalcLiveRangeUtilSetBase;
321 void insertAtEnd(
const Segment &
S) {
330 iterator PrevI = std::prev(
I);
331 if (Pos < (*PrevI).end)
336 iterator findInsertPos(Segment
S) {
352 [&](
const Segment &
X) {
return X.end <= Pos; });
358 return CalcLiveRangeUtilSet(
this).createDeadDef(
Def, &VNIAlloc,
nullptr);
360 return CalcLiveRangeUtilVector(
this).createDeadDef(
Def, &VNIAlloc,
nullptr);
366 return CalcLiveRangeUtilSet(
this).createDeadDef(VNI->
def,
nullptr, VNI);
368 return CalcLiveRangeUtilVector(
this).createDeadDef(VNI->
def,
nullptr, VNI);
397 assert((StartPos->start <=
i->start || StartPos == other.
begin()) &&
398 StartPos != other.
end() &&
"Bogus start position hint!");
400 if (
i->start <
j->start) {
403 }
else if (
j->start <
i->start) {
405 if (StartPos != other.
end() && StartPos->start <=
i->start) {
414 if (
j == je)
return false;
417 if (
i->start >
j->start) {
422 if (
i->end >
j->start)
450 if (J->start <
I->end) {
459 if (J->end >
I->end) {
467 while (J->end <
I->start);
474 assert(Start < End &&
"Invalid range");
481 return Other.empty();
486 if (
I ==
end() ||
I->start >
O.start)
490 while (
I->end <
O.end) {
504 void LiveRange::markValNoForDeletion(
VNInfo *ValNo) {
521 if (!Seen.
insert(VNI).second)
529 void LiveRange::addSegmentToSet(Segment
S) {
530 CalcLiveRangeUtilSet(
this).addSegment(
S);
540 return CalcLiveRangeUtilVector(
this).addSegment(
S);
553 return CalcLiveRangeUtilSet(
this).extendInBlock(Undefs, StartIdx,
Kill);
555 return CalcLiveRangeUtilVector(
this).extendInBlock(Undefs, StartIdx,
Kill);
561 return CalcLiveRangeUtilSet(
this).extendInBlock(StartIdx,
Kill);
563 return CalcLiveRangeUtilVector(
this).extendInBlock(StartIdx,
Kill);
569 bool RemoveDeadValNo) {
572 assert(
I !=
end() &&
"Segment is not in range!");
573 assert(
I->containsInterval(Start, End)
574 &&
"Segment is not entirely in range!");
578 if (
I->start == Start) {
614 markValNoForDeletion(ValNo);
622 [ValNo](
const Segment &
S) {
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;
682 S.valno = NewVNInfo[RHSValNoAssignments[
S.valno->id]];
686 unsigned NumValNos = 0;
687 for (
unsigned i = 0;
i < NumNewVals; ++
i) {
690 if (NumValNos >= NumVals)
694 VNI->
id = NumValNos++;
697 if (NumNewVals < NumVals)
714 Updater.
add(
S.start,
S.end, LHSValNo);
727 if (
S.valno == RHSValNo)
728 Updater.
add(
S.start,
S.end, LHSValNo);
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) {
873 unsigned ComposeSubRegIdx) {
888 assert(
MI &&
"Cannot find the definition of a value");
891 if (!MOI->isReg() || !MOI->isDef())
893 if (MOI->getReg() !=
Reg)
900 if ((ExpectedDefMask & LaneMask).
none())
907 ToBeRemoved.push_back(VNI);
909 for (
VNInfo *VNI : ToBeRemoved)
920 unsigned ComposeSubRegIdx) {
929 if (SRMask == Matching) {
945 Apply(*MatchingRange);
946 ToApply &= ~Matching;
958 Sum +=
S.start.distance(
S.end);
973 unsigned SubReg = MO.getSubReg();
974 assert(
SubReg != 0 &&
"Undef should only be set on subreg defs");
977 if ((UndefMask & LaneMask).
any()) {
981 Undefs.push_back(Pos);
987 return OS <<
'[' <<
S.start <<
',' <<
S.end <<
':' <<
S.valno->id <<
')';
990 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
992 dbgs() << *
this <<
'\n';
1013 if (vnum) OS <<
' ';
1028 <<
static_cast<const LiveRange &
>(*this);
1035 for (
const SubRange &SR : subranges())
1037 OS <<
" weight:" << Weight;
1040 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1042 dbgs() << *
this <<
'\n';
1046 dbgs() << *
this <<
'\n';
1050 dbgs() << *
this <<
'\n';
1063 if (std::next(
I) !=
E) {
1064 assert(
I->end <= std::next(
I)->start);
1065 if (
I->end == std::next(
I)->start)
1066 assert(
I->valno != std::next(
I)->valno);
1078 for (
const SubRange &SR : subranges()) {
1081 Mask |= SR.LaneMask;
1124 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1128 OS <<
"Clean updater: " << *LR <<
'\n';
1130 OS <<
"Null updater.\n";
1133 assert(LR &&
"Can't have null LR in dirty updater.");
1134 OS <<
" updater with gap = " << (ReadI - WriteI)
1135 <<
", last start = " << LastStart
1140 for (
unsigned I = 0,
E = Spills.size();
I !=
E; ++
I)
1141 OS <<
' ' << Spills[
I];
1156 assert(A.start <=
B.start &&
"Unordered live segments.");
1157 if (A.end ==
B.start)
1158 return A.valno ==
B.valno;
1159 if (A.end <
B.start)
1161 assert(A.valno ==
B.valno &&
"Cannot overlap different values");
1166 assert(LR &&
"Cannot add to a null destination");
1171 LR->addSegmentToSet(Seg);
1176 if (!LastStart.isValid() || LastStart > Seg.
start) {
1180 assert(Spills.empty() &&
"Leftover spilled segments");
1181 WriteI = ReadI = LR->
begin();
1185 LastStart = Seg.
start;
1189 if (ReadI !=
E && ReadI->end <= Seg.
start) {
1191 if (ReadI != WriteI)
1194 if (ReadI == WriteI)
1197 while (ReadI !=
E && ReadI->end <= Seg.
start)
1198 *WriteI++ = *ReadI++;
1204 if (ReadI !=
E && ReadI->start <= Seg.
start) {
1205 assert(ReadI->valno == Seg.
valno &&
"Cannot overlap different values");
1207 if (ReadI->end >= Seg.
end)
1210 Seg.
start = ReadI->start;
1221 if (!Spills.empty() &&
coalescable(Spills.back(), Seg)) {
1222 Seg.
start = Spills.back().start;
1234 if (WriteI != ReadI) {
1242 WriteI = ReadI = LR->
end();
1244 Spills.push_back(Seg);
1249 void LiveRangeUpdater::mergeSpills() {
1251 size_t GapSize = ReadI - WriteI;
1252 size_t NumMoved =
std::min(Spills.size(), GapSize);
1262 while (Src != Dst) {
1263 if (Src !=
B && Src[-1].start > SpillSrc[-1].start)
1266 *--Dst = *--SpillSrc;
1268 assert(NumMoved ==
size_t(Spills.end() - SpillSrc));
1269 Spills.erase(SpillSrc, Spills.end());
1278 assert(LR &&
"Cannot add to a null destination");
1281 if (Spills.empty()) {
1288 size_t GapSize = ReadI - WriteI;
1289 if (GapSize < Spills.size()) {
1291 size_t WritePos = WriteI - LR->
begin();
1294 WriteI = LR->
begin() + WritePos;
1299 ReadI = WriteI + Spills.size();
1309 const VNInfo *
used =
nullptr, *unused =
nullptr;
1316 EqClass.join(unused->id, VNI->
id);
1323 assert(
MBB &&
"Phi-def has no defining MBB");
1327 EqClass.join(VNI->
id, PVNI->id);
1334 EqClass.join(VNI->
id, UVNI->id);
1340 EqClass.join(
used->id, unused->id);
1343 return EqClass.getNumClasses();
1353 if (
MI->isDebugValue()) {
1356 SlotIndex Idx = LIS.getSlotIndexes()->getIndexBefore(*
MI);
1367 if (
unsigned EqClass = getEqClass(VNI))
1368 MO.setReg(LIV[EqClass - 1]->reg());
1373 unsigned NumComponents = EqClass.getNumClasses();
1380 unsigned NumValNos = SR.valnos.size();
1382 VNIMapping.
reserve(NumValNos);
1384 SubRanges.
resize(NumComponents-1,
nullptr);
1385 for (
unsigned I = 0;
I < NumValNos; ++
I) {
1386 const VNInfo &VNI = *SR.valnos[
I];
1387 unsigned ComponentNum;
1392 assert(MainRangeVNI !=
nullptr
1393 &&
"SubRange def must have corresponding main range def");
1394 ComponentNum = getEqClass(MainRangeVNI);
1395 if (ComponentNum > 0 && SubRanges[ComponentNum-1] ==
nullptr) {
1396 SubRanges[ComponentNum-1]
1400 VNIMapping.push_back(ComponentNum);
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
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.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
iterator erase(const_iterator CI)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void flushSegmentSet()
Flush segment set into the regular segment vector.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
void Distribute(LiveInterval &LI, LiveInterval *LIV[], MachineRegisterInfo &MRI)
Distribute values in LI into a separate LiveIntervals for each connected component.
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
void print(raw_ostream &OS) const
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position,...
Reg
All possible values of the reg field in the ModR/M byte.
const TargetRegisterInfo * getTargetRegisterInfo() const
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
This represents a simple continuous liveness interval for a value.
SlotIndex def
The index of the defining instruction.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
place backedge safepoints impl
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void print(raw_ostream &OS) const
static void createDeadDef(SlotIndexes &Indexes, VNInfo::Allocator &Alloc, LiveRange &LR, const MachineOperand &MO)
Result of a LiveRange query.
unsigned const TargetRegisterInfo * TRI
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
std::pair< VNInfo *, bool > extendInBlock(ArrayRef< SlotIndex > Undefs, SlotIndex StartIdx, SlotIndex Kill)
Attempt to extend a value defined after StartIdx to include Use.
bool isLiveAtIndexes(ArrayRef< SlotIndex > Slots) const
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)
Helper function that distributes live range value numbers and the corresponding segments of a primary...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
std::set< Segment > SegmentSet
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
bool covers(const LiveRange &Other) const
Returns true if all segments of the Other live range are completely covered by this live range.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
Segments::const_iterator const_iterator
Helper class for performant LiveRange bulk updates.
void clearSubRanges()
Removes all subregister liveness information.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
This class implements an extremely fast bulk output stream that can only output to a stream.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool overlapsFrom(const LiveRange &Other, const_iterator StartPos) const
overlapsFrom - Return true if the intersection of the two live ranges is not empty.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
LiveInterval - This class represents the liveness of a register, or stack slot.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
void removeValNoIfDead(VNInfo *ValNo)
Mark ValNo for deletion if no segments in this range use it.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
SlotIndex - An opaque wrapper around machine indexes.
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
void append(const LiveRange::Segment S)
Append a segment to the list of segments.
void print(raw_ostream &OS) const
void RenumberValues()
RenumberValues - Renumber all values in order of appearance and remove unused values.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx,...
void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, std::function< void(LiveInterval::SubRange &)> Apply, const SlotIndexes &Indexes, const TargetRegisterInfo &TRI, unsigned ComposeSubRegIdx=0)
Refines the subranges to support LaneMask.
void print(raw_ostream &) const
Representation of each machine instruction.
@ EarlyClobber
Register definition happens before uses.
This class represents the liveness of a register, stack slot, etc.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
unsigned id
The ID number of this value.
Allocate memory in an ever growing pool, as if by bump-pointer.
unsigned getNumValNums() const
constexpr bool any() const
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
VNInfo * getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool isValid() const
isValid - Returns true until all the operands have been visited.
iterator_range< reg_iterator > reg_operands(Register Reg) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned Classify(const LiveRange &LR)
Classify the values in LR into connected components.
print Print MemDeps of function
iterator_range< pred_iterator > predecessors()
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
VNInfo * MergeValueNumberInto(VNInfo *V1, VNInfo *V2)
MergeValueNumberInto - This method is called when two value numbers are found to be equivalent.
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static bool coalescable(const LiveRange::Segment &A, const LiveRange::Segment &B)
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
void flush()
Flush the updater state to LR so it is valid and contains all added segments.
constexpr bool none() const
A helper class for register coalescers.
SlotIndex getNextSlot() const
Returns the next slot in the index list.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
A live range for subregisters.
unsigned const MachineRegisterInfo * MRI
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
iterator_range< def_iterator > def_operands(Register Reg) const
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
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 ...
Segments::iterator iterator
LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
ConstMIBundleOperands - Iterate over all operands in a const bundle of machine instructions.
LaneBitmask composeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask Mask) const
Transforms a LaneMask computed for one subregister to the lanemask that would have been computed when...
void add(LiveRange::Segment)
Add a segment to LR and coalesce when possible, just like LR.addSegment().
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
VNInfo - Value Number Information.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
void copyFrom(VNInfo &src)
Copy from the parameter into this VNInfo.
void verify() const
Walk the range and assert if any invariants fail to hold.
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified segment from this range.
@ Kill
The last use of a register.
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...
std::optional< std::vector< StOtherPiece > > Other
This might compile to this xmm1 xorps xmm0 movss xmm0 ret Now consider if the code caused xmm1 to get spilled This might produce this xmm1 movaps xmm0 movaps xmm1 movss xmm0 ret since the reload is only used by these we could fold it into the producing something like xmm1 movaps xmm0 ret saving two instructions The basic idea is that a reload from a spill if only one byte chunk is used
bool hasSubRanges() const
Returns true if subregister liveness information is available.
static void stripValuesNotDefiningMask(unsigned Reg, LiveInterval::SubRange &SR, LaneBitmask LaneMask, const SlotIndexes &Indexes, const TargetRegisterInfo &TRI, unsigned ComposeSubRegIdx)
For each VNI in SR, check whether or not that value defines part of the mask describe by LaneMask and...
bool isUnused() const
Returns true if this value is unused.
void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
VNInfoList::const_iterator const_vni_iterator
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void reserve(size_type N)
std::unique_ptr< SegmentSet > segmentSet
bool isUndefIn(ArrayRef< SlotIndex > Undefs, SlotIndex Begin, SlotIndex End) const
Returns true if there is an explicit "undef" between Begin End.
static constexpr LaneBitmask getAll()
SubRange * createSubRangeFrom(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, const LiveRange &CopyFrom)
Like createSubRange() but the new range is filled with a copy of the liveness information in CopyFrom...
void markUnused()
Mark this value as unused.
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator insert(iterator I, T &&Elt)
iterator_range< subrange_iterator > subranges()