summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/CodeFolding.cpp22
-rw-r--r--test/lit/passes/code-folding-eh-old.wast191
2 files changed, 207 insertions, 6 deletions
diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp
index 5a18937bb..dc2301f9c 100644
--- a/src/passes/CodeFolding.cpp
+++ b/src/passes/CodeFolding.cpp
@@ -172,7 +172,7 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
}
}
- void visitReturn(Return* curr) {
+ void handleReturn(Expression* curr) {
if (!controlFlowStack.empty()) {
// we can easily optimize if we are at the end of the parent block
Block* parent = controlFlowStack.back()->dynCast<Block>();
@@ -186,6 +186,26 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
returnTails.push_back(Tail(curr, getCurrentPointer()));
}
+ void visitReturn(Return* curr) { handleReturn(curr); }
+
+ void visitCall(Call* curr) {
+ if (curr->isReturn) {
+ handleReturn(curr);
+ }
+ }
+
+ void visitCallIndirect(CallIndirect* curr) {
+ if (curr->isReturn) {
+ handleReturn(curr);
+ }
+ }
+
+ void visitCallRef(CallRef* curr) {
+ if (curr->isReturn) {
+ handleReturn(curr);
+ }
+ }
+
void visitBlock(Block* curr) {
if (curr->list.empty()) {
return;
diff --git a/test/lit/passes/code-folding-eh-old.wast b/test/lit/passes/code-folding-eh-old.wast
index 836df867c..05cd8db8b 100644
--- a/test/lit/passes/code-folding-eh-old.wast
+++ b/test/lit/passes/code-folding-eh-old.wast
@@ -6,7 +6,7 @@
;; CHECK: (tag $e-i32 (param i32))
(tag $e-i32 (param i32))
- ;; CHECK: (func $pop-test (type $0)
+ ;; CHECK: (func $pop-test (type $1)
;; CHECK-NEXT: (block $folding-inner0
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
@@ -67,12 +67,55 @@
)
)
- ;; CHECK: (func $foo (type $0)
+ ;; CHECK: (func $try-call-optimize-terminating-tails-success (type $0) (result i32)
+ ;; CHECK-NEXT: (block $folding-inner0
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (br $folding-inner0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (br $folding-inner0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $try-call-optimize-terminating-tails-success (result i32)
+ (try
+ (do
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (return (i32.const 0))
+ )
+ (catch_all
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (return (i32.const 0))
+ )
+ )
+ (i32.const 0)
+ )
+
+
+ ;; CHECK: (func $foo (type $1)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $foo)
- ;; CHECK: (func $try-call-optimize-terminating-tails (type $1) (result i32)
+ ;; CHECK: (func $try-call-optimize-terminating-tails (type $0) (result i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (call $foo)
@@ -116,7 +159,145 @@
(i32.const 0)
)
- ;; CHECK: (func $try-call-optimize-expression-tails (type $0)
+ ;; CHECK: (func $foo-i32 (type $0) (result i32)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ (func $foo-i32 (result i32)
+ (i32.const 0)
+ )
+
+ ;; CHECK: (func $try-call-optimize-terminating-tails-call-return (type $0) (result i32)
+ ;; CHECK-NEXT: (try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (call $foo-i32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (call $foo-i32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ (func $try-call-optimize-terminating-tails-call-return (result i32)
+ (try
+ (do
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ ;; Cannot be folded out of the try because it might throw.
+ (return (call $foo-i32))
+ )
+ (catch_all
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (return (call $foo-i32))
+ )
+ )
+ (i32.const 0)
+ )
+
+ ;; CHECK: (func $try-call-optimize-terminating-tails-return-call (type $0) (result i32)
+ ;; CHECK-NEXT: (block $folding-inner0
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (br $folding-inner0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (br $folding-inner0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return_call $foo-i32)
+ ;; CHECK-NEXT: )
+ (func $try-call-optimize-terminating-tails-return-call (result i32)
+ (try
+ (do
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (return_call $foo-i32)
+ )
+ (catch_all
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (return_call $foo-i32)
+ )
+ )
+ (i32.const 0)
+ )
+
+ ;; CHECK: (func $try-call-optimize-expression-tails-success (type $1)
+ ;; CHECK-NEXT: (block $x
+ ;; CHECK-NEXT: (try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (br $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (br $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $try-call-optimize-expression-tails-success
+ (block $x
+ (try
+ (do
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (br $x)
+ )
+ (catch_all
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (drop (i32.const 1))
+ (br $x)
+ )
+ )
+ (unreachable)
+ )
+ )
+
+ ;; CHECK: (func $try-call-optimize-expression-tails (type $1)
;; CHECK-NEXT: (block $x
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
@@ -156,7 +337,7 @@
)
)
- ;; CHECK: (func $if-arms-in-catch (type $1) (result i32)
+ ;; CHECK: (func $if-arms-in-catch (type $0) (result i32)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do