@@ -223,6 +223,97 @@ function overdub_pass!(reflection::Reflection,
223
223
append! (overdubbed_code, code_info. code)
224
224
append! (overdubbed_codelocs, code_info. codelocs)
225
225
226
+ #= == mark all `llvmcall`s as nooverdub, optionally mark all `Intrinsics`/`Builtins` nooverdub ===#
227
+
228
+ function unravel_intrinsics (x)
229
+ stmt = Base. Meta. isexpr (x, :(= )) ? x. args[2 ] : x
230
+ if Base. Meta. isexpr (stmt, :call )
231
+ applycall = is_ir_element (stmt. args[1 ], GlobalRef (Core, :_apply ), overdubbed_code)
232
+ f = applycall ? stmt. args[2 ] : stmt. args[1 ]
233
+ f = ir_element (f, overdubbed_code)
234
+ if f isa Expr && Base. Meta. isexpr (f, :call ) &&
235
+ is_ir_element (f. args[1 ], GlobalRef (Base, :getproperty ), overdubbed_code)
236
+
237
+ # resolve getproperty here
238
+ # this is formed by Core.Intrinsics.llvmcall
239
+ # %1 = Base.getproperty(Core, :Intrinsics)
240
+ # %2 = GlobalRef(%1, :llvmcall)
241
+ mod = ir_element (f. args[2 ], overdubbed_code)
242
+ if mod isa GlobalRef
243
+ mod = resolve_early (mod) # returns nothing if fails
244
+ end
245
+ if ! (mod isa Module)
246
+ # might be nothing or a Slot
247
+ return nothing
248
+ end
249
+ fname = ir_element (f. args[3 ], overdubbed_code)
250
+ if fname isa QuoteNode
251
+ fname = fname. value
252
+ end
253
+ f = GlobalRef (mod, fname)
254
+ end
255
+ if f isa GlobalRef
256
+ f = resolve_early (f)
257
+ end
258
+ return f
259
+ end
260
+ return nothing
261
+ end
262
+
263
+ # TODO : add user-facing flag to do this for all intrinsics
264
+ if ! iskwfunc
265
+ insert_statements! (overdubbed_code, overdubbed_codelocs,
266
+ (x, i) -> begin
267
+ intrinsic = unravel_intrinsics (x)
268
+ if intrinsic === nothing
269
+ return nothing
270
+ end
271
+ if intrinsic === Core. Intrinsics. llvmcall
272
+ if istaggingenabled
273
+ count = 0
274
+ for arg in stmt. args
275
+ if isa (arg, SSAValue) || isa (arg, SlotNumber)
276
+ count += 1
277
+ end
278
+ end
279
+ return count + 1
280
+ else
281
+ return 1
282
+ end
283
+ end
284
+ end ,
285
+ (x, i) -> begin
286
+ stmt = Base. Meta. isexpr (x, :(= )) ? x. args[2 ] : x
287
+ applycall = is_ir_element (stmt. args[1 ], GlobalRef (Core, :_apply ), overdubbed_code)
288
+ intrinsic = unravel_intrinsics (x)
289
+ items = Any[]
290
+ args = nothing
291
+ if istaggingenabled
292
+ args = Any[]
293
+ for arg in stmt. args
294
+ if isa (arg, SSAValue) || isa (arg, SlotNumber)
295
+ push! (args, SSAValue (i + length (items)))
296
+ push! (items, Expr (:call , Expr (:nooverdub , GlobalRef (Cassette, :untag )), arg, overdub_ctx_slot))
297
+ else
298
+ push! (result. args, arg)
299
+ end
300
+ end
301
+ end
302
+ idx = 1
303
+ if applycall
304
+ idx = 2
305
+ end
306
+ # using stmt.args[idx] instead of `intrinsic` leads to a bug
307
+ stmt. args[idx] = Expr (:nooverdub , intrinsic)
308
+ if args != = nothing
309
+ idx += 1
310
+ stmt. args[idx: end ] = args
311
+ end
312
+ push! (items, x)
313
+ return items
314
+ end )
315
+ end
316
+
226
317
#= == perform tagged module transformation if tagging is enabled ===#
227
318
228
319
if istaggingenabled && ! iskwfunc
0 commit comments