@@ -144,20 +144,20 @@ function concrete_eval_invoke(interp::AbstractInterpreter,
144144 inst:: Expr , mi:: MethodInstance , irsv:: IRInterpretationState )
145145 mi_cache = WorldView (code_cache (interp), irsv. world)
146146 code = get (mi_cache, mi, nothing )
147- code === nothing && return nothing
147+ code === nothing && return Pair {Any, Bool} ( nothing , false )
148148 argtypes = collect_argtypes (interp, inst. args[2 : end ], nothing , irsv. ir)
149- argtypes === nothing && return Union{}
149+ argtypes === nothing && return Pair {Any, Bool} ( Union{}, false )
150150 effects = decode_effects (code. ipo_purity_bits)
151151 if is_foldable (effects) && is_all_const_arg (argtypes, #= start=# 1 )
152152 args = collect_const_args (argtypes, #= start=# 1 )
153153 world = get_world_counter (interp)
154154 value = try
155155 Core. _call_in_world_total (world, args... )
156156 catch
157- return Union{}
157+ return Pair {Any, Bool} ( Union{}, false )
158158 end
159159 if is_inlineable_constant (value)
160- return Const (value)
160+ return Pair {Any, Bool} ( Const (value), true )
161161 end
162162 else
163163 ir′ = codeinst_to_ir (interp, code)
@@ -166,7 +166,7 @@ function concrete_eval_invoke(interp::AbstractInterpreter,
166166 return _ir_abstract_constant_propagation (interp, irsv′)
167167 end
168168 end
169- return nothing
169+ return Pair {Any, Bool} ( nothing , is_nothrow (effects))
170170end
171171
172172function abstract_eval_phi_stmt (interp:: AbstractInterpreter , phi:: PhiNode , :: Int , irsv:: IRInterpretationState )
@@ -183,6 +183,12 @@ function reprocess_instruction!(interp::AbstractInterpreter,
183183 if condval isa Bool
184184 function update_phi! (from:: Int , to:: Int )
185185 if length (ir. cfg. blocks[to]. preds) == 0
186+ # Kill the entire block
187+ for idx in ir. cfg. blocks[to]. stmts
188+ ir. stmts[idx][:inst ] = nothing
189+ ir. stmts[idx][:type ] = Union{}
190+ ir. stmts[idx][:flag ] = IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW
191+ end
186192 return
187193 end
188194 for idx in ir. cfg. blocks[to]. stmts
@@ -205,6 +211,7 @@ function reprocess_instruction!(interp::AbstractInterpreter,
205211 if bb === nothing
206212 bb = block_for_inst (ir, idx)
207213 end
214+ ir. stmts[idx][:flag ] |= IR_FLAG_NOTHROW
208215 if condval
209216 ir. stmts[idx][:inst ] = nothing
210217 ir. stmts[idx][:type ] = Any
@@ -221,20 +228,25 @@ function reprocess_instruction!(interp::AbstractInterpreter,
221228 rt = nothing
222229 if isa (inst, Expr)
223230 head = inst. head
224- if head === :call || head === :foreigncall || head === :new
231+ if head === :call || head === :foreigncall || head === :new || head === :splatnew
225232 (; rt, effects) = abstract_eval_statement_expr (interp, inst, nothing , ir, irsv. mi)
226233 # All other effects already guaranteed effect free by construction
227234 if is_nothrow (effects)
235+ ir. stmts[idx][:flag ] |= IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW
228236 if isa (rt, Const) && is_inlineable_constant (rt. val)
229237 ir. stmts[idx][:inst ] = quoted (rt. val)
230- else
231- ir. stmts[idx][:flag ] |= IR_FLAG_EFFECT_FREE
232238 end
233239 end
234240 elseif head === :invoke
235241 mi′ = inst. args[1 ]:: MethodInstance
236242 if mi′ != = irsv. mi # prevent infinite loop
237- rt = concrete_eval_invoke (interp, inst, mi′, irsv)
243+ rt, nothrow = concrete_eval_invoke (interp, inst, mi′, irsv)
244+ if nothrow
245+ ir. stmts[idx][:flag ] |= IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW
246+ if isa (rt, Const) && is_inlineable_constant (rt. val)
247+ ir. stmts[idx][:inst ] = quoted (rt. val)
248+ end
249+ end
238250 end
239251 elseif head === :throw_undef_if_not || # TODO : Terminate interpretation early if known false?
240252 head === :gc_preserve_begin ||
@@ -416,7 +428,15 @@ function _ir_abstract_constant_propagation(interp::AbstractInterpreter, irsv::IR
416428 end
417429 end
418430
419- return maybe_singleton_const (ultimate_rt)
431+ nothrow = true
432+ for i = 1 : length (ir. stmts)
433+ if (ir. stmts[i][:flag ] & IR_FLAG_NOTHROW) == 0
434+ nothrow = false
435+ break
436+ end
437+ end
438+
439+ return Pair {Any, Bool} (maybe_singleton_const (ultimate_rt), nothrow)
420440end
421441
422442function ir_abstract_constant_propagation (interp:: AbstractInterpreter , irsv:: IRInterpretationState )
0 commit comments