From b0fa11ca41d85e35d3c1155c6a3af1b67788fce6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 20 Oct 2005 07:39:25 +0000 Subject: [PATCH] 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 --- lib/CodeGen/LiveInterval.cpp | 66 ++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 93d32d8edba..18faacf4450 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 &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); + } + } }