[llvm-commits] CVS: llvm/lib/CodeGen/LiveInterval.cpp LiveIntervalAnalysis.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Sep 1 22:27:13 PDT 2006
Changes in directory llvm/lib/CodeGen:
LiveInterval.cpp updated: 1.34 -> 1.35
LiveIntervalAnalysis.cpp updated: 1.179 -> 1.180
---
Log message:
When joining two intervals where the RHS is really simple, use a light-weight
method for joining the live ranges instead of the fully-general one.
---
Diffs of the changes: (+172 -11)
LiveInterval.cpp | 17 ++++
LiveIntervalAnalysis.cpp | 166 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 172 insertions(+), 11 deletions(-)
Index: llvm/lib/CodeGen/LiveInterval.cpp
diff -u llvm/lib/CodeGen/LiveInterval.cpp:1.34 llvm/lib/CodeGen/LiveInterval.cpp:1.35
--- llvm/lib/CodeGen/LiveInterval.cpp:1.34 Thu Aug 31 00:54:43 2006
+++ llvm/lib/CodeGen/LiveInterval.cpp Sat Sep 2 00:26:59 2006
@@ -351,6 +351,23 @@
weight += Other.weight;
}
+/// 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,
+ unsigned LHSValNo) {
+ // TODO: Make this more efficient.
+ iterator InsertPos = begin();
+ for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) {
+ // Map the ValId in the other live range to the current live range.
+ LiveRange Tmp = *I;
+ Tmp.ValId = LHSValNo;
+ InsertPos = addRangeFrom(Tmp, InsertPos);
+ }
+}
+
+
/// MergeInClobberRanges - For any live ranges that are not defined in the
/// current interval, but are defined in the Clobbers interval, mark them
/// used with an unknown definition value.
Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.179 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.180
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.179 Fri Sep 1 02:00:23 2006
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Sat Sep 2 00:26:59 2006
@@ -883,6 +883,140 @@
return ThisValNoAssignments[VN] = UltimateVN;
}
+Statistic<> A("x", "a");
+Statistic<> B("x", "b");
+Statistic<> C("x", "c");
+Statistic<> D("x", "d");
+
+
+static bool InVector(unsigned Val, const SmallVector<unsigned, 8> &V) {
+ return std::find(V.begin(), V.end(), Val) != V.end();
+}
+
+/// SimpleJoin - Attempt to joint the specified interval into this one. The
+/// caller of this method must guarantee that the RHS only contains a single
+/// value number and that the RHS is not defined by a copy from this
+/// interval. This returns false if the intervals are not joinable, or it
+/// joins them and returns true.
+bool LiveIntervals::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS) {
+ assert(RHS.containsOneValue());
+
+ // Some number (potentially more than one) value numbers in the current
+ // interval may be defined as copies from the RHS. Scan the overlapping
+ // portions of the LHS and RHS, keeping track of this and looking for
+ // overlapping live ranges that are NOT defined as copies. If these exist, we
+ // cannot coallesce.
+
+ LiveInterval::iterator LHSIt = LHS.begin(), LHSEnd = LHS.end();
+ LiveInterval::iterator RHSIt = RHS.begin(), RHSEnd = RHS.end();
+
+ if (LHSIt->start < RHSIt->start) {
+ LHSIt = std::upper_bound(LHSIt, LHSEnd, RHSIt->start);
+ if (LHSIt != LHS.begin()) --LHSIt;
+ } else if (RHSIt->start < LHSIt->start) {
+ RHSIt = std::upper_bound(RHSIt, RHSEnd, LHSIt->start);
+ if (RHSIt != RHS.begin()) --RHSIt;
+ }
+
+ SmallVector<unsigned, 8> EliminatedLHSVals;
+
+ while (1) {
+ // Determine if these live intervals overlap.
+ bool Overlaps = false;
+ if (LHSIt->start <= RHSIt->start)
+ Overlaps = LHSIt->end > RHSIt->start;
+ else
+ Overlaps = RHSIt->end > LHSIt->start;
+
+ // If the live intervals overlap, there are two interesting cases: if the
+ // LHS interval is defined by a copy from the RHS, it's ok and we record
+ // that the LHS value # is the same as the RHS. If it's not, then we cannot
+ // coallesce these live ranges and we bail out.
+ if (Overlaps) {
+ // If we haven't already recorded that this value # is safe, check it.
+ if (!InVector(LHSIt->ValId, EliminatedLHSVals)) {
+ // Copy from the RHS?
+ unsigned SrcReg = LHS.getSrcRegForValNum(LHSIt->ValId);
+ if (rep(SrcReg) != RHS.reg)
+ return false; // Nope, bail out.
+
+ EliminatedLHSVals.push_back(LHSIt->ValId);
+ }
+
+ // We know this entire LHS live range is okay, so skip it now.
+ if (++LHSIt == LHSEnd) break;
+ continue;
+ }
+
+ if (LHSIt->end < RHSIt->end) {
+ if (++LHSIt == LHSEnd) break;
+ } else {
+ // One interesting case to check here. It's possible that we have
+ // something like "X3 = Y" which defines a new value number in the LHS,
+ // and is the last use of this liverange of the RHS. In this case, we
+ // want to notice this copy (so that it gets coallesced away) even though
+ // the live ranges don't actually overlap.
+ if (LHSIt->start == RHSIt->end) {
+ if (InVector(LHSIt->ValId, EliminatedLHSVals)) {
+ // We already know that this value number is going to be merged in
+ // if coallescing succeeds. Just skip the liverange.
+ if (++LHSIt == LHSEnd) break;
+ } else {
+ // Otherwise, if this is a copy from the RHS, mark it as being merged
+ // in.
+ if (rep(LHS.getSrcRegForValNum(LHSIt->ValId)) == RHS.reg) {
+ EliminatedLHSVals.push_back(LHSIt->ValId);
+
+ // We know this entire LHS live range is okay, so skip it now.
+ if (++LHSIt == LHSEnd) break;
+ }
+ }
+ }
+
+ if (++RHSIt == RHSEnd) break;
+ }
+ }
+
+ // If we got here, we know that the coallescing will be successful and that
+ // the value numbers in EliminatedLHSVals will all be merged together. Since
+ // the most common case is that EliminatedLHSVals has a single number, we
+ // optimize for it: if there is more than one value, we merge them all into
+ // the lowest numbered one, then handle the interval as if we were merging
+ // with one value number.
+ unsigned LHSValNo;
+ if (EliminatedLHSVals.size() > 1) {
+ // Loop through all the equal value numbers merging them into the smallest
+ // one.
+ unsigned Smallest = EliminatedLHSVals[0];
+ for (unsigned i = 1, e = EliminatedLHSVals.size(); i != e; ++i) {
+ if (EliminatedLHSVals[i] < Smallest) {
+ // Merge the current notion of the smallest into the smaller one.
+ LHS.MergeValueNumberInto(Smallest, EliminatedLHSVals[i]);
+ Smallest = EliminatedLHSVals[i];
+ } else {
+ // Merge into the smallest.
+ LHS.MergeValueNumberInto(EliminatedLHSVals[i], Smallest);
+ }
+ }
+ LHSValNo = Smallest;
+ } else {
+ assert(!EliminatedLHSVals.empty() && "No copies from the RHS?");
+ LHSValNo = EliminatedLHSVals[0];
+ }
+
+ // Okay, now that there is a single LHS value number that we're merging the
+ // RHS into, update the value number info for the LHS to indicate that the
+ // value number is defined where the RHS value number was.
+ LHS.setValueNumberInfo(LHSValNo, RHS.getValNumInfo(0));
+
+ // Okay, the final step is to loop over the RHS live intervals, adding them to
+ // the LHS.
+ LHS.MergeRangesInAsValue(RHS, LHSValNo);
+ LHS.weight += RHS.weight;
+
+ return true;
+}
+
/// JoinIntervals - Attempt to join these two intervals. On failure, this
/// returns false. Otherwise, if one of the intervals being joined is a
/// physreg, this method always canonicalizes LHS to be it. The output
@@ -894,9 +1028,6 @@
SmallVector<int, 16> LHSValNoAssignments;
SmallVector<int, 16> RHSValNoAssignments;
SmallVector<std::pair<unsigned,unsigned>, 16> ValueNumberInfo;
- LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
- RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
- ValueNumberInfo.reserve(LHS.getNumValNums() + RHS.getNumValNums());
// Compute ultimate value numbers for the LHS and RHS values.
if (RHS.containsOneValue()) {
@@ -907,19 +1038,27 @@
// Find out if the RHS is defined as a copy from some value in the LHS.
int RHSValID = -1;
std::pair<unsigned,unsigned> RHSValNoInfo;
- if (unsigned RHSSrcReg = RHS.getSrcRegForValNum(0)) {
- if (rep(RHSSrcReg) != LHS.reg) {
- RHSValNoInfo = RHS.getValNumInfo(0);
+ unsigned RHSSrcReg = RHS.getSrcRegForValNum(0);
+ if ((RHSSrcReg == 0 || rep(RHSSrcReg) != LHS.reg)) {
+ // If RHS is not defined as a copy from the LHS, we can use simpler and
+ // faster checks to see if the live ranges are coallescable. This joiner
+ // can't swap the LHS/RHS intervals though.
+ if (!MRegisterInfo::isPhysicalRegister(RHS.reg)) {
+ return SimpleJoin(LHS, RHS);
} else {
- // It was defined as a copy from the LHS, find out what value # it is.
- unsigned ValInst = RHS.getInstForValNum(0);
- RHSValID = LHS.getLiveRangeContaining(ValInst-1)->ValId;
- RHSValNoInfo = LHS.getValNumInfo(RHSValID);
+ RHSValNoInfo = RHS.getValNumInfo(0);
}
+ ++A;
} else {
- RHSValNoInfo = RHS.getValNumInfo(0);
+ // It was defined as a copy from the LHS, find out what value # it is.
+ unsigned ValInst = RHS.getInstForValNum(0);
+ RHSValID = LHS.getLiveRangeContaining(ValInst-1)->ValId;
+ RHSValNoInfo = LHS.getValNumInfo(RHSValID);
+ ++B;
}
+ LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
+ RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
ValueNumberInfo.resize(LHS.getNumValNums());
// Okay, *all* of the values in LHS that are defined as a copy from RHS
@@ -954,6 +1093,7 @@
RHSValNoAssignments[0] = RHSValID;
} else {
+ ++D;
// Loop over the value numbers of the LHS, seeing if any are defined from
// the RHS.
SmallVector<int, 16> LHSValsDefinedFromRHS;
@@ -992,6 +1132,10 @@
RHSValsDefinedFromLHS[VN] = LHS.getLiveRangeContaining(ValInst-1)->ValId;
}
+ LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
+ RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
+ ValueNumberInfo.reserve(LHS.getNumValNums() + RHS.getNumValNums());
+
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
if (LHSValNoAssignments[VN] >= 0 || LHS.getInstForValNum(VN) == ~2U)
continue;
More information about the llvm-commits
mailing list