-
Notifications
You must be signed in to change notification settings - Fork 786
Always inline trivial calls that always shrink #7669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
A "trivial call" is a function that just calls another function. (func $foo ... (call $target ...)) Currently we inline these functions always only when not optimizing for code size. When optimizing for code size, these functions can always be inlined when 1. The arguments to `$target` are all function argument locals. 2. The locals are not used more than once 3. The locals are used in the same order they appear in the function arguments. When these hold, inlining `$foo` never increases code size as it doesn't cause introducing more locals at call sites. Improve `FunctionInfo` type and `FunctionInfoScanner` to annotate functions with "trivial call" information that also contains whether inlining shrinks code size. If a function shrinks when inlined always inline it even with `-Os`. Otherwise inline it as before, i.e. when not optimizing for code size.
;; CHECK-NEXT: (local.get $17) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little bit verbose. Should we run a simple pass to clean this up? (eliminate blocks and locals)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have --inlining-optimizing
for that, and that is what the normal pass pipeline uses. --inlining
without optimizing is mainly useful for debugging and tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. --inlining-optimizing
simplifies the wat in this test quite a bit. Should I use it in these tests, or do we prefer testing smaller units of code with just --inlining
?
} | ||
// Trivial calls are already handled. Inline if | ||
// 1. The function doesn't have calls, and | ||
// 2. The function doesn't have loops, or we allow inlining with loops. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworded the old comment block here but it just repeats the single line of code below, so I think we can also just drop this comment.
@kripken It looks like this revealed an existing undefined behavior in this line: binaryen/src/passes/OptimizeInstructions.cpp Line 3612 in 8470f1b
Apparently Lines 267 to 270 in 8470f1b
Is this a blocker? It looks like an existing issue that |
Currently a "trivial call" is a function that just calls another function.
Where the arguments to
$target
are all flat instructions likelocal.get
, orconsts.
Currently we inline these functions always only when not optimizing for code
size.
When optimizing for code size, these functions can always be inlined when
$target
are all function argument locals.$foo
's signature.When these hold, inlining
$foo
never increases code size as it doesn't causeintroducing more locals (or
drop
s etc.) at the call sites.$foo
above when these hold looks like this:Update
FunctionInfo
type andFunctionInfoScanner
to annotate functions withmore detailed "trivial call" information that also contains whether inlining
shrinks code size.
If a function shrinks when inlined always inline it even with
-Os
.Otherwise inline it as before, i.e. when not optimizing for code size.