Thanks, @Sukera ! ![]()
For reference, here is some code to illustrate the issue with global variables:
module blinking_leds
using ESP32RISCVCompiler.Arduino
const counter = Ref{Int32}()
function setup()
counter[] = 0
end
function loop()
end
end
This gets compiled into:
define i32 @_Z5setupv() local_unnamed_addr {
top:
store i32 0, ptr inttoptr (i32 -779740248 to ptr), align 4, !tbaa !2, !alias.scope !7, !noalias !10
ret i32 0
}
where -779740248 corresponds to Int32(pointer_from_objref(blinking_leds.counter)) on the host.
Maybe one approach is to collect all global variables in the module and to keep track of their memory address and indeed to iterate over the LLVM IR and to transform all for these pointers.
Unfortunately, at the LLVM IR level (produced by GPUCompiler.jl), there seems to be no information left that an operation involved a global variable. (Maybe this can be added as LLVM Metadata ?)
Or maybe there is a better way higher up the compiler pipeline?
Interestingly, in @code_llvm global variables are not directly subsituted by the corresponding memory address:
julia> @code_llvm blinking_leds.setup()
; Function Signature: setup()
; @ /home/abarth/src/ESP32RISCVCompiler/examples/blinking_leds_globals.jl:11 within `setup`
define i32 @julia_setup_13840() #0 {
top:
; @ /home/abarth/src/ESP32RISCVCompiler/examples/blinking_leds_globals.jl:12 within `setup`
; ┌ @ refvalue.jl:60 within `setindex!`
; │┌ @ Base_compiler.jl:58 within `setproperty!`
store i32 0, ptr @"jl_global#13842.jit", align 8
ret i32 0
; └└
}