370
370
371
371
function ir_inline_item! (compact:: IncrementalCompact , idx:: Int , argexprs:: Vector{Any} ,
372
372
linetable:: Vector{LineInfoNode} , item:: InliningTodo ,
373
- boundscheck:: Symbol , todo_bbs:: Vector{Tuple{Int, Int}} )
373
+ boundscheck:: Symbol , todo_bbs:: Vector{Tuple{Int, Int}} ,
374
+ extra_flags:: UInt8 )
374
375
# Ok, do the inlining here
375
376
sparam_vals = item. mi. sparam_vals
376
377
def = item. mi. def:: Method
@@ -411,6 +412,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
411
412
break
412
413
end
413
414
inline_compact[idx′] = stmt′
415
+ inline_compact[SSAValue (idx′)][:flag ] |= extra_flags
414
416
end
415
417
just_fixup! (inline_compact, new_new_offset, late_fixup_offset)
416
418
compact. result_idx = inline_compact. result_idx
@@ -445,6 +447,14 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
445
447
stmt′ = PhiNode (Int32[edge+ bb_offset for edge in stmt′. edges], stmt′. values)
446
448
end
447
449
inline_compact[idx′] = stmt′
450
+ if extra_flags != 0 && ! isa (stmt′, Union{GotoNode, GotoIfNot})
451
+ if (extra_flags & IR_FLAG_NOTHROW) != 0 && inline_compact[SSAValue (idx′)][:type ] === Union{}
452
+ # Shown nothrow, but also guaranteed to throw => unreachable
453
+ inline_compact[idx′] = ReturnNode ()
454
+ else
455
+ inline_compact[SSAValue (idx′)][:flag ] |= extra_flags
456
+ end
457
+ end
448
458
end
449
459
just_fixup! (inline_compact, new_new_offset, late_fixup_offset)
450
460
compact. result_idx = inline_compact. result_idx
@@ -589,7 +599,7 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
589
599
end
590
600
end
591
601
if isa (case, InliningTodo)
592
- val = ir_inline_item! (compact, idx, argexprs′, linetable, case, boundscheck, todo_bbs)
602
+ val = ir_inline_item! (compact, idx, argexprs′, linetable, case, boundscheck, todo_bbs, flags_for_effects (case . effects) )
593
603
elseif isa (case, InvokeCase)
594
604
inst = Expr (:invoke , case. invoke, argexprs′... )
595
605
flag = flags_for_effects (case. effects)
@@ -689,7 +699,7 @@ function batch_inline!(ir::IRCode, todo::Vector{Pair{Int,Any}}, propagate_inboun
689
699
end
690
700
end
691
701
if isa (item, InliningTodo)
692
- compact. ssa_rename[old_idx] = ir_inline_item! (compact, idx, argexprs, ir. linetable, item, boundscheck, state. todo_bbs)
702
+ compact. ssa_rename[old_idx] = ir_inline_item! (compact, idx, argexprs, ir. linetable, item, boundscheck, state. todo_bbs, flags_for_effects (item . effects) )
693
703
elseif isa (item, UnionSplit)
694
704
compact. ssa_rename[old_idx] = ir_inline_unionsplit! (compact, idx, argexprs, ir. linetable, item, boundscheck, state. todo_bbs, params)
695
705
end
838
848
839
849
# the general resolver for usual and const-prop'ed calls
840
850
function resolve_todo (mi:: MethodInstance , result:: Union{MethodMatch,InferenceResult} ,
841
- argtypes:: Vector{Any} , @nospecialize (info:: CallInfo ), flag:: UInt8 ,
842
- state:: InliningState ; invokesig:: Union{Nothing,Vector{Any}} = nothing )
851
+ argtypes:: Vector{Any} , @nospecialize (info:: CallInfo ), flag:: UInt8 ,
852
+ state:: InliningState ; invokesig:: Union{Nothing,Vector{Any}} = nothing ,
853
+ override_effects:: Union{Nothing,Effects} = nothing )
843
854
et = InliningEdgeTracker (state. et, invokesig)
844
855
845
856
# XXX : update_valid_age!(min_valid[1], max_valid[1], sv)
@@ -860,6 +871,10 @@ function resolve_todo(mi::MethodInstance, result::Union{MethodMatch,InferenceRes
860
871
(; src, effects) = cached_result
861
872
end
862
873
874
+ if override_effects != = nothing
875
+ effects = override_effects
876
+ end
877
+
863
878
# the duplicated check might have been done already within `analyze_method!`, but still
864
879
# we need it here too since we may come here directly using a constant-prop' result
865
880
if ! state. params. inlining || is_stmt_noinline (flag)
@@ -937,7 +952,7 @@ can_inline_typevars(m::MethodMatch, argtypes::Vector{Any}) = can_inline_typevars
937
952
938
953
function analyze_method! (match:: MethodMatch , argtypes:: Vector{Any} ,
939
954
@nospecialize (info:: CallInfo ), flag:: UInt8 , state:: InliningState ;
940
- allow_typevars:: Bool , invokesig:: Union{Nothing,Vector{Any}} = nothing )
955
+ allow_typevars:: Bool , invokesig:: Union{Nothing,Vector{Any}} = nothing , override_effects :: Union{Nothing,Effects} = nothing )
941
956
method = match. method
942
957
spec_types = match. spec_types
943
958
@@ -967,11 +982,11 @@ function analyze_method!(match::MethodMatch, argtypes::Vector{Any},
967
982
mi = specialize_method (match; preexisting= true ) # Union{Nothing, MethodInstance}
968
983
if mi === nothing
969
984
et = InliningEdgeTracker (state. et, invokesig)
970
- return compileable_specialization (match, Effects (), et, info;
985
+ return compileable_specialization (match, override_effects === nothing ? Effects () : override_effects , et, info;
971
986
compilesig_invokes= state. params. compilesig_invokes)
972
987
end
973
988
974
- return resolve_todo (mi, match, argtypes, info, flag, state; invokesig)
989
+ return resolve_todo (mi, match, argtypes, info, flag, state; invokesig, override_effects )
975
990
end
976
991
977
992
function retrieve_ir_for_inlining (mi:: MethodInstance , src:: Array{UInt8, 1} )
@@ -1170,21 +1185,26 @@ function handle_invoke_call!(todo::Vector{Pair{Int,Any}},
1170
1185
end
1171
1186
result = info. result
1172
1187
invokesig = sig. argtypes
1173
- if isa (result, ConcreteResult) && may_inline_concrete_result (result)
1174
- item = concrete_result_item (result, state; invokesig)
1175
- else
1176
- argtypes = invoke_rewrite (sig. argtypes)
1177
- if isa (result, ConstPropResult)
1178
- mi = result. result. linfo
1179
- validate_sparams (mi. sparam_vals) || return nothing
1180
- if argtypes_to_type (argtypes) <: mi.def.sig
1181
- item = resolve_todo (mi, result. result, argtypes, info, flag, state; invokesig)
1182
- handle_single_case! (todo, ir, idx, stmt, item, state. params, true )
1183
- return nothing
1184
- end
1188
+ override_effects = nothing
1189
+ if isa (result, ConcreteResult)
1190
+ if may_inline_concrete_result (result)
1191
+ item = concrete_result_item (result, state; invokesig)
1192
+ handle_single_case! (todo, ir, idx, stmt, item, state. params, true )
1193
+ return nothing
1185
1194
end
1186
- item = analyze_method! (match, argtypes, info, flag, state; allow_typevars = false , invokesig)
1195
+ override_effects = result . effects
1187
1196
end
1197
+ argtypes = invoke_rewrite (sig. argtypes)
1198
+ if isa (result, ConstPropResult)
1199
+ mi = result. result. linfo
1200
+ validate_sparams (mi. sparam_vals) || return nothing
1201
+ if argtypes_to_type (argtypes) <: mi.def.sig
1202
+ item = resolve_todo (mi, result. result, argtypes, info, flag, state; invokesig, override_effects)
1203
+ handle_single_case! (todo, ir, idx, stmt, item, state. params, true )
1204
+ return nothing
1205
+ end
1206
+ end
1207
+ item = analyze_method! (match, argtypes, info, flag, state; allow_typevars= false , invokesig, override_effects)
1188
1208
handle_single_case! (todo, ir, idx, stmt, item, state. params, true )
1189
1209
return nothing
1190
1210
end
@@ -1296,10 +1316,12 @@ function handle_any_const_result!(cases::Vector{InliningCase},
1296
1316
@nospecialize (result), match:: MethodMatch , argtypes:: Vector{Any} ,
1297
1317
@nospecialize (info:: CallInfo ), flag:: UInt8 , state:: InliningState ;
1298
1318
allow_abstract:: Bool , allow_typevars:: Bool )
1319
+ override_effects = nothing
1299
1320
if isa (result, ConcreteResult)
1300
1321
if may_inline_concrete_result (result)
1301
1322
return handle_concrete_result! (cases, result, state)
1302
1323
else
1324
+ override_effects = result. effects
1303
1325
result = nothing
1304
1326
end
1305
1327
end
@@ -1313,7 +1335,7 @@ function handle_any_const_result!(cases::Vector{InliningCase},
1313
1335
return handle_const_prop_result! (cases, result, argtypes, info, flag, state; allow_abstract, allow_typevars)
1314
1336
else
1315
1337
@assert result === nothing
1316
- return handle_match! (cases, match, argtypes, info, flag, state; allow_abstract, allow_typevars)
1338
+ return handle_match! (cases, match, argtypes, info, flag, state; allow_abstract, allow_typevars, override_effects )
1317
1339
end
1318
1340
end
1319
1341
@@ -1444,14 +1466,14 @@ end
1444
1466
function handle_match! (cases:: Vector{InliningCase} ,
1445
1467
match:: MethodMatch , argtypes:: Vector{Any} , @nospecialize (info:: CallInfo ), flag:: UInt8 ,
1446
1468
state:: InliningState ;
1447
- allow_abstract:: Bool , allow_typevars:: Bool )
1469
+ allow_abstract:: Bool , allow_typevars:: Bool , override_effects :: Union{Effects, Nothing} )
1448
1470
spec_types = match. spec_types
1449
1471
allow_abstract || isdispatchtuple (spec_types) || return false
1450
1472
# We may see duplicated dispatch signatures here when a signature gets widened
1451
1473
# during abstract interpretation: for the purpose of inlining, we can just skip
1452
1474
# processing this dispatch candidate (unless unmatched type parameters are present)
1453
1475
! allow_typevars && _any (case-> case. sig === spec_types, cases) && return true
1454
- item = analyze_method! (match, argtypes, info, flag, state; allow_typevars)
1476
+ item = analyze_method! (match, argtypes, info, flag, state; allow_typevars, override_effects )
1455
1477
item === nothing && return false
1456
1478
push! (cases, InliningCase (spec_types, item))
1457
1479
return true
@@ -1526,8 +1548,13 @@ function handle_opaque_closure_call!(todo::Vector{Pair{Int,Any}},
1526
1548
mi = result. result. linfo
1527
1549
validate_sparams (mi. sparam_vals) || return nothing
1528
1550
item = resolve_todo (mi, result. result, sig. argtypes, info, flag, state)
1529
- elseif isa (result, ConcreteResult) && may_inline_concrete_result (result)
1530
- item = concrete_result_item (result, state)
1551
+ elseif isa (result, ConcreteResult)
1552
+ if may_inline_concrete_result (result)
1553
+ item = concrete_result_item (result, state)
1554
+ else
1555
+ override_effects = result. effects
1556
+ item = analyze_method! (info. match, sig. argtypes, info, flag, state; allow_typevars= false , override_effects)
1557
+ end
1531
1558
else
1532
1559
item = analyze_method! (info. match, sig. argtypes, info, flag, state; allow_typevars= false )
1533
1560
end
0 commit comments