Skip to content

Commit 2ffe187

Browse files
authored
Inlining: Make MaxCombinedBinarySize configurable (WebAssembly#7820)
--inline-max-combined-binary-size=N (or -imcbs) sets a maximum to the combined binary size after inlining, which will prevent inlining of things that would cross that limit. This can avoid generating very large functions.
1 parent cd37223 commit 2ffe187

File tree

9 files changed

+868
-11
lines changed

9 files changed

+868
-11
lines changed

src/binaryen-c.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5754,6 +5754,14 @@ void BinaryenSetFlexibleInlineMaxSize(BinaryenIndex size) {
57545754
globalPassOptions.inlining.flexibleInlineMaxSize = size;
57555755
}
57565756

5757+
BinaryenIndex BinaryenGetMaxCombinedBinarySize(void) {
5758+
return globalPassOptions.inlining.maxCombinedBinarySize;
5759+
}
5760+
5761+
void BinaryenSetMaxCombinedBinarySize(BinaryenIndex size) {
5762+
globalPassOptions.inlining.maxCombinedBinarySize = size;
5763+
}
5764+
57575765
BinaryenIndex BinaryenGetOneCallerInlineMaxSize(void) {
57585766
return globalPassOptions.inlining.oneCallerInlineMaxSize;
57595767
}

src/binaryen-c.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,14 @@ BINARYEN_API BinaryenIndex BinaryenGetFlexibleInlineMaxSize(void);
31483148
// Applies to all modules, globally.
31493149
BINARYEN_API void BinaryenSetFlexibleInlineMaxSize(BinaryenIndex size);
31503150

3151+
// Gets the limit for the combined size of the code after inlining.
3152+
// Applies to all modules, globally.
3153+
BINARYEN_API BinaryenIndex BinaryenGetMaxCombinedBinarySize(void);
3154+
3155+
// Sets the limit for the combined size of the code after inlining.
3156+
// Applies to all modules, globally.
3157+
BINARYEN_API void BinaryenSetMaxCombinedBinarySize(BinaryenIndex size);
3158+
31513159
// Gets the function size which we inline when there is only one caller.
31523160
// Applies to all modules, globally.
31533161
BINARYEN_API BinaryenIndex BinaryenGetOneCallerInlineMaxSize(void);

src/pass.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ struct InliningOptions {
8989
// This is checked after alwaysInlineMaxSize and oneCallerInlineMaxSize, but
9090
// the order normally won't matter.
9191
Index flexibleInlineMaxSize = 20;
92+
// The limit for the combined size of the code after inlining.
93+
// We have an absolute limit in order to avoid extremely-large sizes after
94+
// inlining, as they may hit limits in VMs and/or slow down startup
95+
// (measurements there indicate something like ~1 second to optimize a 100K
96+
// function). See e.g.
97+
// https://github.com/WebAssembly/binaryen/pull/3730#issuecomment-867939138
98+
// https://github.com/emscripten-core/emscripten/issues/13899#issuecomment-825073344
99+
// The limit is arbitrary, but based on the links above. It is a very high
100+
// value that should appear very rarely in practice (for example, it does
101+
// not occur on the Emscripten benchmark suite of real-world codebases).
102+
Index maxCombinedBinarySize = 400 * 1024;
92103
// Loops usually mean the function does heavy work, so the call overhead
93104
// is not significant and we do not inline such functions by default.
94105
bool allowFunctionsWithLoops = false;

src/passes/Inlining.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,21 +1501,13 @@ struct Inlining : public Pass {
15011501
}
15021502

15031503
// Checks if the combined size of the code after inlining is under the
1504-
// absolute size limit. We have an absolute limit in order to avoid
1505-
// extremely-large sizes after inlining, as they may hit limits in VMs and/or
1506-
// slow down startup (measurements there indicate something like ~1 second to
1507-
// optimize a 100K function). See e.g.
1508-
// https://github.com/WebAssembly/binaryen/pull/3730#issuecomment-867939138
1509-
// https://github.com/emscripten-core/emscripten/issues/13899#issuecomment-825073344
1504+
// absolute size limit.
15101505
bool isUnderSizeLimit(Name target, Name source) {
15111506
// Estimate the combined binary size from the number of instructions.
15121507
auto combinedSize = infos[target].size + infos[source].size;
15131508
auto estimatedBinarySize = Measurer::BytesPerExpr * combinedSize;
1514-
// The limit is arbitrary, but based on the links above. It is a very high
1515-
// value that should appear very rarely in practice (for example, it does
1516-
// not occur on the Emscripten benchmark suite of real-world codebases).
1517-
const Index MaxCombinedBinarySize = 400 * 1024;
1518-
return estimatedBinarySize < MaxCombinedBinarySize;
1509+
auto& options = getPassRunner()->options;
1510+
return estimatedBinarySize < options.inlining.maxCombinedBinarySize;
15191511
}
15201512
};
15211513

src/tools/optimization-options.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,17 @@ struct OptimizationOptions : public ToolOptions {
246246
passOptions.inlining.oneCallerInlineMaxSize =
247247
static_cast<Index>(atoi(argument.c_str()));
248248
})
249+
.add("--inline-max-combined-binary-size",
250+
"-imcbs",
251+
"Max size of combined functions after inlining. "
252+
"Default: " +
253+
std::to_string(InliningOptions().maxCombinedBinarySize),
254+
OptimizationOptionsCategory,
255+
Options::Arguments::One,
256+
[this](Options* o, const std::string& argument) {
257+
passOptions.inlining.maxCombinedBinarySize =
258+
static_cast<Index>(atoi(argument.c_str()));
259+
})
249260
.add("--inline-functions-with-loops",
250261
"-ifwl",
251262
"Allow inlining functions with loops",

test/lit/help/wasm-metadce.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,9 @@
634634
;; CHECK-NEXT: caller (default -1, which means
635635
;; CHECK-NEXT: all such functions are inlined)
636636
;; CHECK-NEXT:
637+
;; CHECK-NEXT: --inline-max-combined-binary-size,-imcbs Max size of combined functions
638+
;; CHECK-NEXT: after inlining. Default: 409600
639+
;; CHECK-NEXT:
637640
;; CHECK-NEXT: --inline-functions-with-loops,-ifwl Allow inlining functions with
638641
;; CHECK-NEXT: loops
639642
;; CHECK-NEXT:

test/lit/help/wasm-opt.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,9 @@
658658
;; CHECK-NEXT: caller (default -1, which means
659659
;; CHECK-NEXT: all such functions are inlined)
660660
;; CHECK-NEXT:
661+
;; CHECK-NEXT: --inline-max-combined-binary-size,-imcbs Max size of combined functions
662+
;; CHECK-NEXT: after inlining. Default: 409600
663+
;; CHECK-NEXT:
661664
;; CHECK-NEXT: --inline-functions-with-loops,-ifwl Allow inlining functions with
662665
;; CHECK-NEXT: loops
663666
;; CHECK-NEXT:

test/lit/help/wasm2js.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@
598598
;; CHECK-NEXT: caller (default -1, which means
599599
;; CHECK-NEXT: all such functions are inlined)
600600
;; CHECK-NEXT:
601+
;; CHECK-NEXT: --inline-max-combined-binary-size,-imcbs Max size of combined functions
602+
;; CHECK-NEXT: after inlining. Default: 409600
603+
;; CHECK-NEXT:
601604
;; CHECK-NEXT: --inline-functions-with-loops,-ifwl Allow inlining functions with
602605
;; CHECK-NEXT: loops
603606
;; CHECK-NEXT:

0 commit comments

Comments
 (0)