Skip to content

Commit

Permalink
Support noub refinement in irinterp
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Aug 29, 2023
1 parent 3ffd3a2 commit 1ed5f15
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 14 deletions.
5 changes: 4 additions & 1 deletion base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ function semi_concrete_eval_call(interp::AbstractInterpreter,
irsv = IRInterpretationState(interp, code, mi, arginfo.argtypes, world)
if irsv !== nothing
irsv.parent = sv
rt, nothrow = ir_abstract_constant_propagation(interp, irsv)
rt, (nothrow, noub) = ir_abstract_constant_propagation(interp, irsv)
@assert !(rt isa Conditional || rt isa MustAlias) "invalid lattice element returned from irinterp"
if !(isa(rt, Type) && hasintersect(rt, Bool))
ir = irsv.ir
Expand All @@ -1162,6 +1162,9 @@ function semi_concrete_eval_call(interp::AbstractInterpreter,
if !is_nothrow(effects)
effects = Effects(effects; nothrow)
end
if noub
effects = Effects(effects; noub = ALWAYS_TRUE)
end
return ConstCallResults(rt, SemiConcreteResult(mi, ir, effects), effects, mi)
end
end
Expand Down
5 changes: 3 additions & 2 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -554,9 +554,10 @@ function ipo_dataflow_analysis!(interp::AbstractInterpreter, ir::IRCode, result:
# Special case: `:boundscheck` into `getfield`
is_getfield_with_boundscheck_arg(inst) || return false
barg = inst[:stmt].args[end]
isexpr(ir[barg][:stmt], :boundscheck) || return false
bstmt = ir[barg][:stmt]
isexpr(bstmt, :boundscheck) || return false
# If IR_FLAG_INBOUNDS is already set, no more conditional ub
(ir[barg][:flag] & IR_FLAG_INBOUNDS) != 0 && return false
(length(bstmt.args) != 0 && bstmt.args[1] === false) && return false
any_conditional_ub = true
return true
end
Expand Down
3 changes: 3 additions & 0 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,9 @@ function flags_for_effects(effects::Effects)
if is_nothrow(effects)
flags |= IR_FLAG_NOTHROW
end
if is_noub(effects, false)
flags |= IR_FLAG_NOUB
end
return flags
end

Expand Down
25 changes: 15 additions & 10 deletions base/compiler/ssair/irinterp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ function concrete_eval_invoke(interp::AbstractInterpreter,
world = frame_world(irsv)
mi_cache = WorldView(code_cache(interp), world)
code = get(mi_cache, mi, nothing)
code === nothing && return Pair{Any,Bool}(nothing, false)
code === nothing && return Pair{Any,Tuple{Bool, Bool}}(nothing, (false, false))
argtypes = collect_argtypes(interp, inst.args[2:end], nothing, irsv)
argtypes === nothing && return Pair{Any,Bool}(Bottom, false)
argtypes === nothing && return Pair{Any,Tuple{Bool, Bool}}(Bottom, (false, false))
effects = decode_effects(code.ipo_purity_bits)
if (is_foldable(effects) && is_all_const_arg(argtypes, #=start=#1) &&
is_nonoverlayed(effects) && is_nonoverlayed(mi.def::Method))
Expand All @@ -21,20 +21,20 @@ function concrete_eval_invoke(interp::AbstractInterpreter,
try
Core._call_in_world_total(world, args...)
catch
return Pair{Any,Bool}(Bottom, false)
return Pair{Any,Tuple{Bool, Bool}}(Bottom, (false, is_noub(effects, false)))
end
end
return Pair{Any,Bool}(Const(value), true)
return Pair{Any,Tuple{Bool, Bool}}(Const(value), (true, true))
else
if is_constprop_edge_recursed(mi, irsv)
return Pair{Any,Bool}(nothing, is_nothrow(effects))
return Pair{Any,Tuple{Bool, Bool}}(nothing, (is_nothrow(effects), is_noub(effects, false)))
end
newirsv = IRInterpretationState(interp, code, mi, argtypes, world)
if newirsv !== nothing
newirsv.parent = irsv
return ir_abstract_constant_propagation(interp, newirsv)
end
return Pair{Any,Bool}(nothing, is_nothrow(effects))
return Pair{Any,Tuple{Bool, Bool}}(nothing, (is_nothrow(effects), is_noub(effects, false)))
end
end

Expand Down Expand Up @@ -129,10 +129,13 @@ function reprocess_instruction!(interp::AbstractInterpreter, idx::Int, bb::Union
(; rt, effects) = abstract_eval_statement_expr(interp, stmt, nothing, irsv)
inst[:flag] |= flags_for_effects(effects)
elseif head === :invoke
rt, nothrow = concrete_eval_invoke(interp, stmt, stmt.args[1]::MethodInstance, irsv)
rt, (nothrow, noub) = concrete_eval_invoke(interp, stmt, stmt.args[1]::MethodInstance, irsv)
if nothrow
inst[:flag] |= IR_FLAG_NOTHROW
end
if noub
inst[:flag] |= IR_FLAG_NOUB
end
elseif head === :throw_undef_if_not
condval = maybe_extract_const_bool(argextype(stmt.args[2], ir))
condval isa Bool || return false
Expand Down Expand Up @@ -375,11 +378,13 @@ function _ir_abstract_constant_propagation(interp::AbstractInterpreter, irsv::IR
end
end

nothrow = true
nothrow = noub = true
for idx = 1:length(ir.stmts)
if (ir[SSAValue(idx)][:flag] & IR_FLAG_NOTHROW) == 0
nothrow = false
break
end
if (ir[SSAValue(idx)][:flag] & IR_FLAG_NOUB) == 0
noub = false
end
end

Expand All @@ -389,7 +394,7 @@ function _ir_abstract_constant_propagation(interp::AbstractInterpreter, irsv::IR
store_backedges(frame_instance(irsv), irsv.edges)
end

return Pair{Any,Bool}(maybe_singleton_const(ultimate_rt), nothrow)
return Pair{Any,Tuple{Bool, Bool}}(maybe_singleton_const(ultimate_rt), (nothrow, noub))
end

function ir_abstract_constant_propagation(interp::NativeInterpreter, irsv::IRInterpretationState)
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5833,7 +5833,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
jl_errorf("Expr(:%s) in value position", jl_symbol_name(head));
}
else if (head == jl_boundscheck_sym) {
jl_value_t *def = nargs == 0 ? jl_true : args[0];
jl_value_t *def = (nargs == 0) ? jl_true : args[0];
return mark_julia_const(ctx, bounds_check_enabled(ctx, def) ? jl_true : jl_false);
}
else if (head == jl_gc_preserve_begin_sym) {
Expand Down

0 comments on commit 1ed5f15

Please sign in to comment.