示例#1
0
// Merge a LiveInterval's segments. Guarantee no overlaps.
void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) {
  if (Range.empty())
    return;
  ++Tag;

  // Insert each of the virtual register's live segments into the map.
  LiveRange::const_iterator RegPos = Range.begin();
  LiveRange::const_iterator RegEnd = Range.end();
  SegmentIter SegPos = Segments.find(RegPos->start);

  while (SegPos.valid()) {
    SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
    if (++RegPos == RegEnd)
      return;
    SegPos.advanceTo(RegPos->start);
  }

  // We have reached the end of Segments, so it is no longer necessary to search
  // for the insertion position.
  // It is faster to insert the end first.
  --RegEnd;
  SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg);
  for (; RegPos != RegEnd; ++RegPos, ++SegPos)
    SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
}
/// MergeValueInAsValue - Merge all of the live segments of a specific val#
/// in RHS into this live range as the specified value number.
/// The segments in RHS are allowed to overlap with segments in the
/// current range, it will replace the value numbers of the overlaped
/// segments with the specified value number.
void LiveRange::MergeValueInAsValue(const LiveRange &RHS,
                                    const VNInfo *RHSValNo,
                                    VNInfo *LHSValNo) {
  LiveRangeUpdater Updater(this);
  for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
    if (I->valno == RHSValNo)
      Updater.add(I->start, I->end, LHSValNo);
}
// overlaps - Return true if the intersection of the two live ranges is
// not empty.
//
// An example for overlaps():
//
// 0: A = ...
// 4: B = ...
// 8: C = A + B ;; last use of A
//
// The live ranges should look like:
//
// A = [3, 11)
// B = [7, x)
// C = [11, y)
//
// A->overlaps(C) should return false since we want to be able to join
// A and C.
//
bool LiveRange::overlapsFrom(const LiveRange& other,
                             const_iterator StartPos) const {
  assert(!empty() && "empty range");
  const_iterator i = begin();
  const_iterator ie = end();
  const_iterator j = StartPos;
  const_iterator je = other.end();

  assert((StartPos->start <= i->start || StartPos == other.begin()) &&
         StartPos != other.end() && "Bogus start position hint!");

  if (i->start < j->start) {
    i = std::upper_bound(i, ie, j->start);
    if (i != begin()) --i;
  } else if (j->start < i->start) {
    ++StartPos;
    if (StartPos != other.end() && StartPos->start <= i->start) {
      assert(StartPos < other.end() && i < end());
      j = std::upper_bound(j, je, i->start);
      if (j != other.begin()) --j;
    }
  } else {
    return true;
  }

  if (j == je) return false;

  while (i != ie) {
    if (i->start > j->start) {
      std::swap(i, j);
      std::swap(ie, je);
    }

    if (i->end > j->start)
      return true;
    ++i;
  }

  return false;
}
bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP,
                         const SlotIndexes &Indexes) const {
  assert(!empty() && "empty range");
  if (Other.empty())
    return false;

  // Use binary searches to find initial positions.
  const_iterator I = find(Other.beginIndex());
  const_iterator IE = end();
  if (I == IE)
    return false;
  const_iterator J = Other.find(I->start);
  const_iterator JE = Other.end();
  if (J == JE)
    return false;

  for (;;) {
    // J has just been advanced to satisfy:
    assert(J->end >= I->start);
    // Check for an overlap.
    if (J->start < I->end) {
      // I and J are overlapping. Find the later start.
      SlotIndex Def = std::max(I->start, J->start);
      // Allow the overlap if Def is a coalescable copy.
      if (Def.isBlock() ||
          !CP.isCoalescable(Indexes.getInstructionFromIndex(Def)))
        return true;
    }
    // Advance the iterator that ends first to check for more overlaps.
    if (J->end > I->end) {
      std::swap(I, J);
      std::swap(IE, JE);
    }
    // Advance J until J->end >= I->start.
    do
      if (++J == JE)
        return false;
    while (J->end < I->start);
  }
}
示例#5
0
// Remove a live virtual register's segments from this union.
void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) {
  if (Range.empty())
    return;
  ++Tag;

  // Remove each of the virtual register's live segments from the map.
  LiveRange::const_iterator RegPos = Range.begin();
  LiveRange::const_iterator RegEnd = Range.end();
  SegmentIter SegPos = Segments.find(RegPos->start);

  while (true) {
    assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval");
    SegPos.erase();
    if (!SegPos.valid())
      return;

    // Skip all segments that may have been coalesced.
    RegPos = Range.advanceTo(RegPos, SegPos.start());
    if (RegPos == RegEnd)
      return;

    SegPos.advanceTo(RegPos->start);
  }
}
/// Merge all of the segments in RHS into this live range as the specified
/// value number.  The segments in RHS are allowed to overlap with segments in
/// the current range, but only if the overlapping segments have the
/// specified value number.
void LiveRange::MergeSegmentsInAsValue(const LiveRange &RHS,
                                       VNInfo *LHSValNo) {
  LiveRangeUpdater Updater(this);
  for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
    Updater.add(I->start, I->end, LHSValNo);
}
void LiveRange::join(LiveRange &Other,
                     const int *LHSValNoAssignments,
                     const int *RHSValNoAssignments,
                     SmallVectorImpl<VNInfo *> &NewVNInfo) {
  verify();

  // Determine if any of our values are mapped.  This is uncommon, so we want
  // to avoid the range scan if not.
  bool MustMapCurValNos = false;
  unsigned NumVals = getNumValNums();
  unsigned NumNewVals = NewVNInfo.size();
  for (unsigned i = 0; i != NumVals; ++i) {
    unsigned LHSValID = LHSValNoAssignments[i];
    if (i != LHSValID ||
        (NewVNInfo[LHSValID] && NewVNInfo[LHSValID] != getValNumInfo(i))) {
      MustMapCurValNos = true;
      break;
    }
  }

  // If we have to apply a mapping to our base range assignment, rewrite it now.
  if (MustMapCurValNos && !empty()) {
    // Map the first live range.

    iterator OutIt = begin();
    OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]];
    for (iterator I = std::next(OutIt), E = end(); I != E; ++I) {
      VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]];
      assert(nextValNo != 0 && "Huh?");

      // If this live range has the same value # as its immediate predecessor,
      // and if they are neighbors, remove one Segment.  This happens when we
      // have [0,4:0)[4,7:1) and map 0/1 onto the same value #.
      if (OutIt->valno == nextValNo && OutIt->end == I->start) {
        OutIt->end = I->end;
      } else {
        // Didn't merge. Move OutIt to the next segment,
        ++OutIt;
        OutIt->valno = nextValNo;
        if (OutIt != I) {
          OutIt->start = I->start;
          OutIt->end = I->end;
        }
      }
    }
    // If we merge some segments, chop off the end.
    ++OutIt;
    segments.erase(OutIt, end());
  }

  // Rewrite Other values before changing the VNInfo ids.
  // This can leave Other in an invalid state because we're not coalescing
  // touching segments that now have identical values. That's OK since Other is
  // not supposed to be valid after calling join();
  for (iterator I = Other.begin(), E = Other.end(); I != E; ++I)
    I->valno = NewVNInfo[RHSValNoAssignments[I->valno->id]];

  // Update val# info. Renumber them and make sure they all belong to this
  // LiveRange now. Also remove dead val#'s.
  unsigned NumValNos = 0;
  for (unsigned i = 0; i < NumNewVals; ++i) {
    VNInfo *VNI = NewVNInfo[i];
    if (VNI) {
      if (NumValNos >= NumVals)
        valnos.push_back(VNI);
      else
        valnos[NumValNos] = VNI;
      VNI->id = NumValNos++;  // Renumber val#.
    }
  }
  if (NumNewVals < NumVals)
    valnos.resize(NumNewVals);  // shrinkify

  // Okay, now insert the RHS live segments into the LHS.
  LiveRangeUpdater Updater(this);
  for (iterator I = Other.begin(), E = Other.end(); I != E; ++I)
    Updater.add(*I);
}
示例#8
0
bool LiveRangeCalc::isDefOnEntry(LiveRange &LR, ArrayRef<SlotIndex> Undefs,
                                 MachineBasicBlock &MBB, BitVector &DefOnEntry,
                                 BitVector &UndefOnEntry) {
  unsigned BN = MBB.getNumber();
  if (DefOnEntry[BN])
    return true;
  if (UndefOnEntry[BN])
    return false;

  auto MarkDefined = [BN, &DefOnEntry](MachineBasicBlock &B) -> bool {
    for (MachineBasicBlock *S : B.successors())
      DefOnEntry[S->getNumber()] = true;
    DefOnEntry[BN] = true;
    return true;
  };

  SetVector<unsigned> WorkList;
  // Checking if the entry of MBB is reached by some def: add all predecessors
  // that are potentially defined-on-exit to the work list.
  for (MachineBasicBlock *P : MBB.predecessors())
    WorkList.insert(P->getNumber());

  for (unsigned i = 0; i != WorkList.size(); ++i) {
    // Determine if the exit from the block is reached by some def.
    unsigned N = WorkList[i];
    MachineBasicBlock &B = *MF->getBlockNumbered(N);
    if (Seen[N]) {
      const LiveOutPair &LOB = Map[&B];
      if (LOB.first != nullptr && LOB.first != &UndefVNI)
        return MarkDefined(B);
    }
    SlotIndex Begin, End;
    std::tie(Begin, End) = Indexes->getMBBRange(&B);
    // Treat End as not belonging to B.
    // If LR has a segment S that starts at the next block, i.e. [End, ...),
    // std::upper_bound will return the segment following S. Instead,
    // S should be treated as the first segment that does not overlap B.
    LiveRange::iterator UB = std::upper_bound(LR.begin(), LR.end(),
                                              End.getPrevSlot());
    if (UB != LR.begin()) {
      LiveRange::Segment &Seg = *std::prev(UB);
      if (Seg.end > Begin) {
        // There is a segment that overlaps B. If the range is not explicitly
        // undefined between the end of the segment and the end of the block,
        // treat the block as defined on exit. If it is, go to the next block
        // on the work list.
        if (LR.isUndefIn(Undefs, Seg.end, End))
          continue;
        return MarkDefined(B);
      }
    }

    // No segment overlaps with this block. If this block is not defined on
    // entry, or it undefines the range, do not process its predecessors.
    if (UndefOnEntry[N] || LR.isUndefIn(Undefs, Begin, End)) {
      UndefOnEntry[N] = true;
      continue;
    }
    if (DefOnEntry[N])
      return MarkDefined(B);

    // Still don't know: add all predecessors to the work list.
    for (MachineBasicBlock *P : B.predecessors())
      WorkList.insert(P->getNumber());
  }

  UndefOnEntry[BN] = true;
  return false;
}
/// shrinkToUses - After removing some uses of a register, shrink its live
/// range to just the remaining uses. This method does not compute reaching
/// defs for new uses, and it doesn't remove dead defs.
bool LiveIntervals::shrinkToUses(LiveInterval *li,
                                 SmallVectorImpl<MachineInstr*> *dead) {
    DEBUG(dbgs() << "Shrink: " << *li << '\n');
    assert(TargetRegisterInfo::isVirtualRegister(li->reg)
           && "Can only shrink virtual registers");
    // Find all the values used, including PHI kills.
    SmallVector<std::pair<SlotIndex, VNInfo*>, 16> WorkList;

    // Blocks that have already been added to WorkList as live-out.
    SmallPtrSet<MachineBasicBlock*, 16> LiveOut;

    // Visit all instructions reading li->reg.
    for (MachineRegisterInfo::reg_instr_iterator
            I = MRI->reg_instr_begin(li->reg), E = MRI->reg_instr_end();
            I != E; ) {
        MachineInstr *UseMI = &*(I++);
        if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg))
            continue;
        SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
        LiveQueryResult LRQ = li->Query(Idx);
        VNInfo *VNI = LRQ.valueIn();
        if (!VNI) {
            // This shouldn't happen: readsVirtualRegister returns true, but there is
            // no live value. It is likely caused by a target getting <undef> flags
            // wrong.
            DEBUG(dbgs() << Idx << '\t' << *UseMI
                  << "Warning: Instr claims to read non-existent value in "
                  << *li << '\n');
            continue;
        }
        // Special case: An early-clobber tied operand reads and writes the
        // register one slot early.
        if (VNInfo *DefVNI = LRQ.valueDefined())
            Idx = DefVNI->def;

        WorkList.push_back(std::make_pair(Idx, VNI));
    }

    // Create new live ranges with only minimal live segments per def.
    LiveRange NewLR;
    for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
            I != E; ++I) {
        VNInfo *VNI = *I;
        if (VNI->isUnused())
            continue;
        NewLR.addSegment(LiveRange::Segment(VNI->def, VNI->def.getDeadSlot(), VNI));
    }

    // Keep track of the PHIs that are in use.
    SmallPtrSet<VNInfo*, 8> UsedPHIs;

    // Extend intervals to reach all uses in WorkList.
    while (!WorkList.empty()) {
        SlotIndex Idx = WorkList.back().first;
        VNInfo *VNI = WorkList.back().second;
        WorkList.pop_back();
        const MachineBasicBlock *MBB = getMBBFromIndex(Idx.getPrevSlot());
        SlotIndex BlockStart = getMBBStartIdx(MBB);

        // Extend the live range for VNI to be live at Idx.
        if (VNInfo *ExtVNI = NewLR.extendInBlock(BlockStart, Idx)) {
            (void)ExtVNI;
            assert(ExtVNI == VNI && "Unexpected existing value number");
            // Is this a PHIDef we haven't seen before?
            if (!VNI->isPHIDef() || VNI->def != BlockStart || !UsedPHIs.insert(VNI))
                continue;
            // The PHI is live, make sure the predecessors are live-out.
            for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
                    PE = MBB->pred_end(); PI != PE; ++PI) {
                if (!LiveOut.insert(*PI))
                    continue;
                SlotIndex Stop = getMBBEndIdx(*PI);
                // A predecessor is not required to have a live-out value for a PHI.
                if (VNInfo *PVNI = li->getVNInfoBefore(Stop))
                    WorkList.push_back(std::make_pair(Stop, PVNI));
            }
            continue;
        }

        // VNI is live-in to MBB.
        DEBUG(dbgs() << " live-in at " << BlockStart << '\n');
        NewLR.addSegment(LiveRange::Segment(BlockStart, Idx, VNI));

        // Make sure VNI is live-out from the predecessors.
        for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
                PE = MBB->pred_end(); PI != PE; ++PI) {
            if (!LiveOut.insert(*PI))
                continue;
            SlotIndex Stop = getMBBEndIdx(*PI);
            assert(li->getVNInfoBefore(Stop) == VNI &&
                   "Wrong value out of predecessor");
            WorkList.push_back(std::make_pair(Stop, VNI));
        }
    }

    // Handle dead values.
    bool CanSeparate = false;
    for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end();
            I != E; ++I) {
        VNInfo *VNI = *I;
        if (VNI->isUnused())
            continue;
        LiveRange::iterator LRI = NewLR.FindSegmentContaining(VNI->def);
        assert(LRI != NewLR.end() && "Missing segment for PHI");
        if (LRI->end != VNI->def.getDeadSlot())
            continue;
        if (VNI->isPHIDef()) {
            // This is a dead PHI. Remove it.
            VNI->markUnused();
            NewLR.removeSegment(LRI->start, LRI->end);
            DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
            CanSeparate = true;
        } else {
            // This is a dead def. Make sure the instruction knows.
            MachineInstr *MI = getInstructionFromIndex(VNI->def);
            assert(MI && "No instruction defining live value");
            MI->addRegisterDead(li->reg, TRI);
            if (dead && MI->allDefsAreDead()) {
                DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI);
                dead->push_back(MI);
            }
        }
    }

    // Move the trimmed segments back.
    li->segments.swap(NewLR.segments);
    DEBUG(dbgs() << "Shrunk: " << *li << '\n');
    return CanSeparate;
}
示例#10
0
void InterferenceCache::Entry::update(unsigned MBBNum) {
  SlotIndex Start, Stop;
  tie(Start, Stop) = Indexes->getMBBRange(MBBNum);

  // Use advanceTo only when possible.
  if (PrevPos != Start) {
    if (!PrevPos.isValid() || Start < PrevPos) {
      for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
        RegUnitInfo &RUI = RegUnits[i];
        RUI.VirtI.find(Start);
        RUI.FixedI = RUI.Fixed->find(Start);
      }
    } else {
      for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
        RegUnitInfo &RUI = RegUnits[i];
        RUI.VirtI.advanceTo(Start);
        if (RUI.FixedI != RUI.Fixed->end())
          RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start);
      }
    }
    PrevPos = Start;
  }

  MachineFunction::const_iterator MFI = MF->getBlockNumbered(MBBNum);
  BlockInterference *BI = &Blocks[MBBNum];
  ArrayRef<SlotIndex> RegMaskSlots;
  ArrayRef<const uint32_t*> RegMaskBits;
  for (;;) {
    BI->Tag = Tag;
    BI->First = BI->Last = SlotIndex();

    // Check for first interference from virtregs.
    for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
      LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
      if (!I.valid())
        continue;
      SlotIndex StartI = I.start();
      if (StartI >= Stop)
        continue;
      if (!BI->First.isValid() || StartI < BI->First)
        BI->First = StartI;
    }

    // Same thing for fixed interference.
    for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
      LiveInterval::const_iterator I = RegUnits[i].FixedI;
      LiveInterval::const_iterator E = RegUnits[i].Fixed->end();
      if (I == E)
        continue;
      SlotIndex StartI = I->start;
      if (StartI >= Stop)
        continue;
      if (!BI->First.isValid() || StartI < BI->First)
        BI->First = StartI;
    }

    // Also check for register mask interference.
    RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum);
    RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum);
    SlotIndex Limit = BI->First.isValid() ? BI->First : Stop;
    for (unsigned i = 0, e = RegMaskSlots.size();
         i != e && RegMaskSlots[i] < Limit; ++i)
      if (MachineOperand::clobbersPhysReg(RegMaskBits[i], PhysReg)) {
        // Register mask i clobbers PhysReg before the LIU interference.
        BI->First = RegMaskSlots[i];
        break;
      }

    PrevPos = Stop;
    if (BI->First.isValid())
      break;

    // No interference in this block? Go ahead and precompute the next block.
    if (++MFI == MF->end())
      return;
    MBBNum = MFI->getNumber();
    BI = &Blocks[MBBNum];
    if (BI->Tag == Tag)
      return;
    tie(Start, Stop) = Indexes->getMBBRange(MBBNum);
  }

  // Check for last interference in block.
  for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
    LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
    if (!I.valid() || I.start() >= Stop)
      continue;
    I.advanceTo(Stop);
    bool Backup = !I.valid() || I.start() >= Stop;
    if (Backup)
      --I;
    SlotIndex StopI = I.stop();
    if (!BI->Last.isValid() || StopI > BI->Last)
      BI->Last = StopI;
    if (Backup)
      ++I;
  }

  // Fixed interference.
  for (unsigned i = 0, e = RegUnits.size(); i != e; ++i) {
    LiveInterval::iterator &I = RegUnits[i].FixedI;
    LiveRange *LR = RegUnits[i].Fixed;
    if (I == LR->end() || I->start >= Stop)
      continue;
    I = LR->advanceTo(I, Stop);
    bool Backup = I == LR->end() || I->start >= Stop;
    if (Backup)
      --I;
    SlotIndex StopI = I->end;
    if (!BI->Last.isValid() || StopI > BI->Last)
      BI->Last = StopI;
    if (Backup)
      ++I;
  }

  // Also check for register mask interference.
  SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start;
  for (unsigned i = RegMaskSlots.size();
       i && RegMaskSlots[i-1].getDeadSlot() > Limit; --i)
    if (MachineOperand::clobbersPhysReg(RegMaskBits[i-1], PhysReg)) {
      // Register mask i-1 clobbers PhysReg after the LIU interference.
      // Model the regmask clobber as a dead def.
      BI->Last = RegMaskSlots[i-1].getDeadSlot();
      break;
    }
}