Effect analysis for indirect call expressions#8625
Conversation
690ee8d to
75481a7
Compare
189d543 to
2630eff
Compare
75481a7 to
36a4fb5
Compare
|
Seems like JJ + Github don't play well when I'm on a branch based on another branch that had a merge commit. Will fix this after merging the other branch. |
When running in --closed-world, compute effects for indirect calls by unioning the effects of all potential functions of that type. In --closed-world, we assume that all references originate in our module, so the only possible functions that we don't know about are imports. Previously [we gave up on effects analysis](https://github.com/WebAssembly/binaryen/blob/29b2d42e8a748fbe1095696d58a52b7bf83e2253/src/passes/GlobalEffects.cpp#L83-L87) for indirect calls. Yields a very small byte count reduction in calcworker (3799354 - 3799297 = 57 bytes). Also shows no significant difference in Binaryen runtime: (0.1346069 -> 0.13375045 = <1% improvement, probably within noise). We expect more benefits after we're able to share indirect call effects with other passes, since currently they're only seen one layer up for callers of functions that indirectly call functions (see the newly-added tests for examples). Followups: * Share effect information per type with other passes besides just via Function::effects (#8625) * Exclude functions that don't have an address (i.e. functions that aren't the target of ref.func) from effect analysis () * Compute effects more precisely for exact + nullable/non-nullable references Part of #8615.
36a4fb5 to
e65a243
Compare
30a31e1 to
60665f3
Compare
60665f3 to
2156d99
Compare
7eed45c to
979db05
Compare
|
Will run the fuzzer for a few hours. |
|
Ran 3900 iterations with no issues. |
| // When types are rewritten globally, the target type inherits the effects of | ||
| // source type (see type-updating.cpp). If the type of just one function is | ||
| // rewritten, we don't update this, because such a rewrite is only valid | ||
| // if the function is not the target of an indirect call (otherwise the | ||
| // indirect call would have to be rewritten too). |
There was a problem hiding this comment.
I don't understand the second paragraph here.
It sounds like it might be an optimization (we save an update we don't need) - if so, it doesn't need to be in the header. But it sounds like it also might be an invariant, in which case I am confused?
70194ce to
038480b
Compare
|
(Sorry for the force-push, I thought it would be fine to force-push changes to the latest commit that hasn't been looked at yet, but it seems that that still messed with the comment history) |
|
Hmm, yeah, the force-push is making it hard to read the diff here. This is all I see from github's "compare changes" button, one comment changed: Not shown there is your new comment with Were there other changes? (In general I always recommend not force-pushing, but this is something I've had no success in convincing anyone about 😄 ) |
I have been endorsing this too. You can see changes with the "Compare" button, AFAIK it only compares one commit; when several changes have been pushed since you last reviewed a PR, Github doesn't show them as aggregate changes. (And worse if one of them is a force-push) |
kripken
left a comment
There was a problem hiding this comment.
Some testing comments (but I haven't read them all yet).
kripken
left a comment
There was a problem hiding this comment.
Nice!
Thanks for your patience with my comments.
| ;; RUN: foreach %s %t wasm-opt -all --closed-world --ignore-implicit-traps --generate-global-effects --vacuum -S -o - | filecheck %s | ||
|
|
||
| ;; Tests for aggregating effects from indirect calls in GlobalEffects when | ||
| ;; --closed-world is true. Continued from global-effects-closed-world.wast. |
There was a problem hiding this comment.
| ;; --closed-world is true. Continued from global-effects-closed-world.wast. | |
| ;; --closed-world is true. Continued from global-effects-closed-world.wast, | |
| ;; but adding --ignore-implicit-traps. |
Part of #8615. After #8609, we compute effects for indirect call expressions, but only reflect this in the call-site via the effects of the
Functionthat contains the indirect call. That let us reason about effects only one layer of indirection away, for example in the following module:If we know that an indirect call to $t can't possibly have any effects (e.g. its only potential target is a nop), we'd be able to optimize away
(call $a)but not the(call_ref)itself, since the effects only got stored in the effects of$a.This PR lets us reason about indirect call effects at the expression level within function bodies by adding a map from HeapType to effects
typeEffectsinwasm::Module. As a result we can completely optimize out thecall_refin the above example.Drive-by fixes:
Correctly setWill follow up in return_call with call.without.effects optimizes incorrectly #8693.branchesOutforreturn_calloncall.without.effects. Previously this would not have abranchesOuteffect which may have allowed incorrect reorderings (we shouldn't move an effectful expression above areturn_callbut we would have allowed this).