Skip to content

Add PostAsyncify* passes#2348

Closed
kripken wants to merge 0 commit intomasterfrom
lazy
Closed

Add PostAsyncify* passes#2348
kripken wants to merge 0 commit intomasterfrom
lazy

Conversation

@kripken
Copy link
Copy Markdown
Member

@kripken kripken commented Sep 20, 2019

These two passes are meant to be run after Asyncify has been run. One pass assumes that we will unwind if we reach an import, but never rewind. The other pass assumes that we may rewind but will never unwind.

This is meant to help with lazy code loading, that is, the ability for an initially-downloaded wasm to not contain all the code, and if code not present there is called, we download all the rest and continue with that. That could work something like this:

  • The wasm is created. It contains calls to a special import for lazy code loading.
  • Asyncify is run on it.
  • The initially downloaded wasm is created by running --post-asyncify-always-and-only-unwind: if the special import for lazy code loading is called, we will definitely unwind, and we won't rewind in this binary.
  • The lazily downloaded wasm is created by running --post-asyncify-never-unwind: we will rewind into this binary, but no longer need support for unwinding.
  • (Optionally, there could also be a third wasm, which has not had Asyncify run on it, and which we'd swap to for max speed.)

These --post-asyncify passes allow the optimizer to do a lot of work, especially for the initially downloaded wasm if we have lots of calls to the lazy code loading import. In that case the optimizer will see that those calls unwind, which means the code after them is not reached, potentially making lots of code dead and removable.

This requires some runtime code to load the second wasm etc., which for Emscripten I'll implement in a PR there, but in principle this could be used in other runtimes too, just like Asyncify itself.

cc @surma @RReverser

Comment thread src/passes/Asyncify.cpp Outdated
// Helper passes that can be run after Asyncify.

template<bool neverRewind, bool neverUnwind, bool importsAlwaysUnwind>
struct PostAsyncify
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm understanding this at a high level, these are passes that run on already-asyncified code, in order to bake in assumptions about when the code is called, so we can optimize the runtime overhead away.

I'm not sure if "post asyncify" is a great name for this pass. That just says "this runs afterward" but doesn't explain why, or what it does. In particular it seems reasonable to assume that PostAsyncify always runs and does some sort of necessary fixup, rather than optimizing.
So maybe "optimize asyncify"? That's not quite right either because it misses the connotation of baking in assumptions.

Similarly, there's three bools here, but we only instantiate it two ways. Another way to factor this is as explicitly supporting the lazy-load case, and then the pass can be called "lazy load asyncify", parameterized on whether this is the loader or the loadee. If this is expected to be more general, and have options or configurations added, it would make sense to go the other way and have this take an options struct (or bitfield of flags) to keep the parameter list shorter.

Copy link
Copy Markdown
Member Author

@kripken kripken Sep 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good point, "post" is not clear enough.

I think this is more general than lazy loading, though, so I'd prefer something more general somehow.

Maybe PostAsyncify => AsyncifyAssume because it bakes assumptions into asyncified code?

Comment thread src/passes/Asyncify.cpp Outdated
@kripken
Copy link
Copy Markdown
Member Author

kripken commented Oct 23, 2019

Interesting, I force-pushed this branch, and it seems to hit a github bug where it closed the PR as if it was merged... which it was not.

@kripken
Copy link
Copy Markdown
Member Author

kripken commented Oct 23, 2019

..and it can't be reopened :) Opening a new PR...

@kripken kripken deleted the lazy branch October 23, 2019 17:13
@kripken kripken restored the lazy branch October 23, 2019 17:14
@kripken
Copy link
Copy Markdown
Member Author

kripken commented Oct 23, 2019

.. but I can't open a new PR as it thinks this code was already merged :(

@kripken kripken mentioned this pull request Oct 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants