From 2e9f926ca04e52bb0b3ed48aac4414028db1ad37 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 20 Feb 2018 22:15:09 +0000 Subject: [PATCH] [PBQP] Fix PR33038 by pruning empty intervals in initializeGraph. Spilling may cause previously non-empty intervals (both for the spilled vreg and others) to become empty. Moving the pruning into initializeGraph catches these cases and fixes PR33038. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325632 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/RegAllocPBQP.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 69a879701fa..c2a970ceab6 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -561,16 +561,7 @@ void RegAllocPBQP::findVRegIntervalsToAlloc(const MachineFunction &MF, 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); - } + VRegsToAlloc.insert(Reg); } } @@ -594,13 +585,24 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM, std::vector Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end()); + std::map> VRegAllowedMap; + while (!Worklist.empty()) { unsigned VReg = Worklist.back(); Worklist.pop_back(); - const TargetRegisterClass *TRC = MRI.getRegClass(VReg); LiveInterval &VRegLI = LIS.getInterval(VReg); + // If this is an empty interval move it to the EmptyIntervalVRegs set then + // continue. + if (VRegLI.empty()) { + EmptyIntervalVRegs.insert(VRegLI.reg); + VRegsToAlloc.erase(VRegLI.reg); + continue; + } + + const TargetRegisterClass *TRC = MRI.getRegClass(VReg); + // Record any overlaps with regmask operands. BitVector RegMaskOverlaps; LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps); @@ -639,8 +641,22 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM, spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller); Worklist.insert(Worklist.end(), NewVRegs.begin(), NewVRegs.end()); continue; + } else + VRegAllowedMap[VReg] = std::move(VRegAllowed); + } + + for (auto &KV : VRegAllowedMap) { + auto VReg = KV.first; + + // Move empty intervals to the EmptyIntervalVReg set. + if (LIS.getInterval(VReg).empty()) { + EmptyIntervalVRegs.insert(VReg); + VRegsToAlloc.erase(VReg); + continue; } + auto &VRegAllowed = KV.second; + PBQPRAGraph::RawVector NodeCosts(VRegAllowed.size() + 1, 0); // Tweak cost of callee saved registers, as using then force spilling and -- 2.11.0