summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-03-25 10:34:54 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-03-25 10:34:54 +0000
commitf8c8a9cbb40972b07432d6b25d1a351556485b1e (patch)
tree11ea4111259fbecf4e56c70ca691ba8f8c266ffe /test
parent0417d7dca09b0beb7f27045b0ab9e93096905c74 (diff)
downloadllvm-f8c8a9cbb40972b07432d6b25d1a351556485b1e.tar.gz
llvm-f8c8a9cbb40972b07432d6b25d1a351556485b1e.tar.bz2
llvm-f8c8a9cbb40972b07432d6b25d1a351556485b1e.tar.xz
Teach the function cloner (and thus the inliner) to simplify PHINodes
aggressively. There are lots of dire warnings about this being expensive that seem to predate switching to the TrackingVH-based value remapper that is automatically updated on RAUW. This makes it easy to not just prune single-entry PHIs, but to fully simplify PHIs, and to recursively simplify the newly inlined code to propagate PHINode simplifications. This introduces a bit of a thorny problem though. We may end up simplifying a branch condition to a constant when we fold PHINodes, and we would like to nuke any dead blocks resulting from this so that time isn't wasted continually analyzing them, but this isn't easy. Deleting basic blocks *after* they are fully cloned and mapped into the new function currently requires manually updating the value map. The last piece of the simplification-during-inlining puzzle will require either switching to WeakVH mappings or some other piece of refactoring. I've left a FIXME in the testcase about this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153410 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/Inline/inline_cleanup.ll36
1 files changed, 33 insertions, 3 deletions
diff --git a/test/Transforms/Inline/inline_cleanup.ll b/test/Transforms/Inline/inline_cleanup.ll
index 7583dddea9..cf57cf0641 100644
--- a/test/Transforms/Inline/inline_cleanup.ll
+++ b/test/Transforms/Inline/inline_cleanup.ll
@@ -74,7 +74,7 @@ entry:
declare void @f(i32 %x)
-define void @inner2(i32 %x, i32 %y, i32 %z) {
+define void @inner2(i32 %x, i32 %y, i32 %z, i1 %b) {
entry:
%cmp1 = icmp ne i32 %x, 0
br i1 %cmp1, label %then1, label %end1
@@ -102,17 +102,47 @@ then3:
br label %end3
end3:
+ br i1 %b, label %end3.1, label %end3.2
+
+end3.1:
+ %x3.1 = or i32 %x, 10
+ br label %end3.3
+
+end3.2:
+ %x3.2 = or i32 %x, 10
+ br label %end3.3
+
+end3.3:
+ %x3.3 = phi i32 [ %x3.1, %end3.1 ], [ %x3.2, %end3.2 ]
+ %cmp4 = icmp slt i32 %x3.3, 1
+ br i1 %cmp4, label %then4, label %end4
+
+then4:
+ call void @f(i32 %x3.3)
+ br label %end4
+
+end4:
ret void
}
-define void @outer2(i32 %z) {
+define void @outer2(i32 %z, i1 %b) {
; Ensure that after inlining, none of the blocks with a call to @f actually
; make it through inlining.
; CHECK: define void @outer2
; CHECK-NOT: call
+;
+; FIXME: Currently, we aren't smart enough to delete the last dead basic block.
+; However, we do make the condition a constant. Check that at least until we can
+; start removing the block itself.
+; CHECK: br i1 false, label %[[LABEL:[a-z0-9_.]+]],
+; CHECK-NOT: call
+; CHECK: [[LABEL]]:
+; CHECK-NEXT: call void @f(i32 10)
+; CHECK-NOT: call
+;
; CHECK: ret void
entry:
- call void @inner2(i32 0, i32 -1, i32 %z)
+ call void @inner2(i32 0, i32 -1, i32 %z, i1 %b)
ret void
}