From d6a4417af880d140e4e3702550906c8fc25bdd50 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Fri, 13 May 2022 17:59:37 +0900 Subject: [PATCH] optimize a bit further --- base/compiler/abstractinterpretation.jl | 7 +++--- base/compiler/inferencestate.jl | 6 ++--- base/compiler/typeinfer.jl | 30 ++++++++++++------------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 365791707a1b5..5c50add7192fa 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2057,7 +2057,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), t = Const(t.instance) end if !isempty(sv.pclimitations) - if t isa Const || t === Union{} + if t isa Const || t === Bottom empty!(sv.pclimitations) else t = LimitedAccuracy(t, sv.pclimitations) @@ -2276,7 +2276,6 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) for frame.currpc in frame.currpc:bbend stmt = frame.src.code[frame.currpc] - push!(frame.was_reached, frame.currpc) # If we're at the end of the basic block ... if frame.currpc == bbend # Handle control flow @@ -2291,6 +2290,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) condx = stmt.cond condt = abstract_eval_value(interp, condx, currstate, frame) if condt === Bottom + ssavaluetypes[frame.currpc] = Bottom empty!(frame.pclimitations) @goto find_next_bb end @@ -2402,7 +2402,8 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) # Process non control-flow statements (; changes, type) = abstract_eval_basic_statement(interp, stmt, currstate, frame) - if type === Union{} + if type === Bottom + ssavaluetypes[frame.currpc] = Bottom @goto find_next_bb end if changes !== nothing diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 1ce3ff10f2a30..7f4f4cbf673d1 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -94,7 +94,6 @@ mutable struct InferenceState currbb::Int currpc::Int ip::BitSet#=TODO BoundedMinPrioritySet=# # current active instruction pointers - was_reached::BitSet handler_at::Vector{Int} # current exception handler info ssavalue_uses::Vector{BitSet} # ssavalue sparsity and restart info # TODO: Could keep this sparsely by doing structural liveness analysis ahead of time. @@ -141,7 +140,6 @@ mutable struct InferenceState currbb = currpc = 1 ip = BitSet(1) # TODO BitSetBoundedMinPrioritySet(1) - was_reached = BitSet() handler_at = compute_trycatch(code, BitSet()) nssavalues = src.ssavaluetypes::Int ssavalue_uses = find_ssavalue_uses(code, nssavalues) @@ -192,7 +190,7 @@ mutable struct InferenceState frame = new( linfo, world, mod, sptypes, slottypes, src, cfg, - currbb, currpc, ip, was_reached, handler_at, ssavalue_uses, bb_vartables, stmt_edges, stmt_info, + currbb, currpc, ip, handler_at, ssavalue_uses, bb_vartables, stmt_edges, stmt_info, pclimitations, limitations, cycle_backedges, callers_in_cycle, dont_work_on_me, parent, inferred, result, valid_worlds, bestguess, ipo_effects, params, restrict_abstract_call_sites, cached, @@ -234,7 +232,7 @@ function any_inbounds(code::Vector{Any}) return false end -was_reached((; was_reached)::InferenceState, pc::Int) = pc in was_reached +was_reached(sv::InferenceState, pc::Int) = sv.src.ssavaluetypes[pc] !== NOT_FOUND function compute_trycatch(code::Vector{Any}, ip::BitSet) # The goal initially is to record the frame like this for the state at exit: diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 54369757fa70a..374fad519bde4 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -565,15 +565,6 @@ function widen_all_consts!(src::CodeInfo) return src end -function widen_ssavaluetypes!(sv::InferenceState) - ssavaluetypes = sv.src.ssavaluetypes::Vector{Any} - for j = 1:length(ssavaluetypes) - t = ssavaluetypes[j] - ssavaluetypes[j] = t === NOT_FOUND ? Bottom : widenconditional(t) - end - return nothing -end - function record_slot_assign!(sv::InferenceState) # look at all assignments to slots # and union the set of types stored there @@ -587,7 +578,9 @@ function record_slot_assign!(sv::InferenceState) if was_reached(sv, i) && isexpr(expr, :(=)) lhs = expr.args[1] if isa(lhs, SlotNumber) - vt = widenconst(ssavaluetypes[i]) + typ = ssavaluetypes[i] + @assert typ !== NOT_FOUND "active slot in unreached region" + vt = widenconst(typ) if vt !== Bottom id = slot_id(lhs) otherTy = slottypes[id] @@ -627,6 +620,7 @@ function annotate_slot_load!(undefs::Vector{Bool}, idx::Int, sv::InferenceState, typ = widenconditional(ignorelimited(vt.typ)) else typ = sv.src.ssavaluetypes[pc] + @assert typ !== NOT_FOUND "active slot in unreached region" end # add type annotations where needed if !(sv.slottypes[id] ⊑ typ) @@ -670,10 +664,16 @@ function find_dominating_assignment(id::Int, idx::Int, sv::InferenceState) return nothing end +function widen_ssavaluetypes!(ssavaluetypes::Vector{Any}) + for j = 1:length(ssavaluetypes) + t = ssavaluetypes[j] + ssavaluetypes[j] = t === NOT_FOUND ? Bottom : widenconditional(t) + end + return ssavaluetypes +end + # annotate types of all symbols in AST function type_annotate!(sv::InferenceState, run_optimizer::Bool) - widen_ssavaluetypes!(sv) - # compute the required type for each slot # to hold all of the items assigned into it record_slot_assign!(sv) @@ -722,8 +722,8 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool) # introduce temporary TypedSlot for the later optimization passes # and also mark used-undef slots body[i] = annotate_slot_load!(undefs, oldidx, sv, expr) - else # unreached statement (see issue #7836) - if isa(expr, Expr) && is_meta_expr_head(expr.head) + else # unreached statement (see issue #7836) + if is_meta_expr(expr) # keep any lexically scoped expressions elseif run_optimizer deleteat!(body, i) @@ -752,7 +752,7 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool) end src.code = body - src.ssavaluetypes = ssavaluetypes + src.ssavaluetypes = widen_ssavaluetypes!(ssavaluetypes) nothing end