Ejemplo n.º 1
0
bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
                                     const PBQP::Solution &Solution,
                                     VirtRegMap &VRM,
                                     Spiller &VRegSpiller) {
  MachineFunction &MF = G.getMetadata().MF;
  LiveIntervals &LIS = G.getMetadata().LIS;
  const TargetRegisterInfo &TRI =
    *MF.getTarget().getSubtargetImpl()->getRegisterInfo();
  (void)TRI;

  // Set to true if we have any spills
  bool AnotherRoundNeeded = false;

  // Clear the existing allocation.
  VRM.clearAllVirt();

  // Iterate over the nodes mapping the PBQP solution to a register
  // assignment.
  for (auto NId : G.nodeIds()) {
    unsigned VReg = G.getNodeMetadata(NId).getVReg();
    unsigned AllocOption = Solution.getSelection(NId);

    if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) {
      unsigned PReg = G.getNodeMetadata(NId).getOptionRegs()[AllocOption - 1];
      DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> "
            << TRI.getName(PReg) << "\n");
      assert(PReg != 0 && "Invalid preg selected.");
      VRM.assignVirt2Phys(VReg, PReg);
    } else {
      VRegsToAlloc.erase(VReg);
      SmallVector<unsigned, 8> NewSpills;
      LiveRangeEdit LRE(&LIS.getInterval(VReg), NewSpills, MF, LIS, &VRM);
      VRegSpiller.spill(LRE);

      DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> SPILLED (Cost: "
                   << LRE.getParent().weight << ", New vregs: ");

      // Copy any newly inserted live intervals into the list of regs to
      // allocate.
      for (LiveRangeEdit::iterator I = LRE.begin(), E = LRE.end();
           I != E; ++I) {
        LiveInterval &LI = LIS.getInterval(*I);
        assert(!LI.empty() && "Empty spill range.");
        DEBUG(dbgs() << PrintReg(LI.reg, &TRI) << " ");
        VRegsToAlloc.insert(LI.reg);
      }

      DEBUG(dbgs() << ")\n");

      // We need another round if spill intervals were added.
      AnotherRoundNeeded |= !LRE.empty();
    }
  }

  return !AnotherRoundNeeded;
}
Ejemplo n.º 2
0
void RegAllocBase::init(VirtRegMap &vrm,
                        LiveIntervals &lis,
                        LiveRegMatrix &mat) {
  TRI = &vrm.getTargetRegInfo();
  MRI = &vrm.getRegInfo();
  VRM = &vrm;
  LIS = &lis;
  Matrix = &mat;
  MRI->freezeReservedRegs(vrm.getMachineFunction());
  RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());
}
Ejemplo n.º 3
0
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
SplitEditor::SplitEditor(SplitAnalysis &sa,
                         LiveIntervals &lis,
                         VirtRegMap &vrm,
                         MachineDominatorTree &mdt)
  : SA(sa), LIS(lis), VRM(vrm),
    MRI(vrm.getMachineFunction().getRegInfo()),
    MDT(mdt),
    TII(*vrm.getMachineFunction().getTarget().getInstrInfo()),
    TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()),
    Edit(0),
    OpenIdx(0),
    SpillMode(SM_Partition),
    RegAssign(Allocator)
{}
Ejemplo n.º 4
0
void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis) {
  NamedRegionTimer T("Initialize", TimerGroupName, TimePassesIsEnabled);
  TRI = &vrm.getTargetRegInfo();
  MRI = &vrm.getRegInfo();
  VRM = &vrm;
  LIS = &lis;
  RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());

  const unsigned NumRegs = TRI->getNumRegs();
  if (NumRegs != PhysReg2LiveUnion.numRegs()) {
    PhysReg2LiveUnion.init(UnionAllocator, NumRegs);
    // Cache an interferece query for each physical reg
    Queries.reset(new LiveIntervalUnion::Query[PhysReg2LiveUnion.numRegs()]);
  }
}
Ejemplo n.º 5
0
// Compare VirtRegMap::getRegAllocPref().
AllocationOrder::AllocationOrder(unsigned VirtReg,
                                 const VirtRegMap &VRM,
                                 const BitVector &ReservedRegs)
  : Pos(0), Reserved(ReservedRegs) {
  const TargetRegisterClass *RC = VRM.getRegInfo().getRegClass(VirtReg);
  std::pair<unsigned, unsigned> HintPair =
    VRM.getRegInfo().getRegAllocationHint(VirtReg);

  // HintPair.second is a register, phys or virt.
  Hint = HintPair.second;

  // Translate to physreg, or 0 if not assigned yet.
  if (TargetRegisterInfo::isVirtualRegister(Hint))
    Hint = VRM.getPhys(Hint);

  // The remaining allocation order may depend on the hint.
  tie(Begin, End) = VRM.getTargetRegInfo()
        .getAllocationOrder(RC, HintPair.first, Hint, VRM.getMachineFunction());

  // Target-dependent hints require resolution.
  if (HintPair.first)
    Hint = VRM.getTargetRegInfo().ResolveRegAllocHint(HintPair.first, Hint,
                                                      VRM.getMachineFunction());

  // The hint must be a valid physreg for allocation.
  if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) ||
               !RC->contains(Hint) || ReservedRegs.test(Hint)))
    Hint = 0;
}
Ejemplo n.º 6
0
void
UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) {
  // Iterate over locations in reverse makes it easier to handle coalescing.
  for (unsigned i = locations.size(); i ; --i) {
    unsigned LocNo = i-1;
    MachineOperand &Loc = locations[LocNo];
    // Only virtual registers are rewritten.
    if (!Loc.isReg() || !Loc.getReg() ||
        !TargetRegisterInfo::isVirtualRegister(Loc.getReg()))
      continue;
    unsigned VirtReg = Loc.getReg();
    if (VRM.isAssignedReg(VirtReg) &&
        TargetRegisterInfo::isPhysicalRegister(VRM.getPhys(VirtReg))) {
      Loc.substPhysReg(VRM.getPhys(VirtReg), TRI);
    } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT &&
               VRM.isSpillSlotUsed(VRM.getStackSlot(VirtReg))) {
      // FIXME: Translate SubIdx to a stackslot offset.
      Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
    } else {
      Loc.setReg(0);
      Loc.setSubReg(0);
    }
    coalesceLocation(LocNo);
  }
  DEBUG(print(dbgs(), &TRI));
}
Ejemplo n.º 7
0
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm,
                         SmallVectorImpl<LiveInterval*> &intervals)
  : sa_(sa), lis_(lis), vrm_(vrm),
    mri_(vrm.getMachineFunction().getRegInfo()),
    tii_(*vrm.getMachineFunction().getTarget().getInstrInfo()),
    curli_(sa_.getCurLI()),
    dupli_(0), openli_(0),
    intervals_(intervals),
    firstInterval(intervals_.size())
{
  assert(curli_ && "SplitEditor created from empty SplitAnalysis");

  // Make sure curli_ is assigned a stack slot, so all our intervals get the
  // same slot as curli_.
  if (vrm_.getStackSlot(curli_->reg) == VirtRegMap::NO_STACK_SLOT)
    vrm_.assignVirt2StackSlot(curli_->reg);

}
Ejemplo n.º 8
0
// Compare VirtRegMap::getRegAllocPref().
AllocationOrder::AllocationOrder(unsigned VirtReg,
                                 const VirtRegMap &VRM,
                                 const RegisterClassInfo &RegClassInfo)
  : Pos(0) {
  const MachineFunction &MF = VRM.getMachineFunction();
  const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
  Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
  TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM);
  rewind();

  DEBUG({
    if (!Hints.empty()) {
      dbgs() << "hints:";
      for (unsigned I = 0, E = Hints.size(); I != E; ++I)
        dbgs() << ' ' << PrintReg(Hints[I], TRI);
      dbgs() << '\n';
    }
  });
Ejemplo n.º 9
0
SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm,
                             const LiveIntervals &lis,
                             const MachineLoopInfo &mli)
  : MF(vrm.getMachineFunction()),
    VRM(vrm),
    LIS(lis),
    Loops(mli),
    TII(*MF.getTarget().getInstrInfo()),
    CurLI(0),
    LastSplitPoint(MF.getNumBlockIDs()) {}
Ejemplo n.º 10
0
// Compare VirtRegMap::getRegAllocPref().
AllocationOrder::AllocationOrder(unsigned VirtReg,
                                 const VirtRegMap &VRM,
                                 const RegisterClassInfo &RegClassInfo,
                                 const LiveRegMatrix *Matrix)
  : Pos(0), HardHints(false) {
  const MachineFunction &MF = VRM.getMachineFunction();
  const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
  Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
  if (TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix))
    HardHints = true;
  rewind();

  LLVM_DEBUG({
    if (!Hints.empty()) {
      dbgs() << "hints:";
      for (unsigned I = 0, E = Hints.size(); I != E; ++I)
        dbgs() << ' ' << printReg(Hints[I], TRI);
      dbgs() << '\n';
    }
  });
Ejemplo n.º 11
0
bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
                                     const PBQP::Solution &Solution,
                                     VirtRegMap &VRM,
                                     Spiller &VRegSpiller) {
  MachineFunction &MF = G.getMetadata().MF;
  LiveIntervals &LIS = G.getMetadata().LIS;
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
  (void)TRI;

  // Set to true if we have any spills
  bool AnotherRoundNeeded = false;

  // Clear the existing allocation.
  VRM.clearAllVirt();

  // Iterate over the nodes mapping the PBQP solution to a register
  // assignment.
  for (auto NId : G.nodeIds()) {
    unsigned VReg = G.getNodeMetadata(NId).getVReg();
    unsigned AllocOption = Solution.getSelection(NId);

    if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) {
      unsigned PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOption - 1];
      DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> "
            << TRI.getName(PReg) << "\n");
      assert(PReg != 0 && "Invalid preg selected.");
      VRM.assignVirt2Phys(VReg, PReg);
    } else {
      // Spill VReg. If this introduces new intervals we'll need another round
      // of allocation.
      SmallVector<unsigned, 8> NewVRegs;
      spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);
      AnotherRoundNeeded |= !NewVRegs.empty();
    }
  }

  return !AnotherRoundNeeded;
}
Ejemplo n.º 12
0
void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
                                 LiveIntervals &LIS,
                                 VirtRegMap &VRM) const {
  MachineRegisterInfo &MRI = MF.getRegInfo();

  // First allocate registers for the empty intervals.
  for (RegSet::const_iterator
         I = EmptyIntervalVRegs.begin(), E = EmptyIntervalVRegs.end();
         I != E; ++I) {
    LiveInterval &LI = LIS.getInterval(*I);

    unsigned PReg = MRI.getSimpleHint(LI.reg);

    if (PReg == 0) {
      const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg);
      PReg = RC.getRawAllocationOrder(MF).front();
    }

    VRM.assignVirt2Phys(LI.reg, PReg);
  }
}
Ejemplo n.º 13
0
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
                                      LiveIntervals &LIS, VirtRegMap &VRM,
                                      const TargetInstrInfo &TII) {
  SetVector<LiveInterval*,
            SmallVector<LiveInterval*, 8>,
            SmallPtrSet<LiveInterval*, 8> > ToShrink;
  MachineRegisterInfo &MRI = VRM.getRegInfo();

  for (;;) {
    // Erase all dead defs.
    while (!Dead.empty()) {
      MachineInstr *MI = Dead.pop_back_val();
      assert(MI->allDefsAreDead() && "Def isn't really dead");
      SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex();

      // Never delete inline asm.
      if (MI->isInlineAsm()) {
        DEBUG(dbgs() << "Won't delete: " << Idx << '\t' << *MI);
        continue;
      }

      // Use the same criteria as DeadMachineInstructionElim.
      bool SawStore = false;
      if (!MI->isSafeToMove(&TII, 0, SawStore)) {
        DEBUG(dbgs() << "Can't delete: " << Idx << '\t' << *MI);
        continue;
      }

      DEBUG(dbgs() << "Deleting dead def " << Idx << '\t' << *MI);

      // Check for live intervals that may shrink
      for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
             MOE = MI->operands_end(); MOI != MOE; ++MOI) {
        if (!MOI->isReg())
          continue;
        unsigned Reg = MOI->getReg();
        if (!TargetRegisterInfo::isVirtualRegister(Reg))
          continue;
        LiveInterval &LI = LIS.getInterval(Reg);

        // Shrink read registers, unless it is likely to be expensive and
        // unlikely to change anything. We typically don't want to shrink the
        // PIC base register that has lots of uses everywhere.
        // Always shrink COPY uses that probably come from live range splitting.
        if (MI->readsVirtualRegister(Reg) &&
            (MI->isCopy() || MOI->isDef() || MRI.hasOneNonDBGUse(Reg) ||
             LI.killedAt(Idx)))
          ToShrink.insert(&LI);

        // Remove defined value.
        if (MOI->isDef()) {
          if (VNInfo *VNI = LI.getVNInfoAt(Idx)) {
            if (delegate_)
              delegate_->LRE_WillShrinkVirtReg(LI.reg);
            LI.removeValNo(VNI);
            if (LI.empty()) {
              ToShrink.remove(&LI);
              eraseVirtReg(Reg, LIS);
            }
          }
        }
      }

      if (delegate_)
        delegate_->LRE_WillEraseInstruction(MI);
      LIS.RemoveMachineInstrFromMaps(MI);
      MI->eraseFromParent();
      ++NumDCEDeleted;
    }

    if (ToShrink.empty())
      break;

    // Shrink just one live interval. Then delete new dead defs.
    LiveInterval *LI = ToShrink.back();
    ToShrink.pop_back();
    if (foldAsLoad(LI, Dead, MRI, LIS, TII))
      continue;
    if (delegate_)
      delegate_->LRE_WillShrinkVirtReg(LI->reg);
    if (!LIS.shrinkToUses(LI, &Dead))
      continue;

    // LI may have been separated, create new intervals.
    LI->RenumberValues(LIS);
    ConnectedVNInfoEqClasses ConEQ(LIS);
    unsigned NumComp = ConEQ.Classify(LI);
    if (NumComp <= 1)
      continue;
    ++NumFracRanges;
    bool IsOriginal = VRM.getOriginal(LI->reg) == LI->reg;
    DEBUG(dbgs() << NumComp << " components: " << *LI << '\n');
    SmallVector<LiveInterval*, 8> Dups(1, LI);
    for (unsigned i = 1; i != NumComp; ++i) {
      Dups.push_back(&createFrom(LI->reg, LIS, VRM));
      // If LI is an original interval that hasn't been split yet, make the new
      // intervals their own originals instead of referring to LI. The original
      // interval must contain all the split products, and LI doesn't.
      if (IsOriginal)
        VRM.setIsSplitFromReg(Dups.back()->reg, 0);
      if (delegate_)
        delegate_->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
    }
    ConEQ.Distribute(&Dups[0], MRI);
  }
}