+/// 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
+/// "RHS" will not have been modified, so we can use this information
+/// below to update aliases.
+bool LiveIntervals::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS) {
+ // Compute the final value assignment, assuming that the live ranges can be
+ // coallesced.
+ SmallVector<int, 16> LHSValNoAssignments;
+ SmallVector<int, 16> RHSValNoAssignments;
+ SmallVector<std::pair<unsigned,unsigned>, 16> ValueNumberInfo;
+
+ // Compute ultimate value numbers for the LHS and RHS values.
+ if (RHS.containsOneValue()) {
+ // Copies from a liveinterval with a single value are simple to handle and
+ // very common, handle the special case here. This is important, because
+ // often RHS is small and LHS is large (e.g. a physreg).
+
+ // Find out if the RHS is defined as a copy from some value in the LHS.
+ int RHSValID = -1;
+ std::pair<unsigned,unsigned> RHSValNoInfo;
+ 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 {
+ RHSValNoInfo = RHS.getValNumInfo(0);
+ }
+ } 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);
+ }
+
+ 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
+ // should now get updated.
+ for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
+ if (unsigned LHSSrcReg = LHS.getSrcRegForValNum(VN)) {
+ if (rep(LHSSrcReg) != RHS.reg) {
+ // If this is not a copy from the RHS, its value number will be
+ // unmodified by the coallescing.
+ ValueNumberInfo[VN] = LHS.getValNumInfo(VN);
+ LHSValNoAssignments[VN] = VN;
+ } else if (RHSValID == -1) {
+ // Otherwise, it is a copy from the RHS, and we don't already have a
+ // value# for it. Keep the current value number, but remember it.
+ LHSValNoAssignments[VN] = RHSValID = VN;
+ ValueNumberInfo[VN] = RHSValNoInfo;
+ } else {
+ // Otherwise, use the specified value #.
+ LHSValNoAssignments[VN] = RHSValID;
+ if (VN != (unsigned)RHSValID)
+ ValueNumberInfo[VN].first = ~1U;
+ else
+ ValueNumberInfo[VN] = RHSValNoInfo;
+ }
+ } else {
+ ValueNumberInfo[VN] = LHS.getValNumInfo(VN);
+ LHSValNoAssignments[VN] = VN;
+ }
+ }
+
+ assert(RHSValID != -1 && "Didn't find value #?");
+ RHSValNoAssignments[0] = RHSValID;
+
+ } else {
+ // Loop over the value numbers of the LHS, seeing if any are defined from
+ // the RHS.
+ SmallVector<int, 16> LHSValsDefinedFromRHS;
+ LHSValsDefinedFromRHS.resize(LHS.getNumValNums(), -1);
+ for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
+ unsigned ValSrcReg = LHS.getSrcRegForValNum(VN);
+ if (ValSrcReg == 0) // Src not defined by a copy?
+ continue;
+
+ // DstReg is known to be a register in the LHS interval. If the src is
+ // from the RHS interval, we can use its value #.
+ if (rep(ValSrcReg) != RHS.reg)
+ continue;
+
+ // Figure out the value # from the RHS.
+ unsigned ValInst = LHS.getInstForValNum(VN);
+ LHSValsDefinedFromRHS[VN] = RHS.getLiveRangeContaining(ValInst-1)->ValId;
+ }
+
+ // Loop over the value numbers of the RHS, seeing if any are defined from
+ // the LHS.
+ SmallVector<int, 16> RHSValsDefinedFromLHS;
+ RHSValsDefinedFromLHS.resize(RHS.getNumValNums(), -1);
+ for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
+ unsigned ValSrcReg = RHS.getSrcRegForValNum(VN);
+ if (ValSrcReg == 0) // Src not defined by a copy?
+ continue;
+
+ // DstReg is known to be a register in the RHS interval. If the src is
+ // from the LHS interval, we can use its value #.
+ if (rep(ValSrcReg) != LHS.reg)
+ continue;
+
+ // Figure out the value # from the LHS.
+ unsigned ValInst = RHS.getInstForValNum(VN);
+ 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;
+ ComputeUltimateVN(VN, ValueNumberInfo,
+ LHSValsDefinedFromRHS, RHSValsDefinedFromLHS,
+ LHSValNoAssignments, RHSValNoAssignments, LHS, RHS);
+ }
+ for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
+ if (RHSValNoAssignments[VN] >= 0 || RHS.getInstForValNum(VN) == ~2U)
+ continue;
+ // If this value number isn't a copy from the LHS, it's a new number.
+ if (RHSValsDefinedFromLHS[VN] == -1) {
+ ValueNumberInfo.push_back(RHS.getValNumInfo(VN));
+ RHSValNoAssignments[VN] = ValueNumberInfo.size()-1;
+ continue;
+ }
+
+ ComputeUltimateVN(VN, ValueNumberInfo,
+ RHSValsDefinedFromLHS, LHSValsDefinedFromRHS,
+ RHSValNoAssignments, LHSValNoAssignments, RHS, LHS);
+ }
+ }
+
+ // Armed with the mappings of LHS/RHS values to ultimate values, walk the
+ // interval lists to see if these intervals are coallescable.
+ LiveInterval::const_iterator I = LHS.begin();
+ LiveInterval::const_iterator IE = LHS.end();
+ LiveInterval::const_iterator J = RHS.begin();
+ LiveInterval::const_iterator JE = RHS.end();
+
+ // Skip ahead until the first place of potential sharing.
+ if (I->start < J->start) {
+ I = std::upper_bound(I, IE, J->start);
+ if (I != LHS.begin()) --I;
+ } else if (J->start < I->start) {
+ J = std::upper_bound(J, JE, I->start);
+ if (J != RHS.begin()) --J;
+ }
+
+ while (1) {
+ // Determine if these two live ranges overlap.
+ bool Overlaps;
+ if (I->start < J->start) {
+ Overlaps = I->end > J->start;
+ } else {
+ Overlaps = J->end > I->start;
+ }
+
+ // If so, check value # info to determine if they are really different.
+ if (Overlaps) {
+ // If the live range overlap will map to the same value number in the
+ // result liverange, we can still coallesce them. If not, we can't.
+ if (LHSValNoAssignments[I->ValId] != RHSValNoAssignments[J->ValId])
+ return false;
+ }
+
+ if (I->end < J->end) {
+ ++I;
+ if (I == IE) break;
+ } else {
+ ++J;
+ if (J == JE) break;
+ }
+ }
+
+ // If we get here, we know that we can coallesce the live ranges. Ask the
+ // intervals to coallesce themselves now.
+ LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0],
+ ValueNumberInfo);
+ return true;
+}
+
+