diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-11-16 09:22:57 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-16 09:22:57 -0800 |
commit | dcdaa5de3b2c63a1349faacfe921527d972fc95c (patch) | |
tree | 74c88ccd054b2c419e0c76827e566b8d08f7d5b3 | |
parent | 27474b7482ad2673ef3c9aca09aa443769e7447f (diff) | |
download | binaryen-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.cpp | 10 | ||||
-rw-r--r-- | src/wasm-builder.h | 32 | ||||
-rw-r--r-- | test/passes/inlining.txt | 31 | ||||
-rw-r--r-- | test/passes/inlining.wast | 29 |
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) + ) +) |