1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[ShrinkWrapping] Handle restores on no-return paths

Shrink-wrapping uses post-dominators to find a restore point that
post-dominates all the uses of CSR / stack.

The way dominator trees are modeled in LLVM today is that unreachable
blocks are not present in a generic dominator tree, so, an unreachable node is
dominated by anything: include/llvm/Support/GenericDomTree.h:467.

Since for post-dominators, a no-return block is considered
"unreachable", calling findNearestCommonDominator on an unreachable node
A and a non-unreachable node B, will return B, which can be false. If we
find such node, we bail out since there is no good restore point
available.

rdar://problem/30186931

llvm-svn: 303130
This commit is contained in:
Francis Visoiu Mistrih 2017-05-15 23:13:35 +00:00
parent 44299ec1d0
commit 6212dd268d
3 changed files with 60 additions and 5 deletions

View File

@ -282,8 +282,14 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
if (!Restore)
Restore = &MBB;
else
else if (MPDT->getNode(&MBB)) // If the block is not in the post dom tree, it
// means the block never returns. If that's the
// case, we don't want to call
// `findNearestCommonDominator`, which will
// return `Restore`.
Restore = MPDT->findNearestCommonDominator(Restore, &MBB);
else
Restore = nullptr; // Abort, we can't find a restore point in this case.
// Make sure we would be able to insert the restore code before the
// terminator.
@ -293,7 +299,7 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB,
continue;
// One of the terminator needs to happen before the restore point.
if (MBB.succ_empty()) {
Restore = nullptr;
Restore = nullptr; // Abort, we can't find a restore point in this case.
break;
}
// Look for a restore point that post-dominates all the successors.

View File

@ -9,7 +9,7 @@
; CHECK-NEXT: b
; CHECK: [[JUMPTARGET]]:{{.*}}%if.else173
; CHECK-NEXT: mov.w
; CHECK-NEXT: bx lr
; CHECK-NEXT: pop
; CHECK-NEXT: %if.else145
; CHECK-NEXT: mov.w

View File

@ -270,8 +270,6 @@ if.end: ; preds = %if.else, %for.end
ret i32 %sum.1
}
declare void @somethingElse(...)
; Check with a more complex case that we do not have restore within the loop and
; save outside.
; CHECK-LABEL: loopInfoRestoreOutsideLoop:
@ -982,3 +980,54 @@ for.inc:
}
attributes #4 = { "no-frame-pointer-elim"="true" }
@x = external global i32, align 4
@y = external global i32, align 4
; The post-dominator tree does not include the branch containing the infinite
; loop, which can occur into a misplacement of the restore block, if we're
; looking for the nearest common post-dominator of an "unreachable" block.
; CHECK-LABEL: infiniteLoopNoSuccessor:
; CHECK: ## BB#0:
; Make sure the prologue happens in the entry block.
; CHECK-NEXT: pushq %rbp
; ...
; Make sure we don't shrink-wrap.
; CHECK: ## BB#1
; CHECK-NOT: pushq %rbp
; ...
; Make sure the epilogue happens in the exit block.
; CHECK: ## BB#5
; CHECK: popq %rbp
; CHECK-NEXT: retq
define void @infiniteLoopNoSuccessor() #5 {
%1 = load i32, i32* @x, align 4
%2 = icmp ne i32 %1, 0
br i1 %2, label %3, label %4
; <label>:3:
store i32 0, i32* @x, align 4
br label %4
; <label>:4:
call void (...) @somethingElse()
%5 = load i32, i32* @y, align 4
%6 = icmp ne i32 %5, 0
br i1 %6, label %10, label %7
; <label>:7:
%8 = call i32 (...) @something()
br label %9
; <label>:9:
call void (...) @somethingElse()
br label %9
; <label>:10:
ret void
}
declare void @somethingElse(...)
attributes #5 = { nounwind "no-frame-pointer-elim-non-leaf" }