diff --git a/base/compiler/ssair/irinterp.jl b/base/compiler/ssair/irinterp.jl index a2a5deccba838..717a4eec102c2 100644 --- a/base/compiler/ssair/irinterp.jl +++ b/base/compiler/ssair/irinterp.jl @@ -251,6 +251,8 @@ function reprocess_instruction!(interp::AbstractInterpreter, return false elseif isa(inst, PiNode) rt = tmeet(typeinf_lattice(interp), argextype(inst.val, ir), widenconst(inst.typ)) + elseif inst === nothing + return false else ccall(:jl_, Cvoid, (Any,), inst) error() diff --git a/base/compiler/ssair/slot2ssa.jl b/base/compiler/ssair/slot2ssa.jl index 62795cb7e3fd0..79bdf817dc866 100644 --- a/base/compiler/ssair/slot2ssa.jl +++ b/base/compiler/ssair/slot2ssa.jl @@ -338,7 +338,9 @@ function iterated_dominance_frontier(cfg::CFG, liveness::BlockLiveness, domtree: end function rename_incoming_edge(old_edge::Int, old_to::Int, result_order::Vector{Int}, bb_rename::Vector{Int}) + old_edge == 0 && return 0 new_edge_from = bb_rename[old_edge] + new_edge_from < 0 && return new_edge_from if old_edge == old_to - 1 # Could have been a crit edge break if new_edge_from < length(result_order) && result_order[new_edge_from + 1] == 0 @@ -364,7 +366,7 @@ function rename_phinode_edges(node::PhiNode, bb::Int, result_order::Vector{Int}, new_edges = Int32[] for (idx, edge) in pairs(node.edges) edge = Int(edge) - (edge == 0 || bb_rename[edge] != 0) || continue + (edge == 0 || bb_rename[edge] != -1) || continue new_edge_from = edge == 0 ? 0 : rename_incoming_edge(edge, bb, result_order, bb_rename) push!(new_edges, new_edge_from) if isassigned(node.values, idx) @@ -387,7 +389,7 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree) # First compute the new order of basic blocks result_order = Int[] stack = Int[] - bb_rename = zeros(Int, length(ir.cfg.blocks)) + bb_rename = fill(-1, length(ir.cfg.blocks)) node = 1 ncritbreaks = 0 nnewfallthroughs = 0 @@ -498,7 +500,7 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree) bb_start_off += length(inst_range) local new_preds, new_succs let bb = bb, bb_rename = bb_rename, result_order = result_order - new_preds = Int[i == 0 ? 0 : rename_incoming_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].preds] + new_preds = Int[bb for bb in (rename_incoming_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].preds) if bb != -1] new_succs = Int[ rename_outgoing_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].succs] end new_bbs[new_bb] = BasicBlock(inst_range, new_preds, new_succs) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 29c4a7e6e477a..8cbc086112e1a 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -556,8 +556,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter) # annotate fulltree with type information, # either because we are the outermost code, or we might use this later doopt = (me.cached || me.parent !== nothing) - changemap = type_annotate!(interp, me, doopt) - recompute_cfg = changemap !== nothing + recompute_cfg = type_annotate!(interp, me, doopt) if doopt && may_optimize(interp) me.result.src = OptimizationState(me, OptimizationParams(interp), interp, recompute_cfg) else @@ -715,6 +714,7 @@ function type_annotate!(interp::AbstractInterpreter, sv::InferenceState, run_opt slotflags = src.slotflags nslots = length(slotflags) undefs = fill(false, nslots) + any_unreachable = false # this statement traversal does five things: # 1. introduce temporary `TypedSlot`s that are supposed to be replaced with π-nodes later @@ -742,13 +742,9 @@ function type_annotate!(interp::AbstractInterpreter, sv::InferenceState, run_opt body[i] = annotate_slot_load!(undefs, i, sv, expr) # 1&2 ssavaluetypes[i] = widenslotwrapper(ssavaluetypes[i]) # 4 else # i.e. any runtime execution will never reach this statement + any_unreachable = true if is_meta_expr(expr) # keep any lexically scoped expressions ssavaluetypes[i] = Any # 4 - elseif run_optimizer - if changemap === nothing - changemap = fill(0, nexpr) - end - changemap[i] = -1 # 3&4: mark for the bulk deletion else ssavaluetypes[i] = Bottom # 4 body[i] = Const(expr) # annotate that this statement actually is dead @@ -763,19 +759,7 @@ function type_annotate!(interp::AbstractInterpreter, sv::InferenceState, run_opt end end - # do the bulk deletion of unreached statements - if changemap !== nothing - inds = Int[i for (i,v) in enumerate(changemap) if v == -1] - deleteat!(body, inds) - deleteat!(ssavaluetypes, inds) - deleteat!(codelocs, inds) - deleteat!(stmt_info, inds) - deleteat!(ssaflags, inds) - renumber_ir_elements!(body, changemap) - return changemap - else - return nothing - end + return any_unreachable end # at the end, all items in b's cycle