summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-07-09 00:25:03 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-07-09 00:25:03 +0000
commit56573cc1aee419b5cc9e3446a59a73577bf26fac (patch)
tree04d94a1e6f3979f9a4483f7dfacd7318c21d8e8b
parent439d05d587b225d912ece9ce038ae298bc55e1c2 (diff)
downloadllvm-56573cc1aee419b5cc9e3446a59a73577bf26fac.tar.gz
llvm-56573cc1aee419b5cc9e3446a59a73577bf26fac.tar.bz2
llvm-56573cc1aee419b5cc9e3446a59a73577bf26fac.tar.xz
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
-rw-r--r--lib/CodeGen/InlineSpiller.cpp31
-rw-r--r--test/CodeGen/X86/reghinting.ll35
2 files changed, 63 insertions, 3 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 4bd35c3812..44e87ae972 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -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;
}
}
diff --git a/test/CodeGen/X86/reghinting.ll b/test/CodeGen/X86/reghinting.ll
new file mode 100644
index 0000000000..87f65ed624
--- /dev/null
+++ b/test/CodeGen/X86/reghinting.ll
@@ -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)