summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/LiveInterval.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/lib/CodeGen/LiveInterval.cpp
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/lib/CodeGen/LiveInterval.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/LiveInterval.cpp401
1 files changed, 204 insertions, 197 deletions
diff --git a/contrib/llvm/lib/CodeGen/LiveInterval.cpp b/contrib/llvm/lib/CodeGen/LiveInterval.cpp
index dccd847..2b8feb8 100644
--- a/contrib/llvm/lib/CodeGen/LiveInterval.cpp
+++ b/contrib/llvm/lib/CodeGen/LiveInterval.cpp
@@ -9,12 +9,12 @@
//
// 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
-// live interval for register v if there is no instruction with number j' > j
+// live range 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.
+// that v is live at i'. In this implementation ranges can have holes,
+// i.e. a range might look like [1,20), [50,65), [1000,1001). Each
+// individual segment is represented as an instance of LiveRange::Segment,
+// and the whole range is represented as an instance of LiveRange.
//
//===----------------------------------------------------------------------===//
@@ -31,14 +31,14 @@
#include <algorithm>
using namespace llvm;
-LiveInterval::iterator LiveInterval::find(SlotIndex Pos) {
+LiveRange::iterator LiveRange::find(SlotIndex Pos) {
// This algorithm is basically std::upper_bound.
// Unfortunately, std::upper_bound cannot be used with mixed types until we
// adopt C++0x. Many libraries can do it, but not all.
if (empty() || Pos >= endIndex())
return end();
iterator I = begin();
- size_t Len = ranges.size();
+ size_t Len = size();
do {
size_t Mid = Len >> 1;
if (Pos < I[Mid].end)
@@ -49,13 +49,13 @@ LiveInterval::iterator LiveInterval::find(SlotIndex Pos) {
return I;
}
-VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
- VNInfo::Allocator &VNInfoAllocator) {
+VNInfo *LiveRange::createDeadDef(SlotIndex Def,
+ VNInfo::Allocator &VNInfoAllocator) {
assert(!Def.isDead() && "Cannot define a value at the dead slot");
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,11 +73,11 @@ 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;
}
-// overlaps - Return true if the intersection of the two live intervals is
+// overlaps - Return true if the intersection of the two live ranges is
// not empty.
//
// An example for overlaps():
@@ -86,7 +86,7 @@ VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
// 4: B = ...
// 8: C = A + B ;; last use of A
//
-// The live intervals should look like:
+// The live ranges should look like:
//
// A = [3, 11)
// B = [7, x)
@@ -95,9 +95,9 @@ VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
// A->overlaps(C) should return false since we want to be able to join
// A and C.
//
-bool LiveInterval::overlapsFrom(const LiveInterval& other,
- const_iterator StartPos) const {
- assert(!empty() && "empty interval");
+bool LiveRange::overlapsFrom(const LiveRange& other,
+ const_iterator StartPos) const {
+ assert(!empty() && "empty range");
const_iterator i = begin();
const_iterator ie = end();
const_iterator j = StartPos;
@@ -108,13 +108,13 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other,
if (i->start < j->start) {
i = std::upper_bound(i, ie, j->start);
- if (i != ranges.begin()) --i;
+ if (i != begin()) --i;
} else if (j->start < i->start) {
++StartPos;
if (StartPos != other.end() && StartPos->start <= i->start) {
assert(StartPos < other.end() && i < end());
j = std::upper_bound(j, je, i->start);
- if (j != other.ranges.begin()) --j;
+ if (j != other.begin()) --j;
}
} else {
return true;
@@ -136,10 +136,9 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other,
return false;
}
-bool LiveInterval::overlaps(const LiveInterval &Other,
- const CoalescerPair &CP,
- const SlotIndexes &Indexes) const {
- assert(!empty() && "empty interval");
+bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP,
+ const SlotIndexes &Indexes) const {
+ assert(!empty() && "empty range");
if (Other.empty())
return false;
@@ -178,9 +177,9 @@ bool LiveInterval::overlaps(const LiveInterval &Other,
}
}
-/// overlaps - Return true if the live interval overlaps a range specified
+/// overlaps - Return true if the live range overlaps an interval specified
/// by [Start, End).
-bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const {
+bool LiveRange::overlaps(SlotIndex Start, SlotIndex End) const {
assert(Start < End && "Invalid range");
const_iterator I = std::lower_bound(begin(), end(), End);
return I != begin() && (--I)->end > Start;
@@ -190,7 +189,7 @@ bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const {
/// ValNo is dead, remove it. If it is the largest value number, just nuke it
/// (and any other deleted values neighboring it), otherwise mark it as ~1U so
/// it can be nuked later.
-void LiveInterval::markValNoForDeletion(VNInfo *ValNo) {
+void LiveRange::markValNoForDeletion(VNInfo *ValNo) {
if (ValNo->id == getNumValNums()-1) {
do {
valnos.pop_back();
@@ -202,137 +201,135 @@ void LiveInterval::markValNoForDeletion(VNInfo *ValNo) {
/// RenumberValues - Renumber all values in order of appearance and delete the
/// remaining unused values.
-void LiveInterval::RenumberValues(LiveIntervals &lis) {
+void LiveRange::RenumberValues() {
SmallPtrSet<VNInfo*, 8> Seen;
valnos.clear();
for (const_iterator I = begin(), E = end(); I != E; ++I) {
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(Ranges::iterator I, SlotIndex NewEnd) {
- assert(I != ranges.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 LiveRange::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.
- Ranges::iterator MergeTo = llvm::next(I);
- for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) {
+ // 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 a 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 (MergeTo != ranges.end() && MergeTo->start <= I->end &&
+ // 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.
-LiveInterval::Ranges::iterator
-LiveInterval::extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStart) {
- assert(I != ranges.end() && "Not a valid interval!");
+/// 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.
+LiveRange::iterator
+LiveRange::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.
- Ranges::iterator MergeTo = I;
+ // Search for the first segment that we can't merge with.
+ iterator MergeTo = I;
do {
- if (MergeTo == ranges.begin()) {
+ 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;
- iterator it = std::upper_bound(From, ranges.end(), Start);
+LiveRange::iterator LiveRange::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 (it != ranges.begin()) {
+ // 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.
- if (it != ranges.end()) {
- if (LR.valno == it->valno) {
+ // Otherwise, if this segment ends in the middle of, or right next to, another
+ // segment, merge it into that segment.
+ if (it != end()) {
+ 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
+/// extendInBlock - If this range 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.
-VNInfo *LiveInterval::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
+VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) {
if (empty())
return 0;
iterator I = std::upper_bound(begin(), end(), Kill.getPrevSlot());
@@ -342,20 +339,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.
- Ranges::iterator I = find(Start);
- assert(I != ranges.end() && "Range is not in interval!");
- assert(I->containsRange(Start, End) && "Range is not entirely in interval!");
+/// Remove the specified segment from this range. Note that the segment must
+/// be in a single Segment in its entirety.
+void LiveRange::removeSegment(SlotIndex Start, SlotIndex End,
+ bool RemoveDeadValNo) {
+ // Find the Segment containing this span.
+ iterator I = find(Start);
+ assert(I != end() && "Segment is not in range!");
+ assert(I->containsInterval(Start, End)
+ && "Segment is not entirely in range!");
- // 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,54 +371,50 @@ 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.
+ I->end = Start; // Trim the old segment.
// 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) {
+void LiveRange::removeValNo(VNInfo *ValNo) {
if (empty()) return;
- Ranges::iterator I = ranges.end();
- Ranges::iterator E = ranges.begin();
+ iterator I = end();
+ iterator E = begin();
do {
--I;
if (I->valno == ValNo)
- ranges.erase(I);
+ segments.erase(I);
} while (I != E);
// Now that ValNo is dead, remove it.
markValNoForDeletion(ValNo);
}
-/// join - Join two live intervals (this, and other) together. This applies
-/// mappings to the value numbers in the LHS/RHS intervals as specified. If
-/// the intervals are not joinable, this aborts.
-void LiveInterval::join(LiveInterval &Other,
- const int *LHSValNoAssignments,
- const int *RHSValNoAssignments,
- SmallVector<VNInfo*, 16> &NewVNInfo,
- MachineRegisterInfo *MRI) {
+void LiveRange::join(LiveRange &Other,
+ const int *LHSValNoAssignments,
+ const int *RHSValNoAssignments,
+ 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 range scan if not.
bool MustMapCurValNos = false;
unsigned NumVals = getNumValNums();
unsigned NumNewVals = NewVNInfo.size();
@@ -433,8 +427,7 @@ void LiveInterval::join(LiveInterval &Other,
}
}
- // If we have to apply a mapping to our base interval assignment, rewrite it
- // now.
+ // If we have to apply a mapping to our base range assignment, rewrite it now.
if (MustMapCurValNos && !empty()) {
// Map the first live range.
@@ -445,12 +438,12 @@ 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;
} else {
- // Didn't merge. Move OutIt to the next interval,
+ // Didn't merge. Move OutIt to the next segment,
++OutIt;
OutIt->valno = nextValNo;
if (OutIt != I) {
@@ -459,9 +452,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.
@@ -472,7 +465,7 @@ void LiveInterval::join(LiveInterval &Other,
I->valno = NewVNInfo[RHSValNoAssignments[I->valno->id]];
// Update val# info. Renumber them and make sure they all belong to this
- // LiveInterval now. Also remove dead val#'s.
+ // LiveRange now. Also remove dead val#'s.
unsigned NumValNos = 0;
for (unsigned i = 0; i < NumNewVals; ++i) {
VNInfo *VNI = NewVNInfo[i];
@@ -487,31 +480,31 @@ 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 range as the specified
+/// value number. The segments in RHS are allowed to overlap with segments in
+/// the current range, but only if the overlapping segments have the
+/// specified value number.
+void LiveRange::MergeSegmentsInAsValue(const LiveRange &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#
-/// 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 LiveInterval::MergeValueInAsValue(const LiveInterval &RHS,
- const VNInfo *RHSValNo,
- VNInfo *LHSValNo) {
+/// MergeValueInAsValue - Merge all of the live segments of a specific val#
+/// in RHS into this live range as the specified value number.
+/// The segments in RHS are allowed to overlap with segments in the
+/// current range, it will replace the value numbers of the overlaped
+/// segments with the specified value number.
+void LiveRange::MergeValueInAsValue(const LiveRange &RHS,
+ const VNInfo *RHSValNo,
+ VNInfo *LHSValNo) {
LiveRangeUpdater Updater(this);
for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
if (I->valno == RHSValNo)
@@ -520,9 +513,9 @@ 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) {
+VNInfo *LiveRange::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
assert(V1 != V2 && "Identical value#'s are always equivalent!");
// This code actually merges the (numerically) larger value number into the
@@ -536,37 +529,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;
}
}
}
@@ -584,22 +577,21 @@ 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 LiveRange::Segment &S) {
+ return os << '[' << S.start << ',' << S.end << ':' << S.valno->id << ")";
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void LiveRange::dump() const {
+void LiveRange::Segment::dump() const {
dbgs() << *this << "\n";
}
#endif
-void LiveInterval::print(raw_ostream &OS) const {
+void LiveRange::print(raw_ostream &OS) const {
if (empty())
OS << "EMPTY";
else {
- for (LiveInterval::Ranges::const_iterator I = ranges.begin(),
- E = ranges.end(); I != E; ++I) {
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
OS << *I;
assert(I->valno == getValNumInfo(I->valno->id) && "Bad VNInfo");
}
@@ -625,19 +617,29 @@ void LiveInterval::print(raw_ostream &OS) const {
}
}
+void LiveInterval::print(raw_ostream &OS) const {
+ OS << PrintReg(reg) << ' ';
+ super::print(OS);
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void LiveRange::dump() const {
+ dbgs() << *this << "\n";
+}
+
void LiveInterval::dump() const {
dbgs() << *this << "\n";
}
#endif
#ifndef NDEBUG
-void LiveInterval::verify() const {
+void LiveRange::verify() const {
for (const_iterator I = begin(), E = end(); I != E; ++I) {
assert(I->start.isValid());
assert(I->end.isValid());
assert(I->start < I->end);
assert(I->valno != 0);
+ assert(I->valno->id < valnos.size());
assert(I->valno == valnos[I->valno->id]);
if (llvm::next(I) != E) {
assert(I->end <= llvm::next(I)->start);
@@ -649,10 +651,6 @@ void LiveInterval::verify() const {
#endif
-void LiveRange::print(raw_ostream &os) const {
- os << *this;
-}
-
//===----------------------------------------------------------------------===//
// LiveRangeUpdater class
//===----------------------------------------------------------------------===//
@@ -665,11 +663,11 @@ void LiveRange::print(raw_ostream &os) const {
//
// Otherwise, segments are kept in three separate areas:
//
-// 1. [begin; WriteI) at the front of LI.
-// 2. [ReadI; end) at the back of LI.
+// 1. [begin; WriteI) at the front of LR.
+// 2. [ReadI; end) at the back of LR.
// 3. Spills.
//
-// - LI.begin() <= WriteI <= ReadI <= LI.end().
+// - LR.begin() <= WriteI <= ReadI <= LR.end().
// - Segments in all three areas are fully ordered and coalesced.
// - Segments in area 1 precede and can't coalesce with segments in area 2.
// - Segments in Spills precede and can't coalesce with segments in area 2.
@@ -684,23 +682,23 @@ void LiveRange::print(raw_ostream &os) const {
void LiveRangeUpdater::print(raw_ostream &OS) const {
if (!isDirty()) {
- if (LI)
- OS << "Clean " << PrintReg(LI->reg) << " updater: " << *LI << '\n';
+ if (LR)
+ OS << "Clean updater: " << *LR << '\n';
else
OS << "Null updater.\n";
return;
}
- assert(LI && "Can't have null LI in dirty updater.");
- OS << PrintReg(LI->reg) << " updater with gap = " << (ReadI - WriteI)
+ assert(LR && "Can't have null LR in dirty updater.");
+ OS << " updater with gap = " << (ReadI - WriteI)
<< ", last start = " << LastStart
<< ":\n Area 1:";
- for (LiveInterval::const_iterator I = LI->begin(); I != WriteI; ++I)
+ for (LiveRange::const_iterator I = LR->begin(); I != WriteI; ++I)
OS << ' ' << *I;
OS << "\n Spills:";
for (unsigned I = 0, E = Spills.size(); I != E; ++I)
OS << ' ' << Spills[I];
OS << "\n Area 2:";
- for (LiveInterval::const_iterator I = ReadI, E = LI->end(); I != E; ++I)
+ for (LiveRange::const_iterator I = ReadI, E = LR->end(); I != E; ++I)
OS << ' ' << *I;
OS << '\n';
}
@@ -711,8 +709,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 LiveRange::Segment &A,
+ const LiveRange::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)
@@ -721,8 +720,8 @@ static inline bool coalescable(const LiveRange &A, const LiveRange &B) {
return true;
}
-void LiveRangeUpdater::add(LiveRange Seg) {
- assert(LI && "Cannot add to a null destination");
+void LiveRangeUpdater::add(LiveRange::Segment Seg) {
+ assert(LR && "Cannot add to a null destination");
// Flush the state if Start moves backwards.
if (!LastStart.isValid() || LastStart > Seg.start) {
@@ -730,21 +729,21 @@ void LiveRangeUpdater::add(LiveRange Seg) {
flush();
// This brings us to an uninitialized state. Reinitialize.
assert(Spills.empty() && "Leftover spilled segments");
- WriteI = ReadI = LI->begin();
+ WriteI = ReadI = LR->begin();
}
// Remember start for next time.
LastStart = Seg.start;
// Advance ReadI until it ends after Seg.start.
- LiveInterval::iterator E = LI->end();
+ LiveRange::iterator E = LR->end();
if (ReadI != E && ReadI->end <= Seg.start) {
// First try to close the gap between WriteI and ReadI with spills.
if (ReadI != WriteI)
mergeSpills();
// Then advance ReadI.
if (ReadI == WriteI)
- ReadI = WriteI = LI->find(Seg.start);
+ ReadI = WriteI = LR->find(Seg.start);
else
while (ReadI != E && ReadI->end <= Seg.start)
*WriteI++ = *ReadI++;
@@ -777,7 +776,7 @@ void LiveRangeUpdater::add(LiveRange Seg) {
}
// Try coalescing Seg into WriteI[-1].
- if (WriteI != LI->begin() && coalescable(WriteI[-1], Seg)) {
+ if (WriteI != LR->begin() && coalescable(WriteI[-1], Seg)) {
WriteI[-1].end = std::max(WriteI[-1].end, Seg.end);
return;
}
@@ -788,10 +787,10 @@ void LiveRangeUpdater::add(LiveRange Seg) {
return;
}
- // Finally, append to LI or Spills.
+ // Finally, append to LR or Spills.
if (WriteI == E) {
- LI->ranges.push_back(Seg);
- WriteI = ReadI = LI->ranges.end();
+ LR->segments.push_back(Seg);
+ WriteI = ReadI = LR->end();
} else
Spills.push_back(Seg);
}
@@ -802,10 +801,10 @@ void LiveRangeUpdater::mergeSpills() {
// Perform a backwards merge of Spills and [SpillI;WriteI).
size_t GapSize = ReadI - WriteI;
size_t NumMoved = std::min(Spills.size(), GapSize);
- LiveInterval::iterator Src = WriteI;
- LiveInterval::iterator Dst = Src + NumMoved;
- LiveInterval::iterator SpillSrc = Spills.end();
- LiveInterval::iterator B = LI->begin();
+ LiveRange::iterator Src = WriteI;
+ LiveRange::iterator Dst = Src + NumMoved;
+ LiveRange::iterator SpillSrc = Spills.end();
+ LiveRange::iterator B = LR->begin();
// This is the new WriteI position after merging spills.
WriteI = Dst;
@@ -827,12 +826,12 @@ void LiveRangeUpdater::flush() {
// Clear the dirty state.
LastStart = SlotIndex();
- assert(LI && "Cannot add to a null destination");
+ assert(LR && "Cannot add to a null destination");
// Nothing to merge?
if (Spills.empty()) {
- LI->ranges.erase(WriteI, ReadI);
- LI->verify();
+ LR->segments.erase(WriteI, ReadI);
+ LR->verify();
return;
}
@@ -840,17 +839,17 @@ void LiveRangeUpdater::flush() {
size_t GapSize = ReadI - WriteI;
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());
+ size_t WritePos = WriteI - LR->begin();
+ LR->segments.insert(ReadI, Spills.size() - GapSize, LiveRange::Segment());
// This also invalidated ReadI, but it is recomputed below.
- WriteI = LI->ranges.begin() + WritePos;
+ WriteI = LR->begin() + WritePos;
} else {
// Shrink the gap if necessary.
- LI->ranges.erase(WriteI + Spills.size(), ReadI);
+ LR->segments.erase(WriteI + Spills.size(), ReadI);
}
ReadI = WriteI + Spills.size();
mergeSpills();
- LI->verify();
+ LR->verify();
}
unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
@@ -909,8 +908,16 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[],
MachineOperand &MO = RI.getOperand();
MachineInstr *MI = MO.getParent();
++RI;
- // DBG_VALUE instructions should have been eliminated earlier.
- LiveRangeQuery LRQ(LI, LIS.getInstructionIndex(MI));
+ // DBG_VALUE instructions don't have slot indexes, so get the index of the
+ // instruction before them.
+ // Normally, DBG_VALUE instructions are removed before this function is
+ // called, but it is not a requirement.
+ SlotIndex Idx;
+ if (MI->isDebugValue())
+ Idx = LIS.getSlotIndexes()->getIndexBefore(MI);
+ else
+ Idx = LIS.getInstructionIndex(MI);
+ LiveQueryResult LRQ = LI.Query(Idx);
const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined();
// In the case of an <undef> use that isn't tied to any def, VNI will be
// NULL. If the use is tied to a def, VNI will be the defined value.
@@ -927,11 +934,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();
OpenPOWER on IntegriCloud