@@ -272,135 +272,132 @@ end
272
272
273
273
const IRVar = Union{Core. SSAValue, Core. SlotNumber}
274
274
275
- struct TempBindings
276
- data:: Bindings
277
- book:: Dict{IRVar, Int}
278
- end
279
-
280
- function bind_var! (var_literal, tbind:: TempBindings , ir:: Core.CodeInfo )
275
+ function bind_var! (var_literal, bindings:: Bindings , ir:: Core.CodeInfo )
281
276
# for literal constants
282
- push! (tbind . data , var_literal)
283
- idx = length (tbind . data )
277
+ push! (bindings , var_literal)
278
+ idx = length (bindings )
284
279
return idx
285
280
end
286
- function bind_var! (var:: GlobalRef , tbind :: TempBindings , ir:: Core.CodeInfo )
281
+ function bind_var! (var:: GlobalRef , bindings :: Bindings , ir:: Core.CodeInfo )
287
282
in (var. mod, (Base, Core)) ||
288
283
LOGGING[] && @info " evaluating GlobalRef $var at compile time"
289
- bind_var! (getproperty (var. mod, var. name), tbind , ir)
284
+ bind_var! (getproperty (var. mod, var. name), bindings , ir)
290
285
end
291
- function bind_var! (var:: QuoteNode , tbind :: TempBindings , ir:: Core.CodeInfo )
286
+ function bind_var! (var:: QuoteNode , bindings :: Bindings , ir:: Core.CodeInfo )
292
287
LOGGING[] && @info " evaluating QuoteNode $var at compile time"
293
- bind_var! (eval (var), tbind , ir)
288
+ bind_var! (eval (var), bindings , ir)
294
289
end
295
- function bind_var! (var:: Core.TypedSlot , tbind :: TempBindings , ir:: Core.CodeInfo )
290
+ function bind_var! (var:: Core.TypedSlot , bindings :: Bindings , ir:: Core.CodeInfo )
296
291
# turn TypedSlot to SlotNumber
297
- bind_var! (Core. SlotNumber (var. id), tbind , ir)
292
+ bind_var! (Core. SlotNumber (var. id), bindings , ir)
298
293
end
299
- function bind_var! (var:: Core.SlotNumber , tbind :: TempBindings , ir:: Core.CodeInfo )
300
- get! (tbind . book , var, allocate_binding! (var, tbind , ir. slottypes[var. id]))
294
+ function bind_var! (var:: Core.SlotNumber , bindings :: Bindings , ir:: Core.CodeInfo )
295
+ get! (bindings[ 1 ] , var, allocate_binding! (var, bindings , ir. slottypes[var. id]))
301
296
end
302
- function bind_var! (var:: Core.SSAValue , tbind :: TempBindings , ir:: Core.CodeInfo )
303
- get! (tbind . book , var, allocate_binding! (var, tbind , ir. ssavaluetypes[var. id]))
297
+ function bind_var! (var:: Core.SSAValue , bindings :: Bindings , ir:: Core.CodeInfo )
298
+ get! (bindings[ 1 ] , var, allocate_binding! (var, bindings , ir. ssavaluetypes[var. id]))
304
299
end
305
300
306
- allocate_binding! (var, tbind :: TempBindings , c:: Core.Const ) =
307
- allocate_binding! (var, tbind , _loose_type (Type{c. val}))
308
- allocate_binding! (var, tbind :: TempBindings , c:: Core.PartialStruct ) =
309
- allocate_binding! (var, tbind , _loose_type (c. typ))
310
- function allocate_binding! (var, tbind :: TempBindings , :: Type{T} ) where T
301
+ allocate_binding! (var, bindings :: Bindings , c:: Core.Const ) =
302
+ allocate_binding! (var, bindings , _loose_type (Type{c. val}))
303
+ allocate_binding! (var, bindings :: Bindings , c:: Core.PartialStruct ) =
304
+ allocate_binding! (var, bindings , _loose_type (c. typ))
305
+ function allocate_binding! (var, bindings :: Bindings , :: Type{T} ) where T
311
306
# we may use the type info (T) here
312
- push! (tbind . data , nothing )
313
- idx = length (tbind . data )
307
+ push! (bindings , nothing )
308
+ idx = length (bindings )
314
309
return idx
315
310
end
316
311
317
312
function translate! (tape:: RawTape , ir:: Core.CodeInfo )
318
313
binding_values = Bindings ()
319
314
sizehint! (binding_values, 128 )
320
315
bcache = Dict {IRVar, Int} ()
321
- tbind = TempBindings (binding_values, bcache)
316
+ # the first slot of binding_values is used to store a cache at compile time
317
+ push! (binding_values, bcache)
322
318
slots = Dict {Int, Int} ()
323
319
324
320
for (idx, line) in enumerate (ir. code)
325
321
isa (line, Core. Const) && (line = line. val) # unbox Core.Const
326
322
isconst = isa (ir. ssavaluetypes[idx], Core. Const)
327
- ins = translate!! (Core. SSAValue (idx), line, tbind , isconst, ir)
323
+ ins = translate!! (Core. SSAValue (idx), line, binding_values , isconst, ir)
328
324
push! (tape, ins)
329
325
end
330
- for (k, v) in tbind . book
326
+ for (k, v) in bcache
331
327
isa (k, Core. SlotNumber) && (slots[k. id] = v)
332
328
end
333
329
arg_binding_slots = fill (0 , maximum (keys (slots)))
334
330
for (k, v) in slots
335
331
arg_binding_slots[k] = v
336
332
end
333
+ binding_values[1 ] = 0 # drop bcache
337
334
return (binding_values, arg_binding_slots, tape)
338
335
end
339
336
340
- function _const_instruction (var:: IRVar , v, tbind :: TempBindings , ir)
337
+ function _const_instruction (var:: IRVar , v, bindings :: Bindings , ir)
341
338
if isa (var, Core. SSAValue)
342
- box = bind_var! (var, tbind , ir)
343
- tbind . data [box] = v
339
+ box = bind_var! (var, bindings , ir)
340
+ bindings [box] = v
344
341
return NOOPInstruction ()
345
342
end
346
- return Instruction (identity, (bind_var! (v, tbind , ir),), bind_var! (var, tbind , ir))
343
+ return Instruction (identity, (bind_var! (v, bindings , ir),), bind_var! (var, bindings , ir))
347
344
end
348
345
349
346
function translate!! (var:: IRVar , line:: Core.NewvarNode ,
350
- tbind :: TempBindings , isconst:: Bool , @nospecialize (ir))
347
+ bindings :: Bindings , isconst:: Bool , @nospecialize (ir))
351
348
# use a no-op to ensure the 1-to-1 mapping from ir.code to instructions on tape.
352
349
return NOOPInstruction ()
353
350
end
354
351
355
352
function translate!! (var:: IRVar , line:: GlobalRef ,
356
- tbind :: TempBindings , isconst:: Bool , ir)
353
+ bindings :: Bindings , isconst:: Bool , ir)
357
354
if isconst
358
355
v = ir. ssavaluetypes[var. id]. val
359
- return _const_instruction (var, v, tbind , ir)
356
+ return _const_instruction (var, v, bindings , ir)
360
357
end
361
358
func () = getproperty (line. mod, line. name)
362
- return Instruction (func, (), bind_var! (var, tbind , ir))
359
+ return Instruction (func, (), bind_var! (var, bindings , ir))
363
360
end
364
361
365
362
function translate!! (var:: IRVar , line:: Core.SlotNumber ,
366
- tbind :: TempBindings , isconst:: Bool , ir)
363
+ bindings :: Bindings , isconst:: Bool , ir)
367
364
if isconst
368
365
v = ir. ssavaluetypes[var. id]. val
369
- return _const_instruction (var, v, tbind , ir)
366
+ return _const_instruction (var, v, bindings , ir)
370
367
end
371
368
func = identity
372
- input = (bind_var! (line, tbind , ir),)
373
- output = bind_var! (var, tbind , ir)
369
+ input = (bind_var! (line, bindings , ir),)
370
+ output = bind_var! (var, bindings , ir)
374
371
return Instruction (func, input, output)
375
372
end
376
373
377
374
function translate!! (var:: IRVar , line:: Core.TypedSlot ,
378
- tbind :: TempBindings , isconst:: Bool , ir)
379
- input_box = bind_var! (Core. SlotNumber (line. id), tbind , ir)
380
- return Instruction (identity, (input_box,), bind_var! (var, tbind , ir))
375
+ bindings :: Bindings , isconst:: Bool , ir)
376
+ input_box = bind_var! (Core. SlotNumber (line. id), bindings , ir)
377
+ return Instruction (identity, (input_box,), bind_var! (var, bindings , ir))
381
378
end
382
379
383
380
function translate!! (var:: IRVar , line:: Core.GotoIfNot ,
384
- tbind :: TempBindings , isconst:: Bool , ir)
385
- cond = bind_var! (line. cond, tbind , ir)
381
+ bindings :: Bindings , isconst:: Bool , ir)
382
+ cond = bind_var! (line. cond, bindings , ir)
386
383
return CondGotoInstruction (cond, line. dest)
387
384
end
388
385
389
386
function translate!! (var:: IRVar , line:: Core.GotoNode ,
390
- tbind :: TempBindings , isconst:: Bool , @nospecialize (ir))
387
+ bindings :: Bindings , isconst:: Bool , @nospecialize (ir))
391
388
return GotoInstruction (line. label)
392
389
end
393
390
394
391
function translate!! (var:: IRVar , line:: Core.ReturnNode ,
395
- tbind :: TempBindings , isconst:: Bool , ir)
396
- return ReturnInstruction (bind_var! (line. val, tbind , ir))
392
+ bindings :: Bindings , isconst:: Bool , ir)
393
+ return ReturnInstruction (bind_var! (line. val, bindings , ir))
397
394
end
398
395
399
396
_canbeoptimized (v) = isa (v, DataType) || isprimitivetype (typeof (v))
400
397
function translate!! (var:: IRVar , line:: Expr ,
401
- tbind :: TempBindings , isconst:: Bool , ir:: Core.CodeInfo )
398
+ bindings :: Bindings , isconst:: Bool , ir:: Core.CodeInfo )
402
399
head = line. head
403
- _bind_fn = (x) -> bind_var! (x, tbind , ir)
400
+ _bind_fn = (x) -> bind_var! (x, bindings , ir)
404
401
if head === :new
405
402
args = map (_bind_fn, line. args)
406
403
return Instruction (__new__, args |> Tuple, _bind_fn (var))
@@ -410,7 +407,7 @@ function translate!!(var::IRVar, line::Expr,
410
407
# optimised function calls, we will evaluate the function at compile-time and cache results.
411
408
if isconst
412
409
v = ir. ssavaluetypes[var. id]. val
413
- _canbeoptimized (v) && return _const_instruction (var, v, tbind , ir)
410
+ _canbeoptimized (v) && return _const_instruction (var, v, bindings , ir)
414
411
end
415
412
args = map (_bind_fn, line. args)
416
413
# args[1] is the function
@@ -428,7 +425,7 @@ function translate!!(var::IRVar, line::Expr,
428
425
lhs = line. args[1 ]
429
426
rhs = line. args[2 ] # the right hand side, maybe a Expr, or a var, or ...
430
427
if Meta. isexpr (rhs, (:new , :call ))
431
- return translate!! (lhs, rhs, tbind , false , ir)
428
+ return translate!! (lhs, rhs, bindings , false , ir)
432
429
else # rhs is a single value
433
430
if isconst
434
431
v = ir. ssavaluetypes[var. id]. val
@@ -442,7 +439,7 @@ function translate!!(var::IRVar, line::Expr,
442
439
end
443
440
end
444
441
445
- function translate!! (var, line, tbind , ir)
442
+ function translate!! (var, line, bindings , ir)
446
443
@error " Unknown IR code: " typeof (var) var typeof (line) line
447
444
throw (ErrorException (" Unknown IR code" ))
448
445
end
0 commit comments