Would the Asyncify pass from Binaryen work in LLVM/Clang?

In an effort to try to get LLVM 13 to compile successfully under WASI for the Wasmer runtime, I have been informed that there is a custom pass needed to implement enough multitasking to get libAtomic and other PThreads-style execution models to work. LLVM 13 is clearly multithreaded code and I need it to work on WASI which is presently a single-threaded environment. The source to Asyncify is https://github.com/WebAssembly/binaryen/blob/main/src/passes/Asyncify.cpp. Will it work out of the box? How much work will this take? If multithreading is already in the works for WASI, how long until it lands?

I’m not sure if it would work “directly” out-of-the box (the current intended use case is for async APIs, alongside some JS code in emscripten, see here for example, and a more low-level example here), but I think it could probably be made to work. You’d basically be making a green-threads-style cooperative system, so you’d need to figure out where to put the yield points (e.g. instrumenting the threads/atomics library calls) and how to manage the threads, and asyncify would take care of the suspension and resumption.

But backing up, I’m not sure you’d need to actually do all of that just to get LLVM to work. IIRC LLVM doesn’t actually need to run with multiple threads, so you could probably get by with stub implementations of the atomics/threads libraries. IIRC people have built LLVM/clang for the web a couple of times and I don’t think they used threads either (emscripten has stub implementations already).

Regarding the past running of Clang on web browsers, the last time that was done was Clang version 8. Version 13 doesn’t have a way to stub out libAtomic that I’ve seen. That’s why I’m trying to create a stubbed-out version of PThreads to allow some primitive multitasking in the place of multithreading.
That’s the reason I was asking about Asyncify as a means of doing so.

I would suggest stubbing out the required atomic functions with simple non-atomic operations yourself (which will be totally fine if you don’t use threads nor signal handlers). And the threading support should already be conditional, see llvm/lib/Support/Threading.cpp.

Thanks. This leads me back to what I tried to start out doing when I started the project a month ago. :frowning_face:

I still don’t really understand why you need multitasking, and can’t get by with a single thread, with stubs for libpthread (e.g. something like emscripten’s for libpthread; a stub libatomic would mostly just be some memory ops and arithmetic).

I don’t need multitasking but can’t require JavaScript in a pure WASI WebAssembly target. Emscripten generates “dirty” code for WASI as a result and can’t be directly used in my application.

I see. My point was that I think you should be able to make a stub library like emscripten’s (I think that particular code I linked doesn’t depend on any of emscripten’s JS anyway?). I think if you do that, you won’t need multitasking and therefore won’t need asyncify.

1 Like