Ejemplo n.º 1
0
void
UserValue::computeIntervals(MachineRegisterInfo &MRI,
                            const TargetRegisterInfo &TRI,
                            LiveIntervals &LIS,
                            MachineDominatorTree &MDT,
                            UserValueScopes &UVS) {
  SmallVector<std::pair<SlotIndex, unsigned>, 16> Defs;

  // Collect all defs to be extended (Skipping undefs).
  for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I)
    if (I.value() != ~0u)
      Defs.push_back(std::make_pair(I.start(), I.value()));

  // Extend all defs, and possibly add new ones along the way.
  for (unsigned i = 0; i != Defs.size(); ++i) {
    SlotIndex Idx = Defs[i].first;
    unsigned LocNo = Defs[i].second;
    const MachineOperand &Loc = locations[LocNo];

    if (!Loc.isReg()) {
      extendDef(Idx, LocNo, nullptr, nullptr, nullptr, LIS, MDT, UVS);
      continue;
    }

    // Register locations are constrained to where the register value is live.
    if (TargetRegisterInfo::isVirtualRegister(Loc.getReg())) {
      LiveInterval *LI = nullptr;
      const VNInfo *VNI = nullptr;
      if (LIS.hasInterval(Loc.getReg())) {
        LI = &LIS.getInterval(Loc.getReg());
        VNI = LI->getVNInfoAt(Idx);
      }
      SmallVector<SlotIndex, 16> Kills;
      extendDef(Idx, LocNo, LI, VNI, &Kills, LIS, MDT, UVS);
      if (LI)
        addDefsFromCopies(LI, LocNo, Kills, Defs, MRI, LIS);
      continue;
    }

    // For physregs, use the live range of the first regunit as a guide.
    unsigned Unit = *MCRegUnitIterator(Loc.getReg(), &TRI);
    LiveRange *LR = &LIS.getRegUnit(Unit);
    const VNInfo *VNI = LR->getVNInfoAt(Idx);
    // Don't track copies from physregs, it is too expensive.
    extendDef(Idx, LocNo, LR, VNI, nullptr, LIS, MDT, UVS);
  }

  // Finally, erase all the undefs.
  for (LocMap::iterator I = locInts.begin(); I.valid();)
    if (I.value() == ~0u)
      I.erase();
    else
      ++I;
}
Ejemplo n.º 2
0
/// 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,
                                        VNInfo *LHSValNo) {
    // TODO: Make this more efficient.
    iterator InsertPos = begin();
    for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) {
        // Map the valno in the other live range to the current live range.
        LiveRange Tmp = *I;
        Tmp.valno = LHSValNo;
        InsertPos = addRangeFrom(Tmp, InsertPos);
    }
}
Ejemplo n.º 3
0
/// MergeValueInAsValue - Merge all of the live ranges of a specific val#
/// 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, it will replace the value numbers of the overlaped
/// live ranges with the specified value number.
void LiveInterval::MergeValueInAsValue(
                                    const LiveInterval &RHS,
                                    const VNInfo *RHSValNo, VNInfo *LHSValNo) {
  SmallVector<VNInfo*, 4> ReplacedValNos;
  iterator IP = begin();
  for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) {
    assert(I->valno == RHS.getValNumInfo(I->valno->id) && "Bad VNInfo");
    if (I->valno != RHSValNo)
      continue;
    SlotIndex Start = I->start, End = I->end;
    IP = std::upper_bound(IP, end(), Start);
    // If the start of this range overlaps with an existing liverange, trim it.
    if (IP != begin() && IP[-1].end > Start) {
      if (IP[-1].valno != LHSValNo) {
        ReplacedValNos.push_back(IP[-1].valno);
        IP[-1].valno = LHSValNo; // Update val#.
      }
      Start = IP[-1].end;
      // Trimmed away the whole range?
      if (Start >= End) continue;
    }
    // If the end of this range overlaps with an existing liverange, trim it.
    if (IP != end() && End > IP->start) {
      if (IP->valno != LHSValNo) {
        ReplacedValNos.push_back(IP->valno);
        IP->valno = LHSValNo;  // Update val#.
      }
      End = IP->start;
      // If this trimmed away the whole range, ignore it.
      if (Start == End) continue;
    }

    // Map the valno in the other live range to the current live range.
    IP = addRangeFrom(LiveRange(Start, End, LHSValNo), IP);
  }


  SmallSet<VNInfo*, 4> Seen;
  for (unsigned i = 0, e = ReplacedValNos.size(); i != e; ++i) {
    VNInfo *V1 = ReplacedValNos[i];
    if (Seen.insert(V1)) {
      bool isDead = true;
      for (const_iterator I = begin(), E = end(); I != E; ++I)
        if (I->valno == V1) {
          isDead = false;
          break;
        }
      if (isDead) {
        // Now that V1 is dead, remove it.
        markValNoForDeletion(V1);
      }
    }
  }
}
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
        BitVector &UsableRegs) {
    if (LI.empty())
        return false;
    LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end();

    // Use a smaller arrays for local live ranges.
    ArrayRef<SlotIndex> Slots;
    ArrayRef<const uint32_t*> Bits;
    if (MachineBasicBlock *MBB = intervalIsInOneMBB(LI)) {
        Slots = getRegMaskSlotsInBlock(MBB->getNumber());
        Bits = getRegMaskBitsInBlock(MBB->getNumber());
    } else {
        Slots = getRegMaskSlots();
        Bits = getRegMaskBits();
    }

    // We are going to enumerate all the register mask slots contained in LI.
    // Start with a binary search of RegMaskSlots to find a starting point.
    ArrayRef<SlotIndex>::iterator SlotI =
        std::lower_bound(Slots.begin(), Slots.end(), LiveI->start);
    ArrayRef<SlotIndex>::iterator SlotE = Slots.end();

    // No slots in range, LI begins after the last call.
    if (SlotI == SlotE)
        return false;

    bool Found = false;
    for (;;) {
        assert(*SlotI >= LiveI->start);
        // Loop over all slots overlapping this segment.
        while (*SlotI < LiveI->end) {
            // *SlotI overlaps LI. Collect mask bits.
            if (!Found) {
                // This is the first overlap. Initialize UsableRegs to all ones.
                UsableRegs.clear();
                UsableRegs.resize(TRI->getNumRegs(), true);
                Found = true;
            }
            // Remove usable registers clobbered by this mask.
            UsableRegs.clearBitsNotInMask(Bits[SlotI-Slots.begin()]);
            if (++SlotI == SlotE)
                return Found;
        }
        // *SlotI is beyond the current LI segment.
        LiveI = LI.advanceTo(LiveI, *SlotI);
        if (LiveI == LiveE)
            return Found;
        // Advance SlotI until it overlaps.
        while (*SlotI < LiveI->start)
            if (++SlotI == SlotE)
                return Found;
    }
}
Ejemplo n.º 5
0
bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
                                             unsigned PhysReg) {
  if (VirtReg.empty())
    return false;
  CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);
  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
    const LiveRange &UnitRange = LIS->getRegUnit(*Units);
    if (VirtReg.overlaps(UnitRange, CP, *LIS->getSlotIndexes()))
      return true;
  }
  return false;
}
Ejemplo n.º 6
0
bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) {
  for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) {
    LiveRange::Segment &LR = *I;
    // Range must start at a register...
    if (!LR.start.isRegister())
      return false;
    // ...and end in a register or in a dead slot.
    if (!LR.end.isRegister() && !LR.end.isDead())
      return false;
  }
  return true;
}
Ejemplo n.º 7
0
/// insertSpill - Insert a spill of NewLI.reg after MI.
void InlineSpiller::insertSpill(LiveInterval &NewLI, const LiveInterval &OldLI,
                                SlotIndex Idx, MachineBasicBlock::iterator MI) {
  MachineBasicBlock &MBB = *MI->getParent();
  TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot,
                          MRI.getRegClass(NewLI.reg), &TRI);
  --MI; // Point to store instruction.
  SlotIndex StoreIdx = LIS.InsertMachineInstrInMaps(MI).getRegSlot();
  DEBUG(dbgs() << "\tspilled: " << StoreIdx << '\t' << *MI);
  VNInfo *StoreVNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator());
  NewLI.addRange(LiveRange(Idx, StoreIdx, StoreVNI));
  ++NumSpills;
}
Ejemplo n.º 8
0
/// rewrite - after all the new live ranges have been created, rewrite
/// instructions using curli to use the new intervals.
void SplitEditor::rewrite() {
  assert(!openli_ && "Previous LI not closed before rewrite");
  const LiveInterval *curli = sa_.getCurLI();
  for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(curli->reg),
       RE = mri_.reg_end(); RI != RE;) {
    MachineOperand &MO = RI.getOperand();
    MachineInstr *MI = MO.getParent();
    ++RI;
    if (MI->isDebugValue()) {
      DEBUG(dbgs() << "Zapping " << *MI);
      // FIXME: We can do much better with debug values.
      MO.setReg(0);
      continue;
    }
    SlotIndex Idx = lis_.getInstructionIndex(MI);
    Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();
    LiveInterval *LI = dupli_;
    for (unsigned i = firstInterval, e = intervals_.size(); i != e; ++i) {
      LiveInterval *testli = intervals_[i];
      if (testli->liveAt(Idx)) {
        LI = testli;
        break;
      }
    }
    if (LI) {
      MO.setReg(LI->reg);
      sa_.removeUse(MI);
      DEBUG(dbgs() << "  rewrite " << Idx << '\t' << *MI);
    }
  }

  // dupli_ goes in last, after rewriting.
  if (dupli_) {
    if (dupli_->empty()) {
      DEBUG(dbgs() << "  dupli became empty?\n");
      lis_.removeInterval(dupli_->reg);
      dupli_ = 0;
    } else {
      dupli_->RenumberValues(lis_);
      intervals_.push_back(dupli_);
    }
  }

  // Calculate spill weight and allocation hints for new intervals.
  VirtRegAuxInfo vrai(vrm_.getMachineFunction(), lis_, sa_.loops_);
  for (unsigned i = firstInterval, e = intervals_.size(); i != e; ++i) {
    LiveInterval &li = *intervals_[i];
    vrai.CalculateRegClass(li.reg);
    vrai.CalculateWeightAndHint(li);
    DEBUG(dbgs() << "  new interval " << mri_.getRegClass(li.reg)->getName()
                 << ":" << li << '\n');
  }
}
Ejemplo n.º 9
0
// Check if all values in LI are rematerializable
static bool isRematerializable(const LiveInterval &LI,
                               const LiveIntervals &LIS,
                               VirtRegMap *VRM,
                               const TargetInstrInfo &TII) {
  unsigned Reg = LI.reg;
  unsigned Original = VRM ? VRM->getOriginal(Reg) : 0;
  for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
       I != E; ++I) {
    const VNInfo *VNI = *I;
    if (VNI->isUnused())
      continue;
    if (VNI->isPHIDef())
      return false;

    MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
    assert(MI && "Dead valno in interval");

    // Trace copies introduced by live range splitting.  The inline
    // spiller can rematerialize through these copies, so the spill
    // weight must reflect this.
    if (VRM) {
      while (MI->isFullCopy()) {
        // The copy destination must match the interval register.
        if (MI->getOperand(0).getReg() != Reg)
          return false;

        // Get the source register.
        Reg = MI->getOperand(1).getReg();

        // If the original (pre-splitting) registers match this
        // copy came from a split.
        if (!TargetRegisterInfo::isVirtualRegister(Reg) ||
            VRM->getOriginal(Reg) != Original)
          return false;

        // Follow the copy live-in value.
        const LiveInterval &SrcLI = LIS.getInterval(Reg);
        LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
        VNI = SrcQ.valueIn();
        assert(VNI && "Copy from non-existing value");
        if (VNI->isPHIDef())
          return false;
        MI = LIS.getInstructionFromIndex(VNI->def);
        assert(MI && "Dead valno in interval");
      }
    }

    if (!TII.isTriviallyReMaterializable(*MI, LIS.getAliasAnalysis()))
      return false;
  }
  return true;
}
Ejemplo n.º 10
0
/// insertSpill - Insert a spill of NewLI.reg after MI.
void InlineSpiller::insertSpill(LiveInterval &NewLI,
                                MachineBasicBlock::iterator MI) {
  MachineBasicBlock &MBB = *MI->getParent();
  SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex();
  tii_.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, stackSlot_, rc_, &tri_);
  --MI; // Point to store instruction.
  SlotIndex StoreIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
  vrm_.addSpillSlotUse(stackSlot_, MI);
  DEBUG(dbgs() << "\tspilled: " << StoreIdx << '\t' << *MI);
  VNInfo *StoreVNI = NewLI.getNextValue(Idx, 0, true,
                                        lis_.getVNInfoAllocator());
  NewLI.addRange(LiveRange(Idx, StoreIdx, StoreVNI));
}
Ejemplo n.º 11
0
/// insertReload - Insert a reload of NewLI.reg before MI.
void InlineSpiller::insertReload(LiveInterval &NewLI,
                                 MachineBasicBlock::iterator MI) {
  MachineBasicBlock &MBB = *MI->getParent();
  SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex();
  tii_.loadRegFromStackSlot(MBB, MI, NewLI.reg, stackSlot_, rc_, &tri_);
  --MI; // Point to load instruction.
  SlotIndex LoadIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
  vrm_.addSpillSlotUse(stackSlot_, MI);
  DEBUG(dbgs() << "\treload:  " << LoadIdx << '\t' << *MI);
  VNInfo *LoadVNI = NewLI.getNextValue(LoadIdx, 0, true,
                                       lis_.getVNInfoAllocator());
  NewLI.addRange(LiveRange(LoadIdx, Idx, LoadVNI));
}
/// computeVirtRegInterval - Compute the live interval of a virtual register,
/// based on defs and uses.
void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
    assert(LRCalc && "LRCalc not initialized.");
    assert(LI.empty() && "Should only compute empty intervals.");
    LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
    LRCalc->createDeadDefs(LI);
    LRCalc->extendToUses(LI);
}
Ejemplo n.º 13
0
/// join - Join two live intervals (this, and other) together.  This operation
/// is the result of a copy instruction in the source program, that occurs at
/// index 'CopyIdx' that copies from 'Other' to 'this'.
void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
  const LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1);
  const LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
  assert(SourceLR && DestLR && "Not joining due to a copy?");
  unsigned MergedSrcValIdx = SourceLR->ValId;
  unsigned MergedDstValIdx = DestLR->ValId;

  // Try to do the least amount of work possible.  In particular, if there are
  // more liverange chunks in the other set than there are in the 'this' set,
  // swap sets to merge the fewest chunks in possible.
  if (Other.ranges.size() > ranges.size()) {
    std::swap(MergedSrcValIdx, MergedDstValIdx);
    std::swap(ranges, Other.ranges);
    std::swap(NumValues, Other.NumValues);
  }

  // Join the ranges of other into the ranges of this interval.
  Ranges::iterator InsertPos = ranges.begin();
  std::map<unsigned, unsigned> Dst2SrcIdxMap;
  for (Ranges::iterator I = Other.ranges.begin(),
         E = Other.ranges.end(); I != E; ++I) {
    // Map the ValId in the other live range to the current live range.
    if (I->ValId == MergedSrcValIdx)
      I->ValId = MergedDstValIdx;
    else {
      unsigned &NV = Dst2SrcIdxMap[I->ValId];
      if (NV == 0) NV = getNextValue();
      I->ValId = NV;
    }

    InsertPos = addRangeFrom(*I, InsertPos);
  }

  weight += Other.weight;
}
Ejemplo n.º 14
0
void LiveInterval::Copy(const LiveInterval &RHS,
                        BumpPtrAllocator &VNInfoAllocator) {
  ranges.clear();
  valnos.clear();
  preference = RHS.preference;
  weight = RHS.weight;
  for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) {
    const VNInfo *VNI = RHS.getValNumInfo(i);
    VNInfo *NewVNI = getNextValue(~0U, 0, VNInfoAllocator);
    copyValNumInfo(NewVNI, VNI);
  }
  for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) {
    const LiveRange &LR = RHS.ranges[i];
    addRange(LiveRange(LR.start, LR.end, getValNumInfo(LR.valno->id)));
  }
}
Ejemplo n.º 15
0
static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
  for (const LiveInterval::SubRange &SR : LI.subranges()) {
    if (SR.liveAt(Pos))
      return true;
  }
  return false;
}
// Merge a LiveInterval's segments. Guarantee no overlaps.
void LiveIntervalUnion::unify(LiveInterval &VirtReg) {
  if (VirtReg.empty())
    return;

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

  for (;;) {
    SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
    if (++RegPos == RegEnd)
      return;
    SegPos.advanceTo(RegPos->start);
  }
}
Ejemplo n.º 17
0
/// computeVirtRegInterval - Compute the live interval of a virtual register,
/// based on defs and uses.
void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
  assert(LRCalc && "LRCalc not initialized.");
  assert(LI.empty() && "Should only compute empty intervals.");
  LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
  LRCalc->calculate(LI);
  computeDeadValues(LI, nullptr);
}
Ejemplo n.º 18
0
void StackColoring::removeInvalidSlotRanges() {
  MachineFunction::const_iterator BB, BBE;
  MachineBasicBlock::const_iterator I, IE;
  for (BB = MF->begin(), BBE = MF->end(); BB != BBE; ++BB)
    for (I = BB->begin(), IE = BB->end(); I != IE; ++I) {

      if (I->getOpcode() == TargetOpcode::LIFETIME_START ||
          I->getOpcode() == TargetOpcode::LIFETIME_END || I->isDebugValue())
        continue;

      // Some intervals are suspicious! In some cases we find address
      // calculations outside of the lifetime zone, but not actual memory
      // read or write. Memory accesses outside of the lifetime zone are a clear
      // violation, but address calculations are okay. This can happen when
      // GEPs are hoisted outside of the lifetime zone.
      // So, in here we only check instructions which can read or write memory.
      if (!I->mayLoad() && !I->mayStore())
        continue;

      // Check all of the machine operands.
      for (unsigned i = 0 ; i <  I->getNumOperands(); ++i) {
        const MachineOperand &MO = I->getOperand(i);

        if (!MO.isFI())
          continue;

        int Slot = MO.getIndex();

        if (Slot<0)
          continue;

        if (Intervals[Slot]->empty())
          continue;

        // Check that the used slot is inside the calculated lifetime range.
        // If it is not, warn about it and invalidate the range.
        LiveInterval *Interval = Intervals[Slot];
        SlotIndex Index = Indexes->getInstructionIndex(I);
        if (Interval->find(Index) == Interval->end()) {
          Intervals[Slot]->clear();
          DEBUG(dbgs()<<"Invalidating range #"<<Slot<<"\n");
          EscapedAllocas++;
        }
      }
    }
}
Ejemplo n.º 19
0
/// insertReload - Insert a reload of NewLI.reg before MI.
void InlineSpiller::insertReload(LiveInterval &NewLI,
                                 SlotIndex Idx,
                                 MachineBasicBlock::iterator MI) {
  MachineBasicBlock &MBB = *MI->getParent();
  TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot,
                           MRI.getRegClass(NewLI.reg), &TRI);
  --MI; // Point to load instruction.
  SlotIndex LoadIdx = LIS.InsertMachineInstrInMaps(MI).getRegSlot();
  // Some (out-of-tree) targets have EC reload instructions.
  if (MachineOperand *MO = MI->findRegisterDefOperand(NewLI.reg))
    if (MO->isEarlyClobber())
      LoadIdx = LoadIdx.getRegSlot(true);
  DEBUG(dbgs() << "\treload:  " << LoadIdx << '\t' << *MI);
  VNInfo *LoadVNI = NewLI.getNextValue(LoadIdx, LIS.getVNInfoAllocator());
  NewLI.addRange(LiveRange(LoadIdx, Idx, LoadVNI));
  ++NumReloads;
}
Ejemplo n.º 20
0
/// Given an updated live interval LI for register Reg, update the kill flags
/// in instructions using Reg to reflect the liveness changes.
void HexagonExpandCondsets::updateKillFlags(unsigned Reg, LiveInterval &LI) {
  MRI->clearKillFlags(Reg);
  for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) {
    SlotIndex EX = I->end;
    if (!EX.isRegister())
      continue;
    MachineInstr *MI = LIS->getInstructionFromIndex(EX);
    for (auto &Op : MI->operands()) {
      if (!Op.isReg() || !Op.isUse() || Op.getReg() != Reg)
        continue;
      // Only set the kill flag on the first encountered use of Reg in this
      // instruction.
      Op.setIsKill(true);
      break;
    }
  }
}
Ejemplo n.º 21
0
void LiveInterval::Copy(const LiveInterval &RHS,
                        MachineRegisterInfo *MRI,
                        VNInfo::Allocator &VNInfoAllocator) {
  ranges.clear();
  valnos.clear();
  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(RHS.reg);
  MRI->setRegAllocationHint(reg, Hint.first, Hint.second);

  weight = RHS.weight;
  for (unsigned i = 0, e = RHS.getNumValNums(); i != e; ++i) {
    const VNInfo *VNI = RHS.getValNumInfo(i);
    createValueCopy(VNI, VNInfoAllocator);
  }
  for (unsigned i = 0, e = RHS.ranges.size(); i != e; ++i) {
    const LiveRange &LR = RHS.ranges[i];
    addRange(LiveRange(LR.start, LR.end, getValNumInfo(LR.valno->id)));
  }
}
Ejemplo n.º 22
0
bool
LiveIntervals::hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const {
  for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
       I != E; ++I) {
    const VNInfo *PHI = *I;
    if (PHI->isUnused() || !PHI->isPHIDef())
      continue;
    const MachineBasicBlock *PHIMBB = getMBBFromIndex(PHI->def);
    // Conservatively return true instead of scanning huge predecessor lists.
    if (PHIMBB->pred_size() > 100)
      return true;
    for (MachineBasicBlock::const_pred_iterator
         PI = PHIMBB->pred_begin(), PE = PHIMBB->pred_end(); PI != PE; ++PI)
      if (VNI == LI.getVNInfoBefore(Indexes->getMBBEndIdx(*PI)))
        return true;
  }
  return false;
}
Ejemplo n.º 23
0
void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
                                             unsigned PhysReg) const {
  assert(!LI.empty());
  assert(LI.hasSubRanges());

  using SubRangeIteratorPair =
      std::pair<const LiveInterval::SubRange *, LiveInterval::const_iterator>;

  SmallVector<SubRangeIteratorPair, 4> SubRanges;
  SlotIndex First;
  SlotIndex Last;
  for (const LiveInterval::SubRange &SR : LI.subranges()) {
    SubRanges.push_back(std::make_pair(&SR, SR.begin()));
    if (!First.isValid() || SR.segments.front().start < First)
      First = SR.segments.front().start;
    if (!Last.isValid() || SR.segments.back().end > Last)
      Last = SR.segments.back().end;
  }

  // Check all mbb start positions between First and Last while
  // simulatenously advancing an iterator for each subrange.
  for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First);
       MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) {
    SlotIndex MBBBegin = MBBI->first;
    // Advance all subrange iterators so that their end position is just
    // behind MBBBegin (or the iterator is at the end).
    LaneBitmask LaneMask;
    for (auto &RangeIterPair : SubRanges) {
      const LiveInterval::SubRange *SR = RangeIterPair.first;
      LiveInterval::const_iterator &SRI = RangeIterPair.second;
      while (SRI != SR->end() && SRI->end <= MBBBegin)
        ++SRI;
      if (SRI == SR->end())
        continue;
      if (SRI->start <= MBBBegin)
        LaneMask |= SR->LaneMask;
    }
    if (LaneMask.none())
      continue;
    MachineBasicBlock *MBB = MBBI->second;
    MBB->addLiveIn(PhysReg, LaneMask);
  }
}
Ejemplo n.º 24
0
void RegAllocPBQP::findVRegIntervalsToAlloc() {

  // Iterate over all live ranges.
  for (unsigned i = 0, e = mri->getNumVirtRegs(); i != e; ++i) {
    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
    if (mri->reg_nodbg_empty(Reg))
      continue;
    LiveInterval *li = &lis->getInterval(Reg);

    // If this live interval is non-empty we will use pbqp to allocate it.
    // Empty intervals we allocate in a simple post-processing stage in
    // finalizeAlloc.
    if (!li->empty()) {
      vregsToAlloc.insert(li->reg);
    } else {
      emptyIntervalVRegs.insert(li->reg);
    }
  }
}
Ejemplo n.º 25
0
void SplitEditor::removeBackCopies(SmallVectorImpl<VNInfo*> &Copies) {
  LiveInterval *LI = Edit->get(0);
  DEBUG(dbgs() << "Removing " << Copies.size() << " back-copies.\n");
  RegAssignMap::iterator AssignI;
  AssignI.setMap(RegAssign);

  for (unsigned i = 0, e = Copies.size(); i != e; ++i) {
    VNInfo *VNI = Copies[i];
    SlotIndex Def = VNI->def;
    MachineInstr *MI = LIS.getInstructionFromIndex(Def);
    assert(MI && "No instruction for back-copy");

    MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::iterator MBBI(MI);
    bool AtBegin;
    do AtBegin = MBBI == MBB->begin();
    while (!AtBegin && (--MBBI)->isDebugValue());

    DEBUG(dbgs() << "Removing " << Def << '\t' << *MI);
    LI->removeValNo(VNI);
    LIS.RemoveMachineInstrFromMaps(MI);
    MI->eraseFromParent();

    // Adjust RegAssign if a register assignment is killed at VNI->def.  We
    // want to avoid calculating the live range of the source register if
    // possible.
    AssignI.find(VNI->def.getPrevSlot());
    if (!AssignI.valid() || AssignI.start() >= Def)
      continue;
    // If MI doesn't kill the assigned register, just leave it.
    if (AssignI.stop() != Def)
      continue;
    unsigned RegIdx = AssignI.value();
    if (AtBegin || !MBBI->readsVirtualRegister(Edit->getReg())) {
      DEBUG(dbgs() << "  cannot find simple kill of RegIdx " << RegIdx << '\n');
      forceRecompute(RegIdx, Edit->getParent().getVNInfoAt(Def));
    } else {
      SlotIndex Kill = LIS.getInstructionIndex(MBBI).getDefIndex();
      DEBUG(dbgs() << "  move kill to " << Kill << '\t' << *MBBI);
      AssignI.setStop(Kill);
    }
  }
}
Ejemplo n.º 26
0
// Check if all values in LI are rematerializable
static bool isRematerializable(const LiveInterval &LI,
                               const LiveIntervals &LIS,
                               const TargetInstrInfo &TII) {
  for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
       I != E; ++I) {
    const VNInfo *VNI = *I;
    if (VNI->isUnused())
      continue;
    if (VNI->isPHIDef())
      return false;

    MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
    assert(MI && "Dead valno in interval");

    if (!TII.isTriviallyReMaterializable(MI, LIS.getAliasAnalysis()))
      return false;
  }
  return true;
}
Ejemplo n.º 27
0
bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
    SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
    LiveInterval &LI) const {
  // First step: Create connected components for the VNInfos inside the
  // subranges and count the global number of such components.
  unsigned NumComponents = 0;
  for (LiveInterval::SubRange &SR : LI.subranges()) {
    SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
    ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;

    unsigned NumSubComponents = ConEQ.Classify(SR);
    NumComponents += NumSubComponents;
  }
  // Shortcut: With only 1 subrange, the normal separate component tests are
  // enough and we do not need to perform the union-find on the subregister
  // segments.
  if (SubRangeInfos.size() < 2)
    return false;

  // Next step: Build union-find structure over all subranges and merge classes
  // across subranges when they are affected by the same MachineOperand.
  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
  Classes.grow(NumComponents);
  unsigned Reg = LI.reg;
  for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    if (!MO.isDef() && !MO.readsReg())
      continue;
    unsigned SubRegIdx = MO.getSubReg();
    LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
    unsigned MergedID = ~0u;
    for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
      const LiveInterval::SubRange &SR = *SRInfo.SR;
      if ((SR.LaneMask & LaneMask) == 0)
        continue;
      SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
      Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
                       : Pos.getBaseIndex();
      const VNInfo *VNI = SR.getVNInfoAt(Pos);
      if (VNI == nullptr)
        continue;

      // Map to local representant ID.
      unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
      // Global ID
      unsigned ID = LocalID + SRInfo.Index;
      // Merge other sets
      MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
    }
  }

  // Early exit if we ended up with a single equivalence class.
  Classes.compress();
  unsigned NumClasses = Classes.getNumClasses();
  return NumClasses > 1;
}
Ejemplo n.º 28
0
static void determineMissingVNIs(const SlotIndexes &Indexes, LiveInterval &LI) {
  SmallPtrSet<const MachineBasicBlock*, 5> Visited;

  LiveRange::iterator OutIt;
  VNInfo *PrevValNo = nullptr;
  for (LiveRange::iterator I = LI.begin(), E = LI.end(); I != E; ++I) {
    LiveRange::Segment &S = *I;
    // Determine final VNI if necessary.
    if (S.valno == nullptr) {
      // This can only happen at the begin of a basic block.
      assert(S.start.isBlock() && "valno should only be missing at block begin");

      Visited.clear();
      const MachineBasicBlock *MBB = Indexes.getMBBFromIndex(S.start);
      for (const MachineBasicBlock *Pred : MBB->predecessors()) {
        VNInfo *VNI = searchForVNI(Indexes, LI, Pred, Visited);
        if (VNI != nullptr) {
          S.valno = VNI;
          break;
        }
      }
      assert(S.valno != nullptr && "could not determine valno");
    }
    // Merge with previous segment if it has the same VNI.
    if (PrevValNo == S.valno && OutIt->end == S.start) {
      OutIt->end = S.end;
    } else {
      // Didn't merge. Move OutIt to next segment.
      if (PrevValNo == nullptr)
        OutIt = LI.begin();
      else
        ++OutIt;

      if (OutIt != I)
        *OutIt = *I;
      PrevValNo = S.valno;
    }
  }
  // If we merged some segments chop off the end.
  ++OutIt;
  LI.segments.erase(OutIt, LI.end());
}
Ejemplo n.º 29
0
/// computeLiveInRegUnits - Precompute the live ranges of any register units
/// that are live-in to an ABI block somewhere. Register values can appear
/// without a corresponding def when entering the entry block or a landing pad.
///
void LiveIntervals::computeLiveInRegUnits() {
  RegUnitIntervals.resize(TRI->getNumRegUnits());
  DEBUG(dbgs() << "Computing live-in reg-units in ABI blocks.\n");

  // Keep track of the intervals allocated.
  SmallVector<LiveInterval*, 8> NewIntvs;

  // Check all basic blocks for live-ins.
  for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
       MFI != MFE; ++MFI) {
    const MachineBasicBlock *MBB = MFI;

    // We only care about ABI blocks: Entry + landing pads.
    if ((MFI != MF->begin() && !MBB->isLandingPad()) || MBB->livein_empty())
      continue;

    // Create phi-defs at Begin for all live-in registers.
    SlotIndex Begin = Indexes->getMBBStartIdx(MBB);
    DEBUG(dbgs() << Begin << "\tBB#" << MBB->getNumber());
    for (MachineBasicBlock::livein_iterator LII = MBB->livein_begin(),
         LIE = MBB->livein_end(); LII != LIE; ++LII) {
      for (MCRegUnitIterator Units(*LII, TRI); Units.isValid(); ++Units) {
        unsigned Unit = *Units;
        LiveInterval *Intv = RegUnitIntervals[Unit];
        if (!Intv) {
          Intv = RegUnitIntervals[Unit] = new LiveInterval(Unit, HUGE_VALF);
          NewIntvs.push_back(Intv);
        }
        VNInfo *VNI = Intv->createDeadDef(Begin, getVNInfoAllocator());
        (void)VNI;
        DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI) << '#' << VNI->id);
      }
    }
    DEBUG(dbgs() << '\n');
  }
  DEBUG(dbgs() << "Created " << NewIntvs.size() << " new intervals.\n");

  // Compute the 'normal' part of the intervals.
  for (unsigned i = 0, e = NewIntvs.size(); i != e; ++i)
    computeRegUnitInterval(NewIntvs[i]);
}
Ejemplo n.º 30
0
void StackColoring::removeInvalidSlotRanges() {
  for (MachineBasicBlock &BB : *MF)
    for (MachineInstr &I : BB) {
      if (I.getOpcode() == TargetOpcode::LIFETIME_START ||
          I.getOpcode() == TargetOpcode::LIFETIME_END || I.isDebugValue())
        continue;

      // Some intervals are suspicious! In some cases we find address
      // calculations outside of the lifetime zone, but not actual memory
      // read or write. Memory accesses outside of the lifetime zone are a clear
      // violation, but address calculations are okay. This can happen when
      // GEPs are hoisted outside of the lifetime zone.
      // So, in here we only check instructions which can read or write memory.
      if (!I.mayLoad() && !I.mayStore())
        continue;

      // Check all of the machine operands.
      for (const MachineOperand &MO : I.operands()) {
        if (!MO.isFI())
          continue;

        int Slot = MO.getIndex();

        if (Slot<0)
          continue;

        if (Intervals[Slot]->empty())
          continue;

        // Check that the used slot is inside the calculated lifetime range.
        // If it is not, warn about it and invalidate the range.
        LiveInterval *Interval = &*Intervals[Slot];
        SlotIndex Index = Indexes->getInstructionIndex(I);
        if (Interval->find(Index) == Interval->end()) {
          Interval->clear();
          DEBUG(dbgs()<<"Invalidating range #"<<Slot<<"\n");
          EscapedAllocas++;
        }
      }
    }
}