The Julia language [1] uses LLVM's JIT to dynamically create
code. It's closer to being able to generate static code [2],
including (I think) LLVM bitcode.
As a trial, I used Julia to generate a large bitcode
file (sys.bc) for much of Julia's standard set of functions. For
simple functions that use standard LLVM types, a recent
Emscripten (fastcomp) generates good JavaScript. For more complex
functions that use other types, I'm getting a variety of errors.
Here is an example of a common error:
Value: %Complex.16 %0
LLVM ERROR: Unrecognized struct value
Traceback (most recent call last):
File "/usr/bin/emcc", line 1200, in <module>
The disassembled code for the function that triggered this error
looks like this:
define %Complex.15 @"julia_sin;108403"(%Complex.15) {
top:
%1 = load %jl_value_t** @"*Main.Core.Float3267512", align 8
%2 = getelementptr inbounds %jl_value_t* %1, i64 1, i32 0
%3 = load %jl_value_t** %2, align 8
%4 = extractvalue %Complex.15 %0, 0, !julia_type !98
%5 = call float @"julia_convert;85919"(%jl_value_t* %3, i16 %4)
%6 = load %jl_value_t** @"*Main.Core.Float3267512", align 8
%7 = getelementptr inbounds %jl_value_t* %6, i64 1, i32 0
%8 = load %jl_value_t** %7, align 8
%9 = extractvalue %Complex.15 %0, 1, !julia_type !98
%10 = call float @"julia_convert;85919"(%jl_value_t* %8, i16 %9)
%11 = insertvalue %Complex.16 undef, float %5, 0
%12 = insertvalue %Complex.16 %11, float %10, 1, !julia_type !103
%13 = call %Complex.16 @"julia_sin;89568"(%Complex.16 %12), !julia_type !103
%14 = load %jl_value_t** @"*Main.Core.Float1667510", align 8
%15 = getelementptr inbounds %jl_value_t* %14, i64 1, i32 0
%16 = load %jl_value_t** %15, align 8
%17 = extractvalue %Complex.16 %13, 0
%18 = call i16 @"julia_convert;85922"(%jl_value_t* %16, float %17), !julia_type !98
%19 = load %jl_value_t** @"*Main.Core.Float1667510", align 8
%20 = getelementptr inbounds %jl_value_t* %19, i64 1, i32 0
%21 = load %jl_value_t** %20, align 8
%22 = extractvalue %Complex.16 %13, 1
%23 = call i16 @"julia_convert;85922"(%jl_value_t* %21, float %22), !julia_type !98
%24 = insertvalue %Complex.15 undef, i16 %18, 0
%25 = insertvalue %Complex.15 %24, i16 %23, 1, !julia_type !104
ret %Complex.15 %25
}
The type mentioned in the error was defined earlier as:
%Complex.16 = type { float, float }
My main question is: where do I start to try to debug LLVM errors
like this? Are there LLVM references that'd help? Any way to use
Clang or other LLVM tool to try to narrow it down or test this?
The .bc code from Julia could well be wrong or be missing code,
but I don't really know where to start here.
[1]
http://julialang.org[2]
https://groups.google.com/d/msg/julia-dev/qdnggTuIp9s/BoQSNGNXxV0J