bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem, const PBQP::Solution &solution) { // Set to true if we have any spills bool anotherRoundNeeded = false; // Clear the existing allocation. vrm->clearAllVirt(); const PBQP::Graph &g = problem.getGraph(); // Iterate over the nodes mapping the PBQP solution to a register // assignment. for (PBQP::Graph::ConstNodeItr node = g.nodesBegin(), nodeEnd = g.nodesEnd(); node != nodeEnd; ++node) { unsigned vreg = problem.getVRegForNode(node); unsigned alloc = solution.getSelection(node); if (problem.isPRegOption(vreg, alloc)) { unsigned preg = problem.getPRegForOption(vreg, alloc); DEBUG(dbgs() << "VREG " << vreg << " -> " << tri->getName(preg) << "\n"); assert(preg != 0 && "Invalid preg selected."); vrm->assignVirt2Phys(vreg, preg); } else if (problem.isSpillOption(vreg, alloc)) { vregsToAlloc.erase(vreg); const LiveInterval* spillInterval = &lis->getInterval(vreg); double oldWeight = spillInterval->weight; SmallVector<LiveInterval*, 8> spillIs; rmf->rememberUseDefs(spillInterval); std::vector<LiveInterval*> newSpills = lis->addIntervalsForSpills(*spillInterval, spillIs, loopInfo, *vrm); addStackInterval(spillInterval, mri); rmf->rememberSpills(spillInterval, newSpills); (void) oldWeight; DEBUG(dbgs() << "VREG " << vreg << " -> SPILLED (Cost: " << oldWeight << ", New vregs: "); // Copy any newly inserted live intervals into the list of regs to // allocate. for (std::vector<LiveInterval*>::const_iterator itr = newSpills.begin(), end = newSpills.end(); itr != end; ++itr) { assert(!(*itr)->empty() && "Empty spill range."); DEBUG(dbgs() << (*itr)->reg << " "); vregsToAlloc.insert((*itr)->reg); } DEBUG(dbgs() << ")\n"); // We need another round if spill intervals were added. anotherRoundNeeded |= !newSpills.empty(); } else { assert(false && "Unknown allocation option."); } } return !anotherRoundNeeded; }
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; }
bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem, const PBQP::Solution &solution) { // Set to true if we have any spills bool anotherRoundNeeded = false; // Clear the existing allocation. vrm->clearAllVirt(); const PBQP::Graph &g = problem.getGraph(); // Iterate over the nodes mapping the PBQP solution to a register // assignment. for (PBQP::Graph::NodeItr nodeItr = g.nodesBegin(), nodeEnd = g.nodesEnd(); nodeItr != nodeEnd; ++nodeItr) { unsigned vreg = problem.getVRegForNode(*nodeItr); unsigned alloc = solution.getSelection(*nodeItr); if (problem.isPRegOption(vreg, alloc)) { unsigned preg = problem.getPRegForOption(vreg, alloc); DEBUG(dbgs() << "VREG " << PrintReg(vreg, tri) << " -> " << tri->getName(preg) << "\n"); assert(preg != 0 && "Invalid preg selected."); vrm->assignVirt2Phys(vreg, preg); } else if (problem.isSpillOption(vreg, alloc)) { vregsToAlloc.erase(vreg); SmallVector<unsigned, 8> newSpills; LiveRangeEdit LRE(&lis->getInterval(vreg), newSpills, *mf, *lis, vrm); spiller->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 itr = LRE.begin(), end = LRE.end(); itr != end; ++itr) { LiveInterval &li = lis->getInterval(*itr); 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(); } else { llvm_unreachable("Unknown allocation option."); } } return !anotherRoundNeeded; }
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; }