From 7c4afbf358f4f8dd20d66c993d28452e1eea160c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 24 Nov 2022 16:16:43 +0900 Subject: [PATCH] inference: mark flag for effect-free `:call`s during abstractinterpret 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. --- base/compiler/abstractinterpretation.jl | 6 ++++++ base/compiler/inferencestate.jl | 2 ++ test/compiler/inline.jl | 23 +++++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 0fb85c4d00d1a2..8ecb690880b0d5 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2243,6 +2243,12 @@ 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 + 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 diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 49315fd67834c0..d7d06757ded2e3 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -537,6 +537,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 diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 1119c6d01b8e9e..8de005a9ef48d4 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -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 @@ -1817,6 +1816,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