@@ -20,9 +20,46 @@ struct KernelState
2020end
2121
2222@inline @generated kernel_state () = GPUCompiler. kernel_state_value (KernelState)
23- @inline @generated random_keys () = GPUCompiler. call_custom_noarg_readnone_intrinsic (
24- LLVMPtr{UInt32, AS. Workgroup}, " julia.spirv.random_keys" , " random_keys" ,
25- )
26- @inline @generated random_counters () = GPUCompiler. call_custom_noarg_readnone_intrinsic (
27- LLVMPtr{UInt32, AS. Workgroup}, " julia.spirv.random_counters" , " random_counters" ,
28- )
23+
24+ function additional_arg_intr (mod:: LLVM.Module , T_state, name)
25+ state_intr = if haskey (functions (mod), " julia.spirv.$name " )
26+ functions (mod)[" julia.spirv.$name " ]
27+ else
28+ LLVM. Function (mod, " julia.spirv.$name " , LLVM. FunctionType (T_state))
29+ end
30+ push! (function_attributes (state_intr), EnumAttribute (" readnone" , 0 ))
31+
32+ return state_intr
33+ end
34+
35+ # run-time equivalent
36+ function additional_arg_value (state, name)
37+ @dispose ctx= Context () begin
38+ T_state = convert (LLVMType, state)
39+
40+ # create function
41+ llvm_f, _ = create_function (T_state)
42+ mod = LLVM. parent (llvm_f)
43+
44+ # get intrinsic
45+ state_intr = additional_arg_intr (mod, T_state, name)
46+ state_intr_ft = function_type (state_intr)
47+
48+ # generate IR
49+ @dispose builder= IRBuilder () begin
50+ entry = BasicBlock (llvm_f, " entry" )
51+ position! (builder, entry)
52+
53+ val = call! (builder, state_intr_ft, state_intr, Value[], name)
54+
55+ ret! (builder, val)
56+ end
57+
58+ call_function (llvm_f, state)
59+ end
60+ end
61+
62+ for name in [:random_keys , :random_counters ]
63+ @eval @inline @generated $ name () =
64+ additional_arg_value (LLVMPtr{UInt32, AS. Workgroup}, $ (String (name)))
65+ end
0 commit comments