-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static compilation to WebAssembly #5
Comments
For static compilation, I'm looking for feedback on an approach that adds another compilation mode to Julia. It'd be somewhat like JuliaLang/julia@jn/codegen-norecursion...tshort:jn/codegen-norecursion I used @vtjnash's Does this look like a good way to go for AOT compilation of wasm? Any things to watch out for? Here's code I used to output a compiled LLVM module (mostly from CUDAnative): import LLVM
function irgen(@nospecialize(f), @nospecialize(tt))
# get the method instance
world = typemax(UInt)
meth = which(f, tt)
sig_tt = Tuple{typeof(f), tt.parameters...}
(ti, env) = ccall(:jl_type_intersection_with_env, Any,
(Any, Any), sig_tt, meth.sig)::Core.SimpleVector
meth = Base.func_for_method_checked(meth, ti)
linfo = ccall(:jl_specializations_get_linfo, Ref{Core.MethodInstance},
(Any, Any, Any, UInt), meth, ti, env, world)
# set-up the compiler interface
function hook_raise_exception(insblock::Ptr{Cvoid}, ex::Ptr{Cvoid})
insblock = convert(LLVM.API.LLVMValueRef, insblock)
ex = convert(LLVM.API.LLVMValueRef, ex)
raise_exception(BasicBlock(insblock), Value(ex))
end
params = Base.CodegenParams(track_allocations=false,
code_coverage=false,
static_alloc=false,
prefer_specsig=true,
raise_exception=hook_raise_exception)
# generate IR
ccall(:jl_set_standalone_aot_mode, Nothing, ())
native_code = ccall(:jl_create_native, Ptr{Cvoid},
(Vector{Core.MethodInstance}, Base.CodegenParams), [linfo], params)
@assert native_code != C_NULL
llvm_mod_ref = ccall(:jl_get_llvm_module, LLVM.API.LLVMModuleRef,
(Ptr{Cvoid},), native_code)
@assert llvm_mod_ref != C_NULL
ccall(:jl_clear_standalone_aot_mode, Nothing, ())
LLVM.Module(llvm_mod_ref)
end
f1() = ccall("myfun", Int, ())
m1 = irgen(f1, Tuple{})
f2() = cglobal("myglobal", Int)
m2 = irgen(f2, Tuple{}) |
I've made a bit more progress on a "standalone_aot_mode". Updates here. Some items are straightforward:
What I'm struggling with is how to handle global variables. For generated types and other things that are immutable, it's probably possible to create LLVM global variables for these. For general mutable objects, I'm more confused. Should I try to re-use Julia's sysimg machinery? I don't want the whole sysimg, only the parts the exported functions use. |
I've made more progress on a "standalone_aot_mode". See the following for a description and some test files, so you can get an idea of what works: https://github.com/tshort/julia/tree/standalone-mode/test/standalone-aot |
Ahead-of-time static compilation to WebAssembly would enable smaller downloads to execute Julia code in the browser. We now have a
libjulia
that compiles nicely to WebAssembly. How to generate code to link to that is uncertain. Some options include:PackageCompiler style--Here, Julia's
--output-bc
option is used to create LLVM IR with thewasm32-unknown-unknown
triple. This approach is currently really slow for native code generation because it recompiles everything starting frombase/sysimg.jl
. If code generation can be enabled in the wasm version of Julia, this approach could be done in the browser to generate wasm-compatible code. Emscripten would be used for final compilation/linking to WebAssembly. Right now, Emscripten chokes on theaddrspace
s that Julia generates.CUDAnative style--In this approach, LLVM IR modules are created for Julia code, similar to how
@code_llvm
works. This works well for simple code, and it should be fast. It doesn't currently work for recursive code. It also doesn't work well for code that callslibjulia
functions.foreigncall
s are often converted to calls to raw addresses, and it also has theaddrspace
issue.Charlotte--By directly compiling Julia's IR to WebAssembly, it is possible to customize the compilation. This should be fast and flexible. The downsides of this approach are: no LLVM optimizations and no automatic linking (LLD is supposed to be able to link wasm files).
The text was updated successfully, but these errors were encountered: