diff options
-rw-r--r-- | src/binaryen-c.cpp | 8 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 10 | ||||
-rw-r--r-- | src/pass.h | 3 | ||||
-rw-r--r-- | src/passes/Inlining.cpp | 2 | ||||
-rw-r--r-- | src/tools/optimization-options.h | 7 | ||||
-rw-r--r-- | test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.txt | 54 | ||||
-rw-r--r-- | test/passes/O3_inline-heavyweight-functions_flexible-inline-max-function-size=30.wast | 39 |
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) +) |