Hoist spills within a basic block.

Try to move spills as early as possible in their basic block. This can
help eliminate interferences by shortening the live range being
spilled.

This fixes PR10221.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134776 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-07-09 00:25:03 +00:00
parent 439d05d587
commit 56573cc1ae
2 changed files with 63 additions and 3 deletions

View File

@ -303,7 +303,8 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
// Best spill candidate seen so far. This must dominate UseVNI.
SibValueInfo SVI(UseReg, UseVNI);
MachineBasicBlock *UseMBB = LIS.getMBBFromIndex(UseVNI->def);
unsigned SpillDepth = Loops.getLoopDepth(UseMBB);
MachineBasicBlock *SpillMBB = UseMBB;
unsigned SpillDepth = Loops.getLoopDepth(SpillMBB);
bool SeenOrigPHI = false; // Original PHI met.
do {
@ -316,15 +317,39 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
// Is this value a better spill candidate?
if (!isRegToSpill(Reg)) {
MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
if (MBB != UseMBB && MDT.dominates(MBB, UseMBB)) {
if (MBB == SpillMBB) {
// This is an alternative def earlier in the same MBB.
// Hoist the spill as far as possible in SpillMBB. This can ease
// register pressure:
//
// x = def
// y = use x
// s = copy x
//
// Hoisting the spill of s to immediately after the def removes the
// interference between x and y:
//
// x = def
// spill x
// y = use x<kill>
//
if (VNI->def < SVI.SpillVNI->def) {
DEBUG(dbgs() << " hoist in BB#" << MBB->getNumber() << ": "
<< PrintReg(Reg) << ':' << VNI->id << '@' << VNI->def
<< '\n');
SVI.SpillReg = Reg;
SVI.SpillVNI = VNI;
}
} else if (MBB != UseMBB && MDT.dominates(MBB, UseMBB)) {
// This is a valid spill location dominating UseVNI.
// Prefer to spill at a smaller loop depth.
unsigned Depth = Loops.getLoopDepth(MBB);
if (Depth < SpillDepth) {
if (Depth <= SpillDepth) {
DEBUG(dbgs() << " spill depth " << Depth << ": " << PrintReg(Reg)
<< ':' << VNI->id << '@' << VNI->def << '\n');
SVI.SpillReg = Reg;
SVI.SpillVNI = VNI;
SpillMBB = MBB;
SpillDepth = Depth;
}
}

View File

@ -0,0 +1,35 @@
; RUN: llc < %s -mtriple=x86_64-apple-macosx | FileCheck %s
; PR10221
;; The registers %x and %y must both spill across the finit call.
;; Check that they are spilled early enough that not copies are needed for the
;; fadd and fpext.
; CHECK: pr10221
; CHECK-NOT: movaps
; CHECK: movss
; CHECK-NEXT: movss
; CHECK-NEXT: addss
; CHECK-NEXT: cvtss2sd
; CHECK-NEXT: finit
define i32 @pr10221(float %x, float %y, i8** nocapture %_retval) nounwind uwtable ssp {
entry:
%add = fadd float %x, %y
%conv = fpext float %add to double
%call = tail call i32 @finit(double %conv) nounwind
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %return, label %if.end
if.end: ; preds = %entry
tail call void @foo(float %x, float %y) nounwind
br label %return
return: ; preds = %entry, %if.end
%retval.0 = phi i32 [ 0, %if.end ], [ 5, %entry ]
ret i32 %retval.0
}
declare i32 @finit(double)
declare void @foo(float, float)