320
320
end
321
321
322
322
struct GPUInterpreter <: CC.AbstractInterpreter
323
+ meta:: Any
323
324
world:: UInt
324
325
method_table:: GPUMethodTableView
325
326
336
337
337
338
@static if HAS_INTEGRATED_CACHE
338
339
function GPUInterpreter (world:: UInt = Base. get_world_counter ();
340
+ meta = nothing ,
339
341
method_table:: MTType ,
340
342
token:: Any ,
341
343
inf_params:: CC.InferenceParams ,
@@ -345,26 +347,28 @@ function GPUInterpreter(world::UInt=Base.get_world_counter();
345
347
method_table = get_method_table_view (world, method_table)
346
348
inf_cache = Vector {CC.InferenceResult} ()
347
349
348
- return GPUInterpreter (world, method_table,
350
+ return GPUInterpreter (meta, world, method_table,
349
351
token, inf_cache,
350
352
inf_params, opt_params)
351
353
end
352
354
353
355
function GPUInterpreter (interp:: GPUInterpreter ;
356
+ meta= interp. meta,
354
357
world:: UInt = interp. world,
355
358
method_table:: GPUMethodTableView = interp. method_table,
356
359
token:: Any = interp. token,
357
360
inf_cache:: Vector{CC.InferenceResult} = interp. inf_cache,
358
361
inf_params:: CC.InferenceParams = interp. inf_params,
359
362
opt_params:: CC.OptimizationParams = interp. opt_params)
360
- return GPUInterpreter (world, method_table,
363
+ return GPUInterpreter (meta, world, method_table,
361
364
token, inf_cache,
362
365
inf_params, opt_params)
363
366
end
364
367
365
368
else
366
369
367
370
function GPUInterpreter (world:: UInt = Base. get_world_counter ();
371
+ meta= nothing ,
368
372
method_table:: MTType ,
369
373
code_cache:: CodeCache ,
370
374
inf_params:: CC.InferenceParams ,
@@ -374,19 +378,20 @@ function GPUInterpreter(world::UInt=Base.get_world_counter();
374
378
method_table = get_method_table_view (world, method_table)
375
379
inf_cache = Vector {CC.InferenceResult} ()
376
380
377
- return GPUInterpreter (world, method_table,
381
+ return GPUInterpreter (meta, world, method_table,
378
382
code_cache, inf_cache,
379
383
inf_params, opt_params)
380
384
end
381
385
382
386
function GPUInterpreter (interp:: GPUInterpreter ;
387
+ meta= interp. meta,
383
388
world:: UInt = interp. world,
384
389
method_table:: GPUMethodTableView = interp. method_table,
385
390
code_cache:: CodeCache = interp. code_cache,
386
391
inf_cache:: Vector{CC.InferenceResult} = interp. inf_cache,
387
392
inf_params:: CC.InferenceParams = interp. inf_params,
388
393
opt_params:: CC.OptimizationParams = interp. opt_params)
389
- return GPUInterpreter (world, method_table,
394
+ return GPUInterpreter (meta, world, method_table,
390
395
code_cache, inf_cache,
391
396
inf_params, opt_params)
392
397
end
@@ -437,6 +442,8 @@ function CC.concrete_eval_eligible(interp::GPUInterpreter,
437
442
end
438
443
439
444
445
+ within_gpucompiler () = false
446
+
440
447
# # deferred compilation
441
448
442
449
struct DeferredCallInfo <: CC.CallInfo
@@ -445,9 +452,11 @@ struct DeferredCallInfo <: CC.CallInfo
445
452
end
446
453
447
454
# recognize calls to gpuc.deferred and save DeferredCallInfo metadata
448
- function CC. abstract_call_known (interp:: GPUInterpreter , @nospecialize (f),
449
- arginfo:: CC.ArgInfo , si:: CC.StmtInfo , sv:: CC.AbsIntState ,
450
- max_methods:: Int = CC. get_max_methods (interp, f, sv))
455
+ # default implementation, extensible through meta argument.
456
+ # XXX : (or should we dispatch on `f`)?
457
+ function abstract_call_known (meta:: Nothing , interp:: GPUInterpreter , @nospecialize (f),
458
+ arginfo:: CC.ArgInfo , si:: CC.StmtInfo , sv:: CC.AbsIntState ,
459
+ max_methods:: Int = CC. get_max_methods (interp, f, sv))
451
460
(; fargs, argtypes) = arginfo
452
461
if f === var"gpuc.deferred"
453
462
argvec = argtypes[2 : end ]
@@ -458,7 +467,34 @@ function CC.abstract_call_known(interp::GPUInterpreter, @nospecialize(f),
458
467
else
459
468
return CC. CallMeta (Ptr{Cvoid}, Union{}, CC. Effects (), callinfo)
460
469
end
470
+ elseif f === within_gpucompiler
471
+ if length (argtypes) != 1
472
+ @static if VERSION < v " 1.11.0-"
473
+ return CC. CallMeta (Union{}, CC. Effects (), CC. NoCallInfo ())
474
+ else
475
+ return CC. CallMeta (Union{}, Union{}, CC. Effects (), CC. NoCallInfo ())
476
+ end
477
+ end
478
+ @static if VERSION < v " 1.11.0-"
479
+ return CC. CallMeta (Core. Const (true ), CC. EFFECTS_TOTAL, CC. MethodResultPure ())
480
+ else
481
+ return CC. CallMeta (Core. Const (true ), Union{}, CC. EFFECTS_TOTAL, CC. MethodResultPure (),)
482
+ end
461
483
end
484
+ return nothing
485
+ end
486
+
487
+ function CC. abstract_call_known (interp:: GPUInterpreter , @nospecialize (f),
488
+ arginfo:: CC.ArgInfo , si:: CC.StmtInfo , sv:: CC.AbsIntState ,
489
+ max_methods:: Int = CC. get_max_methods (interp, f, sv))
490
+ candidate = abstract_call_known (interp. meta, interp, f, arginfo, si, sv, max_methods)
491
+ if candidate === nothing && interp. meta != = nothing
492
+ candidate = abstract_call_known (interp. meta, interp, f, arginfo, si, sv, max_methods)
493
+ end
494
+ if candidate != = nothing
495
+ return candidate
496
+ end
497
+
462
498
return @invoke CC. abstract_call_known (interp:: CC.AbstractInterpreter , f,
463
499
arginfo:: CC.ArgInfo , si:: CC.StmtInfo , sv:: CC.AbsIntState ,
464
500
max_methods:: Int )
@@ -542,6 +578,101 @@ function CC.finish(interp::GPUInterpreter, opt::CC.OptimizationState, ir::CC.IRC
542
578
end
543
579
end
544
580
581
+ import . CC: CallInfo
582
+ struct NoInlineCallInfo <: CallInfo
583
+ info:: CallInfo # wrapped call
584
+ tt:: Any # ::Type
585
+ kind:: Symbol
586
+ NoInlineCallInfo (@nospecialize (info:: CallInfo ), @nospecialize (tt), kind:: Symbol ) =
587
+ new (info, tt, kind)
588
+ end
589
+
590
+ CC. nsplit_impl (info:: NoInlineCallInfo ) = CC. nsplit (info. info)
591
+ CC. getsplit_impl (info:: NoInlineCallInfo , idx:: Int ) = CC. getsplit (info. info, idx)
592
+ CC. getresult_impl (info:: NoInlineCallInfo , idx:: Int ) = CC. getresult (info. info, idx)
593
+ struct AlwaysInlineCallInfo <: CallInfo
594
+ info:: CallInfo # wrapped call
595
+ tt:: Any # ::Type
596
+ AlwaysInlineCallInfo (@nospecialize (info:: CallInfo ), @nospecialize (tt)) = new (info, tt)
597
+ end
598
+
599
+ CC. nsplit_impl (info:: AlwaysInlineCallInfo ) = Core. Compiler. nsplit (info. info)
600
+ CC. getsplit_impl (info:: AlwaysInlineCallInfo , idx:: Int ) = CC. getsplit (info. info, idx)
601
+ CC. getresult_impl (info:: AlwaysInlineCallInfo , idx:: Int ) = CC. getresult (info. info, idx)
602
+
603
+
604
+ function inlining_handler (meta:: Nothing , interp:: GPUInterpreter , @nospecialize (atype), callinfo)
605
+ return nothing
606
+ end
607
+
608
+ using Core. Compiler: ArgInfo, StmtInfo, AbsIntState
609
+ function CC. abstract_call_gf_by_type (interp:: GPUInterpreter , @nospecialize (f), arginfo:: ArgInfo ,
610
+ si:: StmtInfo , @nospecialize (atype), sv:: AbsIntState , max_methods:: Int )
611
+ ret = @invoke CC. abstract_call_gf_by_type (interp:: CC.AbstractInterpreter , f:: Any , arginfo:: ArgInfo ,
612
+ si:: StmtInfo , atype:: Any , sv:: AbsIntState , max_methods:: Int )
613
+
614
+ callinfo = nothing
615
+ if interp. meta != = nothing
616
+ callinfo = inlining_handler (interp. meta, interp, atype, ret. info)
617
+ end
618
+ if callinfo === nothing
619
+ callinfo = inlining_handler (nothing , interp, atype, ret. info)
620
+ end
621
+ if callinfo === nothing
622
+ callinfo = ret. info
623
+ end
624
+
625
+ @static if VERSION ≥ v " 1.11-"
626
+ return CC. CallMeta (ret. rt, ret. exct, ret. effects, callinfo)
627
+ else
628
+ return CC. CallMeta (ret. rt, ret. effects, callinfo)
629
+ end
630
+ end
631
+
632
+ let # overload `inlining_policy`
633
+ @static if VERSION ≥ v " 1.11.0-DEV.879"
634
+ sigs_ex = :(
635
+ interp:: GPUInterpreter ,
636
+ @nospecialize (src),
637
+ @nospecialize (info:: CC.CallInfo ),
638
+ stmt_flag:: UInt32 ,
639
+ )
640
+ args_ex = :(
641
+ interp:: CC.AbstractInterpreter ,
642
+ src:: Any ,
643
+ info:: CC.CallInfo ,
644
+ stmt_flag:: UInt32 ,
645
+ )
646
+ else
647
+ sigs_ex = :(
648
+ interp:: GPUInterpreter ,
649
+ @nospecialize (src),
650
+ @nospecialize (info:: CC.CallInfo ),
651
+ stmt_flag:: UInt8 ,
652
+ mi:: MethodInstance ,
653
+ argtypes:: Vector{Any} ,
654
+ )
655
+ args_ex = :(
656
+ interp:: CC.AbstractInterpreter ,
657
+ src:: Any ,
658
+ info:: CC.CallInfo ,
659
+ stmt_flag:: UInt8 ,
660
+ mi:: MethodInstance ,
661
+ argtypes:: Vector{Any} ,
662
+ )
663
+ end
664
+ @eval function Core. Compiler. inlining_policy ($ (sigs_ex. args... ))
665
+ if info isa NoInlineCallInfo
666
+ @safe_debug " Blocking inlining" info. tt info. kind
667
+ return nothing
668
+ elseif info isa AlwaysInlineCallInfo
669
+ @safe_debug " Forcing inlining for" info. tt
670
+ return src
671
+ end
672
+ return @invoke Core. Compiler. inlining_policy ($ (args_ex. args... ))
673
+ end
674
+ end
675
+
545
676
546
677
# # world view of the cache
547
678
using Core. Compiler: WorldView
@@ -704,7 +835,7 @@ function compile_method_instance(@nospecialize(job::CompilerJob))
704
835
source = pop! (worklist)
705
836
haskey (compiled, source) && continue # We have fulfilled the request already
706
837
# Create a new compiler job for this edge, reusing the config settings from the inital one
707
- job2 = CompilerJob (source, job. config)
838
+ job2 = CompilerJob (source, job. config) # TODO : GPUInterpreter.meta in config?
708
839
llvm_mod2, outstanding = compile_method_instance (job2, compiled)
709
840
append! (worklist, outstanding) # merge worklist with new outstanding edges
710
841
@assert context (llvm_mod) == context (llvm_mod2)
0 commit comments