https://emscripten.org/docs/compiling/WebAssembly.html
解决方案:
在编译时,添加-flto
, -flto=full
, -flto=thin
Backends:
Emscripten emits WebAssembly using the upstream LLVM wasm backend, since version 1.39.0
(October 2019), and the old fastcomp backend is deprecated (you can still use the deprecated fastcomp backend by getting latest-fastcomp
instead of the normal latest
, or 1.39.0-fastcomp
instead of 1.39.0
, etc.).
There are some differences you may notice between the two backends, if you upgrade from fastcomp to upstream(新版本和旧版本的不同):
- The wasm backend is strict about linking files with different features sets - for example, if one file was built with atomics but another was not, it will error at link time. This prevents possible bugs, but may mean you need to make some build system fixes.(新版本对文件链接比较严格)
WASM=0
behaves differently in the two backends. In fastcomp we emit asm.js, while in upstream we emit JS (since not all wasm constructs can be expressed in asm.js). Also, the JS support implements the same externalWebAssembly.*
API, so in particular startup will be async just like wasm by default, and you can control that withWASM_ASYNC_COMPILATION
(even thoughWASM=0
).(wasm=0表现不同)- The wasm backend uses wasm object files by default. That means that it does codegen at the compile step, which makes the link step much faster - like a normal native compiler. For comparison, in fastcomp the compile step emits LLVM IR in object files.(链接更快了)
- You normally wouldn’t notice this, but some compiler flags affect codegen, like
DISABLE_EXCEPTION_CATCHING
. Such flags must be passed during codegen. The simple and safe thing is to pass all-s
flags at both compile and link time. - You can enable Link Time Optimization (LTO) with the usual llvm flags (
-flto
,-flto=full
,-flto=thin
, at both compile and link times). These flags will make the wasm backend behave more like fastcomp. - With fastcomp LTO optimization passes will not be run by default; for that you must pass
--llvm-lto 1
. With the llvm backend LTO passes will be run on any object files that are in bitcode format. - Another thing you might notice is that fastcomp’s link stage is able to perform some minor types of link time optimization even without LTO being set. The LLVM backend requires actually setting LTO for those things.
- wasm-ld, the linker used by the wasm backend, requires libraries (.a archives) to contain symbol indexes. This matches the behaviour the native GNU linker. While emar will create such indexes by default, native tools such as GNU ar and GNU strip are not aware of the WebAssembly object format and cannot create archive indexes. In particular, if you run GNU strip on an archive file that contains WebAssembly object files it will remove the index which makes the archive unusable at link time.
- Fastcomp emits asm.js and so has some limitations on function pointers. For example, the
RESERVED_FUNCTION_POINTERS
setting exists there to work around the fact that we can’t grow the table. In the upstream backend table growth is easy, and you can just enableALLOW_TABLE_GROWTH
. - Fastcomp and upstream use very different LLVM and clang versions (fastcomp has been stuck on LLVM 6, upstream is many releases after). This affects optimizations, usually by making the upstream version faster and smaller. However, in rare cases you may see a regression (for example, in some cases UN-optimized code may be less optimal in upstream, so make sure to optimize both when compiling and when linking).