LLVM backend by default!

1,738 views
Skip to first unread message

Alon Zakai

unread,
Oct 21, 2019, 6:17:48 PM10/21/19
to emscripte...@googlegroups.com
Hello everyone,

The emsdk will now install the upstream LLVM backend by default, instead of fastcomp, as of


That is, if you install/activate "latest" then you get the same as "latest-upstream". It used to be an alias for "latest-fastcomp".

You can still use "latest-fastcomp" to get fastcomp if you need that. You can also install stuff like "1.39.0-fastcomp", a version with a specific backend.

The emsdk defaults to the upstream backend from 1.39.0, but not earlier versions, as the upstream backend wasn't stable enough yet at those times. (But you can as always do "1.38.39-upstream" to get upstream for those versions.) In other words, the only thing that changed now is that for 1.39.0 and onwards, if you don't specify the backend, you'll get upstream.

We are changing the default now after a long period of recommending people upgrade to the LLVM backend and fixing issues based on their feedback, as a result of which at this point we feel comfortable changing the default.

Please test and file bugs if you find any! All you need to do is update to the latest emsdk master from github, and

./emsdk install latest
./emsdk activate latest

If this is your first time using the upstream backend, see the list of differences,


Our goal is to remove fastcomp eventually, and it is now officially deprecated, but we will only start to plan that after seeing the feedback from users after this switch.

- Alon

Gabriel Cuvillier

unread,
Oct 22, 2019, 5:40:08 AM10/22/19
to emscripte...@googlegroups.com

Great!

A question regarding this in the documentation, which confuses me a bit:

You can disable wasm object files with -s WASM_OBJECT_FILES=0, which will make the wasm backend behave more like fastcomp.
Neither fastcomp nor the wasm backend without wasm object files will run the LLVM optimization passes by default, even if using LLVM IR in object files;
for that you must pass --llvm-lto 1.

With the 3 options "-s WASM_OBJECT_FILES=0", "--llvm-lto 1", and "-flto", there is a lot of combinations possible and the outcome is not quite clear.

So, on the Wasm backed, what's the difference between doing (or what is meaningful/meaningless):
    -flto
  --llvm-lto 1
  -s WASM_OBJECT_FILES=0
  -flto --llvm-lto 1
  -flto -s WASM_OBJECT_FILES=0
  -flto -s WASM_OBJECT_FILES=0 --llvm-lto 1
  -s WASM_OBJECT_FILES=0 --llvm-lto 1

+ Which option shall be passed at compilation time / at link time ? 

Thanks!

--
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/CAEX4NpTHC%3DRz2UZrqLBBaPQ0ROT4JXGA7RnH5iDEsLeUdvRmMA%40mail.gmail.com.

Shachar Langbeheim

unread,
Oct 22, 2019, 6:02:07 AM10/22/19
to emscripten-discuss
Hi,
I'm seeing a crash when running an app linked with opencv. openCV is built using the command below, and an exception is thrown in cvRegisterType. I've tried to print the exception using make install -s EXCEPTION_DEBUG=1 -s DISABLE_EXCEPTION_CATCHING=0, but I still can't get the exception printed. Did anyone else try to compile OpenCV with the new backend and see this? Or any tips on how can I try to flesh out the issue?

emcmake cmake ../$1 \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX='./' \
    -DCPU_BASELINE=''\
    -DCPU_DISPATCH='' \
    -DCV_TRACE=OFF \
    -DBUILD_SHARED_LIBS=OFF \
    -DWITH_1394=OFF \
    -DWITH_ADE=OFF \
    -DWITH_VTK=OFF \
    -DWITH_EIGEN=OFF \
    -DWITH_FFMPEG=OFF \
    -DWITH_GSTREAMER=OFF \
    -DWITH_GTK=OFF \
    -DWITH_GTK_2_X=OFF \
    -DWITH_IPP=OFF \
    -DWITH_JASPER=OFF \
    -DWITH_JPEG=ON \
    -DWITH_WEBP=OFF \
    -DWITH_OPENEXR=OFF \
    -DWITH_OPENGL=OFF \
    -DWITH_OPENVX=OFF \
    -DWITH_OPENNI=OFF \
    -DWITH_OPENNI2=OFF \
    -DWITH_PNG=ON \
    -DWITH_TBB=OFF \
    -DWITH_PTHREADS_PF=OFF \
    -DWITH_TIFF=OFF \
    -DWITH_V4L=OFF \
    -DWITH_OPENCL=OFF \
    -DWITH_OPENCL_SVM=OFF \
    -DWITH_OPENCLAMDFFT=OFF \
    -DWITH_OPENCLAMDBLAS=OFF \
    -DWITH_GPHOTO2=OFF \
    -DWITH_LAPACK=OFF \
    -DWITH_ITT=OFF \
    -DWITH_QUIRC=OFF \
    -DBUILD_ZLIB=ON \
    -DBUILD_opencv_apps=OFF \
    -DBUILD_opencv_calib3d=ON \
    -DBUILD_opencv_dnn=ON  \
    -DBUILD_opencv_features2d=ON \
    -DBUILD_opencv_flann=ON \
    -DBUILD_opencv_gapi=OFF \
    -DBUILD_opencv_ml=OFF \
    -DBUILD_opencv_photo=ON \
    -DBUILD_opencv_imgcodecs=OFF \
    -DBUILD_opencv_shape=OFF \
    -DBUILD_opencv_videoio=OFF \
    -DBUILD_opencv_videostab=OFF \
    -DBUILD_opencv_highgui=OFF \
    -DBUILD_opencv_superres=OFF \
    -DBUILD_opencv_stitching=OFF \
    -DBUILD_opencv_java=OFF \
    -DBUILD_opencv_java_bindings_generator=OFF \
    -DBUILD_opencv_js=OFF \
    -DBUILD_opencv_python2=OFF \
    -DBUILD_opencv_python3=OFF \
    -DBUILD_EXAMPLES=OFF \
    -DBUILD_PACKAGE=OFF \
    -DBUILD_opencv_python_bindings_generator=OFF \
    -DBUILD_TESTS=OFF \
    -DBUILD_PERF_TESTS=OFF &&
make install

Sam Clegg

unread,
Oct 22, 2019, 12:08:34 PM10/22/19
to emscripte...@googlegroups.com
Thats a really great question. Right now having all of those options
is confusing and I don't even know which ones make sense. I think
that ultimately for the wasm backend we will want to have `-flto` be
the flag that enables this, to match the existing flag in upstream
clang and the other flags be removed. I've got a very old PR that
starts to move in that direction:
https://github.com/emscripten-core/emscripten/pull/7961.

I thought we had a bug open to address this already but I can't find
it now. Feel free to open one if you feel motivated.
> To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/06858de5-a732-0e70-6ce7-e60c1a9e2667%40gmail.com.

Alon Zakai

unread,
Oct 22, 2019, 3:39:18 PM10/22/19
to emscripte...@googlegroups.com
The LTO docs are here:


Basically

 * -flto is a clang flag that says "emit LLVM IR in the bitcode file"
 * WASM_OBJECT_FILES=0 is an emscripten flag that says "don't use wasm object files, so use LLVM IR in bitcode files, *and also in system libs*"
 * --llvm-lto 1 is an emscripten flag that also runs LLVM's default LTO opts at link time.

Perhaps -flto should automatically set --llvm-lto 1? I'm not sure what clang normally does, but we should do the same probably...

- Alon


On Tue, Oct 22, 2019 at 2:40 AM Gabriel Cuvillier <gabriel....@gmail.com> wrote:

John Harvey

unread,
Oct 24, 2019, 7:58:13 AM10/24/19
to emscripten-discuss


I am seeing 2 problems with 1.39.0 upstream
1) If i use -s WASM_OBJECT_FILES=0  when building our application i end up with an undefined symbol
wasm-ld: error: d:\users\jpharvey\.emscripten_cache_1.39.0-upstream\wasm-bc\libcompiler_rt.bc: undefined symbol: __threwValue

Any idea how i can try to fix or debug this?

2) When building for asm-js and using -O3 optimization level the the code builds but doesn't run with the following message in the console
TypeError: o[r[((r[(w2 >> 2)] + 8) >> 2)]] is not a function libthingview.js:33:1061013
At -O2 level this is fine. And using fastcomp it is fine at both optimization levels
Again any idea how i can try to help debug this.

John

Alon Zakai

unread,
Oct 24, 2019, 1:00:55 PM10/24/19
to emscripte...@googlegroups.com
What exactly is thrown, a C assertion, a wasm exception, or something else? Pasting the full output (preferably in a build with --profiling -s ASSERTIONS) might help understand what you're seeing.

--
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,
Oct 24, 2019, 4:21:53 PM10/24/19
to emscripte...@googlegroups.com
Thanks for the feedback John!

1. First thing I'd make sure is that all source files and libraries are built with the new version. Mixing object files between versions can lead to link errors.

If it's not that, then looks like that symbol should arrive from libcompiler_rt. Looking in EMCC_DEBUG=1 output during link can show which libs it decides to link in. Is compiler-rt not there? It should always be linked in, unless overridden by EMCC_ONLY_FORCED_STDLIBS, I believe. (If you are using that option, then you need to include all necessary libs, and the list does change by the backend, I believe.)

2. "is not a function" is probably a bad function pointer call. Building with --profiling might show a useful stack trace. But this may just be a bug in wasm2js, if the same optimization level works in wasm output in the new backend. If you can provide a testcase that would be good.

- Alon






--
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.

Gabriel Cuvillier

unread,
Oct 25, 2019, 8:31:48 AM10/25/19
to emscripte...@googlegroups.com

Ok, I understand better.

What makes things confusing is probably more that the usual distinction between compiler flags and linker flags are a bit blurred in Emscripten.

As "WASM_OBJECT_FILES=0" is doing the same as "-flto", but also applying it to system libs, maybe it would be cleaner to have it replaced by a "-s ENABLE_SYSTEM_LIBS_LTO=1" that would only focus on enabling LTO on the system libs (letting the user control the LTO of its own code with the usual -flto flag).


Btw, the docs mention that --lvm-lto might have the values 1,2 or 3 => is this still applicable to the new Wasm backend ? I guess no (?)


Cheers,

Gabriel

John Harvey

unread,
Oct 25, 2019, 12:51:33 PM10/25/19
to emscripten-discuss
Thanks for the reply


On Thursday, 24 October 2019 21:21:53 UTC+1, Alon Zakai wrote:
Thanks for the feedback John!

1. First thing I'd make sure is that all source files and libraries are built with the new version. Mixing object files between versions can lead to link errors.

If it's not that, then looks like that symbol should arrive from libcompiler_rt. Looking in EMCC_DEBUG=1 output during link can show which libs it decides to link in. Is compiler-rt not there? It should always be linked in, unless overridden by EMCC_ONLY_FORCED_STDLIBS, I believe. (If you are using that option, then you need to include all necessary libs, and the list does change by the backend, I believe.)
I didn't get a lot. Everything is built with the same compiler and flags definitely.  Its definitely linking libcompiler_rt in and that definitely contains the __threwValue symbol. The error message is odd in that it implies that it is libcompiler_rt.bc that wants the symbol but cant find it. I am fairly sure this was working at 1.38.45 so will try to go through the intermediate version to find out when it started happening, but that will take some time. It also doesn't happen with our small test libraries. 

2. "is not a function" is probably a bad function pointer call. Building with --profiling might show a useful stack trace. But this may just be a bug in wasm2js, if the same optimization level works in wasm output in the new backend. If you can provide a testcase that would be good.

This really annoying. Adding --profiling to the compile flags and it goes away. Just changing --memory-init-file from 0 to 1 it also goes away. So not quite sure how to get to the bottom of it. I will keep experimenting to see if i can work out a good way to find out more information about what is going wrong.
I will see what happens in smaller examples to see if i can get a test case. Same flags with wasm output works fine.
 
- Alon



Derek Schuff

unread,
Oct 25, 2019, 12:54:15 PM10/25/19
to emscripten-discuss
This is a good point, actually. Before, almost all of the emscripten-specific flags only mattered at link time, and now there are probably several that also matter at compile time. We should probably take a pass over the docs and figure that out, or else just declare that everything should also go at compile time. Emscripten is already a little weird that so many things matter at link time so I think the default expectation of most users (and build systems) would be that you only have to pass things at compile time. It would be nice to push the upstream backend more in that direction rather than going back.

Alon Zakai

unread,
Oct 25, 2019, 1:09:18 PM10/25/19
to emscripte...@googlegroups.com
On Fri, Oct 25, 2019 at 5:31 AM Gabriel Cuvillier <gabriel....@gmail.com> wrote:

Ok, I understand better.

What makes things confusing is probably more that the usual distinction between compiler flags and linker flags are a bit blurred in Emscripten.

As "WASM_OBJECT_FILES=0" is doing the same as "-flto", but also applying it to system libs, maybe it would be cleaner to have it replaced by a "-s ENABLE_SYSTEM_LIBS_LTO=1" that would only focus on enabling LTO on the system libs (letting the user control the LTO of its own code with the usual -flto flag).


Btw, the docs mention that --lvm-lto might have the values 1,2 or 3 => is this still applicable to the new Wasm backend ? I guess no (?)



Yeah, the flags here might be better renamed. And yes, 1,2,3 still work AFAIK, but we should probably remove 2 and 3 since they were only useful in the far past.

- Alon


Alon Zakai

unread,
Oct 25, 2019, 1:15:18 PM10/25/19
to emscripten-discuss
So far the most serious bug report since the switch is -fPIC,


As a workaround, don't pass -fPIC unless you are building a MAIN_MODULE or a SIDE_MODULE.

Or, switch back to fastcomp for now until we fix this. Sorry!

- Alon

Alon Zakai

unread,
Oct 25, 2019, 1:19:01 PM10/25/19
to emscripte...@googlegroups.com
On Fri, Oct 25, 2019 at 9:54 AM 'Derek Schuff' via emscripten-discuss <emscripte...@googlegroups.com> wrote:
This is a good point, actually. Before, almost all of the emscripten-specific flags only mattered at link time, and now there are probably several that also matter at compile time. We should probably take a pass over the docs and figure that out, or else just declare that everything should also go at compile time.

The docs have recently been update to say that it is best (search for "simple and safe") to pass the flags at both times,


But maybe that's not prominent enough?

I can do a pass through settings.js to mark options as "link" or "compile" if that would help? Not sure it would.

- Alon


Derek Schuff

unread,
Oct 25, 2019, 1:26:21 PM10/25/19
to emscripten-discuss
Yeah, I'm not sure if that would help much or not. I guess another option could be to just make everything work at compile time and then pass the flags through the object files similarly to what we do with target features. That would be convenient for build systems (all the flags in one place). Then we'd have to reason about what happens when object files disagree (but that would also be an opportunity to catch mismatches in cases where that matters)

Gabriel Cuvillier

unread,
Oct 25, 2019, 4:49:08 PM10/25/19
to emscripte...@googlegroups.com

Well, to me, having such hint  in the settings.js file (= compile time flag or link time flag) would certainly help to make things cleaner while porting existing program.

While I do agree the "simple and safe" method of passing everything at both compile/link time is convenient, the issue is that having to recompile a full 5000+ CPP files program just because of a tweak in a flag that is only expected to be used at link time is... argh :)

Gabriel Cuvillier

unread,
Oct 25, 2019, 5:01:36 PM10/25/19
to emscripte...@googlegroups.com

So far, the settings.js flag I identified that do have an impact at compilation time are:

- STRICT=1 (as it change some defined symbols)

- DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR

- All the ports flags, USE_<portname> (as it change the system include paths)

- and possibly USE_WASM_OBJECT_FILES, though it look like -flto is doing the same (USE_WASM_OBJECT_FILES may only be used at link time to trigger LTO on system libs)

John Harvey

unread,
Oct 25, 2019, 5:38:40 PM10/25/19
to emscripten-discuss

That was the complete output from firefox. I've just tried Chrome and that shows
Uncaught (in promise) TypeError: o[r[((r[(w2 >> 2)] + 8) >> 2)]] is not a function
    at Bea (libthingview.js:33)
    at SDb (libthingview.js:13)
    at kGb (libthingview.js:89)
    at w2a (libthingview.js:45)
    at qxi (libthingview.js:101)
    at Module.___wasm_call_ctors (libthingview.js:115)
    at func (libthingview.js:115)
    at callRuntimeCallbacks (libthingview.js:115)
    at initRuntime (libthingview.js:115)
    at doRun (libthingview.js:115)
Bea @ libthingview.js:33
SDb @ libthingview.js:13
kGb @ libthingview.js:89
w2a @ libthingview.js:45
qxi @ libthingview.js:101
Module.___wasm_call_ctors @ libthingview.js:115
func @ libthingview.js:115
callRuntimeCallbacks @ libthingview.js:115
initRuntime @ libthingview.js:115
doRun @ libthingview.js:115
run @ libthingview.js:115
runCaller @ libthingview.js:115
removeRunDependency @ libthingview.js:115
receiveInstance @ libthingview.js:115
receiveInstantiatedSource @ libthingview.js:115
Promise.then (async)
instantiateArrayBuffer @ libthingview.js:115
instantiateAsync @ libthingview.js:115
createWasm @ libthingview.js:115
(anonymous) @ libthingview.js:115

Does that help at all? With -O3 i see this error but if i add --profiling it no longer fails.
Thanks
John

Shachar Langbeheim

unread,
Oct 27, 2019, 6:30:02 AM10/27/19
to emscripten-discuss
I'm sorry, I don't have any experience with CMake, so I'm having trouble injecting the relevant flags to OpenCV's compilation.
ATM, these are the logs I get. First a warning is logged:

Compiled code throwing an exception, 5801480,547192,4749

___cxa_throw
@appWASM.js:2010
cv::error(cv::Exception const&)@wasm-01c3004a-12026:1
cv::error(int, cv::String const&, char const*, char const*, int)@wasm-01c3004a-12023:1
cvRegisterType@wasm-01c3004a-11970:1
_GLOBAL__sub_I_persistence_types.cpp@wasm-01c3004a-12009:1
__wasm_call_ctors@wasm-01c3004a-402:1
Module.___wasm_call_ctors@appWASM.js:13159
func@appWASM.js:1799
callRuntimeCallbacks@appWASM.js:1375
initRuntime@appWASM.js:1408
doRun@appWASM.js:14543
run@appWASM.js:14564
runCaller@appWASM.js:14465
removeRunDependency@appWASM.js:1583
receiveInstance@appWASM.js:1693
receiveInstantiatedSource@appWASM.js:1710
Promise.then (async)
(anonymous)@appWASM.js:1731
Promise.then (async)
instantiateAsync@appWASM.js:1729
createWasm@appWASM.js:1756
(anonymous)@appWASM.js:12314

And then an error:
Uncaught (in promise) 5801480

I don't know how to get more info from the exception.


Alon Zakai

unread,
Oct 28, 2019, 4:21:27 PM10/28/19
to emscripte...@googlegroups.com
Sounds reasonable, I'll look into adding more docs in the settings file.

- Alon


Alon Zakai

unread,
Oct 28, 2019, 5:56:29 PM10/28/19
to emscripte...@googlegroups.com
These seem to be separate issues:

> Uncaught (in promise) TypeError: o[r[((r[(w2 >> 2)] + 8) >> 2)]] is not a function

That looks like a wasm2js error perhaps, assuming that is using wasm2js (non-WASM output on 1.39.0, by default). Does using latest-fastcomp fix that for you? And does it work in wasm mode?

It would be good to get a testcase of this. Even a large one might be enough to debug it (I'd just build with wasm and without, and compare the diff in the behavior).

(In general, this "not a function" issue is likely a bad function pointer call, which may be due to memory corruption or something else bad.)

> Compiled code throwing an exception

That is a C++ language exception being thrown, like maybe an assertion failed in cvRegisterType. It would be interesting to know if using fastcomp and/or wasm affects that too.

- Alon



Shachar Langbeheim

unread,
Oct 29, 2019, 3:32:22 AM10/29/19
to emscripten-discuss
Yes, just confirmed that using latest-fastcomp everything is ok, and the c++ exception isn't thrown.

John Harvey

unread,
Oct 29, 2019, 7:05:22 AM10/29/19
to emscripten-discuss
This has all got very confusing and somewhere this issue got associated with the OpenCV issue. There are 3 issues being discussed 1) This uncaught type error, 2) Linking problem 3) OpenCV Crash. I will start new topics for my 2 problems.

John
Reply all
Reply to author
Forward
0 new messages