Skip to content
This repository has been archived by the owner on Sep 2, 2018. It is now read-only.

Commit

Permalink
[RegAllocGreedy] Attempt to split unspillable live intervals
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Dylan McKay committed Sep 29, 2016
1 parent 600864b commit e9d48fc
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 24 deletions.
15 changes: 1 addition & 14 deletions lib/CodeGen/CalcSpillWeights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
14 changes: 8 additions & 6 deletions lib/CodeGen/RegAllocGreedy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2556,18 +2556,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
Expand Down
4 changes: 0 additions & 4 deletions test/CodeGen/AVR/high-pressure-on-ptrregs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
;
Expand Down

0 comments on commit e9d48fc

Please sign in to comment.