Skip to content

Commit

Permalink
inference: mark flag for effect-free :calls during abstractinterpret
Browse files Browse the repository at this point in the history
So that they can be deleted during the first `compact!`-ion.
This allows us to delete an inlineable and effect-free, but unused call.

This is essentially an alternative of #47305, but doesn't introduce a
problem like #47374.
  • Loading branch information
aviatesk committed Dec 22, 2022
1 parent 43d9352 commit 27c1d6c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
15 changes: 15 additions & 0 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,13 @@ function abstract_eval_statement_expr(interp::AbstractInterpreter, e::Expr, vtyp
merge_effects!(interp, sv, effects)
if isa(sv, InferenceState)
sv.stmt_info[sv.currpc] = info
# mark this call statement as DCE-elgible
# TODO better to do this in a single pass based on the `info` object at the end of abstractinterpret?
if is_removable_if_unused(effects)
add_curr_ssaflag!(sv, IR_FLAG_EFFECT_FREE)
else
sub_curr_ssaflag!(sv, IR_FLAG_EFFECT_FREE)
end
end
end
t = rt
Expand Down Expand Up @@ -2359,6 +2366,14 @@ function abstract_eval_statement_expr(interp::AbstractInterpreter, e::Expr, vtyp
(;rt, effects) = abstract_eval_foreigncall(interp, e, vtypes, sv, mi)
t = rt
merge_effects!(interp, sv, effects)
if isa(sv, InferenceState)
# mark this call statement as DCE-elgible
if is_removable_if_unused(effects)
add_curr_ssaflag!(sv, IR_FLAG_EFFECT_FREE)
else
sub_curr_ssaflag!(sv, IR_FLAG_EFFECT_FREE)
end
end
elseif ehead === :cfunction
effects = EFFECTS_UNKNOWN
merge_effects!(interp, sv, effects)
Expand Down
2 changes: 2 additions & 0 deletions base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ function print_callstack(sv::InferenceState)
end

get_curr_ssaflag(sv::InferenceState) = sv.src.ssaflags[sv.currpc]
add_curr_ssaflag!(sv::InferenceState, flag::UInt8) = sv.src.ssaflags[sv.currpc] |= flag
sub_curr_ssaflag!(sv::InferenceState, flag::UInt8) = sv.src.ssaflags[sv.currpc] &= ~flag

function narguments(sv::InferenceState)
def = sv.linfo.def
Expand Down
23 changes: 21 additions & 2 deletions test/compiler/inline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1077,8 +1077,7 @@ Base.setindex!(s::SafeRef, x) = setfield!(s, 1, x)
noninlined_dce_new(s)
nothing
end
# should be resolved once we merge https://github.com/JuliaLang/julia/pull/43923
@test_broken fully_eliminated((Union{Symbol,String},)) do s
@test fully_eliminated((Union{Symbol,String},)) do s
noninlined_dce_new(s)
nothing
end
Expand Down Expand Up @@ -1820,6 +1819,26 @@ let ir = Base.code_ircode(big_tuple_test1, Tuple{})[1][1]
@test length(ir.stmts) == 1
end

# inlineable but removable call should be eligible for DCE
Base.@assume_effects :removable @inline function inlineable_effect_free(a::Float64)
a == Inf && return zero(a)
return sin(a) + cos(a)
end
@test fully_eliminated((Float64,)) do a
b = inlineable_effect_free(a)
c = inlineable_effect_free(b)
nothing
end

# https://github.com/JuliaLang/julia/issues/47374
function f47374(x)
[f47374(i, x) for i in 1:1]
end
function f47374(i::Int, x)
return 1.0
end
@test f47374(rand(1)) == Float64[1.0]

# compiler should recognize effectful :static_parameter
# https://github.com/JuliaLang/julia/issues/45490
issue45490_1(x::Union{T, Nothing}, y::Union{T, Nothing}) where {T} = T
Expand Down

0 comments on commit 27c1d6c

Please sign in to comment.