From dc8857a86f0102b2e935057ac38eb5068833ac44 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 11 Apr 2024 08:05:30 -0400 Subject: [PATCH] ir: Add version of compute_trycatch for IRCode (#54035) For ir transform passes that need to be aware of current_scope. Currently no users in Base, but available for external absint. --------- Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> --- base/compiler/inferencestate.jl | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 48784378ef7c1..3f2ec4734cc21 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -368,7 +368,21 @@ is_inferred(result::InferenceResult) = result.result !== nothing was_reached(sv::InferenceState, pc::Int) = sv.ssavaluetypes[pc] !== NOT_FOUND -function compute_trycatch(code::Vector{Any}, ip::BitSet) +compute_trycatch(ir::IRCode, ip::BitSet) = compute_trycatch(ir.stmts.stmt, ip, ir.cfg.blocks) + +""" + compute_trycatch(code, ip [, bbs]) -> (handler_at, handlers) + +Given the code of a function, compute, at every statement, the current +try/catch handler, and the current exception stack top. This function returns +a tuple of: + + 1. `handler_at`: A statement length vector of tuples `(catch_handler, exception_stack)`, + which are indices into `handlers` + + 2. `handlers`: A `TryCatchFrame` vector of handlers +""" +function compute_trycatch(code::Vector{Any}, ip::BitSet, bbs::Union{Vector{BasicBlock}, Nothing}=nothing) # The goal initially is to record the frame like this for the state at exit: # 1: (enter 3) # == 0 # 3: (expr) # == 1 @@ -388,6 +402,7 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet) stmt = code[pc] if isa(stmt, EnterNode) l = stmt.catch_dest + (bbs !== nothing) && (l = first(bbs[l].stmts)) push!(handlers, TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc)) handler_id = length(handlers) handler_at[pc + 1] = (handler_id, 0) @@ -412,8 +427,10 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet) stmt = code[pc] if isa(stmt, GotoNode) pc´ = stmt.label + (bbs !== nothing) && (pc´ = first(bbs[pc´].stmts)) elseif isa(stmt, GotoIfNot) l = stmt.dest::Int + (bbs !== nothing) && (l = first(bbs[l].stmts)) if handler_at[l] != cur_stacks @assert handler_at[l][1] == 0 || handler_at[l][1] == cur_stacks[1] "unbalanced try/catch" handler_at[l] = cur_stacks @@ -424,6 +441,7 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet) break elseif isa(stmt, EnterNode) l = stmt.catch_dest + (bbs !== nothing) && (l = first(bbs[l].stmts)) # We assigned a handler number above. Here we just merge that # with out current handler information. if l != 0