summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Inlining.cpp16
-rw-r--r--test/passes/inlining.txt75
-rw-r--r--test/passes/inlining.wast59
-rw-r--r--test/unit.fromasm5
-rw-r--r--test/unit.fromasm.clamp5
-rw-r--r--test/unit.fromasm.imprecise5
6 files changed, 154 insertions, 11 deletions
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 377aa5247..20becfe46 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -28,6 +28,7 @@
#include <pass.h>
#include <wasm-builder.h>
#include <ast_utils.h>
+#include <ast/literal-utils.h>
#include <parsing.h>
namespace wasm {
@@ -121,11 +122,12 @@ private:
// Core inlining logic. Modifies the outside function (adding locals as
// needed), and returns the inlined code.
static Expression* doInlining(Module* module, Function* into, InliningAction& action) {
+ Function* from = action.contents;
auto* call = (*action.callSite)->cast<Call>();
Builder builder(*module);
auto* block = Builder(*module).makeBlock();
block->type = call->type;
- block->name = Name(std::string("__inlined_func$") + action.contents->name.str);
+ block->name = Name(std::string("__inlined_func$") + from->name.str);
*action.callSite = block;
// set up a locals mapping
struct Updater : public PostWalker<Updater> {
@@ -145,15 +147,19 @@ static Expression* doInlining(Module* module, Function* into, InliningAction& ac
} updater;
updater.returnName = block->name;
updater.builder = &builder;
- for (Index i = 0; i < action.contents->getNumLocals(); i++) {
- updater.localMapping[i] = builder.addVar(into, action.contents->getLocalType(i));
+ for (Index i = 0; i < from->getNumLocals(); i++) {
+ updater.localMapping[i] = builder.addVar(into, from->getLocalType(i));
}
// assign the operands into the params
- for (Index i = 0; i < action.contents->params.size(); i++) {
+ for (Index i = 0; i < from->params.size(); i++) {
block->list.push_back(builder.makeSetLocal(updater.localMapping[i], call->operands[i]));
}
+ // zero out the vars (as we may be in a loop, and may depend on their zero-init value
+ for (Index i = 0; i < from->vars.size(); i++) {
+ block->list.push_back(builder.makeSetLocal(updater.localMapping[from->getVarIndexBase() + i], LiteralUtils::makeZero(from->vars[i], *module)));
+ }
// generate and update the inlined contents
- auto* contents = ExpressionManipulator::copy(action.contents->body, *module);
+ auto* contents = ExpressionManipulator::copy(from->body, *module);
updater.walk(contents);
block->list.push_back(contents);
return block;
diff --git a/test/passes/inlining.txt b/test/passes/inlining.txt
index 99f764351..838dd1f38 100644
--- a/test/passes/inlining.txt
+++ b/test/passes/inlining.txt
@@ -58,6 +58,9 @@
(block
(block $__inlined_func$with-local
(set_local $2
+ (f32.const 0)
+ )
+ (set_local $2
(f32.const 2.1418280601501465)
)
)
@@ -65,6 +68,9 @@
(block
(block $__inlined_func$with-local2
(set_local $3
+ (i64.const 0)
+ )
+ (set_local $3
(i64.const 4)
)
)
@@ -97,6 +103,9 @@
(set_local $5
(i64.const 890005350012)
)
+ (set_local $6
+ (f32.const 0)
+ )
(block
(drop
(get_local $4)
@@ -143,3 +152,69 @@
)
)
)
+(module
+ (type $0 (func (result i32)))
+ (type $1 (func (param f32 i32) (result i32)))
+ (type $2 (func))
+ (global $hangLimit (mut i32) (i32.const 25))
+ (memory $0 1 1)
+ (export "hangLimitInitializer" (func $hangLimitInitializer))
+ (func $func_4 (type $1) (param $0 f32) (param $1 i32) (result i32)
+ (local $2 i64)
+ (local $3 f64)
+ (local $4 f32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 f64)
+ (local $8 i32)
+ (loop $label$0 (result i32)
+ (block $block
+ (if
+ (i32.eqz
+ (get_global $hangLimit)
+ )
+ (return
+ (i32.const 54)
+ )
+ )
+ (set_global $hangLimit
+ (i32.sub
+ (get_global $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.eqz
+ (if (result i32)
+ (i32.const 1)
+ (if (result i32)
+ (i32.eqz
+ (block (result i32)
+ (block $__inlined_func$func_3 (result i32)
+ (set_local $8
+ (i32.const 0)
+ )
+ (select
+ (get_local $8)
+ (tee_local $8
+ (i32.const -1)
+ )
+ (i32.const 1)
+ )
+ )
+ )
+ )
+ (br $label$0)
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ )
+ )
+ (func $hangLimitInitializer (type $2)
+ (set_global $hangLimit
+ (i32.const 25)
+ )
+ )
+)
diff --git a/test/passes/inlining.wast b/test/passes/inlining.wast
index ce8b1b8be..38370addf 100644
--- a/test/passes/inlining.wast
+++ b/test/passes/inlining.wast
@@ -86,4 +86,63 @@
)
)
)
+(module
+ (global $hangLimit (mut i32) (i32.const 25))
+ (memory $0 1 1)
+ (export "hangLimitInitializer" (func $hangLimitInitializer))
+ (func $func_3 (result i32)
+ (local $0 i32)
+ (select
+ (get_local $0) ;; we depend on the zero-init value here, so it must be set when inlining!
+ (tee_local $0
+ (i32.const -1)
+ )
+ (i32.const 1)
+ )
+ )
+ (func $func_4 (param $0 f32) (param $1 i32) (result i32)
+ (local $2 i64)
+ (local $3 f64)
+ (local $4 f32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 f64)
+ (loop $label$0 (result i32)
+ (block
+ (if
+ (i32.eqz
+ (get_global $hangLimit)
+ )
+ (return
+ (i32.const 54)
+ )
+ )
+ (set_global $hangLimit
+ (i32.sub
+ (get_global $hangLimit)
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.eqz
+ (if (result i32)
+ (i32.const 1)
+ (if (result i32)
+ (i32.eqz
+ (call $func_3)
+ )
+ (br $label$0)
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ )
+ )
+ (func $hangLimitInitializer
+ (set_global $hangLimit
+ (i32.const 25)
+ )
+ )
+)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 7ac63bfcc..ec97a3320 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -1164,7 +1164,6 @@
)
(func $keepAlive
(local $0 i32)
- (local $1 i32)
(drop
(call $sqrts
(f64.const 3.14159)
@@ -1200,7 +1199,9 @@
(i32.const 17)
)
(call_indirect $FUNCSIG$vi
- (get_local $1)
+ (tee_local $0
+ (i32.const 0)
+ )
(block (result i32)
(set_global $Int
(i32.const 1)
diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp
index 8f3e387ae..b110204f9 100644
--- a/test/unit.fromasm.clamp
+++ b/test/unit.fromasm.clamp
@@ -1188,7 +1188,6 @@
)
(func $keepAlive
(local $0 i32)
- (local $1 i32)
(drop
(call $sqrts
(f64.const 3.14159)
@@ -1224,7 +1223,9 @@
(i32.const 17)
)
(call_indirect $FUNCSIG$vi
- (get_local $1)
+ (tee_local $0
+ (i32.const 0)
+ )
(block (result i32)
(set_global $Int
(i32.const 1)
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index 17c9109c3..13c29f151 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -1126,7 +1126,6 @@
)
(func $keepAlive
(local $0 i32)
- (local $1 i32)
(drop
(call $sqrts
(f64.const 3.14159)
@@ -1152,7 +1151,9 @@
(i32.const 17)
)
(call_indirect $FUNCSIG$vi
- (get_local $1)
+ (tee_local $0
+ (i32.const 0)
+ )
(block (result i32)
(set_global $Int
(i32.const 1)