1. LTO off by default
We've been seeing more LLVM LTO bugs recently, probably not new bugs
but just looks like the chance of hitting them rises with bigger
codebases. (Bugs have been filed on LLVM of course.) So I disabled
LLVM LTO by default, it's too dangerous to keep it on. It will now
only run in -O3 by default (-O3 contains other unsafe optimizations).
You might notice slower execution and larger code sizes as a result of
LTO being disabled. If you want to re-enable it, build with --llvm-lto
1
2. EMCC_OPTIMIZE_NORMALLY
Emscripten will *not* optimize individual bitcode files, instead it
optimizes when converting the total combined bitcode into final JS,
https://github.com/kripken/emscripten/wiki/Building-Projects
But this has the downside of LLVM opt and link taking longer in that
final conversion to JS. For huge projects, this can be significant.
The environment variable EMCC_OPTIMIZE_NORMALLY changes that and
optimization works like a "normal" build system: emcc -O2 a.cpp -o
a.bc will run LLVM opt on that individual file, and LLVM optimizations
are *not* run during the final link+conversion to JS. (LLVM LTO might
be, if you enabled it.)
This can speed up the final build stage, with minor slowdowns when
optimizing individual files (but that parallelizes); overall, this
should be faster to build. It is however unsafe - it only works if you
build the individual files and the final JS with *exactly* the same
optimization and emscripten flags (-s stuff, -Ox, etc. etc.), and we
can't check that without inventing a metadata format that we store in
each object file, which has not been done. Any inconsistency could
cause errors or suboptimal results. So this is not recommended (and
just an env var, not a normal option).
3. FULL_ES2
We now have 3 'levels' of GL support:
a. WebGL-friendly subset of OpenGL
b. GLES2 emulation
c. GL emulation, attempt to emulate as much desktop GL features as possible
(a) is the default, and (c) was written to support codebases like
Sauerbraten which need us to emulate older GL features. (b) is new and
was just written by vlad. It attempts to emulate GLES2 as much as
possible, so it supports things like client-side data (however it does
not do things like GL_INT in places where WebGL supports only GL_BYTE
or GL_SHORT, so it isn't 100% complete).
The idea of GLES2 emulation isn't new, I believe LCID_Fire argued in
favor of it a while back. I was negative on it then, but more
codebases have appeared that really need it, so apologies about not
focusing on this earlier.
This should change nothing for existing code, and (a) is still more
recommended, that is, to use the WebGL-friendly subset, since that is
more efficient. But if you do have GLES2 code that you are porting,
then the new GLES2 stuff might help you. To use it, build with -s
FULL_ES2=1 . Note that this is a compiler flag, there is no way to
check at compile time whether it is needed or not. If your code needs
it but you didn't set the flag, the browser error console should show
warnings about array buffers not being bound etc.
4. ASM_JS close to ready for general use
asm.js code generation mode (-s ASM_JS=1) no longer shows the "this is
experimental/not recommended" warning. It's fairly robust at this
point, appears to withstand fuzzing, generates faster code in most
cases even without special JS engine optimizations (but with such
optimizations is significantly faster still), and we've used it on
some large and complex codebases successfully.
It doesn't yet support C++ exceptions or setjmp/longjmp, but aside
from that should be considered ready for general use. It will likely
become the default code generation mode once those limitations are
fixed and we have a minifier for it.
- azakai