Skip to content

Meta-DCE for JS+WASM #5919

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

Merged
merged 26 commits into from
Dec 15, 2017
Merged

Meta-DCE for JS+WASM #5919

merged 26 commits into from
Dec 15, 2017

Conversation

kripken
Copy link
Member

@kripken kripken commented Dec 8, 2017

This starts to use binaryen's wasm-metadce tool in -Os and -Oz, which lets us remove unused code along the boundary of wasm and JS. That is, it can remove things which doing DCE separately on each can't, like cycles between the two worlds.

For example, if wasm imported a JS function, then if the wasm optimizer manages to remove all uses of it, this lets us remove it not just from wasm but also from the JS side too. And the same works the other way as well.

So far, in -Os this shrinks hello world's .js by 3% and .wasm by 18%. This is less effective on large programs, since the removable runtime overhead is smaller - e.g. when using C++ iostreams, it shrinks by 7% / 1%. But where this really shines is on small programs like the testcase in #5836, that just do a little pure computation and don't need a runtime at all: this shrinks that .js by 5% and the .wasm by 84% (mostly thanks to getting rid of malloc/free!). The absolute numbers are interesting for the wasm, it goes from 10,729 bytes to just 1,740, which is getting us most of the way to emitting a really minimal wasm for such inputs. This reason this doesn't get us all the way is because:

  • We need to represent JS's full graph of reachability for wasm-dce to be maximally effective. Currently this just represents imports and exports by parsing them directly. So interesting cycles on the JS side can't be collected yet.
  • We still export a lot of things by default, which prevents this dead code elimination from eliminating them. So as we improve that (JS and wasm shrinking (testcase #1) #5836 etc.) this will get more powerful.

On the other hand, this does increase compile times noticeably, mostly on tiny files: 47% for hello world and 23% for C++ iostreams. That's why I think this makes sense to do in -Os and -Oz, but not other modes.

@nmrugg
Copy link
Contributor

nmrugg commented Dec 9, 2017

Personally, I would like this for -O3 as well since I have found that it produces much faster code than -Os and -Oz. Perhaps there could be another flag to enable this. I don't really care about compile times.

@kripken
Copy link
Member Author

kripken commented Dec 9, 2017

Yeah, I think it's reasonable to do this in -O3 too. That's a mode where people are ok with slow compile times anyhow. And the smaller code can lead to faster startup, which matters on some benchmarks, I see a 1% improvement in JS parse times in the iostream testcase for example.

But @nmrugg I'm curious where you saw it produce much faster code? I wouldn't expect that to be noticeable.

@nmrugg
Copy link
Contributor

nmrugg commented Dec 10, 2017

In Stockfish.js I see a big difference.

With -O3 Stockfish.js can run go depth 15 in under 2 seconds on my computer, but with -Oz, it takes around 5 seconds (-Os is the same).

I can post details if you want to investigate.

@nmrugg
Copy link
Contributor

nmrugg commented Dec 10, 2017

Perhaps I should note that those numbers are for asm.js. When compiled to WASM, -O3 takes about 0.6 seconds and -Oz takes about 1.6 seconds. (I haven't pushed my WASM branch to that repo yet.)

@kripken
Copy link
Member Author

kripken commented Dec 10, 2017

Got it, thanks. Makes sense to me now, I misunderstood what you wrote before.

@kripken
Copy link
Member Author

kripken commented Dec 15, 2017

Feedback here and offline has been positive, merging.

@kripken kripken merged commit 5ccc012 into incoming Dec 15, 2017
@kripken kripken deleted the metadce branch December 15, 2017 02:57
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