@@ -109,7 +109,7 @@ function finish_ir!(@nospecialize(job::CompilerJob{MetalCompilerTarget}), mod::L
109
109
entry_fn = LLVM. name (entry)
110
110
111
111
if job. source. kernel
112
- add_address_spaces! (job, mod, entry)
112
+ add_address_spaces! (mod, entry)
113
113
end
114
114
115
115
return functions (mod)[entry_fn]
148
148
# generic pointer removal
149
149
#
150
150
# every pointer argument (e.g. byref objs) to a kernel needs an address space attached.
151
- function add_address_spaces! (@nospecialize (job :: CompilerJob ), mod:: LLVM.Module , f:: LLVM.Function )
151
+ function add_address_spaces! (mod:: LLVM.Module , f:: LLVM.Function )
152
152
ctx = context (mod)
153
153
ft = eltype (llvmtype (f))
154
- @compiler_assert LLVM. return_type (ft) == LLVM. VoidType (ctx) job
155
154
156
155
function remapType (src)
157
156
# TODO : recurse in structs
@@ -204,6 +203,45 @@ function add_address_spaces!(@nospecialize(job::CompilerJob), mod::LLVM.Module,
204
203
205
204
clone_into! (new_f, f; value_map, changes, type_mapper)
206
205
206
+ # update calls to overloaded intrinsic, re-mangling their names
207
+ # XXX : shouldn't clone_into! do this?
208
+ LLVM. @dispose builder= Builder (ctx) begin
209
+ for bb in blocks (new_f), inst in instructions (bb)
210
+ if inst isa LLVM. CallBase
211
+ callee_f = called_value (inst)
212
+ LLVM. isintrinsic (callee_f) || continue
213
+ intr = Intrinsic (callee_f)
214
+ isoverloaded (intr) || continue
215
+
216
+ # get an appropriately-overloaded intrinsic instantiation
217
+ # XXX : apparently it differs per intrinsics which arguments to take into
218
+ # consideration when generating an overload? for example, with memcpy
219
+ # the trailing i1 argument is not included in the overloaded name.
220
+ intr_f = if intr == Intrinsic (" llvm.memcpy" )
221
+ LLVM. Function (mod, intr, llvmtype .(arguments (inst)[1 : end - 1 ]))
222
+ else
223
+ error (" Unsupported intrinsic; please file an issue." )
224
+ end
225
+
226
+ # create a call to the new intrinsic
227
+ # TODO : wrap setCalledFunction instead of using an IRBuilder
228
+ position! (builder, inst)
229
+ new_inst = if inst isa LLVM. CallInst
230
+ call! (builder, intr_f, arguments (inst), operand_bundles (inst))
231
+ else
232
+ # TODO : invoke and callbr
233
+ error (" Rewrite of $(typeof (inst)) -based calls is not implemented: $inst " )
234
+ end
235
+ callconv! (new_inst, callconv (inst))
236
+
237
+ # replace the old call
238
+ replace_uses! (inst, new_inst)
239
+ @assert isempty (uses (inst))
240
+ unsafe_delete! (LLVM. parent (inst), inst)
241
+ end
242
+ end
243
+ end
244
+
207
245
# remove the old function
208
246
fn = LLVM. name (f)
209
247
@assert isempty (uses (f))
0 commit comments