summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/binaryen-c.cpp8
-rw-r--r--src/js/binaryen.js-post.js10
-rw-r--r--src/pass.h3
-rw-r--r--src/passes/Inlining.cpp2
-rw-r--r--src/tools/optimization-options.h7
-rw-r--r--test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.txt54
-rw-r--r--test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.wast39
7 files changed, 122 insertions, 1 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 3e85a417b..6776b785c 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -3528,6 +3528,14 @@ void BinaryenSetOneCallerInlineMaxSize(BinaryenIndex size) {
globalPassOptions.inlining.oneCallerInlineMaxSize = size;
}
+bool BinaryenGetAllowHeavyweight(void) {
+ return globalPassOptions.inlining.allowHeavyweight;
+}
+
+void BinaryenSetAllowHeavyweight(bool enabled) {
+ globalPassOptions.inlining.allowHeavyweight = enabled;
+}
+
void BinaryenModuleRunPasses(BinaryenModuleRef module,
const char** passes,
BinaryenIndex numPasses) {
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index a9244c2d2..f8a0b8590 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -3030,6 +3030,16 @@ Module['setOneCallerInlineMaxSize'] = function(size) {
Module['_BinaryenSetOneCallerInlineMaxSize'](size);
};
+// Gets the value which allow inline functions that are not "lightweight".
+Module['getAllowHeavyweight'] = function() {
+ return Module['_BinaryenGetAllowHeavyweight']();
+};
+
+// Sets the value which allow inline functions that are not "lightweight".
+Module['setAllowHeavyweight'] = function(value) {
+ Module['_BinaryenSetAllowHeavyweight'](value);
+};
+
// Expression wrappers
// Makes a wrapper class with the specified static members while
diff --git a/src/pass.h b/src/pass.h
index 8b8e73fa0..f6dd52128 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -77,6 +77,9 @@ struct InliningOptions {
// Function size which we inline when there is only one caller.
// FIXME: this should logically be higher than flexibleInlineMaxSize.
Index oneCallerInlineMaxSize = 15;
+ // Allow inlining of functions that are not "lightweight" in the sense the
+ // inlining pass estimates.
+ bool allowHeavyweight = false;
};
struct PassOptions {
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 5737359a3..c8c8a3f7b 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -84,7 +84,7 @@ struct FunctionInfo {
// about size, and if it's lightweight so a good candidate for
// speeding us up.
return options.optimizeLevel >= 3 && options.shrinkLevel == 0 &&
- lightweight;
+ (lightweight || options.inlining.allowHeavyweight);
}
};
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index ef5a7d67a..ff43b7213 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -165,6 +165,13 @@ struct OptimizationOptions : public ToolOptions {
passOptions.inlining.oneCallerInlineMaxSize =
static_cast<Index>(atoi(argument.c_str()));
})
+ .add("--inline-heavyweight-functions",
+ "-ihf",
+ "Allow inlining heavyweight functions",
+ Options::Arguments::Zero,
+ [this](Options* o, const std::string&) {
+ passOptions.inlining.allowHeavyweight = true;
+ })
.add("--ignore-implicit-traps",
"-iit",
"Optimize under the helpful assumption that no surprising traps "
diff --git a/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.txt b/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.txt
new file mode 100644
index 000000000..685ba4513
--- /dev/null
+++ b/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.txt
@@ -0,0 +1,54 @@
+(module
+ (type $i32_=>_i32 (func (param i32) (result i32)))
+ (memory $memory 0)
+ (export "test" (func $test))
+ (export "t0" (func $test))
+ (export "t1" (func $t1))
+ (export "memory" (memory $memory))
+ (func $test (; has Stack IR ;) (param $0 i32) (result i32)
+ (loop $L0
+ (if
+ (i32.ge_s
+ (local.get $0)
+ (i32.const 0)
+ )
+ (block
+ (local.set $0
+ (i32.sub
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (br $L0)
+ )
+ )
+ )
+ (local.get $0)
+ )
+ (func $t1 (; has Stack IR ;) (param $0 i32) (result i32)
+ (local.set $0
+ (i32.add
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (loop $L0
+ (if
+ (i32.ge_s
+ (local.get $0)
+ (i32.const 0)
+ )
+ (block
+ (local.set $0
+ (i32.sub
+ (local.get $0)
+ (i32.const 1)
+ )
+ )
+ (br $L0)
+ )
+ )
+ )
+ (local.get $0)
+ )
+)
diff --git a/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.wast b/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.wast
new file mode 100644
index 000000000..ec8e5bfe5
--- /dev/null
+++ b/test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.wast
@@ -0,0 +1,39 @@
+(module
+ (type $t0 (func (param i32) (result i32)))
+ (func $test (export "test") (type $t0) (param $p0 i32) (result i32)
+ (loop $L0
+ (if $I1
+ (i32.ge_s
+ (local.get $p0)
+ (i32.const 0)
+ )
+ (then
+ (local.set $p0
+ (i32.sub
+ (local.get $p0)
+ (i32.const 1)
+ )
+ )
+ (br $L0)
+ )
+ )
+ )
+ (local.get $p0)
+ )
+
+ (func $t0 (export "t0") (type $t0) (param $p0 i32) (result i32)
+ (call $test
+ (local.get $p0)
+ )
+ )
+
+ (func $t1 (export "t1") (type $t0) (param $p0 i32) (result i32)
+ (call $test
+ (i32.add
+ (local.get $p0)
+ (i32.const 1)
+ )
+ )
+ )
+ (memory $memory (export "memory") 0)
+)