LLVM backend issues

69 views
Skip to first unread message

Zoltan Varga

unread,
Jun 8, 2019, 3:29:11 AM6/8/19
to emscripten-discuss
Hi,

In general the llvm backend seems to work pretty well for us (Mono), incremental compilation works fine as well.

Some questions/issues:
- It looks like some function attributes like noinline are ignored when using the wasm backend, presumably because the wasm object files no longer contain this
  information, so the function still gets inlined in the final executable.
- The final link still takes a lot of time even when all the inputs are wasm object files. Most time seems to be spent in wasm-opt from binaryen. Does wasm-opt do
link-time optimization only, or it still does basic optimizations which are presumably already done by llvm before emitting the wasm object files ?

                thanks

                    Zoltan

Alon Zakai

unread,
Jun 8, 2019, 9:24:27 AM6/8/19
to emscripte...@googlegroups.com
On Sat, Jun 8, 2019 at 12:29 AM Zoltan Varga <var...@gmail.com> wrote:
Hi,

In general the llvm backend seems to work pretty well for us (Mono), incremental compilation works fine as well.

Some questions/issues:
- It looks like some function attributes like noinline are ignored when using the wasm backend, presumably because the wasm object files no longer contain this
  information, so the function still gets inlined in the final executable.

Yes, it's true that noinline is lost after LLVM IR, so binaryen optimizations may inline things you didn't expect. Note that this was true with the asm.js backend before as well, as it also ran the binaryen optimizer, but whether something is inlined depends on lots of stuff so maybe it wasn't as noticeable.

If you do the link step with -O0 then it won't run the Binaryen optimizer at all, and just do a simple link, which avoids this. But that won't help for a release build where you do want to optimize during link to get the best code size. Are you just surprised by the inlining, or is this causing a problem for you? If it's a problem, we can add support for disabling inlining in binaryen.

 
- The final link still takes a lot of time even when all the inputs are wasm object files. Most time seems to be spent in wasm-opt from binaryen. Does wasm-opt do
link-time optimization only, or it still does basic optimizations which are presumably already done by llvm before emitting the wasm object files ?


Related to the above, if you link with -O0 then it won't optimize in Binaryen, and the link step will be just a simple fast link (it also won't do various JS optimizations, so again it's good for an incremental build but not for release).

- Alon

 
                thanks

                    Zoltan

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/bc24cc24-412f-460f-88cd-956d06b619a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Zoltan Varga

unread,
Jun 8, 2019, 12:00:57 PM6/8/19
to emscripte...@googlegroups.com


Yes, it's true that noinline is lost after LLVM IR, so binaryen optimizations may inline things you didn't expect. Note that this was true with the asm.js backend before as well, as it also ran the binaryen optimizer, but whether something is inlined depends on lots of stuff so maybe it wasn't as noticeable.

If you do the link step with -O0 then it won't run the Binaryen optimizer at all, and just do a simple link, which avoids this. But that won't help for a release build where you do want to optimize during link to get the best code size. Are you just surprised by the inlining, or is this causing a problem for you? If it's a problem, we can add support for disabling inlining in binaryen.

Not really a problem, was just suprising. 
 
- The final link still takes a lot of time even when all the inputs are wasm object files. Most time seems to be spent in wasm-opt from binaryen. Does wasm-opt do
link-time optimization only, or it still does basic optimizations which are presumably already done by llvm before emitting the wasm object files ?


Related to the above, if you link with -O0 then it won't optimize in Binaryen, and the link step will be just a simple fast link (it also won't do various JS optimizations, so again it's good for an incremental build but not for release).

In my tests, wasm-opt does seem to save around 10% from the executable size, even if the inputs are wasm object files created by emcc -Oz. Do the savings come from whole program optimization, or wasm-opt is doing some per-function optimizations that the llvm backend currently cannot do ?

              Zoltan
- Alon

 
                thanks

                    Zoltan

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/bc24cc24-412f-460f-88cd-956d06b619a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Alon Zakai

unread,
Jun 8, 2019, 12:18:19 PM6/8/19
to emscripte...@googlegroups.com
On Sat, Jun 8, 2019 at 9:00 AM Zoltan Varga <var...@gmail.com> wrote:


Yes, it's true that noinline is lost after LLVM IR, so binaryen optimizations may inline things you didn't expect. Note that this was true with the asm.js backend before as well, as it also ran the binaryen optimizer, but whether something is inlined depends on lots of stuff so maybe it wasn't as noticeable.

If you do the link step with -O0 then it won't run the Binaryen optimizer at all, and just do a simple link, which avoids this. But that won't help for a release build where you do want to optimize during link to get the best code size. Are you just surprised by the inlining, or is this causing a problem for you? If it's a problem, we can add support for disabling inlining in binaryen.

Not really a problem, was just suprising. 

Ok, thanks. We should probably document this somewhere, since I agree it can be confusing. I'll look into that.

 
- The final link still takes a lot of time even when all the inputs are wasm object files. Most time seems to be spent in wasm-opt from binaryen. Does wasm-opt do
link-time optimization only, or it still does basic optimizations which are presumably already done by llvm before emitting the wasm object files ?


Related to the above, if you link with -O0 then it won't optimize in Binaryen, and the link step will be just a simple fast link (it also won't do various JS optimizations, so again it's good for an incremental build but not for release).

In my tests, wasm-opt does seem to save around 10% from the executable size, even if the inputs are wasm object files created by emcc -Oz. Do the savings come from whole program optimization, or wasm-opt is doing some per-function optimizations that the llvm backend currently cannot do ?


It's a combination of the two. The LLVM wasm backend doesn't emit some wasm patterns like ifs (it emits br_ifs) and block/if return values. Binaryen can optimize wasm into using those patterns. And also binaryen does whole program optimization, like duplicate function elimination, dead argument elimination, inlining, etc.. The code to pick those passes is here: https://github.com/WebAssembly/binaryen/blob/master/src/passes/pass.cpp#L399

Binaryen does whole-program optimization because most people don't use LLVM's LTO (in part due to the slow compile times of compiling bitcode at link; Binaryen is much simpler and lighter-weight, and also runs using multiple cores, so the time is less of a problem). And also we want binaryen to be good at optimizing non-LLVM code too.

- Alon
 
              Zoltan
- Alon

 
                thanks

                    Zoltan

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/bc24cc24-412f-460f-88cd-956d06b619a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/CAEX4NpROVLaJLGQj_CEumryq0Xh2kWoAc3UfkNBBE%3Db-F_p_EA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Floh

unread,
Jun 10, 2019, 6:52:41 AM6/10/19
to emscripten-discuss
> Binaryen does whole-program optimization because most people don't use LLVM's LTO

...hmm, what are the implications when I'm compiling with "--llvm-lto 1"? Is the LLVM-LTO pass essentially redundant now and only increases link time, or is the binaryen whole-program-optimization pass missing important features from LLVM's?

Cheers,
-Floh.

Alon Zakai

unread,
Jun 10, 2019, 10:22:46 AM6/10/19
to emscripte...@googlegroups.com
--llvm-lto 1 hasn't changed, it still passes the flags to LLVM to do LTO. It's still useful as there are many things LLVM LTO can do that binaryen LTO can't (because LLVM IR has richer information than wasm, and because LLVM is more mature and powerful). As before, it can increase build times substantially.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.

Floh

unread,
Jun 11, 2019, 6:16:22 AM6/11/19
to emscripten-discuss
Thanks for the clarification!


On Monday, 10 June 2019 16:22:46 UTC+2, Alon Zakai wrote:
--llvm-lto 1 hasn't changed, it still passes the flags to LLVM to do LTO. It's still useful as there are many things LLVM LTO can do that binaryen LTO can't (because LLVM IR has richer information than wasm, and because LLVM is more mature and powerful). As before, it can increase build times substantially.

On Mon, Jun 10, 2019 at 3:52 AM Floh <flo...@gmail.com> wrote:
> Binaryen does whole-program optimization because most people don't use LLVM's LTO

...hmm, what are the implications when I'm compiling with "--llvm-lto 1"? Is the LLVM-LTO pass essentially redundant now and only increases link time, or is the binaryen whole-program-optimization pass missing important features from LLVM's?

Cheers,
-Floh.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages