Skip to content

Commit 2080b5c

Browse files
committed
inlining: Also apply statement effects when declining to inline
When inlining, we already determine what the effects for all the different cases are, so that we can apply appropriate statement flags on each of the edges. However, if for some reason we decided to decline to inline, we weren't making use of this information. Fix that.
1 parent f7dea04 commit 2080b5c

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

base/compiler/ssair/inlining.jl

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,22 @@ function handle_any_const_result!(cases::Vector{InliningCase}, @nospecialize(res
12881288
end
12891289
end
12901290

1291+
function info_effects(@nospecialize(result), match::MethodMatch, state::InliningState)
1292+
if isa(result, Union{ConcreteResult, SemiConcreteResult})
1293+
return result.effects
1294+
elseif isa(result, ConstPropResult)
1295+
return result.result.ipo_effects
1296+
else
1297+
mi = specialize_method(match; preexisting=true)
1298+
code = get(state.mi_cache, mi, nothing)
1299+
if code isa CodeInstance
1300+
return decode_effects(code.ipo_purity_bits)
1301+
else
1302+
return Effects()
1303+
end
1304+
end
1305+
end
1306+
12911307
function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInfo}},
12921308
flag::UInt8, sig::Signature, state::InliningState)
12931309
argtypes = sig.argtypes
@@ -1306,6 +1322,7 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
13061322
local meth::MethodLookupResult
13071323
local all_result_count = 0
13081324

1325+
joint_effects = EFFECTS_TOTAL
13091326
for i in 1:length(infos)
13101327
meth = infos[i].results
13111328
if meth.ambig
@@ -1331,6 +1348,7 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
13311348
all_result_count += 1
13321349
result = results === nothing ? nothing : results[all_result_count]
13331350
any_fully_covered |= match.fully_covers
1351+
joint_effects = merge_effects(joint_effects, info_effects(result, match, state))
13341352
if !validate_sparams(match.sparams)
13351353
if !match.fully_covers
13361354
handled_all_cases = false
@@ -1348,6 +1366,10 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
13481366
end
13491367
end
13501368

1369+
if !any_fully_covered
1370+
joint_effects = Effects()
1371+
end
1372+
13511373
if handled_all_cases && revisit_idx !== nothing
13521374
# we handled everything except one match with unmatched sparams,
13531375
# so try to handle it by bypassing validate_sparams
@@ -1377,17 +1399,17 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
13771399
filter!(case::InliningCase->isdispatchtuple(case.sig), cases)
13781400
end
13791401

1380-
return cases, handled_all_cases & any_fully_covered
1402+
return cases, handled_all_cases & any_fully_covered, joint_effects
13811403
end
13821404

13831405
function handle_call!(
13841406
ir::IRCode, idx::Int, stmt::Expr, infos::Vector{MethodMatchInfo}, flag::UInt8,
13851407
sig::Signature, state::InliningState, todo::Vector{Pair{Int, Any}})
13861408
cases = compute_inlining_cases(infos, flag, sig, state)
13871409
cases === nothing && return nothing
1388-
cases, all_covered = cases
1410+
cases, all_covered, joint_effects = cases
13891411
handle_cases!(ir, idx, stmt, argtypes_to_type(sig.argtypes), cases,
1390-
all_covered, todo, state.params)
1412+
all_covered, todo, state.params, joint_effects)
13911413
end
13921414

13931415
function handle_const_call!(
@@ -1397,7 +1419,7 @@ function handle_const_call!(
13971419
cases === nothing && return nothing
13981420
cases, all_covered = cases
13991421
handle_cases!(ir, idx, stmt, argtypes_to_type(sig.argtypes), cases,
1400-
all_covered, todo, state.params)
1422+
all_covered, todo, state.params, joint_effects)
14011423
end
14021424

14031425
function handle_match!(
@@ -1452,7 +1474,7 @@ end
14521474

14531475
function handle_cases!(ir::IRCode, idx::Int, stmt::Expr, @nospecialize(atype),
14541476
cases::Vector{InliningCase}, fully_covered::Bool, todo::Vector{Pair{Int, Any}},
1455-
params::OptimizationParams)
1477+
params::OptimizationParams, joint_effects::Effects)
14561478
# If we only have one case and that case is fully covered, we may either
14571479
# be able to do the inlining now (for constant cases), or push it directly
14581480
# onto the todo list
@@ -1464,6 +1486,8 @@ function handle_cases!(ir::IRCode, idx::Int, stmt::Expr, @nospecialize(atype),
14641486
isa(case.sig, DataType) || return nothing
14651487
end
14661488
push!(todo, idx=>UnionSplit(fully_covered, atype, cases))
1489+
else
1490+
ir[SSAValue(idx)][:flag] |= flags_for_effects(joint_effects)
14671491
end
14681492
return nothing
14691493
end

test/compiler/inline.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,3 +1522,13 @@ let src = code_typed1(fvarargN_inline, (Tuple{Vararg{Int}},))
15221522
count(iscall((src, Core._svec_ref)), src.code) == 0 &&
15231523
count(iscall((src, Core.nfields)), src.code) == 1
15241524
end
1525+
1526+
# Test effect annotation of declined inline unionsplit
1527+
f_union_unmatched(x::Union{Nothing, Type{T}}) where {T} = nothing
1528+
function g_union_unmatched(x)
1529+
if isa(x, Union{Nothing, Type})
1530+
foo(x)
1531+
end
1532+
return nothing
1533+
end
1534+
@test fully_eliminated(g_union_unmatched, Tuple{Any})

0 commit comments

Comments
 (0)