109
109
@inline val (x) = x
110
110
@inline val (x:: GlobalRef ) = getproperty (x. mod, x. name)
111
111
@inline val (x:: QuoteNode ) = eval (x)
112
- @inline val (x:: TapedFunction ) = x. func
113
112
@inline result (t:: TapedFunction ) = t. bindings[t. retval]
114
113
115
114
const SLOTS = [Symbol (" _" , i) for i in 1 : 100 ]
@@ -264,39 +263,57 @@ function translate!(tape::RawTape, ir::Core.CodeInfo)
264
263
265
264
for (idx, line) in enumerate (ir. code)
266
265
isa (line, Core. Const) && (line = line. val) # unbox Core.Const
267
- ins = translate!! (Core. SSAValue (idx), line, bindings, ir)
266
+ isconst = isa (ir. ssavaluetypes[idx], Core. Const)
267
+ ins = translate!! (Core. SSAValue (idx), line, bindings, isconst, ir)
268
268
push! (tape, ins)
269
269
end
270
270
return (bindings, tape)
271
271
end
272
272
273
273
const IRVar = Union{Core. SSAValue, Core. SlotNumber}
274
274
275
+ function _const_instruction (var:: IRVar , v, bindings:: Dict{Symbol, Any} , ir)
276
+ if isa (var, Core. SSAValue)
277
+ box = bind_var! (var, bindings, ir)
278
+ bindings[box. id] = v
279
+ return GotoInstruction (Box {Bool} (:_true ), 0 ) # NOOP
280
+ end
281
+ return Instruction (identity, (bind_var! (v, bindings, ir),), bind_var! (var, bindings, ir))
282
+ end
283
+
275
284
function translate!! (var:: IRVar , line:: Core.NewvarNode ,
276
- bindings:: Dict{Symbol, Any} , @nospecialize (ir))
285
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , @nospecialize (ir))
277
286
# use a noop to ensure the 1-to-1 mapping from ir.code to instructions
278
287
# on tape. see GotoInstruction.dest.
279
288
return GotoInstruction (Box {Bool} (:_true ), 0 )
280
289
end
281
290
282
291
function translate!! (var:: IRVar , line:: GlobalRef ,
283
- bindings:: Dict{Symbol, Any} , ir)
292
+ bindings:: Dict{Symbol, Any} , isconst:: Bool , ir)
293
+ if isconst
294
+ v = ir. ssavaluetypes[var. id]. val
295
+ return _const_instruction (var, v, bindings, ir)
296
+ end
284
297
return Instruction (() -> val (line), (), bind_var! (var, bindings, ir))
285
298
end
286
299
287
300
function translate!! (var:: IRVar , line:: Core.SlotNumber ,
288
- bindings:: Dict{Symbol, Any} , ir)
301
+ bindings:: Dict{Symbol, Any} , isconst:: Bool , ir)
302
+ if isconst
303
+ v = ir. ssavaluetypes[var. id]. val
304
+ return _const_instruction (var, v, bindings, ir)
305
+ end
289
306
return Instruction (identity, (bind_var! (line, bindings, ir),), bind_var! (var, bindings, ir))
290
307
end
291
308
292
309
function translate!! (var:: IRVar , line:: Core.TypedSlot ,
293
- bindings:: Dict{Symbol, Any} , ir)
310
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , ir)
294
311
input_box = bind_var! (Core. SlotNumber (line. id), bindings, ir)
295
312
return Instruction (identity, (input_box,), bind_var! (var, bindings, ir))
296
313
end
297
314
298
315
function translate!! (var:: IRVar , line:: Core.GotoIfNot ,
299
- bindings:: Dict{Symbol, Any} , ir)
316
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , ir)
300
317
_cond = bind_var! (line. cond, bindings, ir)
301
318
cond = if isa (_cond, Bool)
302
319
Box {Bool} (_cond ? :_true : :_false )
@@ -307,29 +324,35 @@ function translate!!(var::IRVar, line::Core.GotoIfNot,
307
324
end
308
325
309
326
function translate!! (var:: IRVar , line:: Core.GotoNode ,
310
- bindings:: Dict{Symbol, Any} , @nospecialize (ir))
327
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , @nospecialize (ir))
311
328
return GotoInstruction (Box {Bool} (:_false ), line. label)
312
329
end
313
330
314
331
function translate!! (var:: IRVar , line:: Core.ReturnNode ,
315
- bindings:: Dict{Symbol, Any} , ir)
332
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , ir)
316
333
return ReturnInstruction (bind_var! (line. val, bindings, ir))
317
334
end
318
335
319
336
function translate!! (var:: IRVar , line:: Expr ,
320
- bindings:: Dict{Symbol, Any} , ir:: Core.CodeInfo )
337
+ bindings:: Dict{Symbol, Any} , isconst :: Bool , ir:: Core.CodeInfo )
321
338
head = line. head
322
339
_bind_fn = (x) -> bind_var! (x, bindings, ir)
323
340
if head === :new
324
341
args = map (_bind_fn, line. args)
325
342
return Instruction (__new__, args |> Tuple, _bind_fn (var))
326
343
elseif head === :call
344
+ if isconst
345
+ v = ir. ssavaluetypes[var. id]. val
346
+ return _const_instruction (var, v, bindings, ir)
347
+ end
327
348
args = map (_bind_fn, line. args)
328
349
# args[1] is the function
329
350
func = line. args[1 ]
330
351
if Meta. isexpr (func, :static_parameter ) # func is a type parameter
331
352
func = ir. parent. sparam_vals[func. args[1 ]]
332
- else # isa(func, GlobalRef) or a var?
353
+ elseif isa (func, GlobalRef)
354
+ func = val (func)
355
+ else # a var?
333
356
func = args[1 ] # a var(box)
334
357
end
335
358
return Instruction (func, args[2 : end ] |> Tuple, _bind_fn (var))
@@ -338,8 +361,12 @@ function translate!!(var::IRVar, line::Expr,
338
361
lhs = line. args[1 ]
339
362
rhs = line. args[2 ] # the right hand side, maybe a Expr, or a var, or ...
340
363
if Meta. isexpr (rhs, (:new , :call ))
341
- return translate!! (lhs, rhs, bindings, ir)
364
+ return translate!! (lhs, rhs, bindings, false , ir)
342
365
else # rhs is a single value
366
+ if isconst
367
+ v = ir. ssavaluetypes[var. id]. val
368
+ return Instruction (identity, (_bind_fn (v),), _bind_fn (lhs))
369
+ end
343
370
return Instruction (identity, (_bind_fn (rhs),), _bind_fn (lhs))
344
371
end
345
372
else
0 commit comments