Rename LiveRange to LiveInterval::Segment

The Segment struct contains a single interval; multiple instances of this struct
are used to construct a live range, but the struct is not a live range by
itself.

llvm-svn: 192392
This commit is contained in:
Matthias Braun 2013-10-10 21:28:43 +00:00
parent 919868389c
commit 63c2445abb
16 changed files with 369 additions and 372 deletions

View File

@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveRange and LiveInterval classes. Given some
// numbering of each the machine instructions an interval [i, j) is said to be a
// This file implements the LiveInterval class. Given some numbering of each
// the machine instructions an interval [i, j) is said to be a
// live interval for register v if there is no instruction with number j' >= j
// such that v is live at j' and there is no instruction with number i' < i such
// that v is live at i'. In this implementation intervals can have holes,
// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
// individual range is represented as an instance of LiveRange, and the whole
// interval is represented as an instance of LiveInterval.
// individual segment is represented as an instance of LiveInterval::Segment,
// and the whole range is represented as an instance of LiveInterval.
//
//===----------------------------------------------------------------------===//
@ -78,82 +78,66 @@ namespace llvm {
void markUnused() { def = SlotIndex(); }
};
/// LiveRange structure - This represents a simple register range in the
/// program, with an inclusive start point and an exclusive end point.
/// These ranges are rendered as [start,end).
struct LiveRange {
SlotIndex start; // Start point of the interval (inclusive)
SlotIndex end; // End point of the interval (exclusive)
VNInfo *valno; // identifier for the value contained in this interval.
LiveRange() : valno(0) {}
LiveRange(SlotIndex S, SlotIndex E, VNInfo *V)
: start(S), end(E), valno(V) {
assert(S < E && "Cannot create empty or backwards range");
}
/// contains - Return true if the index is covered by this range.
///
bool contains(SlotIndex I) const {
return start <= I && I < end;
}
/// containsRange - Return true if the given range, [S, E), is covered by
/// this range.
bool containsRange(SlotIndex S, SlotIndex E) const {
assert((S < E) && "Backwards interval?");
return (start <= S && S < end) && (start < E && E <= end);
}
bool operator<(const LiveRange &LR) const {
return start < LR.start || (start == LR.start && end < LR.end);
}
bool operator==(const LiveRange &LR) const {
return start == LR.start && end == LR.end;
}
void dump() const;
void print(raw_ostream &os) const;
};
template <> struct isPodLike<LiveRange> { static const bool value = true; };
raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR);
inline bool operator<(SlotIndex V, const LiveRange &LR) {
return V < LR.start;
}
inline bool operator<(const LiveRange &LR, SlotIndex V) {
return LR.start < V;
}
/// LiveInterval - This class represents some number of live ranges for a
/// LiveInterval - This class represents some number of live segments for a
/// register or value. This class also contains a bit of register allocator
/// state.
class LiveInterval {
public:
typedef SmallVector<LiveRange,4> Ranges;
/// This represents a simple continuous liveness interval for a value.
/// The start point is inclusive, the end point exclusive. These intervals
/// are rendered as [start,end).
struct Segment {
SlotIndex start; // Start point of the interval (inclusive)
SlotIndex end; // End point of the interval (exclusive)
VNInfo *valno; // identifier for the value contained in this segment.
Segment() : valno(0) {}
Segment(SlotIndex S, SlotIndex E, VNInfo *V)
: start(S), end(E), valno(V) {
assert(S < E && "Cannot create empty or backwards segment");
}
/// Return true if the index is covered by this segment.
bool contains(SlotIndex I) const {
return start <= I && I < end;
}
/// Return true if the given interval, [S, E), is covered by this segment.
bool containsInterval(SlotIndex S, SlotIndex E) const {
assert((S < E) && "Backwards interval?");
return (start <= S && S < end) && (start < E && E <= end);
}
bool operator<(const Segment &Other) const {
return start < Other.start || (start == Other.start && end < Other.end);
}
bool operator==(const Segment &Other) const {
return start == Other.start && end == Other.end;
}
void dump() const;
};
typedef SmallVector<Segment,4> Segments;
typedef SmallVector<VNInfo*,4> VNInfoList;
const unsigned reg; // the register or stack slot of this interval.
float weight; // weight of this interval
Ranges ranges; // the ranges in which this register is live
Segments segments; // the segments in which this register is live
VNInfoList valnos; // value#'s
LiveInterval(unsigned Reg, float Weight)
: reg(Reg), weight(Weight) {}
typedef Ranges::iterator iterator;
iterator begin() { return ranges.begin(); }
iterator end() { return ranges.end(); }
typedef Segments::iterator iterator;
iterator begin() { return segments.begin(); }
iterator end() { return segments.end(); }
typedef Ranges::const_iterator const_iterator;
const_iterator begin() const { return ranges.begin(); }
const_iterator end() const { return ranges.end(); }
typedef Segments::const_iterator const_iterator;
const_iterator begin() const { return segments.begin(); }
const_iterator end() const { return segments.end(); }
typedef VNInfoList::iterator vni_iterator;
vni_iterator vni_begin() { return valnos.begin(); }
@ -163,11 +147,11 @@ namespace llvm {
const_vni_iterator vni_begin() const { return valnos.begin(); }
const_vni_iterator vni_end() const { return valnos.end(); }
/// advanceTo - Advance the specified iterator to point to the LiveRange
/// advanceTo - Advance the specified iterator to point to the Segment
/// containing the specified position, or end() if the position is past the
/// end of the interval. If no LiveRange contains this position, but the
/// end of the interval. If no Segment contains this position, but the
/// position is in a hole, this method returns an iterator pointing to the
/// LiveRange immediately after the hole.
/// Segment immediately after the hole.
iterator advanceTo(iterator I, SlotIndex Pos) {
assert(I != end());
if (Pos >= endIndex())
@ -176,12 +160,12 @@ namespace llvm {
return I;
}
/// find - Return an iterator pointing to the first range that ends after
/// find - Return an iterator pointing to the first segment that ends after
/// Pos, or end(). This is the same as advanceTo(begin(), Pos), but faster
/// when searching large intervals.
///
/// If Pos is contained in a LiveRange, that range is returned.
/// If Pos is in a hole, the following LiveRange is returned.
/// If Pos is contained in a Segment, that segment is returned.
/// If Pos is in a hole, the following Segment is returned.
/// If Pos is beyond endIndex, end() is returned.
iterator find(SlotIndex Pos);
@ -191,11 +175,11 @@ namespace llvm {
void clear() {
valnos.clear();
ranges.clear();
segments.clear();
}
size_t size() const {
return ranges.size();
return segments.size();
}
bool hasAtLeastOneValue() const { return !valnos.empty(); }
@ -248,38 +232,38 @@ namespace llvm {
/// MergeValueNumberInto - This method is called when two value numbers
/// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can
/// segments with the V1 value number with the V2 value number. This can
/// cause merging of V1/V2 values numbers and compaction of the value space.
VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
/// MergeValueInAsValue - Merge all of the live ranges of a specific val#
/// in RHS into this live interval as the specified value number.
/// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
/// current interval, it will replace the value numbers of the overlaped
/// live ranges with the specified value number.
void MergeRangesInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo);
/// Merge all of the live segments of a specific val# in RHS into this live
/// interval as the specified value number. The segments in RHS are allowed
/// to overlap with segments in the current interval, it will replace the
/// value numbers of the overlaped live segments with the specified value
/// number.
void MergeSegmentsInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo);
/// MergeValueInAsValue - Merge all of the live ranges of a specific val#
/// MergeValueInAsValue - Merge all of the segments of a specific val#
/// in RHS into this live interval as the specified value number.
/// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
/// current interval, but only if the overlapping LiveRanges have the
/// The segments in RHS are allowed to overlap with segments in the
/// current interval, but only if the overlapping segments have the
/// specified value number.
void MergeValueInAsValue(const LiveInterval &RHS,
const VNInfo *RHSValNo, VNInfo *LHSValNo);
bool empty() const { return ranges.empty(); }
bool empty() const { return segments.empty(); }
/// beginIndex - Return the lowest numbered slot covered by interval.
SlotIndex beginIndex() const {
assert(!empty() && "Call to beginIndex() on empty interval.");
return ranges.front().start;
return segments.front().start;
}
/// endNumber - return the maximum point of the interval of the whole,
/// exclusive.
SlotIndex endIndex() const {
assert(!empty() && "Call to endIndex() on empty interval.");
return ranges.back().end;
return segments.back().end;
}
bool expiredAt(SlotIndex index) const {
@ -291,23 +275,23 @@ namespace llvm {
return r != end() && r->start <= index;
}
/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
const LiveRange *getLiveRangeContaining(SlotIndex Idx) const {
const_iterator I = FindLiveRangeContaining(Idx);
/// Return the segment that contains the specified index, or null if there
/// is none.
const Segment *getSegmentContaining(SlotIndex Idx) const {
const_iterator I = FindSegmentContaining(Idx);
return I == end() ? 0 : &*I;
}
/// getLiveRangeContaining - Return the live range that contains the
/// specified index, or null if there is none.
LiveRange *getLiveRangeContaining(SlotIndex Idx) {
iterator I = FindLiveRangeContaining(Idx);
/// Return the live segment that contains the specified index, or null if
/// there is none.
Segment *getSegmentContaining(SlotIndex Idx) {
iterator I = FindSegmentContaining(Idx);
return I == end() ? 0 : &*I;
}
/// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
VNInfo *getVNInfoAt(SlotIndex Idx) const {
const_iterator I = FindLiveRangeContaining(Idx);
const_iterator I = FindSegmentContaining(Idx);
return I == end() ? 0 : I->valno;
}
@ -315,18 +299,18 @@ namespace llvm {
/// necessarilly including Idx, or NULL. Use this to find the reaching def
/// used by an instruction at this SlotIndex position.
VNInfo *getVNInfoBefore(SlotIndex Idx) const {
const_iterator I = FindLiveRangeContaining(Idx.getPrevSlot());
const_iterator I = FindSegmentContaining(Idx.getPrevSlot());
return I == end() ? 0 : I->valno;
}
/// FindLiveRangeContaining - Return an iterator to the live range that
/// contains the specified index, or end() if there is none.
iterator FindLiveRangeContaining(SlotIndex Idx) {
/// Return an iterator to the segment that contains the specified index, or
/// end() if there is none.
iterator FindSegmentContaining(SlotIndex Idx) {
iterator I = find(Idx);
return I != end() && I->start <= Idx ? I : end();
}
const_iterator FindLiveRangeContaining(SlotIndex Idx) const {
const_iterator FindSegmentContaining(SlotIndex Idx) const {
const_iterator I = find(Idx);
return I != end() && I->start <= Idx ? I : end();
}
@ -347,8 +331,8 @@ namespace llvm {
bool overlaps(const LiveInterval &Other, const CoalescerPair &CP,
const SlotIndexes&) const;
/// overlaps - Return true if the live interval overlaps a range specified
/// by [Start, End).
/// overlaps - Return true if the live interval overlaps an interval
/// specified by [Start, End).
bool overlaps(SlotIndex Start, SlotIndex End) const;
/// overlapsFrom - Return true if the intersection of the two live intervals
@ -356,16 +340,16 @@ namespace llvm {
/// scanning the Other interval starting at I.
bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
/// addRange - Add the specified LiveRange to this interval, merging
/// intervals as appropriate. This returns an iterator to the inserted live
/// range (which may have grown since it was inserted.
iterator addRange(LiveRange LR) {
return addRangeFrom(LR, ranges.begin());
/// Add the specified Segment to this interval, merging segments as
/// appropriate. This returns an iterator to the inserted segment (which
/// may have grown since it was inserted).
iterator addSegment(Segment S) {
return addSegmentFrom(S, segments.begin());
}
/// extendInBlock - If this interval is live before Kill in the basic block
/// that starts at StartIdx, extend it to be live up to Kill, and return
/// the value. If there is no live range before Kill, return NULL.
/// the value. If there is no segment before Kill, return NULL.
VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill);
/// join - Join two live intervals (this, and other) together. This applies
@ -376,7 +360,7 @@ namespace llvm {
const int *RHSValNoAssignments,
SmallVectorImpl<VNInfo *> &NewVNInfo);
/// True iff this live range is a single segment that lies between the
/// True iff this segment is a single segment that lies between the
/// specified boundaries, exclusively. Vregs live across a backedge are not
/// considered local. The boundaries are expected to lie within an extended
/// basic block, so vregs that are not live out should contain no holes.
@ -385,24 +369,24 @@ namespace llvm {
endIndex() < End.getBoundaryIndex();
}
/// removeRange - Remove the specified range from this interval. Note that
/// the range must be a single LiveRange in its entirety.
void removeRange(SlotIndex Start, SlotIndex End,
bool RemoveDeadValNo = false);
/// Remove the specified segment from this interval. Note that the segment
/// must be a single Segment in its entirety.
void removeSegment(SlotIndex Start, SlotIndex End,
bool RemoveDeadValNo = false);
void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
removeRange(LR.start, LR.end, RemoveDeadValNo);
void removeSegment(Segment S, bool RemoveDeadValNo = false) {
removeSegment(S.start, S.end, RemoveDeadValNo);
}
/// removeValNo - Remove all the ranges defined by the specified value#.
/// removeValNo - Remove all the segments defined by the specified value#.
/// Also remove the value# from value# list.
void removeValNo(VNInfo *ValNo);
/// getSize - Returns the sum of sizes of all the LiveRange's.
/// getSize - Returns the sum of sizes of all the Segment's.
///
unsigned getSize() const;
/// Returns true if the live interval is zero length, i.e. no live ranges
/// Returns true if the live interval is zero length, i.e. no segments
/// span instructions. It doesn't pay to spill such an interval.
bool isZeroLength(SlotIndexes *Indexes) const {
for (const_iterator i = begin(), e = end(); i != e; ++i)
@ -443,9 +427,9 @@ namespace llvm {
private:
iterator addRangeFrom(LiveRange LR, iterator From);
void extendIntervalEndTo(iterator I, SlotIndex NewEnd);
iterator extendIntervalStartTo(iterator I, SlotIndex NewStr);
iterator addSegmentFrom(Segment S, iterator From);
void extendSegmentEndTo(iterator I, SlotIndex NewEnd);
iterator extendSegmentStartTo(iterator I, SlotIndex NewStr);
void markValNoForDeletion(VNInfo *V);
LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
@ -457,9 +441,19 @@ namespace llvm {
return OS;
}
raw_ostream &operator<<(raw_ostream &OS, const LiveInterval::Segment &S);
inline bool operator<(SlotIndex V, const LiveInterval::Segment &S) {
return V < S.start;
}
inline bool operator<(const LiveInterval::Segment &S, SlotIndex V) {
return S.start < V;
}
/// Helper class for performant LiveInterval bulk updates.
///
/// Calling LiveInterval::addRange() repeatedly can be expensive on large
/// Calling LiveInterval::addSegment() repeatedly can be expensive on large
/// live ranges because segments after the insertion point may need to be
/// shifted. The LiveRangeUpdater class can defer the shifting when adding
/// many segments in order.
@ -470,7 +464,7 @@ namespace llvm {
SlotIndex LastStart;
LiveInterval::iterator WriteI;
LiveInterval::iterator ReadI;
SmallVector<LiveRange, 16> Spills;
SmallVector<LiveInterval::Segment, 16> Spills;
void mergeSpills();
public:
@ -480,12 +474,13 @@ namespace llvm {
~LiveRangeUpdater() { flush(); }
/// Add a segment to LI and coalesce when possible, just like LI.addRange().
/// Segments should be added in increasing start order for best performance.
void add(LiveRange);
/// Add a segment to LI and coalesce when possible, just like
/// LI.addSegment(). Segments should be added in increasing start order for
/// best performance.
void add(LiveInterval::Segment);
void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
add(LiveRange(Start, End, VNI));
add(LiveInterval::Segment(Start, End, VNI));
}
/// Return true if the LI is currently in an invalid state, and flush()

View File

@ -137,10 +137,10 @@ namespace llvm {
VirtRegIntervals[Reg] = 0;
}
/// addLiveRangeToEndOfBlock - Given a register and an instruction,
/// adds a live range from that instruction to the end of its MBB.
LiveRange addLiveRangeToEndOfBlock(unsigned reg,
MachineInstr* startInst);
/// Given a register and an instruction, adds a live segment from that
/// instruction to the end of its MBB.
LiveInterval::Segment addSegmentToEndOfBlock(unsigned reg,
MachineInstr* startInst);
/// shrinkToUses - After removing some uses of a register, shrink its live
/// range to just the remaining uses. This method does not compute reaching

View File

@ -32,7 +32,7 @@ typedef SparseBitVector<128> LiveVirtRegBitSet;
/// Compare a live virtual register segment to a LiveIntervalUnion segment.
inline bool
overlap(const LiveRange &VRSeg,
overlap(const LiveInterval::Segment &VRSeg,
const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
}

View File

@ -1295,8 +1295,8 @@ void InlineSpiller::spillAll() {
assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
StackInt->MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]),
StackInt->getValNumInfo(0));
StackInt->MergeSegmentsInAsValue(LIS.getInterval(RegsToSpill[i]),
StackInt->getValNumInfo(0));
DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
// Spill around uses of all RegsToSpill.

View File

@ -510,14 +510,14 @@ void UserValue::extendDef(SlotIndex Idx, unsigned LocNo,
// Limit to VNI's live range.
bool ToEnd = true;
if (LI && VNI) {
LiveRange *Range = LI->getLiveRangeContaining(Start);
if (!Range || Range->valno != VNI) {
LiveInterval::Segment *Segment = LI->getSegmentContaining(Start);
if (!Segment || Segment->valno != VNI) {
if (Kills)
Kills->push_back(Start);
continue;
}
if (Range->end < Stop)
Stop = Range->end, ToEnd = false;
if (Segment->end < Stop)
Stop = Segment->end, ToEnd = false;
}
// There could already be a short def at Start.

View File

@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveRange and LiveInterval classes. Given some
// This file implements the LiveInterval class. Given some
// numbering of each the machine instructions an interval [i, j) is said to be a
// live interval for register v if there is no instruction with number j' > j
// such that v is live at j' and there is no instruction with number i' < i such
// that v is live at i'. In this implementation intervals can have holes,
// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
// individual range is represented as an instance of LiveRange, and the whole
// interval is represented as an instance of LiveInterval.
// individual segment is represented as an instance of Segment, and the whole
// range is represented as an instance of LiveInterval.
//
//===----------------------------------------------------------------------===//
@ -55,7 +55,7 @@ VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
iterator I = find(Def);
if (I == end()) {
VNInfo *VNI = getNextValue(Def, VNInfoAllocator);
ranges.push_back(LiveRange(Def, Def.getDeadSlot(), VNI));
segments.push_back(Segment(Def, Def.getDeadSlot(), VNI));
return VNI;
}
if (SlotIndex::isSameInstr(Def, I->start)) {
@ -73,7 +73,7 @@ VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
}
assert(SlotIndex::isEarlierInstr(Def, I->start) && "Already live at def");
VNInfo *VNI = getNextValue(Def, VNInfoAllocator);
ranges.insert(I, LiveRange(Def, Def.getDeadSlot(), VNI));
segments.insert(I, Segment(Def, Def.getDeadSlot(), VNI));
return VNI;
}
@ -178,7 +178,7 @@ bool LiveInterval::overlaps(const LiveInterval &Other,
}
}
/// overlaps - Return true if the live interval overlaps a range specified
/// overlaps - Return true if the live interval overlaps a segment specified
/// by [Start, End).
bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const {
assert(Start < End && "Invalid range");
@ -209,129 +209,128 @@ void LiveInterval::RenumberValues() {
VNInfo *VNI = I->valno;
if (!Seen.insert(VNI))
continue;
assert(!VNI->isUnused() && "Unused valno used by live range");
assert(!VNI->isUnused() && "Unused valno used by live segment");
VNI->id = (unsigned)valnos.size();
valnos.push_back(VNI);
}
}
/// extendIntervalEndTo - This method is used when we want to extend the range
/// specified by I to end at the specified endpoint. To do this, we should
/// merge and eliminate all ranges that this will overlap with. The iterator is
/// not invalidated.
void LiveInterval::extendIntervalEndTo(iterator I, SlotIndex NewEnd) {
assert(I != end() && "Not a valid interval!");
/// This method is used when we want to extend the segment specified by I to end
/// at the specified endpoint. To do this, we should merge and eliminate all
/// segments that this will overlap with. The iterator is not invalidated.
void LiveInterval::extendSegmentEndTo(iterator I, SlotIndex NewEnd) {
assert(I != end() && "Not a valid segment!");
VNInfo *ValNo = I->valno;
// Search for the first interval that we can't merge with.
// Search for the first segment that we can't merge with.
iterator MergeTo = llvm::next(I);
for (; MergeTo != end() && NewEnd >= MergeTo->end; ++MergeTo) {
assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
}
// If NewEnd was in the middle of an interval, make sure to get its endpoint.
// If NewEnd was in the middle of an segment, make sure to get its endpoint.
I->end = std::max(NewEnd, prior(MergeTo)->end);
// If the newly formed range now touches the range after it and if they have
// the same value number, merge the two ranges into one range.
// If the newly formed segment now touches the segment after it and if they
// have the same value number, merge the two segments into one segment.
if (MergeTo != end() && MergeTo->start <= I->end &&
MergeTo->valno == ValNo) {
I->end = MergeTo->end;
++MergeTo;
}
// Erase any dead ranges.
ranges.erase(llvm::next(I), MergeTo);
// Erase any dead segments.
segments.erase(llvm::next(I), MergeTo);
}
/// extendIntervalStartTo - This method is used when we want to extend the range
/// specified by I to start at the specified endpoint. To do this, we should
/// merge and eliminate all ranges that this will overlap with.
/// This method is used when we want to extend the segment specified by I to
/// start at the specified endpoint. To do this, we should merge and eliminate
/// all segments that this will overlap with.
LiveInterval::iterator
LiveInterval::extendIntervalStartTo(iterator I, SlotIndex NewStart) {
assert(I != end() && "Not a valid interval!");
LiveInterval::extendSegmentStartTo(iterator I, SlotIndex NewStart) {
assert(I != end() && "Not a valid segment!");
VNInfo *ValNo = I->valno;
// Search for the first interval that we can't merge with.
// Search for the first segment that we can't merge with.
iterator MergeTo = I;
do {
if (MergeTo == begin()) {
I->start = NewStart;
ranges.erase(MergeTo, I);
segments.erase(MergeTo, I);
return I;
}
assert(MergeTo->valno == ValNo && "Cannot merge with differing values!");
--MergeTo;
} while (NewStart <= MergeTo->start);
// If we start in the middle of another interval, just delete a range and
// extend that interval.
// If we start in the middle of another segment, just delete a range and
// extend that segment.
if (MergeTo->end >= NewStart && MergeTo->valno == ValNo) {
MergeTo->end = I->end;
} else {
// Otherwise, extend the interval right after.
// Otherwise, extend the segment right after.
++MergeTo;
MergeTo->start = NewStart;
MergeTo->end = I->end;
}
ranges.erase(llvm::next(MergeTo), llvm::next(I));
segments.erase(llvm::next(MergeTo), llvm::next(I));
return MergeTo;
}
LiveInterval::iterator
LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
SlotIndex Start = LR.start, End = LR.end;
LiveInterval::addSegmentFrom(Segment S, iterator From) {
SlotIndex Start = S.start, End = S.end;
iterator it = std::upper_bound(From, end(), Start);
// If the inserted interval starts in the middle or right at the end of
// another interval, just extend that interval to contain the range of LR.
// If the inserted segment starts in the middle or right at the end of
// another segment, just extend that segment to contain the segment of S.
if (it != begin()) {
iterator B = prior(it);
if (LR.valno == B->valno) {
if (S.valno == B->valno) {
if (B->start <= Start && B->end >= Start) {
extendIntervalEndTo(B, End);
extendSegmentEndTo(B, End);
return B;
}
} else {
// Check to make sure that we are not overlapping two live ranges with
// Check to make sure that we are not overlapping two live segments with
// different valno's.
assert(B->end <= Start &&
"Cannot overlap two LiveRanges with differing ValID's"
"Cannot overlap two segments with differing ValID's"
" (did you def the same reg twice in a MachineInstr?)");
}
}
// Otherwise, if this range ends in the middle of, or right next to, another
// interval, merge it into that interval.
// Otherwise, if this segment ends in the middle of, or right next to, another
// segment, merge it into that segment.
if (it != end()) {
if (LR.valno == it->valno) {
if (S.valno == it->valno) {
if (it->start <= End) {
it = extendIntervalStartTo(it, Start);
it = extendSegmentStartTo(it, Start);
// If LR is a complete superset of an interval, we may need to grow its
// If S is a complete superset of a segment, we may need to grow its
// endpoint as well.
if (End > it->end)
extendIntervalEndTo(it, End);
extendSegmentEndTo(it, End);
return it;
}
} else {
// Check to make sure that we are not overlapping two live ranges with
// Check to make sure that we are not overlapping two live segments with
// different valno's.
assert(it->start >= End &&
"Cannot overlap two LiveRanges with differing ValID's");
"Cannot overlap two segments with differing ValID's");
}
}
// Otherwise, this is just a new range that doesn't interact with anything.
// Otherwise, this is just a new segment that doesn't interact with anything.
// Insert it.
return ranges.insert(it, LR);
return segments.insert(it, S);
}
/// extendInBlock - If this interval is live before Kill in the basic
/// block that starts at StartIdx, extend it to be live up to Kill and return
/// the value. If there is no live range before Kill, return NULL.
/// the value. If there is no segment before Kill, return NULL.
VNInfo *LiveInterval::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
if (empty())
return 0;
@ -342,20 +341,21 @@ VNInfo *LiveInterval::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
if (I->end <= StartIdx)
return 0;
if (I->end < Kill)
extendIntervalEndTo(I, Kill);
extendSegmentEndTo(I, Kill);
return I->valno;
}
/// removeRange - Remove the specified range from this interval. Note that
/// the range must be in a single LiveRange in its entirety.
void LiveInterval::removeRange(SlotIndex Start, SlotIndex End,
bool RemoveDeadValNo) {
// Find the LiveRange containing this span.
/// Remove the specified segment from this interval. Note that the segment must
/// be in a single Segment in its entirety.
void LiveInterval::removeSegment(SlotIndex Start, SlotIndex End,
bool RemoveDeadValNo) {
// Find the Segment containing this span.
iterator I = find(Start);
assert(I != end() && "Range is not in interval!");
assert(I->containsRange(Start, End) && "Range is not entirely in interval!");
assert(I != end() && "Segment is not in interval!");
assert(I->containsInterval(Start, End)
&& "Segment is not entirely in interval!");
// If the span we are removing is at the start of the LiveRange, adjust it.
// If the span we are removing is at the start of the Segment, adjust it.
VNInfo *ValNo = I->valno;
if (I->start == Start) {
if (I->end == End) {
@ -373,28 +373,28 @@ void LiveInterval::removeRange(SlotIndex Start, SlotIndex End,
}
}
ranges.erase(I); // Removed the whole LiveRange.
segments.erase(I); // Removed the whole Segment.
} else
I->start = End;
return;
}
// Otherwise if the span we are removing is at the end of the LiveRange,
// Otherwise if the span we are removing is at the end of the Segment,
// adjust the other way.
if (I->end == End) {
I->end = Start;
return;
}
// Otherwise, we are splitting the LiveRange into two pieces.
// Otherwise, we are splitting the Segment into two pieces.
SlotIndex OldEnd = I->end;
I->end = Start; // Trim the old interval.
// Insert the new one.
ranges.insert(llvm::next(I), LiveRange(End, OldEnd, ValNo));
segments.insert(llvm::next(I), Segment(End, OldEnd, ValNo));
}
/// removeValNo - Remove all the ranges defined by the specified value#.
/// removeValNo - Remove all the segments defined by the specified value#.
/// Also remove the value# from value# list.
void LiveInterval::removeValNo(VNInfo *ValNo) {
if (empty()) return;
@ -403,7 +403,7 @@ void LiveInterval::removeValNo(VNInfo *ValNo) {
do {
--I;
if (I->valno == ValNo)
ranges.erase(I);
segments.erase(I);
} while (I != E);
// Now that ValNo is dead, remove it.
markValNoForDeletion(ValNo);
@ -418,8 +418,8 @@ void LiveInterval::join(LiveInterval &Other,
SmallVectorImpl<VNInfo *> &NewVNInfo) {
verify();
// Determine if any of our live range values are mapped. This is uncommon, so
// we want to avoid the interval scan if not.
// Determine if any of our values are mapped. This is uncommon, so we want
// to avoid the interval scan if not.
bool MustMapCurValNos = false;
unsigned NumVals = getNumValNums();
unsigned NumNewVals = NewVNInfo.size();
@ -444,7 +444,7 @@ void LiveInterval::join(LiveInterval &Other,
assert(nextValNo != 0 && "Huh?");
// If this live range has the same value # as its immediate predecessor,
// and if they are neighbors, remove one LiveRange. This happens when we
// and if they are neighbors, remove one Segment. This happens when we
// have [0,4:0)[4,7:1) and map 0/1 onto the same value #.
if (OutIt->valno == nextValNo && OutIt->end == I->start) {
OutIt->end = I->end;
@ -458,9 +458,9 @@ void LiveInterval::join(LiveInterval &Other,
}
}
}
// If we merge some live ranges, chop off the end.
// If we merge some segments, chop off the end.
++OutIt;
ranges.erase(OutIt, end());
segments.erase(OutIt, end());
}
// Rewrite Other values before changing the VNInfo ids.
@ -486,28 +486,28 @@ void LiveInterval::join(LiveInterval &Other,
if (NumNewVals < NumVals)
valnos.resize(NumNewVals); // shrinkify
// Okay, now insert the RHS live ranges into the LHS.
// Okay, now insert the RHS live segments into the LHS.
LiveRangeUpdater Updater(this);
for (iterator I = Other.begin(), E = Other.end(); I != E; ++I)
Updater.add(*I);
}
/// MergeRangesInAsValue - Merge all of the intervals in RHS into this live
/// interval as the specified value number. The LiveRanges in RHS are
/// allowed to overlap with LiveRanges in the current interval, but only if
/// the overlapping LiveRanges have the specified value number.
void LiveInterval::MergeRangesInAsValue(const LiveInterval &RHS,
VNInfo *LHSValNo) {
/// Merge all of the segments in RHS into this live interval as the specified
/// value number. The segments in RHS are allowed to overlap with segments in
/// the current interval, but only if the overlapping segments have the
/// specified value number.
void LiveInterval::MergeSegmentsInAsValue(const LiveInterval &RHS,
VNInfo *LHSValNo) {
LiveRangeUpdater Updater(this);
for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
Updater.add(I->start, I->end, LHSValNo);
}
/// MergeValueInAsValue - Merge all of the live ranges of a specific val#
/// MergeValueInAsValue - Merge all of the live segments of a specific val#
/// in RHS into this live interval as the specified value number.
/// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
/// The segments in RHS are allowed to overlap with segments in the
/// current interval, it will replace the value numbers of the overlaped
/// live ranges with the specified value number.
/// segments with the specified value number.
void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS,
const VNInfo *RHSValNo,
VNInfo *LHSValNo) {
@ -519,7 +519,7 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS,
/// MergeValueNumberInto - This method is called when two value nubmers
/// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can
/// segments with the V1 value number with the V2 value number. This can
/// cause merging of V1/V2 values numbers and compaction of the value space.
VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
assert(V1 != V2 && "Identical value#'s are always equivalent!");
@ -535,37 +535,37 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
std::swap(V1, V2);
}
// Merge V1 live ranges into V2.
// Merge V1 segments into V2.
for (iterator I = begin(); I != end(); ) {
iterator LR = I++;
if (LR->valno != V1) continue; // Not a V1 LiveRange.
iterator S = I++;
if (S->valno != V1) continue; // Not a V1 Segment.
// Okay, we found a V1 live range. If it had a previous, touching, V2 live
// range, extend it.
if (LR != begin()) {
iterator Prev = LR-1;
if (Prev->valno == V2 && Prev->end == LR->start) {
Prev->end = LR->end;
if (S != begin()) {
iterator Prev = S-1;
if (Prev->valno == V2 && Prev->end == S->start) {
Prev->end = S->end;
// Erase this live-range.
ranges.erase(LR);
segments.erase(S);
I = Prev+1;
LR = Prev;
S = Prev;
}
}
// Okay, now we have a V1 or V2 live range that is maximally merged forward.
// Ensure that it is a V2 live-range.
LR->valno = V2;
S->valno = V2;
// If we can merge it into later V2 live ranges, do so now. We ignore any
// following V1 live ranges, as they will be merged in subsequent iterations
// If we can merge it into later V2 segments, do so now. We ignore any
// following V1 segments, as they will be merged in subsequent iterations
// of the loop.
if (I != end()) {
if (I->start == LR->end && I->valno == V2) {
LR->end = I->end;
ranges.erase(I);
I = LR+1;
if (I->start == S->end && I->valno == V2) {
S->end = I->end;
segments.erase(I);
I = S+1;
}
}
}
@ -583,12 +583,12 @@ unsigned LiveInterval::getSize() const {
return Sum;
}
raw_ostream& llvm::operator<<(raw_ostream& os, const LiveRange &LR) {
return os << '[' << LR.start << ',' << LR.end << ':' << LR.valno->id << ")";
raw_ostream& llvm::operator<<(raw_ostream& os, const LiveInterval::Segment &S) {
return os << '[' << S.start << ',' << S.end << ':' << S.valno->id << ")";
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void LiveRange::dump() const {
void LiveInterval::Segment::dump() const {
dbgs() << *this << "\n";
}
#endif
@ -647,10 +647,6 @@ void LiveInterval::verify() const {
#endif
void LiveRange::print(raw_ostream &os) const {
os << *this;
}
//===----------------------------------------------------------------------===//
// LiveRangeUpdater class
//===----------------------------------------------------------------------===//
@ -709,8 +705,9 @@ void LiveRangeUpdater::dump() const
}
// Determine if A and B should be coalesced.
static inline bool coalescable(const LiveRange &A, const LiveRange &B) {
assert(A.start <= B.start && "Unordered live ranges.");
static inline bool coalescable(const LiveInterval::Segment &A,
const LiveInterval::Segment &B) {
assert(A.start <= B.start && "Unordered live segments.");
if (A.end == B.start)
return A.valno == B.valno;
if (A.end < B.start)
@ -719,7 +716,7 @@ static inline bool coalescable(const LiveRange &A, const LiveRange &B) {
return true;
}
void LiveRangeUpdater::add(LiveRange Seg) {
void LiveRangeUpdater::add(LiveInterval::Segment Seg) {
assert(LI && "Cannot add to a null destination");
// Flush the state if Start moves backwards.
@ -788,7 +785,7 @@ void LiveRangeUpdater::add(LiveRange Seg) {
// Finally, append to LI or Spills.
if (WriteI == E) {
LI->ranges.push_back(Seg);
LI->segments.push_back(Seg);
WriteI = ReadI = LI->end();
} else
Spills.push_back(Seg);
@ -829,7 +826,7 @@ void LiveRangeUpdater::flush() {
// Nothing to merge?
if (Spills.empty()) {
LI->ranges.erase(WriteI, ReadI);
LI->segments.erase(WriteI, ReadI);
LI->verify();
return;
}
@ -839,12 +836,13 @@ void LiveRangeUpdater::flush() {
if (GapSize < Spills.size()) {
// The gap is too small. Make some room.
size_t WritePos = WriteI - LI->begin();
LI->ranges.insert(ReadI, Spills.size() - GapSize, LiveRange());
LI->segments.insert(ReadI, Spills.size() - GapSize,
LiveInterval::Segment());
// This also invalidated ReadI, but it is recomputed below.
WriteI = LI->begin() + WritePos;
} else {
// Shrink the gap if necessary.
LI->ranges.erase(WriteI + Spills.size(), ReadI);
LI->segments.erase(WriteI + Spills.size(), ReadI);
}
ReadI = WriteI + Spills.size();
mergeSpills();
@ -933,11 +931,11 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[],
if (unsigned eq = EqClass[I->valno->id]) {
assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) &&
"New intervals should be empty");
LIV[eq]->ranges.push_back(*I);
LIV[eq]->segments.push_back(*I);
} else
*J++ = *I;
}
LI.ranges.erase(J, E);
LI.segments.erase(J, E);
// Transfer VNInfos to their new owners and renumber them.
unsigned j = 0, e = LI.getNumValNums();

View File

@ -355,7 +355,8 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
VNInfo *VNI = *I;
if (VNI->isUnused())
continue;
NewLI.addRange(LiveRange(VNI->def, VNI->def.getDeadSlot(), VNI));
NewLI.addSegment(LiveInterval::Segment(VNI->def, VNI->def.getDeadSlot(),
VNI));
}
// Keep track of the PHIs that are in use.
@ -391,7 +392,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
// VNI is live-in to MBB.
DEBUG(dbgs() << " live-in at " << BlockStart << '\n');
NewLI.addRange(LiveRange(BlockStart, Idx, VNI));
NewLI.addSegment(LiveInterval::Segment(BlockStart, Idx, VNI));
// Make sure VNI is live-out from the predecessors.
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
@ -412,14 +413,14 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
VNInfo *VNI = *I;
if (VNI->isUnused())
continue;
LiveInterval::iterator LII = NewLI.FindLiveRangeContaining(VNI->def);
assert(LII != NewLI.end() && "Missing live range for PHI");
LiveInterval::iterator LII = NewLI.FindSegmentContaining(VNI->def);
assert(LII != NewLI.end() && "Missing segment for PHI");
if (LII->end != VNI->def.getDeadSlot())
continue;
if (VNI->isPHIDef()) {
// This is a dead PHI. Remove it.
VNI->markUnused();
NewLI.removeRange(*LII);
NewLI.removeSegment(*LII);
DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
CanSeparate = true;
} else {
@ -434,8 +435,8 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
}
}
// Move the trimmed ranges back.
li->ranges.swap(NewLI.ranges);
// Move the trimmed segments back.
li->segments.swap(NewLI.segments);
DEBUG(dbgs() << "Shrunk: " << *li << '\n');
return CanSeparate;
}
@ -461,13 +462,13 @@ void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
// If VNI isn't live out from KillMBB, the value is trivially pruned.
if (LRQ.endPoint() < MBBEnd) {
LI->removeRange(Kill, LRQ.endPoint());
LI->removeSegment(Kill, LRQ.endPoint());
if (EndPoints) EndPoints->push_back(LRQ.endPoint());
return;
}
// VNI is live out of KillMBB.
LI->removeRange(Kill, MBBEnd);
LI->removeSegment(Kill, MBBEnd);
if (EndPoints) EndPoints->push_back(MBBEnd);
// Find all blocks that are reachable from KillMBB without leaving VNI's live
@ -487,21 +488,21 @@ void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
tie(MBBStart, MBBEnd) = Indexes->getMBBRange(MBB);
LiveRangeQuery LRQ(*LI, MBBStart);
if (LRQ.valueIn() != VNI) {
// This block isn't part of the VNI live range. Prune the search.
// This block isn't part of the VNI segment. Prune the search.
I.skipChildren();
continue;
}
// Prune the search if VNI is killed in MBB.
if (LRQ.endPoint() < MBBEnd) {
LI->removeRange(MBBStart, LRQ.endPoint());
LI->removeSegment(MBBStart, LRQ.endPoint());
if (EndPoints) EndPoints->push_back(LRQ.endPoint());
I.skipChildren();
continue;
}
// VNI is live through MBB.
LI->removeRange(MBBStart, MBBEnd);
LI->removeSegment(MBBStart, MBBEnd);
if (EndPoints) EndPoints->push_back(MBBEnd);
++I;
}
@ -535,7 +536,8 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
RU.push_back(std::make_pair(RUInt, RUInt->find(LI->begin()->end)));
}
// Every instruction that kills Reg corresponds to a live range end point.
// Every instruction that kills Reg corresponds to a segment range end
// point.
for (LiveInterval::iterator RI = LI->begin(), RE = LI->end(); RI != RE;
++RI) {
// A block index indicates an MBB edge.
@ -623,18 +625,18 @@ LiveIntervals::getSpillWeight(bool isDef, bool isUse, BlockFrequency freq) {
return (isDef + isUse) * (freq.getFrequency() * Scale);
}
LiveRange LiveIntervals::addLiveRangeToEndOfBlock(unsigned reg,
MachineInstr* startInst) {
LiveInterval::Segment
LiveIntervals::addSegmentToEndOfBlock(unsigned reg, MachineInstr* startInst) {
LiveInterval& Interval = createEmptyInterval(reg);
VNInfo* VN = Interval.getNextValue(
SlotIndex(getInstructionIndex(startInst).getRegSlot()),
getVNInfoAllocator());
LiveRange LR(
LiveInterval::Segment S(
SlotIndex(getInstructionIndex(startInst).getRegSlot()),
getMBBEndIdx(startInst->getParent()), VN);
Interval.addRange(LR);
Interval.addSegment(S);
return LR;
return S;
}
@ -798,7 +800,7 @@ private:
/// Move def to NewIdx, possibly across another live value.
///
/// 4. Def at OldIdx AND at NewIdx:
/// Remove live range [OldIdx;NewIdx) and value defined at OldIdx.
/// Remove segment [OldIdx;NewIdx) and value defined at OldIdx.
/// (Happens when bundling multiple defs together).
///
/// 5. Value read at OldIdx, killed before NewIdx:
@ -868,7 +870,8 @@ private:
// intermediate ranges up.
assert(NewI != I && "Inconsistent iterators");
std::copy(llvm::next(I), NewI, I);
*llvm::prior(NewI) = LiveRange(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
*llvm::prior(NewI)
= LiveInterval::Segment(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
}
/// Update LI to reflect an instruction has been moved upwards from OldIdx
@ -949,7 +952,7 @@ private:
// DefVNI is a dead def. It may have been moved across other values in LI,
// so move I up to NewI. Slide [NewI;I) down one position.
std::copy_backward(NewI, I, llvm::next(I));
*NewI = LiveRange(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
*NewI = LiveInterval::Segment(DefVNI->def, NewIdx.getDeadSlot(), DefVNI);
}
void updateRegMaskSlots() {
@ -1119,9 +1122,9 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
if (LII != LI.begin())
prevStart = llvm::prior(LII)->start;
// FIXME: This could be more efficient if there was a removeRange
// method that returned an iterator.
LI.removeRange(*LII, true);
// FIXME: This could be more efficient if there was a
// removeSegment method that returned an iterator.
LI.removeSegment(*LII, true);
if (prevStart.isValid())
LII = LI.find(prevStart);
else
@ -1140,13 +1143,14 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
if (!lastUseIdx.isValid()) {
VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(),
VNInfoAllocator);
LiveRange LR(instrIdx.getRegSlot(), instrIdx.getDeadSlot(), VNI);
LII = LI.addRange(LR);
LiveInterval::Segment S(instrIdx.getRegSlot(),
instrIdx.getDeadSlot(), VNI);
LII = LI.addSegment(S);
} else if (LII->start != instrIdx.getRegSlot()) {
VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(),
VNInfoAllocator);
LiveRange LR(instrIdx.getRegSlot(), lastUseIdx, VNI);
LII = LI.addRange(LR);
LiveInterval::Segment S(instrIdx.getRegSlot(), lastUseIdx, VNI);
LII = LI.addSegment(S);
}
if (MO.getSubReg() && !MO.isUndef())

View File

@ -355,9 +355,9 @@ void LiveRangeCalc::updateSSA() {
// Add liveness since updateLiveIns now skips this node.
if (I->Kill.isValid())
I->LI->addRange(LiveRange(Start, I->Kill, VNI));
I->LI->addSegment(LiveInterval::Segment(Start, I->Kill, VNI));
else {
I->LI->addRange(LiveRange(Start, End, VNI));
I->LI->addSegment(LiveInterval::Segment(Start, End, VNI));
LOP = LiveOutPair(VNI, Node);
}
} else if (IDomValue.first) {

View File

@ -861,7 +861,7 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
LiveInterval &LI = LIS->getInterval(Reg);
VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
assert(VNI && "PHI sources should be live out of their predecessors.");
LI.addRange(LiveRange(StartIndex, EndIndex, VNI));
LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
}
}
}
@ -880,9 +880,9 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
if (isLiveOut && isLastMBB) {
VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
assert(VNI && "LiveInterval should have VNInfo where it is live.");
LI.addRange(LiveRange(StartIndex, EndIndex, VNI));
LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
} else if (!isLiveOut && !isLastMBB) {
LI.removeRange(StartIndex, EndIndex);
LI.removeSegment(StartIndex, EndIndex);
}
}

View File

@ -1004,7 +1004,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) {
LiveRangeQuery LRQ(*LI, UseIdx);
if (!LRQ.valueIn()) {
report("No live range at use", MO, MONum);
report("No live segment at use", MO, MONum);
*OS << UseIdx << " is not live in " << PrintRegUnit(*Units, TRI)
<< ' ' << *LI << '\n';
}
@ -1022,7 +1022,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
const LiveInterval &LI = LiveInts->getInterval(Reg);
LiveRangeQuery LRQ(LI, UseIdx);
if (!LRQ.valueIn()) {
report("No live range at use", MO, MONum);
report("No live segment at use", MO, MONum);
*OS << UseIdx << " is not live in " << LI << '\n';
}
// Check for extra kill flags.
@ -1071,7 +1071,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
llvm::next(MRI->def_begin(Reg)) != MRI->def_end())
report("Multiple virtual register defs in SSA form", MO, MONum);
// Check LiveInts for a live range, but only for virtual registers.
// Check LiveInts for a live segment, but only for virtual registers.
if (LiveInts && TargetRegisterInfo::isVirtualRegister(Reg) &&
!LiveInts->isNotInMIMap(MI)) {
SlotIndex DefIdx = LiveInts->getInstructionIndex(MI);
@ -1086,7 +1086,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
<< DefIdx << " in " << LI << '\n';
}
} else {
report("No live range at def", MO, MONum);
report("No live segment at def", MO, MONum);
*OS << DefIdx << " is not live in " << LI << '\n';
}
} else {
@ -1353,7 +1353,7 @@ void MachineVerifier::verifyLiveIntervalValue(const LiveInterval &LI,
}
if (DefVNI != VNI) {
report("Live range at def has different valno", MF, LI);
report("Live segment at def has different valno", MF, LI);
*OS << "Valno #" << VNI->id << " is defined at " << VNI->def
<< " where valno #" << DefVNI->id << " is live\n";
return;
@ -1425,15 +1425,15 @@ void
MachineVerifier::verifyLiveIntervalSegment(const LiveInterval &LI,
LiveInterval::const_iterator I) {
const VNInfo *VNI = I->valno;
assert(VNI && "Live range has no valno");
assert(VNI && "Live segment has no valno");
if (VNI->id >= LI.getNumValNums() || VNI != LI.getValNumInfo(VNI->id)) {
report("Foreign valno in live range", MF, LI);
report("Foreign valno in live segment", MF, LI);
*OS << *I << " has a bad valno\n";
}
if (VNI->isUnused()) {
report("Live range valno is marked unused", MF, LI);
report("Live segment valno is marked unused", MF, LI);
*OS << *I << '\n';
}
@ -1503,7 +1503,7 @@ MachineVerifier::verifyLiveIntervalSegment(const LiveInterval &LI,
// The following checks only apply to virtual registers. Physreg liveness
// is too weird to check.
if (TargetRegisterInfo::isVirtualRegister(LI.reg)) {
// A live range can end with either a redefinition, a kill flag on a
// A live segment can end with either a redefinition, a kill flag on a
// use, or a dead flag on a def.
bool hasRead = false;
bool hasDeadDef = false;
@ -1519,12 +1519,11 @@ MachineVerifier::verifyLiveIntervalSegment(const LiveInterval &LI,
if (I->end.isDead()) {
if (!hasDeadDef) {
report("Instruction doesn't have a dead def operand", MI);
I->print(*OS);
*OS << " in " << LI << '\n';
*OS << *I << " in " << LI << '\n';
}
} else {
if (!hasRead) {
report("Instruction ending live range doesn't read the register", MI);
report("Instruction ending live segment doesn't read the register", MI);
*OS << *I << " in " << LI << '\n';
}
}
@ -1532,7 +1531,7 @@ MachineVerifier::verifyLiveIntervalSegment(const LiveInterval &LI,
// Now check all the basic blocks in this live segment.
MachineFunction::const_iterator MFI = MBB;
// Is this live range the beginning of a non-PHIDef VN?
// Is this live segment the beginning of a non-PHIDef VN?
if (I->start == VNI->def && !VNI->isPHIDef()) {
// Not live-in to any blocks.
if (MBB == EndMBB)

View File

@ -318,9 +318,9 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
if (!IncomingVNI)
IncomingVNI = IncomingLI.getNextValue(MBBStartIndex,
LIS->getVNInfoAllocator());
IncomingLI.addRange(LiveRange(MBBStartIndex,
DestCopyIndex.getRegSlot(),
IncomingVNI));
IncomingLI.addSegment(LiveInterval::Segment(MBBStartIndex,
DestCopyIndex.getRegSlot(),
IncomingVNI));
}
LiveInterval &DestLI = LIS->getInterval(DestReg);
@ -332,14 +332,14 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
// the copy instruction.
VNInfo *OrigDestVNI = DestLI.getVNInfoAt(MBBStartIndex);
assert(OrigDestVNI && "PHI destination should be live at block entry.");
DestLI.removeRange(MBBStartIndex, MBBStartIndex.getDeadSlot());
DestLI.removeSegment(MBBStartIndex, MBBStartIndex.getDeadSlot());
DestLI.createDeadDef(DestCopyIndex.getRegSlot(),
LIS->getVNInfoAllocator());
DestLI.removeValNo(OrigDestVNI);
} else {
// Otherwise, remove the region from the beginning of MBB to the copy
// instruction from DestReg's live interval.
DestLI.removeRange(MBBStartIndex, DestCopyIndex.getRegSlot());
DestLI.removeSegment(MBBStartIndex, DestCopyIndex.getRegSlot());
VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getRegSlot());
assert(DestVNI && "PHI destination should be live at its definition.");
DestVNI->def = DestCopyIndex.getRegSlot();
@ -460,7 +460,7 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
if (LIS) {
if (NewSrcInstr) {
LIS->InsertMachineInstrInMaps(NewSrcInstr);
LIS->addLiveRangeToEndOfBlock(IncomingReg, NewSrcInstr);
LIS->addSegmentToEndOfBlock(IncomingReg, NewSrcInstr);
}
if (!SrcUndef &&
@ -511,8 +511,8 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
"Cannot find kill instruction");
SlotIndex LastUseIndex = LIS->getInstructionIndex(KillInst);
SrcLI.removeRange(LastUseIndex.getRegSlot(),
LIS->getMBBEndIdx(&opBlock));
SrcLI.removeSegment(LastUseIndex.getRegSlot(),
LIS->getMBBEndIdx(&opBlock));
}
}
}

View File

@ -436,9 +436,9 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
// BValNo is a value number in B that is defined by a copy from A. 'B1' in
// the example above.
LiveInterval::iterator BLR = IntB.FindLiveRangeContaining(CopyIdx);
if (BLR == IntB.end()) return false;
VNInfo *BValNo = BLR->valno;
LiveInterval::iterator BS = IntB.FindSegmentContaining(CopyIdx);
if (BS == IntB.end()) return false;
VNInfo *BValNo = BS->valno;
// Get the location that B is defined at. Two options: either this value has
// an unknown definition point or it is defined at CopyIdx. If unknown, we
@ -447,10 +447,10 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
// AValNo is the value number in A that defines the copy, A3 in the example.
SlotIndex CopyUseIdx = CopyIdx.getRegSlot(true);
LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx);
// The live range might not exist after fun with physreg coalescing.
if (ALR == IntA.end()) return false;
VNInfo *AValNo = ALR->valno;
LiveInterval::iterator AS = IntA.FindSegmentContaining(CopyUseIdx);
// The live segment might not exist after fun with physreg coalescing.
if (AS == IntA.end()) return false;
VNInfo *AValNo = AS->valno;
// If AValNo is defined as a copy from IntB, we can potentially process this.
// Get the instruction that defines this value number.
@ -459,54 +459,54 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
if (!CP.isCoalescable(ACopyMI) || !ACopyMI->isFullCopy())
return false;
// Get the LiveRange in IntB that this value number starts with.
LiveInterval::iterator ValLR =
IntB.FindLiveRangeContaining(AValNo->def.getPrevSlot());
if (ValLR == IntB.end())
// Get the Segment in IntB that this value number starts with.
LiveInterval::iterator ValS =
IntB.FindSegmentContaining(AValNo->def.getPrevSlot());
if (ValS == IntB.end())
return false;
// Make sure that the end of the live range is inside the same block as
// Make sure that the end of the live segment is inside the same block as
// CopyMI.
MachineInstr *ValLREndInst =
LIS->getInstructionFromIndex(ValLR->end.getPrevSlot());
if (!ValLREndInst || ValLREndInst->getParent() != CopyMI->getParent())
MachineInstr *ValSEndInst =
LIS->getInstructionFromIndex(ValS->end.getPrevSlot());
if (!ValSEndInst || ValSEndInst->getParent() != CopyMI->getParent())
return false;
// Okay, we now know that ValLR ends in the same block that the CopyMI
// live-range starts. If there are no intervening live ranges between them in
// IntB, we can merge them.
if (ValLR+1 != BLR) return false;
// Okay, we now know that ValS ends in the same block that the CopyMI
// live-range starts. If there are no intervening live segments between them
// in IntB, we can merge them.
if (ValS+1 != BS) return false;
DEBUG(dbgs() << "Extending: " << PrintReg(IntB.reg, TRI));
SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
// that defines this value #'. Update the valnum with the new defining
// instruction #.
BValNo->def = FillerStart;
// Okay, we can merge them. We need to insert a new liverange:
// [ValLR.end, BLR.begin) of either value number, then we merge the
// [ValS.end, BS.begin) of either value number, then we merge the
// two value numbers.
IntB.addRange(LiveRange(FillerStart, FillerEnd, BValNo));
IntB.addSegment(LiveInterval::Segment(FillerStart, FillerEnd, BValNo));
// Okay, merge "B1" into the same value number as "B0".
if (BValNo != ValLR->valno)
IntB.MergeValueNumberInto(BValNo, ValLR->valno);
if (BValNo != ValS->valno)
IntB.MergeValueNumberInto(BValNo, ValS->valno);
DEBUG(dbgs() << " result = " << IntB << '\n');
// If the source instruction was killing the source register before the
// merge, unset the isKill marker given the live range has been extended.
int UIdx = ValLREndInst->findRegisterUseOperandIdx(IntB.reg, true);
int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg, true);
if (UIdx != -1) {
ValLREndInst->getOperand(UIdx).setIsKill(false);
ValSEndInst->getOperand(UIdx).setIsKill(false);
}
// Rewrite the copy. If the copy instruction was killing the destination
// register before the merge, find the last use and trim the live range. That
// will also add the isKill marker.
CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI);
if (ALR->end == CopyIdx)
if (AS->end == CopyIdx)
LIS->shrinkToUses(&IntA);
++numExtends;
@ -627,8 +627,8 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
SlotIndex UseIdx = LIS->getInstructionIndex(UseMI);
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end() || ULR->valno != AValNo)
LiveInterval::iterator US = IntA.FindSegmentContaining(UseIdx);
if (US == IntA.end() || US->valno != AValNo)
continue;
// If this use is tied to a def, we can't rewrite the register.
if (UseMI->isRegTiedToDefOperand(UI.getOperandNo()))
@ -679,8 +679,8 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
continue;
}
SlotIndex UseIdx = LIS->getInstructionIndex(UseMI).getRegSlot(true);
LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
if (ULR == IntA.end() || ULR->valno != AValNo)
LiveInterval::iterator US = IntA.FindSegmentContaining(UseIdx);
if (US == IntA.end() || US->valno != AValNo)
continue;
// Kill flags are no longer accurate. They are recomputed after RA.
UseMO.setIsKill(false);
@ -710,14 +710,14 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
UseMI->eraseFromParent();
}
// Extend BValNo by merging in IntA live ranges of AValNo. Val# definition
// Extend BValNo by merging in IntA live segments of AValNo. Val# definition
// is updated.
VNInfo *ValNo = BValNo;
ValNo->def = AValNo->def;
for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
AI != AE; ++AI) {
if (AI->valno != AValNo) continue;
IntB.addRange(LiveRange(AI->start, AI->end, ValNo));
IntB.addSegment(LiveInterval::Segment(AI->start, AI->end, ValNo));
}
DEBUG(dbgs() << "\t\textended: " << IntB << '\n');
@ -1107,7 +1107,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
return true;
// If we can eliminate the copy without merging the live ranges, do so now.
// If we can eliminate the copy without merging the live segments, do so
// now.
if (!CP.isPartial() && !CP.isPhys()) {
if (adjustCopiesBackFrom(CP, CopyMI) ||
removeCopyByCommutingDef(CP, CopyMI)) {

View File

@ -214,7 +214,7 @@ bool SplitAnalysis::calcLiveBlockInfo() {
// When not live in, the first use should be a def.
if (!BI.LiveIn) {
assert(LVI->start == LVI->valno->def && "Dangling LiveRange start");
assert(LVI->start == LVI->valno->def && "Dangling Segment start");
assert(LVI->start == BI.FirstInstr && "First instr should be a def");
BI.FirstDef = BI.FirstInstr;
}
@ -245,8 +245,8 @@ bool SplitAnalysis::calcLiveBlockInfo() {
BI.FirstInstr = BI.FirstDef = LVI->start;
}
// A LiveRange that starts in the middle of the block must be a def.
assert(LVI->start == LVI->valno->def && "Dangling LiveRange start");
// A Segment that starts in the middle of the block must be a def.
assert(LVI->start == LVI->valno->def && "Dangling Segment start");
if (!BI.FirstDef)
BI.FirstDef = LVI->start;
}
@ -395,14 +395,14 @@ VNInfo *SplitEditor::defValue(unsigned RegIdx,
// If the previous value was a simple mapping, add liveness for it now.
if (VNInfo *OldVNI = InsP.first->second.getPointer()) {
SlotIndex Def = OldVNI->def;
LI->addRange(LiveRange(Def, Def.getDeadSlot(), OldVNI));
LI->addSegment(LiveInterval::Segment(Def, Def.getDeadSlot(), OldVNI));
// No longer a simple mapping. Switch to a complex, non-forced mapping.
InsP.first->second = ValueForcePair();
}
// This is a complex mapping, add liveness for VNI
SlotIndex Def = VNI->def;
LI->addRange(LiveRange(Def, Def.getDeadSlot(), VNI));
LI->addSegment(LiveInterval::Segment(Def, Def.getDeadSlot(), VNI));
return VNI;
}
@ -423,7 +423,7 @@ void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo *ParentVNI) {
// by a trivial live range.
SlotIndex Def = VNI->def;
LiveInterval *LI = &LIS.getInterval(Edit->get(RegIdx));
LI->addRange(LiveRange(Def, Def.getDeadSlot(), VNI));
LI->addSegment(LiveInterval::Segment(Def, Def.getDeadSlot(), VNI));
// Mark as complex mapped, forced.
VFP = ValueForcePair(0, true);
}
@ -868,7 +868,7 @@ bool SplitEditor::transferValues() {
ValueForcePair VFP = Values.lookup(std::make_pair(RegIdx, ParentVNI->id));
if (VNInfo *VNI = VFP.getPointer()) {
DEBUG(dbgs() << ':' << VNI->id);
LI->addRange(LiveRange(Start, End, VNI));
LI->addSegment(LiveInterval::Segment(Start, End, VNI));
Start = End;
continue;
}

View File

@ -450,14 +450,14 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
SlotIndex F = Finishes[i];
if (S < F) {
// We have a single consecutive region.
Intervals[i]->addRange(LiveRange(S, F, ValNum));
Intervals[i]->addSegment(LiveInterval::Segment(S, F, ValNum));
} else {
// We have two non consecutive regions. This happens when
// LIFETIME_START appears after the LIFETIME_END marker.
SlotIndex NewStart = Indexes->getMBBStartIdx(MBB);
SlotIndex NewFin = Indexes->getMBBEndIdx(MBB);
Intervals[i]->addRange(LiveRange(NewStart, F, ValNum));
Intervals[i]->addRange(LiveRange(S, NewFin, ValNum));
Intervals[i]->addSegment(LiveInterval::Segment(NewStart, F, ValNum));
Intervals[i]->addSegment(LiveInterval::Segment(S, NewFin, ValNum));
}
}
}
@ -763,7 +763,7 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
// Merge disjoint slots.
if (!First->overlaps(*Second)) {
Changed = true;
First->MergeRangesInAsValue(*Second, First->getValNumInfo(0));
First->MergeSegmentsInAsValue(*Second, First->getValNumInfo(0));
SlotRemap[SecondSlot] = FirstSlot;
SortedSlots[J] = -1;
DEBUG(dbgs()<<"Merging #"<<FirstSlot<<" and slots #"<<

View File

@ -347,16 +347,16 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &MF) {
assert(DestLI.size() == 1
&& "PHI destination copy's live interval should be a single live "
"range from the beginning of the BB to the copy instruction.");
LiveRange *DestLR = DestLI.begin();
VNInfo *NewVNI = NewLI.getVNInfoAt(DestLR->start);
LiveInterval::Segment *DestS = DestLI.begin();
VNInfo *NewVNI = NewLI.getVNInfoAt(DestS->start);
if (!NewVNI) {
NewVNI = NewLI.createValueCopy(DestLR->valno, LI->getVNInfoAllocator());
NewVNI = NewLI.createValueCopy(DestS->valno, LI->getVNInfoAllocator());
MachineInstr *CopyInstr = I->second;
CopyInstr->getOperand(1).setIsKill(true);
}
LiveRange NewLR(DestLR->start, DestLR->end, NewVNI);
NewLI.addRange(NewLR);
LiveInterval::Segment NewS(DestS->start, DestS->end, NewVNI);
NewLI.addSegment(NewS);
LI->removeInterval(DestReg);
MRI->replaceRegWith(DestReg, NewReg);
@ -389,7 +389,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &MF) {
MachineOperand *LastUse = findLastUse(MBB, SrcReg);
assert(LastUse);
SlotIndex LastUseIndex = LI->getInstructionIndex(LastUse->getParent());
SrcLI.removeRange(LastUseIndex.getRegSlot(), LI->getMBBEndIdx(MBB));
SrcLI.removeSegment(LastUseIndex.getRegSlot(), LI->getMBBEndIdx(MBB));
LastUse->setIsKill(true);
}
@ -702,7 +702,7 @@ void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI,
// addLiveRangeToEndOfBlock() also adds the phikill flag to the VNInfo for
// the newly added range.
LI->addLiveRangeToEndOfBlock(CopyReg, CopyInstr);
LI->addSegmentToEndOfBlock(CopyReg, CopyInstr);
InsertedSrcCopySet.insert(std::make_pair(PredBB, SrcReg));
addReg(CopyReg);
@ -732,7 +732,7 @@ void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI,
SlotIndex PHIIndex = LI->getInstructionIndex(PHI);
SlotIndex NextInstrIndex = PHIIndex.getNextIndex();
if (SrcLI.liveAt(MBBStartIndex) && SrcLI.expiredAt(NextInstrIndex))
SrcLI.removeRange(MBBStartIndex, PHIIndex, true);
SrcLI.removeSegment(MBBStartIndex, PHIIndex, true);
}
unsigned DestReg = PHI->getOperand(0).getReg();
@ -752,9 +752,9 @@ void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI,
// beginning of the basic block.
SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB);
DestVNI->def = MBBStartIndex;
DestLI.addRange(LiveRange(MBBStartIndex,
PHIIndex.getRegSlot(),
DestVNI));
DestLI.addSegment(LiveInterval::Segment(MBBStartIndex,
PHIIndex.getRegSlot(),
DestVNI));
return;
}
@ -777,15 +777,15 @@ void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI,
SlotIndex DestCopyIndex = LI->getInstructionIndex(CopyInstr);
VNInfo *CopyVNI = CopyLI.getNextValue(MBBStartIndex,
LI->getVNInfoAllocator());
CopyLI.addRange(LiveRange(MBBStartIndex,
DestCopyIndex.getRegSlot(),
CopyVNI));
CopyLI.addSegment(LiveInterval::Segment(MBBStartIndex,
DestCopyIndex.getRegSlot(),
CopyVNI));
// Adjust DestReg's live interval to adjust for its new definition at
// CopyInstr.
LiveInterval &DestLI = LI->createEmptyInterval(DestReg);
SlotIndex PHIIndex = LI->getInstructionIndex(PHI);
DestLI.removeRange(PHIIndex.getRegSlot(), DestCopyIndex.getRegSlot());
DestLI.removeSegment(PHIIndex.getRegSlot(), DestCopyIndex.getRegSlot());
VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getRegSlot());
assert(DestVNI);
@ -803,10 +803,10 @@ void StrongPHIElimination::MergeLIsAndRename(unsigned Reg, unsigned NewReg) {
// Merge the live ranges of the two registers.
DenseMap<VNInfo*, VNInfo*> VNMap;
for (LiveInterval::iterator LRI = OldLI.begin(), LRE = OldLI.end();
LRI != LRE; ++LRI) {
LiveRange OldLR = *LRI;
VNInfo *OldVN = OldLR.valno;
for (LiveInterval::iterator SI = OldLI.begin(), SE = OldLI.end();
SI != SE; ++SI) {
LiveInterval::Segment OldS = *SI;
VNInfo *OldVN = OldS.valno;
VNInfo *&NewVN = VNMap[OldVN];
if (!NewVN) {
@ -814,8 +814,8 @@ void StrongPHIElimination::MergeLIsAndRename(unsigned Reg, unsigned NewReg) {
VNMap[OldVN] = NewVN;
}
LiveRange LR(OldLR.start, OldLR.end, NewVN);
NewLI.addRange(LR);
LiveInterval::Segment S(OldS.start, OldS.end, NewVN);
NewLI.addSegment(S);
}
// Remove the LiveInterval for the register being renamed and replace all

View File

@ -1400,7 +1400,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
SlotIndex endIdx =
LIS->getInstructionIndex(MI).getRegSlot(IsEarlyClobber);
LI.addRange(LiveRange(LastCopyIdx, endIdx, VNI));
LI.addSegment(LiveInterval::Segment(LastCopyIdx, endIdx, VNI));
}
}
@ -1457,7 +1457,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
SlotIndex UseIdx = MIIdx.getRegSlot(IsEarlyClobber);
if (I->end == UseIdx)
LI.removeRange(LastCopyIdx, UseIdx);
LI.removeSegment(LastCopyIdx, UseIdx);
}
} else if (RemovedKillFlag) {