@@ -767,7 +767,7 @@ function rewrite_apply_exprargs!(
767767                elseif  isa (new_info, MethodMatchInfo) ||  isa (new_info, UnionSplitInfo)
768768                    new_infos =  isa (new_info, MethodMatchInfo) ?  MethodMatchInfo[new_info] :  new_info. matches
769769                    #  See if we can inline this call to `iterate`
770-                     analyze_single_call !
770+                     handle_call !
771771                        ir, state1. id, new_stmt, new_infos, flag,
772772                        new_sig, istate, todo)
773773                end 
@@ -874,8 +874,7 @@ function validate_sparams(sparams::SimpleVector)
874874end 
875875
876876function  analyze_method! (match:: MethodMatch , argtypes:: Vector{Any} ,
877-                          flag:: UInt8 , state:: InliningState ,
878-                          do_resolve:: Bool  =  true )
877+                          flag:: UInt8 , state:: InliningState )
879878    method =  match. method
880879    spec_types =  match. spec_types
881880
@@ -909,7 +908,7 @@ function analyze_method!(match::MethodMatch, argtypes::Vector{Any},
909908    todo =  InliningTodo (mi, match, argtypes)
910909    #  If we don't have caches here, delay resolving this MethodInstance
911910    #  until the batch inlining step (or an external post-processing pass)
912-     do_resolve  &&   state. mi_cache ===  nothing  &&  return  todo
911+     state. mi_cache ===  nothing  &&  return  todo
913912    return  resolve_todo (todo, state, flag)
914913end 
915914
@@ -921,7 +920,7 @@ function retrieve_ir_for_inlining(mi::MethodInstance, src::Array{UInt8, 1})
921920    src =  ccall (:jl_uncompress_ir , Any, (Any, Ptr{Cvoid}, Any), mi. def, C_NULL , src:: Vector{UInt8} ):: CodeInfo 
922921    return  inflate_ir! (src, mi)
923922end 
924- retrieve_ir_for_inlining (mi:: MethodInstance , src:: CodeInfo ) =  inflate_ir (src, mi):: IRCode 
923+ retrieve_ir_for_inlining (mi:: MethodInstance , src:: CodeInfo ) =  inflate_ir (src, mi)
925924retrieve_ir_for_inlining (mi:: MethodInstance , ir:: IRCode ) =  copy (ir)
926925
927926function  handle_single_case! (
@@ -1225,10 +1224,8 @@ function process_simple!(ir::IRCode, idx::Int, state::InliningState, todo::Vecto
12251224end 
12261225
12271226#  TODO  inline non-`isdispatchtuple`, union-split callsites?
1228- function  compute_inlining_cases (
1229-         infos:: Vector{MethodMatchInfo} , flag:: UInt8 ,
1230-         sig:: Signature , state:: InliningState ,
1231-         do_resolve:: Bool  =  true )
1227+ function  compute_inlining_cases (infos:: Vector{MethodMatchInfo} ,
1228+     flag:: UInt8 , sig:: Signature , state:: InliningState )
12321229    argtypes =  sig. argtypes
12331230    cases =  InliningCase[]
12341231    local  any_fully_covered =  false 
@@ -1245,7 +1242,7 @@ function compute_inlining_cases(
12451242            continue 
12461243        end 
12471244        for  match in  meth
1248-             handled_all_cases &=  handle_match! (match, argtypes, flag, state, cases, true , do_resolve )
1245+             handled_all_cases &=  handle_match! (match, argtypes, flag, state, cases, #= allow_abstract =# true )
12491246            any_fully_covered |=  match. fully_covers
12501247        end 
12511248    end 
@@ -1258,23 +1255,10 @@ function compute_inlining_cases(
12581255    return  cases, handled_all_cases &  any_fully_covered
12591256end 
12601257
1261- function  analyze_single_call! (
1262-     ir:: IRCode , idx:: Int , stmt:: Expr , infos:: Vector{MethodMatchInfo} , flag:: UInt8 ,
1263-     sig:: Signature , state:: InliningState , todo:: Vector{Pair{Int, Any}} )
1264- 
1265-     r =  compute_inlining_cases (infos, flag, sig, state)
1266-     r ===  nothing  &&  return  nothing 
1267-     cases, all_covered =  r
1268-     handle_cases! (ir, idx, stmt, argtypes_to_type (sig. argtypes), cases,
1269-         all_covered, todo, state. params)
1270- end 
1271- 
1272- #  similar to `analyze_single_call!`, but with constant results
1273- function  handle_const_call! (
1274-     ir:: IRCode , idx:: Int , stmt:: Expr , cinfo:: ConstCallInfo , flag:: UInt8 ,
1275-     sig:: Signature , state:: InliningState , todo:: Vector{Pair{Int, Any}} )
1258+ function  compute_inlining_cases (info:: ConstCallInfo ,
1259+     flag:: UInt8 , sig:: Signature , state:: InliningState )
12761260    argtypes =  sig. argtypes
1277-     (; call, results) =  cinfo 
1261+     (; call, results) =  info 
12781262    infos =  isa (call, MethodMatchInfo) ?  MethodMatchInfo[call] :  call. matches
12791263    cases =  InliningCase[]
12801264    local  any_fully_covered =  false 
@@ -1302,7 +1286,7 @@ function handle_const_call!(
13021286                handled_all_cases &=  handle_const_prop_result! (result, argtypes, flag, state, cases, true )
13031287            else 
13041288                @assert  result ===  nothing 
1305-                 handled_all_cases &=  handle_match! (match, argtypes, flag, state, cases, true )
1289+                 handled_all_cases &=  handle_match! (match, argtypes, flag, state, cases, #= allow_abstract =# true )
13061290            end 
13071291        end 
13081292    end 
@@ -1312,21 +1296,39 @@ function handle_const_call!(
13121296        filter! (case:: InliningCase -> isdispatchtuple (case. sig), cases)
13131297    end 
13141298
1315-     handle_cases! (ir, idx, stmt, argtypes_to_type (argtypes), cases,
1316-         handled_all_cases &  any_fully_covered, todo, state. params)
1299+     return  cases, handled_all_cases &  any_fully_covered
1300+ end 
1301+ 
1302+ function  handle_call! (
1303+     ir:: IRCode , idx:: Int , stmt:: Expr , infos:: Vector{MethodMatchInfo} , flag:: UInt8 ,
1304+     sig:: Signature , state:: InliningState , todo:: Vector{Pair{Int, Any}} )
1305+     cases =  compute_inlining_cases (infos, flag, sig, state)
1306+     cases ===  nothing  &&  return  nothing 
1307+     cases, all_covered =  cases
1308+     handle_cases! (ir, idx, stmt, argtypes_to_type (sig. argtypes), cases,
1309+         all_covered, todo, state. params)
1310+ end 
1311+ 
1312+ function  handle_const_call! (
1313+     ir:: IRCode , idx:: Int , stmt:: Expr , info:: ConstCallInfo , flag:: UInt8 ,
1314+     sig:: Signature , state:: InliningState , todo:: Vector{Pair{Int, Any}} )
1315+     cases =  compute_inlining_cases (info, flag, sig, state)
1316+     cases ===  nothing  &&  return  nothing 
1317+     cases, all_covered =  cases
1318+     handle_cases! (ir, idx, stmt, argtypes_to_type (sig. argtypes), cases,
1319+         all_covered, todo, state. params)
13171320end 
13181321
13191322function  handle_match! (
13201323    match:: MethodMatch , argtypes:: Vector{Any} , flag:: UInt8 , state:: InliningState ,
1321-     cases:: Vector{InliningCase} , allow_abstract:: Bool  =  false ,
1322-     do_resolve:: Bool  =  true )
1324+     cases:: Vector{InliningCase} , allow_abstract:: Bool  =  false )
13231325    spec_types =  match. spec_types
13241326    allow_abstract ||  isdispatchtuple (spec_types) ||  return  false 
13251327    #  we may see duplicated dispatch signatures here when a signature gets widened
13261328    #  during abstract interpretation: for the purpose of inlining, we can just skip
13271329    #  processing this dispatch candidate
13281330    _any (case-> case. sig ===  spec_types, cases) &&  return  true 
1329-     item =  analyze_method! (match, argtypes, flag, state, do_resolve )
1331+     item =  analyze_method! (match, argtypes, flag, state)
13301332    item ===  nothing  &&  return  false 
13311333    push! (cases, InliningCase (spec_types, item))
13321334    return  true 
@@ -1384,6 +1386,54 @@ function handle_const_opaque_closure_call!(
13841386    return  nothing 
13851387end 
13861388
1389+ function  handle_finalizer_call! (
1390+     ir:: IRCode , stmt:: Expr , info:: FinalizerInfo , state:: InliningState )
1391+     #  Only inline finalizers that are known nothrow and notls.
1392+     #  This avoids having to set up state for finalizer isolation
1393+     (is_nothrow (info. effects) &&  is_notaskstate (info. effects)) ||  return  nothing 
1394+ 
1395+     info =  info. info
1396+     if  isa (info, MethodMatchInfo)
1397+         infos =  MethodMatchInfo[info]
1398+     elseif  isa (info, UnionSplitInfo)
1399+         infos =  info. matches
1400+     #  elseif isa(info, ConstCallInfo)
1401+     #      # NOTE currently this code path isn't active as constant propagation won't happen
1402+     #      # for `Core.finalizer` call because inference currently isn't able to fold a mutable
1403+     #      # object as a constant
1404+     else 
1405+         return  nothing 
1406+     end 
1407+ 
1408+     ft =  argextype (stmt. args[2 ], ir)
1409+     has_free_typevars (ft) &&  return  nothing 
1410+     f =  singleton_type (ft)
1411+     argtypes =  Vector {Any} (undef, 2 )
1412+     argtypes[1 ] =  ft
1413+     argtypes[2 ] =  argextype (stmt. args[3 ], ir)
1414+     sig =  Signature (f, ft, argtypes)
1415+ 
1416+     cases =  compute_inlining_cases (infos, #= flag=# UInt8 (0 ), sig, state)
1417+     cases ===  nothing  &&  return  nothing 
1418+     cases, all_covered =  cases
1419+     if  all_covered &&  length (cases) ==  1 
1420+         #  NOTE we don't append `item1` to `stmt` here so that we don't serialize
1421+         #  `Core.Compiler` data structure into the global cache
1422+         item1 =  cases[1 ]. item
1423+         if  isa (item1, InliningTodo)
1424+             push! (stmt. args, true )
1425+             push! (stmt. args, item1. mi)
1426+         elseif  isa (item1, InvokeCase)
1427+             push! (stmt. args, false )
1428+             push! (stmt. args, item1. invoke)
1429+         elseif  isa (item1, ConstantCase)
1430+             push! (stmt. args, nothing )
1431+             push! (stmt. args, item1. val)
1432+         end 
1433+     end 
1434+     return  nothing 
1435+ end 
1436+ 
13871437function  inline_const_if_inlineable! (inst:: Instruction )
13881438    rt =  inst[:type ]
13891439    if  rt isa  Const &&  is_inlineable_constant (rt. val)
@@ -1434,53 +1484,15 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
14341484        end 
14351485
14361486        #  Handle invoke
1437-         if  sig. f ===  Core. invoke
1438-             if  isa (info, InvokeCallInfo)
1439-                 inline_invoke! (ir, idx, stmt, info, flag, sig, state, todo)
1440-             end 
1487+         if  isa (info, InvokeCallInfo)
1488+             inline_invoke! (ir, idx, stmt, info, flag, sig, state, todo)
14411489            continue 
14421490        end 
14431491
14441492        #  Handle finalizer
1445-         if  sig. f ===  Core. finalizer
1446-             if  isa (info, FinalizerInfo)
1447-                 #  Only inline finalizers that are known nothrow and notls.
1448-                 #  This avoids having to set up state for finalizer isolation
1449-                 (is_nothrow (info. effects) &&  is_notaskstate (info. effects)) ||  continue 
1450- 
1451-                 info =  info. info
1452-                 if  isa (info, MethodMatchInfo)
1453-                     infos =  MethodMatchInfo[info]
1454-                 elseif  isa (info, UnionSplitInfo)
1455-                     infos =  info. matches
1456-                 else 
1457-                     continue 
1458-                 end 
1459- 
1460-                 ft =  argextype (stmt. args[2 ], ir)
1461-                 has_free_typevars (ft) &&  return  nothing 
1462-                 f =  singleton_type (ft)
1463-                 argtypes =  Vector {Any} (undef, 2 )
1464-                 argtypes[1 ] =  ft
1465-                 argtypes[2 ] =  argextype (stmt. args[3 ], ir)
1466-                 sig =  Signature (f, ft, argtypes)
1467- 
1468-                 cases, all_covered =  compute_inlining_cases (infos, UInt8 (0 ), sig, state, false )
1469-                 length (cases) ==  0  &&  continue 
1470-                 if  all_covered &&  length (cases) ==  1 
1471-                     if  isa (cases[1 ], InliningCase)
1472-                         case1 =  cases[1 ]. item
1473-                         if  isa (case1, InliningTodo)
1474-                             push! (stmt. args, true )
1475-                             push! (stmt. args, case1. mi)
1476-                         elseif  isa (case1, InvokeCase)
1477-                             push! (stmt. args, false )
1478-                             push! (stmt. args, case1. invoke)
1479-                         end 
1480-                     end 
1481-                 end 
1482-                 continue 
1483-             end 
1493+         if  isa (info, FinalizerInfo)
1494+             handle_finalizer_call! (ir, stmt, info, state)
1495+             continue 
14841496        end 
14851497
14861498        #  if inference arrived here with constant-prop'ed result(s),
@@ -1501,7 +1513,7 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
15011513            continue  #  isa(info, ReturnTypeCallInfo), etc.
15021514        end 
15031515
1504-         analyze_single_call !
1516+         handle_call !
15051517    end 
15061518
15071519    return  todo
0 commit comments