diff options
author | Chris Lattner <sabre@nondot.org> | 2005-10-20 07:39:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-10-20 07:39:25 +0000 |
commit | b0fa11ca41d85e35d3c1155c6a3af1b67788fce6 (patch) | |
tree | 78ba3e896df2eb62e633f80f93fcbddaf6b8de2c /lib/CodeGen/LiveInterval.cpp | |
parent | 0692bbd991abe449327276ab8b10f1c822530450 (diff) |
add a new method, play around with some code.
Fix a *bug* in the extendIntervalEndTo method. In particular, if adding
[2:10) to an interval containing [0:2),[10:30), we produced [0:10),[10,30).
Which is not the most smart thing to do. Now produce [0:30).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23841 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveInterval.cpp')
-rw-r--r-- | lib/CodeGen/LiveInterval.cpp | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 93d32d8edb..18faacf445 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -104,20 +104,19 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other, /// NontrivialOverlap - Check to see if the two live ranges specified by i and j /// overlap. If so, check to see if they have value numbers that are not /// iIdx/jIdx respectively. If both conditions are true, return true. -static inline bool NontrivialOverlap(LiveInterval::Ranges::const_iterator i, - LiveInterval::Ranges::const_iterator j, +static inline bool NontrivialOverlap(const LiveRange &I, const LiveRange &J, unsigned iIdx, unsigned jIdx) { - if (i->start == j->start) { + if (I.start == J.start) { // If this is not the allowed value merge, we cannot join. - if (i->ValId != iIdx || j->ValId != jIdx) + if (I.ValId != iIdx || J.ValId != jIdx) return true; - } else if (i->start < j->start) { - if (i->end > j->start && i->ValId != iIdx || j->ValId != jIdx) { + } else if (I.start < J.start) { + if (I.end > J.start && I.ValId != iIdx || J.ValId != jIdx) { return true; } } else { - if (j->end > i->start && - i->ValId != iIdx || j->ValId != jIdx) + if (J.end > I.start && + I.ValId != iIdx || J.ValId != jIdx) return true; } @@ -148,7 +147,7 @@ bool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const { } while (i != ie && j != je) { - if (NontrivialOverlap(i, j, ThisValIdx, OtherValIdx)) + if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx)) return false; if (i->end < j->end) @@ -160,6 +159,43 @@ bool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const { return true; } +/// getOverlapingRanges - Given another live interval which is defined as a +/// copy from this one, return a list of all of the live ranges where the +/// two overlap and have different value numbers. +void LiveInterval::getOverlapingRanges(const LiveInterval &other, + unsigned CopyIdx, + std::vector<LiveRange*> &Ranges) { + const LiveRange *SourceLR = other.getLiveRangeContaining(CopyIdx-1); + const LiveRange *DestLR = getLiveRangeContaining(CopyIdx); + assert(SourceLR && DestLR && "Not joining due to a copy?"); + unsigned OtherValIdx = SourceLR->ValId; + unsigned ThisValIdx = DestLR->ValId; + + Ranges::iterator i = ranges.begin(); + Ranges::iterator ie = ranges.end(); + Ranges::const_iterator j = other.ranges.begin(); + Ranges::const_iterator je = other.ranges.end(); + + if (i->start < j->start) { + i = std::upper_bound(i, ie, j->start); + if (i != ranges.begin()) --i; + } else if (j->start < i->start) { + j = std::upper_bound(j, je, i->start); + if (j != other.ranges.begin()) --j; + } + + while (i != ie && j != je) { + if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx)) + Ranges.push_back(&*i); + + if (i->end < j->end) + ++i; + else + ++j; + } +} + + /// 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 @@ -178,8 +214,18 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) { // If NewEnd was in the middle of an interval, make sure to get its endpoint. I->end = std::max(NewEnd, prior(MergeTo)->end); - // Erase any dead ranges + // Erase any dead ranges. ranges.erase(next(I), MergeTo); + + // 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 (I != ranges.end()) { + Ranges::iterator Next = next(I); + if (Next->start == I->end && Next->ValId == ValId) { + I->end = Next->end; + ranges.erase(Next); + } + } } |