From 9933a173335a7b112fcc57eb08dcc2ec53c96b55 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Thu, 29 Sep 2016 23:20:23 +1300 Subject: [PATCH] [RegAllocGreedy] Attempt to split unspillable live intervals Previously, when allocating unspillable live ranges, we would never attempt to split. We would always bail out and try last ditch graph recoloring. This patch changes this by attempting to split all live intervals before performing recoloring. --- lib/CodeGen/CalcSpillWeights.cpp | 15 +-------------- lib/CodeGen/RegAllocGreedy.cpp | 14 ++++++++------ test/CodeGen/AVR/high-pressure-on-ptrregs.ll | 4 ---- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp index 98237f6c7e6..dc2d38a95f9 100644 --- a/lib/CodeGen/CalcSpillWeights.cpp +++ b/lib/CodeGen/CalcSpillWeights.cpp @@ -221,20 +221,7 @@ VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) { // spilling may be required. if (li.isZeroLength(LIS.getSlotIndexes()) && !li.isLiveAtIndexes(LIS.getRegMaskSlots())) { - // HACK HACK: This is a workaround until PR14879 gets fixed! - // This code allows us to compile memory intensive functions when only the Z - // register is available, otherwise we get the "Ran out of registers ..." - // assertion inside the regalloc. - // Here we avoid marking as not spillable live intervals that use the - // PTRDISPREGS class and have a size greater than 8, smaller ones - // get filtered out, generating better code. - if (strcmp(MF.getSubtarget().getRegisterInfo()->getRegClassName(mri.getRegClass(li.reg)), "PTRDISPREGS") == 0 && - li.getSize() > 8) { - totalWeight *= 10000.0F; - li.weight = normalizeSpillWeight(totalWeight, li.getSize(), numInstr); - } else { - li.markNotSpillable(); - } + li.markNotSpillable(); return; } diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 16391ccbc0a..18326f36b99 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -2588,18 +2588,20 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg, return 0; } + if (Stage == RS_Split || Stage == RS_Split2) { + // Try splitting VirtReg or interferences. + unsigned NewVRegSizeBefore = NewVRegs.size(); + unsigned PhysReg = trySplit(VirtReg, Order, NewVRegs); + if (PhysReg || (NewVRegs.size() - NewVRegSizeBefore)) + return PhysReg; + } + // If we couldn't allocate a register from spilling, there is probably some // invalid inline assembly. The base class wil report it. if (Stage >= RS_Done || !VirtReg.isSpillable()) return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters, Depth); - // Try splitting VirtReg or interferences. - unsigned NewVRegSizeBefore = NewVRegs.size(); - unsigned PhysReg = trySplit(VirtReg, Order, NewVRegs); - if (PhysReg || (NewVRegs.size() - NewVRegSizeBefore)) - return PhysReg; - // Finally spill VirtReg itself. if (EnableDeferredSpilling && getStage(VirtReg) < RS_Memory) { // TODO: This is experimental and in particular, we do not model diff --git a/test/CodeGen/AVR/high-pressure-on-ptrregs.ll b/test/CodeGen/AVR/high-pressure-on-ptrregs.ll index 73a26e723b8..41d80863e50 100644 --- a/test/CodeGen/AVR/high-pressure-on-ptrregs.ll +++ b/test/CodeGen/AVR/high-pressure-on-ptrregs.ll @@ -10,10 +10,6 @@ ; ; There is an existing bug filed for this issue - PR14879. ; -; LLVM should be able to handle this elegantly, because PTRREGS is a -; subset of DREGS, so we should be able to do cross-class copies in -; order to complete register allocation. -; ; The specific failure: ; LLVM ERROR: ran out of registers during register allocation ;