summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-11-16 09:22:57 -0800
committerGitHub <noreply@github.com>2017-11-16 09:22:57 -0800
commitdcdaa5de3b2c63a1349faacfe921527d972fc95c (patch)
tree74c88ccd054b2c419e0c76827e566b8d08f7d5b3
parent27474b7482ad2673ef3c9aca09aa443769e7447f (diff)
downloadbinaryen-dcdaa5de3b2c63a1349faacfe921527d972fc95c.tar.gz
binaryen-dcdaa5de3b2c63a1349faacfe921527d972fc95c.tar.bz2
binaryen-dcdaa5de3b2c63a1349faacfe921527d972fc95c.zip
Fix if copying (#1278)
* fix if copying - we should preserve the forced explicit type if there is one, and not just infer it from the arms. this adds a builder method for makeIf that receives a type to apply to the if, and for blocks a method that makes a block from a list, also with a variant with a provided type
-rw-r--r--src/ir/ExpressionManipulator.cpp10
-rw-r--r--src/wasm-builder.h32
-rw-r--r--test/passes/inlining.txt31
-rw-r--r--test/passes/inlining.wast29
4 files changed, 96 insertions, 6 deletions
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index aa2a10388..812c4f04b 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -38,16 +38,14 @@ Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom
}
Expression* visitBlock(Block *curr) {
- auto* ret = builder.makeBlock();
+ ExpressionList list(wasm.allocator);
for (Index i = 0; i < curr->list.size(); i++) {
- ret->list.push_back(copy(curr->list[i]));
+ list.push_back(copy(curr->list[i]));
}
- ret->name = curr->name;
- ret->finalize(curr->type);
- return ret;
+ return builder.makeBlock(curr->name, list, curr->type);
}
Expression* visitIf(If *curr) {
- return builder.makeIf(copy(curr->condition), copy(curr->ifTrue), copy(curr->ifFalse));
+ return builder.makeIf(copy(curr->condition), copy(curr->ifTrue), copy(curr->ifFalse), curr->type);
}
Expression* visitLoop(Loop *curr) {
return builder.makeLoop(curr->name, copy(curr->body));
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index bc670bb8f..8ab4cfec9 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -90,12 +90,44 @@ public:
ret->finalize();
return ret;
}
+ Block* makeBlock(const ExpressionList& items) {
+ auto* ret = allocator.alloc<Block>();
+ ret->list.set(items);
+ ret->finalize();
+ return ret;
+ }
+ Block* makeBlock(const ExpressionList& items, WasmType type) {
+ auto* ret = allocator.alloc<Block>();
+ ret->list.set(items);
+ ret->finalize(type);
+ return ret;
+ }
+ Block* makeBlock(Name name, const ExpressionList& items) {
+ auto* ret = allocator.alloc<Block>();
+ ret->name = name;
+ ret->list.set(items);
+ ret->finalize();
+ return ret;
+ }
+ Block* makeBlock(Name name, const ExpressionList& items, WasmType type) {
+ auto* ret = allocator.alloc<Block>();
+ ret->name = name;
+ ret->list.set(items);
+ ret->finalize(type);
+ return ret;
+ }
If* makeIf(Expression* condition, Expression* ifTrue, Expression* ifFalse = nullptr) {
auto* ret = allocator.alloc<If>();
ret->condition = condition; ret->ifTrue = ifTrue; ret->ifFalse = ifFalse;
ret->finalize();
return ret;
}
+ If* makeIf(Expression* condition, Expression* ifTrue, Expression* ifFalse, WasmType type) {
+ auto* ret = allocator.alloc<If>();
+ ret->condition = condition; ret->ifTrue = ifTrue; ret->ifFalse = ifFalse;
+ ret->finalize(type);
+ return ret;
+ }
Loop* makeLoop(Name name, Expression* body) {
auto* ret = allocator.alloc<Loop>();
ret->name = name; ret->body = body;
diff --git a/test/passes/inlining.txt b/test/passes/inlining.txt
index 3fd4e025b..67604971d 100644
--- a/test/passes/inlining.txt
+++ b/test/passes/inlining.txt
@@ -218,3 +218,34 @@
)
)
)
+(module
+ (type $T (func (param i32)))
+ (type $1 (func))
+ (table 10 anyfunc)
+ (memory $0 0)
+ (func $0 (; 0 ;) (type $1)
+ (block $__inlined_func$1
+ (call_indirect $T
+ (if (result i32)
+ (i32.const 0)
+ (unreachable)
+ (unreachable)
+ )
+ (i32.const 1)
+ )
+ )
+ )
+)
+(module
+ (type $0 (func))
+ (memory $0 0)
+ (func $1 (; 0 ;) (type $0)
+ (block $__inlined_func$0
+ (block $label$1
+ (br_table $label$1 $label$1
+ (i32.const 0)
+ )
+ )
+ )
+ )
+)
diff --git a/test/passes/inlining.wast b/test/passes/inlining.wast
index 38370addf..f68fb6703 100644
--- a/test/passes/inlining.wast
+++ b/test/passes/inlining.wast
@@ -145,4 +145,33 @@
)
)
)
+(module
+ (type $T (func (param i32)))
+ (table 10 anyfunc)
+ (func $0
+ (call $1)
+ )
+ (func $1
+ (call_indirect $T
+ (if (result i32) ;; if copy must preserve the forced type
+ (i32.const 0)
+ (unreachable)
+ (unreachable)
+ )
+ (i32.const 1)
+ )
+ )
+)
+(module
+ (func $0
+ (block $label$1 ;; copy this name
+ (br_table $label$1 $label$1
+ (i32.const 0)
+ )
+ )
+ )
+ (func $1
+ (call $0)
+ )
+)