@@ -366,7 +366,7 @@ function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCod
366366 if ! validate_sparams (mi. sparam_vals)
367367 # N.B. This works on the caller-side argexprs, (i.e. before the va fixup below)
368368 spvals_ssa = insert_node! (
369- effect_free_and_nothrow (NewInstruction (Expr (:call , Core. _compute_sparams, def, argexprs... ), SimpleVector, topline)))
369+ removable_if_unused (NewInstruction (Expr (:call , Core. _compute_sparams, def, argexprs... ), SimpleVector, topline)))
370370 end
371371 if def. isva
372372 nargs_def = Int (def. nargs:: Int32 )
@@ -425,7 +425,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
425425 inline_compact. result[idx′][:type ] =
426426 argextype (val, isa (val, Argument) || isa (val, Expr) ? compact : inline_compact)
427427 # Everything legal in value position is guaranteed to be effect free in stmt position
428- inline_compact. result[idx′][:flag ] = IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW
428+ inline_compact. result[idx′][:flag ] = IR_FLAGS_REMOVABLE
429429 break
430430 elseif isexpr (stmt′, :boundscheck )
431431 adjust_boundscheck! (inline_compact, idx′, stmt′, boundscheck)
@@ -692,7 +692,7 @@ function batch_inline!(ir::IRCode, todo::Vector{Pair{Int,Any}}, propagate_inboun
692692 for aidx in 1 : length (argexprs)
693693 aexpr = argexprs[aidx]
694694 if isa (aexpr, Expr) || isa (aexpr, GlobalRef)
695- ninst = effect_free_and_nothrow (NewInstruction (aexpr, argextype (aexpr, compact), compact. result[idx][:line ]))
695+ ninst = removable_if_unused (NewInstruction (aexpr, argextype (aexpr, compact), compact. result[idx][:line ]))
696696 argexprs[aidx] = insert_node_here! (compact, ninst)
697697 end
698698 end
@@ -996,28 +996,6 @@ function retrieve_ir_for_inlining(::MethodInstance, ir::IRCode, preserve_local_s
996996 return ir
997997end
998998
999- function flags_for_effects (effects:: Effects )
1000- flags:: UInt32 = 0
1001- if is_consistent (effects)
1002- flags |= IR_FLAG_CONSISTENT
1003- end
1004- if is_effect_free (effects)
1005- flags |= IR_FLAG_EFFECT_FREE
1006- elseif is_effect_free_if_inaccessiblememonly (effects)
1007- flags |= IR_FLAG_EFIIMO
1008- end
1009- if is_inaccessiblemem_or_argmemonly (effects)
1010- flags |= IR_FLAG_INACCESSIBLE_OR_ARGMEM
1011- end
1012- if is_nothrow (effects)
1013- flags |= IR_FLAG_NOTHROW
1014- end
1015- if is_noub (effects)
1016- flags |= IR_FLAG_NOUB
1017- end
1018- return flags
1019- end
1020-
1021999function handle_single_case! (todo:: Vector{Pair{Int,Any}} ,
10221000 ir:: IRCode , idx:: Int , stmt:: Expr , @nospecialize (case),
10231001 isinvoke:: Bool = false )
@@ -1252,29 +1230,12 @@ end
12521230# As a matter of convenience, this pass also computes effect-freenes.
12531231# For primitives, we do that right here. For proper calls, we will
12541232# discover this when we consult the caches.
1255- function check_effect_free! (ir:: IRCode , idx:: Int , @nospecialize (stmt), @nospecialize (rt), state:: InliningState )
1256- return check_effect_free! (ir, idx, stmt, rt, optimizer_lattice (state. interp))
1257- end
1258- function check_effect_free! (ir:: IRCode , idx:: Int , @nospecialize (stmt), @nospecialize (rt), 𝕃ₒ:: AbstractLattice )
1259- (consistent, effect_free_and_nothrow, nothrow) = stmt_effect_flags (𝕃ₒ, stmt, rt, ir)
1260- inst = ir. stmts[idx]
1261- if consistent
1262- add_flag! (inst, IR_FLAG_CONSISTENT)
1263- end
1264- if effect_free_and_nothrow
1265- add_flag! (inst, IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW)
1266- elseif nothrow
1267- add_flag! (inst, IR_FLAG_NOTHROW)
1268- end
1269- if ! (isexpr (stmt, :call ) || isexpr (stmt, :invoke ))
1270- # There is a bit of a subtle point here, which is that some non-call
1271- # statements (e.g. PiNode) can be UB:, however, we consider it
1272- # illegal to introduce such statements that actually cause UB (for any
1273- # input). Ideally that'd be handled at insertion time (TODO ), but for
1274- # the time being just do that here.
1275- add_flag! (inst, IR_FLAG_NOUB)
1276- end
1277- return effect_free_and_nothrow
1233+ add_inst_flag! (inst:: Instruction , ir:: IRCode , state:: InliningState ) =
1234+ add_inst_flag! (inst, ir, optimizer_lattice (state. interp))
1235+ function add_inst_flag! (inst:: Instruction , ir:: IRCode , 𝕃ₒ:: AbstractLattice )
1236+ flags = recompute_effects_flags (𝕃ₒ, inst[:stmt ], inst[:type ], ir)
1237+ add_flag! (inst, flags)
1238+ return ! iszero (flags & IR_FLAGS_REMOVABLE)
12781239end
12791240
12801241# Handles all analysis and inlining of intrinsics and builtins. In particular,
@@ -1283,11 +1244,11 @@ end
12831244function process_simple! (todo:: Vector{Pair{Int,Any}} , ir:: IRCode , idx:: Int , state:: InliningState )
12841245 inst = ir[SSAValue (idx)]
12851246 stmt = inst[:stmt ]
1286- rt = inst[:type ]
12871247 if ! (stmt isa Expr)
1288- check_effect_free! (ir, idx, stmt, rt , state)
1248+ add_inst_flag! (inst, ir , state)
12891249 return nothing
12901250 end
1251+ rt = inst[:type ]
12911252 head = stmt. head
12921253 if head != = :call
12931254 if head === :splatnew
@@ -1299,7 +1260,7 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
12991260 sig === nothing && return nothing
13001261 return stmt, sig
13011262 end
1302- check_effect_free! (ir, idx, stmt, rt , state)
1263+ add_inst_flag! (inst, ir , state)
13031264 return nothing
13041265 end
13051266
@@ -1317,7 +1278,7 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
13171278 return nothing
13181279 end
13191280
1320- if check_effect_free! (ir, idx, stmt, rt , state)
1281+ if add_inst_flag! (inst, ir , state)
13211282 if sig. f === typeassert || ⊑ (optimizer_lattice (state. interp), sig. ft, typeof (typeassert))
13221283 # typeassert is a no-op if effect free
13231284 inst[:stmt ] = stmt. args[2 ]
@@ -1335,7 +1296,7 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
13351296 lateres = late_inline_special_case! (ir, idx, stmt, rt, sig, state)
13361297 if isa (lateres, SomeCase)
13371298 inst[:stmt ] = lateres. val
1338- check_effect_free! (ir, idx, lateres . val, rt , state)
1299+ add_inst_flag! (inst, ir , state)
13391300 return nothing
13401301 end
13411302
@@ -1683,7 +1644,7 @@ function inline_const_if_inlineable!(inst::Instruction)
16831644 inst[:stmt ] = quoted (rt. val)
16841645 return true
16851646 end
1686- add_flag! (inst, IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW )
1647+ add_flag! (inst, IR_FLAGS_REMOVABLE )
16871648 return false
16881649end
16891650
@@ -1808,7 +1769,7 @@ function late_inline_special_case!(
18081769 return SomeCase (quoted (type. val))
18091770 end
18101771 cmp_call = Expr (:call , GlobalRef (Core, :(=== )), stmt. args[2 ], stmt. args[3 ])
1811- cmp_call_ssa = insert_node! (ir, idx, effect_free_and_nothrow (NewInstruction (cmp_call, Bool)))
1772+ cmp_call_ssa = insert_node! (ir, idx, removable_if_unused (NewInstruction (cmp_call, Bool)))
18121773 not_call = Expr (:call , GlobalRef (Core. Intrinsics, :not_int ), cmp_call_ssa)
18131774 return SomeCase (not_call)
18141775 elseif length (argtypes) == 3 && istopfunction (f, :(> :))
@@ -1853,13 +1814,13 @@ end
18531814
18541815function insert_spval! (insert_node!:: Inserter , spvals_ssa:: SSAValue , spidx:: Int , do_isdefined:: Bool )
18551816 ret = insert_node! (
1856- effect_free_and_nothrow (NewInstruction (Expr (:call , Core. _svec_ref, spvals_ssa, spidx), Any)))
1817+ removable_if_unused (NewInstruction (Expr (:call , Core. _svec_ref, spvals_ssa, spidx), Any)))
18571818 tcheck_not = nothing
18581819 if do_isdefined
18591820 tcheck = insert_node! (
1860- effect_free_and_nothrow (NewInstruction (Expr (:call , Core. isa, ret, Core. TypeVar), Bool)))
1821+ removable_if_unused (NewInstruction (Expr (:call , Core. isa, ret, Core. TypeVar), Bool)))
18611822 tcheck_not = insert_node! (
1862- effect_free_and_nothrow (NewInstruction (Expr (:call , not_int, tcheck), Bool)))
1823+ removable_if_unused (NewInstruction (Expr (:call , not_int, tcheck), Bool)))
18631824 end
18641825 return (ret, tcheck_not)
18651826end
0 commit comments