From 973ff33240c257f0ee7f4161252ac263b3922f06 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Tue, 24 May 2022 18:09:26 +0900 Subject: [PATCH] some very minor optimizations --- base/compiler/abstractinterpretation.jl | 1 + base/compiler/inferencestate.jl | 10 ++++++-- base/compiler/typeinfer.jl | 34 +++++++++++-------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index f6d9302348564..a41b6482fc4f7 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2298,6 +2298,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) for currpc in bbstart:bbend frame.currpc = currpc + empty_backedges!(frame, currpc) stmt = frame.src.code[currpc] # If we're at the end of the basic block ... if currpc == bbend diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 7a22d1a6be252..15057b45fa2a7 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -468,7 +468,7 @@ function add_backedge!(li::MethodInstance, caller::InferenceState) edges = caller.stmt_edges[caller.currpc] = [] end push!(edges, li) - nothing + return nothing end # used to temporarily accumulate our no method errors to later add as backedges in the callee method table @@ -480,7 +480,13 @@ function add_mt_backedge!(mt::Core.MethodTable, @nospecialize(typ), caller::Infe end push!(edges, mt) push!(edges, typ) - nothing + return nothing +end + +function empty_backedges!(frame::InferenceState, currpc::Int = frame.currpc) + edges = frame.stmt_edges[currpc] + edges === nothing || empty!(edges) + return nothing end function print_callstack(sv::InferenceState) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index e619d1391c83d..97e8a0cfa1d29 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -687,33 +687,29 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool) nslots = length(slotflags) undefs = fill(false, nslots) - # eliminate GotoIfNot if either of branch target is unreachable - if run_optimizer - for idx = 1:nexpr - stmt = body[idx] - if isa(stmt, GotoIfNot) && widenconst(argextype(stmt.cond, src, sv.sptypes)) === Bool - # replace live GotoIfNot with: - # - GotoNode if the fallthrough target is unreachable - # - no-op if the branch target is unreachable - if !was_reached(sv, idx+1) - body[idx] = GotoNode(stmt.dest) - elseif !was_reached(sv, stmt.dest) - body[idx] = nothing - end - end - end - end - - # this statement traversal does three things: + # this statement traversal does five things: # 1. introduce temporary `TypedSlot`s that are supposed to be replaced with π-nodes later # 2. mark used-undef slots (required by the `slot2reg` conversion) # 3. mark unreached statements for a bulk code deletion (see issue #7836) # 4. widen `Conditional`s and remove `NOT_FOUND` from `ssavaluetypes` - # NOTE: because of 4, `was_reached` will no longer be available after this point + # NOTE because of this, `was_reached` will no longer be available after this point + # 5. eliminate GotoIfNot if either branch target is unreachable changemap = nothing # initialized if there is any dead region for i = 1:nexpr expr = body[i] if was_reached(sv, i) + if run_optimizer + if isa(expr, GotoIfNot) && widenconst(argextype(expr.cond, src, sv.sptypes)) === Bool + # 5: replace this live GotoIfNot with: + # - GotoNode if the fallthrough target is unreachable + # - no-op if the branch target is unreachable + if !was_reached(sv, i+1) + expr = GotoNode(expr.dest) + elseif !was_reached(sv, expr.dest) + expr = nothing + end + end + end body[i] = annotate_slot_load!(undefs, i, sv, expr) # 1&2 ssavaluetypes[i] = widenconditional(ssavaluetypes[i]) # 4 else # i.e. any runtime execution will never reach this statement