Skip to content
LiveIntervalAnalysis.cpp 53.6 KiB
Newer Older
  // 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
/// "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);
      // 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],
namespace {
  // DepthMBBCompare - Comparison predicate that sort first based on the loop
  // depth of the basic block (the unsigned), and then on the MBB number.
  struct DepthMBBCompare {
    typedef std::pair<unsigned, MachineBasicBlock*> DepthMBBPair;
    bool operator()(const DepthMBBPair &LHS, const DepthMBBPair &RHS) const {
      if (LHS.first > RHS.first) return true;   // Deeper loops first
Alkis Evlogimenos's avatar
Alkis Evlogimenos committed
      return LHS.first == RHS.first &&
        LHS.second->getNumber() < RHS.second->getNumber();
void LiveIntervals::CopyCoallesceInMBB(MachineBasicBlock *MBB,
                                       std::vector<CopyRec> &TryAgain) {
  DOUT << ((Value*)MBB->getBasicBlock())->getName() << ":\n";
  
  for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
       MII != E;) {
    MachineInstr *Inst = MII++;
    
    // If this isn't a copy, we can't join intervals.
    unsigned SrcReg, DstReg;
    if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg)) continue;
    
    if (!JoinCopy(Inst, SrcReg, DstReg))
      TryAgain.push_back(getCopyRec(Inst, SrcReg, DstReg));
void LiveIntervals::joinIntervals() {
  DOUT << "********** JOINING INTERVALS ***********\n";
  const LoopInfo &LI = getAnalysis<LoopInfo>();
  if (LI.begin() == LI.end()) {
    // If there are no loops in the function, join intervals in function order.
    for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
         I != E; ++I)
      CopyCoallesceInMBB(I, TryAgainList);
  } else {
    // Otherwise, join intervals in inner loops before other intervals.
    // Unfortunately we can't just iterate over loop hierarchy here because
    // there may be more MBB's than BB's.  Collect MBB's for sorting.
    std::vector<std::pair<unsigned, MachineBasicBlock*> > MBBs;
    for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
         I != E; ++I)
      MBBs.push_back(std::make_pair(LI.getLoopDepth(I->getBasicBlock()), I));

    // Sort by loop depth.
    std::sort(MBBs.begin(), MBBs.end(), DepthMBBCompare());

Alkis Evlogimenos's avatar
Alkis Evlogimenos committed
    // Finally, join intervals in loop nest order.
    for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
      CopyCoallesceInMBB(MBBs[i].second, TryAgainList);
  }
  
  // Joining intervals can allow other intervals to be joined.  Iteratively join
  // until we make no progress.
  bool ProgressMade = true;
  while (ProgressMade) {
    ProgressMade = false;

    for (unsigned i = 0, e = TryAgainList.size(); i != e; ++i) {
      CopyRec &TheCopy = TryAgainList[i];
      if (TheCopy.MI &&
          JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg)) {
        TheCopy.MI = 0;   // Mark this one as done.
        ProgressMade = true;
      }
    }
  DOUT << "*** Register mapping ***\n";
  for (int i = 0, e = r2rMap_.size(); i != e; ++i)
    if (r2rMap_[i]) {
      DOUT << "  reg " << i << " -> ";
      DEBUG(printRegName(r2rMap_[i]));
      DOUT << "\n";
    }
/// Return true if the two specified registers belong to different register
/// classes.  The registers may be either phys or virt regs.
bool LiveIntervals::differingRegisterClasses(unsigned RegA,
                                             unsigned RegB) const {

  // Get the register classes for the first reg.
  if (MRegisterInfo::isPhysicalRegister(RegA)) {
    assert(MRegisterInfo::isVirtualRegister(RegB) &&
           "Shouldn't consider two physregs!");
    return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);

  // Compare against the regclass for the second reg.
  const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA);
  if (MRegisterInfo::isVirtualRegister(RegB))
    return RegClass != mf_->getSSARegMap()->getRegClass(RegB);
  else
    return !RegClass->contains(RegB);
LiveInterval LiveIntervals::createInterval(unsigned reg) {
  float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
                       HUGE_VALF : 0.0F;