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:
parent
44299ec1d0
commit
6212dd268d
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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" }
|
||||
|
Loading…
Reference in New Issue
Block a user