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); } }
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; }