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;
}
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);
  }
}
示例#3
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;
}