-
Notifications
You must be signed in to change notification settings - Fork 786
StackIR: Run StackIR during binary writing #6568
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
Conversation
Could we simplify the printing situation by generating StackIR both in the binary writer and also separately on demand when printing, rather than requiring the printer to depend on the binary writer? |
Good idea, yeah, I can try that direction. Will take some work though... |
Ok, I still need to clean up some comments and such, but I think this now has the right shape following your suggestion. I went all the way now and removed all StackIR from |
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.
Nice, removing StackIR entirely from wasm.h seems like a huge win, conceptually, at least. I'd be happy landing this.
Yeah, I think the |
(Also fuzzed and verified no code size/metadce changes on Emscripten.) |
#6859) This is in quite ancient code, so it's a long-standing issue, but it got worse when we enabled StackIR in more situations (#6568), which made it more noticeable, I think. For example, testing on test_biggerswitch in Emscripten, the LLVM part is pretty slow too so the Binaryen slowdown didn't stand out hugely, but just doing wasm-opt --optimize-level=2 input.wasm -o output.wasm (that is, do no work, but set the optimize level to 2 so that StackIR opts are run) used to take 28 seconds (!). With this PR that goes down to less than 1.
In WebAssembly/binaryen#6568, StackIR was changed from a set of passes to a global option. This meant that the `true` argument passed into _BinaryenModuleAllocateAndWriteStackIR (to optimize the StackIR) no longer had an effect. This commit restores that and also runs the optimizations under the same {optimize,shrink}Levels as wasm-opt.
Previously we had passes
--generate-stack-ir
,--optimize-stack-ir
,--print-stack-ir
that could be run like any other passes. After generating StackIR it was stashed on
the function and invalidated if we modified BinaryenIR. If it wasn't invalidated then
it was used during binary writing. This PR switches things so that we optionally
generate, optimize, and print StackIR only during binary writing.
This is almost NFC, but there are some minor noticeable differences:
has StackIR
in the text format when we see it is there. Itwill not be there during normal printing, as it is only present during binary writing.
(but
--print-stack-ir
still works as before; as mentioned above it runs during writing).--generate/optimize/print-stack-ir
change from being passes to being flags thatcontrol that behavior instead. As passes, their order on the commandline mattered,
while now it does not, and they only "globally" affect things during writing.
optimize
" tothe StackIR APIs. Whether we optimize is handled by
--optimize-stack-ir
which isset like other optimization flags on the
PassOptions
object, so we don't need theold option to those C APIs.
The benefits this means to bring are
them during binary writing we can make that change if we want it: it would be a
small change to the binary writing process to always generate StackIR and
optimize it.
br_if
thatneeds extra work due to type system differences with the wasm spec. After this
PR we can make such dependencies if we want them, both because of the previous
point and also that we no longer "split" binary writing across the codebase: before
the
--generate-stack-ir
pass began the binary writing process, in effect, and so itstashed StackIR for the writing later. If we want more things, like
br_if
lowering,then we'd have more to stash. Doing it all during binary writing avoids that, since
nothing is done ahead of time.
invalidate StackIR during passes (no longer needed since it happens after passes
run), and the new wasm EH lowering logic no longer needs to do anything special
for StackIR (things just work properly: if we are optimizing, then during binary
writing we'll emit and optimize StackIR).
In more detail, this moves
passes/StackIR.cpp
towasm/wasm-stack-opts.cpp
.Those are all the StackIR opts and they are unchanged. Otherwise the binary
writing logic calls a
StackIROptimizer
that does those opts (if we are doingthem). The binary writing logic still generates and optimizes StackIR in parallel,
so this should have no downside in compile times.
Several tests change due to losing
(; has StackIR ;)
comments, as explainedabove. A more significant change happens in e.g.
O2_print-stack-ir
as the--print-stack-ir
flag is a global setting, affecting writing, which happens at theend, so the order of the outputs is reversed (before it was a pass that executed
according to the order on the commandline); the contents are unchanged though.