Skip to content

Commit

Permalink
optimize: fix effect_free refinement in post-opt dataflow analysis (#…
Browse files Browse the repository at this point in the history
…51185)

Currently we never refine this information though.

@nanosoldier `runbenchmarks("inference", vs=":master")`
  • Loading branch information
aviatesk committed Sep 8, 2023
1 parent b3741c0 commit 39a5316
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
37 changes: 20 additions & 17 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,13 @@ function ipo_dataflow_analysis!(interp::AbstractInterpreter, ir::IRCode, result:

function scan_non_dataflow_flags!(inst::Instruction)
flag = inst[:flag]
all_effect_free &= (flag & IR_FLAG_EFFECT_FREE) != 0
istmt = inst[:stmt]
if !isterminator(istmt) && istmt !== nothing
# ignore control flow node – they are not removable on their own and thus not
# have `IR_FLAG_EFFECT_FREE` but still do not taint `:effect_free`-ness of
# the whole method invocation
all_effect_free &= (flag & IR_FLAG_EFFECT_FREE) != 0
end
all_nothrow &= (flag & IR_FLAG_NOTHROW) != 0
if (flag & IR_FLAG_NOUB) == 0
if !is_conditional_noub(inst)
Expand Down Expand Up @@ -628,7 +634,7 @@ function ipo_dataflow_analysis!(interp::AbstractInterpreter, ir::IRCode, result:
# If we do not know this function terminates, taint consistency, now,
# :consistent requires consistent termination. TODO: Just look at the
# inconsistent region.
if !effects.terminates
if !result.ipo_effects.terminates
all_retpaths_consistent = false
# Check if there are potential throws that require
elseif conditional_successors_may_throw(lazypostdomtree, ir, bb)
Expand All @@ -652,7 +658,13 @@ function ipo_dataflow_analysis!(interp::AbstractInterpreter, ir::IRCode, result:

return true
end
if !scan!(scan_stmt!, scanner, true)

completed_scan = scan!(scan_stmt!, scanner, true)

effects = result.ipo_effects
if completed_scan
had_trycatch && return effects
else
if !all_retpaths_consistent
# No longer any dataflow concerns, just scan the flags
scan!(scanner, false) do inst::Instruction, idx::Int, lstmt::Int, bb::Int
Expand Down Expand Up @@ -707,20 +719,11 @@ function ipo_dataflow_analysis!(interp::AbstractInterpreter, ir::IRCode, result:
end
end

had_trycatch && return
if all_effect_free
effects = Effects(effects; effect_free = true)
end
if all_nothrow
effects = Effects(effects; nothrow = true)
end
if all_retpaths_consistent
effects = Effects(effects; consistent = ALWAYS_TRUE)
end
if all_noub
effects = Effects(effects; noub = any_conditional_ub ? NOUB_IF_NOINBOUNDS : ALWAYS_TRUE)
end
result.ipo_effects = effects
return result.ipo_effects = Effects(effects;
consistent = all_retpaths_consistent ? ALWAYS_TRUE : effects.consistent,
effect_free = all_effect_free ? ALWAYS_TRUE : effects.effect_free,
nothrow = all_nothrow ? true : effects.nothrow,
noub = all_noub ? (any_conditional_ub ? NOUB_IF_NOINBOUNDS : ALWAYS_TRUE) : effects.noub)
end

# run the optimization work
Expand Down
16 changes: 16 additions & 0 deletions test/compiler/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1078,3 +1078,19 @@ GLOBAL_MUTABLE_SWITCH[] = true
@test (Base.return_types(check_switch2) |> only) === Nothing

@test !Core.Compiler.is_consistent(Base.infer_effects(check_switch, (Base.RefValue{Bool},)))

# post-opt IPO analysis refinement of `:effect_free`-ness
function post_opt_refine_effect_free(y, c=true)
x = Ref(c)
if x[]
return true
else
r = y[] isa Number
y[] = nothing
end
return r
end
@test Core.Compiler.is_effect_free(Base.infer_effects(post_opt_refine_effect_free, (Base.RefValue{Any},)))
@test Base.infer_effects((Base.RefValue{Any},)) do y
post_opt_refine_effect_free(y, true)
end |> Core.Compiler.is_effect_free

0 comments on commit 39a5316

Please sign in to comment.