forked from OSchip/llvm-project
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. llvm-svn: 134776
This commit is contained in:
parent
02a07299b7
commit
bf6afec312
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue