+ /// scanning the Other range starting at I.
+ bool overlapsFrom(const LiveRange &Other, const_iterator I) const;
+
+ /// Returns true if all segments of the @p Other live range are completely
+ /// covered by this live range.
+ /// Adjacent live ranges do not affect the covering:the liverange
+ /// [1,5](5,10] covers (3,7].
+ bool covers(const LiveRange &Other) const;
+
+ /// Add the specified Segment to this range, merging segments as
+ /// appropriate. This returns an iterator to the inserted segment (which
+ /// may have grown since it was inserted).
+ iterator addSegment(Segment S);
+
+ /// If this range is live before @p Use in the basic block that starts at
+ /// @p StartIdx, extend it to be live up to @p Use, and return the value. If
+ /// there is no segment before @p Use, return nullptr.
+ VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Use);
+
+ /// join - Join two live ranges (this, and other) together. This applies
+ /// mappings to the value numbers in the LHS/RHS ranges as specified. If
+ /// the ranges are not joinable, this aborts.
+ void join(LiveRange &Other,
+ const int *ValNoAssignments,
+ const int *RHSValNoAssignments,
+ SmallVectorImpl<VNInfo *> &NewVNInfo);
+
+ /// 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.
+ bool isLocal(SlotIndex Start, SlotIndex End) const {
+ return beginIndex() > Start.getBaseIndex() &&
+ endIndex() < End.getBoundaryIndex();
+ }
+
+ /// Remove the specified segment from this range. Note that the segment
+ /// must be a single Segment in its entirety.
+ void removeSegment(SlotIndex Start, SlotIndex End,
+ bool RemoveDeadValNo = false);
+
+ void removeSegment(Segment S, bool RemoveDeadValNo = false) {
+ removeSegment(S.start, S.end, RemoveDeadValNo);
+ }
+
+ /// Remove segment pointed to by iterator @p I from this range. This does
+ /// not remove dead value numbers.
+ iterator removeSegment(iterator I) {
+ return segments.erase(I);
+ }
+
+ /// Query Liveness at Idx.
+ /// The sub-instruction slot of Idx doesn't matter, only the instruction
+ /// it refers to is considered.
+ LiveQueryResult Query(SlotIndex Idx) const {
+ // Find the segment that enters the instruction.
+ const_iterator I = find(Idx.getBaseIndex());
+ const_iterator E = end();
+ if (I == E)
+ return LiveQueryResult(nullptr, nullptr, SlotIndex(), false);
+
+ // Is this an instruction live-in segment?
+ // If Idx is the start index of a basic block, include live-in segments
+ // that start at Idx.getBaseIndex().
+ VNInfo *EarlyVal = nullptr;
+ VNInfo *LateVal = nullptr;
+ SlotIndex EndPoint;
+ bool Kill = false;
+ if (I->start <= Idx.getBaseIndex()) {
+ EarlyVal = I->valno;
+ EndPoint = I->end;
+ // Move to the potentially live-out segment.
+ if (SlotIndex::isSameInstr(Idx, I->end)) {
+ Kill = true;
+ if (++I == E)
+ return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
+ }
+ // Special case: A PHIDef value can have its def in the middle of a
+ // segment if the value happens to be live out of the layout
+ // predecessor.
+ // Such a value is not live-in.
+ if (EarlyVal->def == Idx.getBaseIndex())
+ EarlyVal = nullptr;
+ }
+ // I now points to the segment that may be live-through, or defined by
+ // this instr. Ignore segments starting after the current instr.
+ if (!SlotIndex::isEarlierInstr(Idx, I->start)) {
+ LateVal = I->valno;
+ EndPoint = I->end;
+ }
+ return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
+ }
+
+ /// removeValNo - Remove all the segments defined by the specified value#.
+ /// Also remove the value# from value# list.
+ void removeValNo(VNInfo *ValNo);