Generate LLVM IR for a void* wrapper function. This is the codegen implementation shared by all void* wrappers. It processes each argument according to its _ArgSpec mode, calls the inner function, and stores the result if needed. Args: context: Numba codegen context
(
context, builder, args, arg_specs, func_device, inner_sig
)
| 138 | |
| 139 | |
| 140 | def _codegen_void_ptr_wrapper( |
| 141 | context, builder, args, arg_specs, func_device, inner_sig |
| 142 | ): |
| 143 | """Generate LLVM IR for a void* wrapper function. |
| 144 | |
| 145 | This is the codegen implementation shared by all void* wrappers. |
| 146 | It processes each argument according to its _ArgSpec mode, calls |
| 147 | the inner function, and stores the result if needed. |
| 148 | |
| 149 | Args: |
| 150 | context: Numba codegen context |
| 151 | builder: LLVM IR builder |
| 152 | args: LLVM values for the void* arguments |
| 153 | arg_specs: List of _ArgSpec describing each argument |
| 154 | func_device: The device function to call |
| 155 | inner_sig: Numba signature for the inner function |
| 156 | |
| 157 | Returns: |
| 158 | LLVM dummy value (for void return) |
| 159 | """ |
| 160 | |
| 161 | input_vals = [] |
| 162 | state_array_vals = [] |
| 163 | ret_ptr = None |
| 164 | |
| 165 | for i, (arg, spec) in enumerate(zip(args, arg_specs)): |
| 166 | match spec.mode: |
| 167 | case _ArgMode.LOAD: |
| 168 | # Cast void* to typed pointer and load value |
| 169 | llvm_type = context.get_value_type(spec.numba_type) |
| 170 | typed_ptr = builder.bitcast(arg, llvm_type.as_pointer()) |
| 171 | val = builder.load(typed_ptr) |
| 172 | input_vals.append(val) |
| 173 | case _ArgMode.PTR: |
| 174 | # Cast void* to typed pointer, pass pointer directly |
| 175 | llvm_type = context.get_value_type(spec.numba_type.dtype) |
| 176 | typed_ptr = builder.bitcast(arg, llvm_type.as_pointer()) |
| 177 | input_vals.append(typed_ptr) |
| 178 | case _ArgMode.STORE: |
| 179 | # Cast void* to typed pointer for storing result |
| 180 | llvm_type = context.get_value_type(spec.numba_type) |
| 181 | ret_ptr = builder.bitcast(arg, llvm_type.as_pointer()) |
| 182 | case _ArgMode.STATE: |
| 183 | # Cast void* to a packed array of pointers and unpack them |
| 184 | array_vals = _unpack_state_arrays( |
| 185 | context, builder, arg, spec.numba_type |
| 186 | ) |
| 187 | state_array_vals.extend(array_vals) |
| 188 | case _: |
| 189 | raise ValueError(f"Invalid arg mode: {spec.mode}") |
| 190 | |
| 191 | # Prepend state arrays at the beginning (inner_sig expects state args first) |
| 192 | input_vals = state_array_vals + input_vals |
| 193 | |
| 194 | # Call the inner function |
| 195 | cres = context.compile_subroutine(builder, func_device, inner_sig, caching=False) |
| 196 | result = context.call_internal(builder, cres.fndesc, inner_sig, input_vals) |
| 197 |
nothing calls this directly
no test coverage detected