diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 03174aeed3e5a9..753eb4c6a13b77 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -71,7 +71,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), rt = const_call_result.rt exct = const_call_result.exct (; effects, const_result, edge) = const_call_result - elseif better_effects(const_call_result.effects, effects) + elseif is_better_effects(const_call_result.effects, effects) exct = const_call_result.exct (; effects, const_result, edge) = const_call_result elseif !(exct โŠ‘โ‚š const_call_result.exct) @@ -120,7 +120,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), this_rt = this_const_rt this_exct = const_call_result.exct (; effects, const_result, edge) = const_call_result - elseif better_effects(const_call_result.effects, effects) + elseif is_better_effects(const_call_result.effects, effects) this_exct = const_call_result.exct (; effects, const_result, edge) = const_call_result elseif !(this_exct โŠ‘โ‚š const_call_result.exct) @@ -2043,7 +2043,19 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), elseif f === applicable return abstract_applicable(interp, argtypes, sv, max_methods) elseif f === throw - return CallMeta(Union{}, la == 2 ? argtypes[2] : ArgumentError, EFFECTS_THROWS, NoCallInfo()) + if la == 2 + arg2 = argtypes[2] + if isvarargtype(arg2) + exct = tmerge(๐•ƒแตข, unwrapva(argtypes[2]), ArgumentError) + else + exct = arg2 + end + elseif la == 3 && isvarargtype(argtypes[3]) + exct = tmerge(๐•ƒแตข, argtypes[2], ArgumentError) + else + exct = ArgumentError + end + return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo()) end rt = abstract_call_builtin(interp, f, arginfo, sv) ft = popfirst!(argtypes) @@ -2372,7 +2384,7 @@ end function abstract_eval_the_exception(interp::AbstractInterpreter, sv::InferenceState) return sv.handlers[sv.handler_at[sv.currpc][2]].exct end -abstract_eval_the_exception(interp, sv) = Any +abstract_eval_the_exception(::AbstractInterpreter, ::IRInterpretationState) = Any function abstract_eval_statement_expr(interp::AbstractInterpreter, e::Expr, vtypes::Union{VarTable,Nothing}, sv::AbsIntState) diff --git a/base/compiler/effects.jl b/base/compiler/effects.jl index 4b5f3b392107a4..d4c972ab89e951 100644 --- a/base/compiler/effects.jl +++ b/base/compiler/effects.jl @@ -171,12 +171,20 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN; nonoverlayed) end -function better_effects(new::Effects, old::Effects) +function is_better_effects(new::Effects, old::Effects) any_improved = false if new.consistent == ALWAYS_TRUE any_improved |= old.consistent != ALWAYS_TRUE - elseif new.consistent != old.consistent - return false + else + if !iszero(new.consistent & CONSISTENT_IF_NOTRETURNED) + old.consistent == ALWAYS_TRUE && return false + any_improved |= iszero(old.consistent & CONSISTENT_IF_NOTRETURNED) + elseif !iszero(new.consistent & CONSISTENT_IF_INACCESSIBLEMEMONLY) + old.consistent == ALWAYS_TRUE && return false + any_improved |= iszero(old.consistent & CONSISTENT_IF_INACCESSIBLEMEMONLY) + else + return false + end end if new.effect_free == ALWAYS_TRUE any_improved |= old.consistent != ALWAYS_TRUE diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 5f9855372ff08b..07c20521ab67c9 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -206,6 +206,7 @@ const CACHE_MODE_VOLATILE = 0x01 << 2 # not cached, optimization allowed mutable struct TryCatchFrame exct const enter_idx + TryCatchFrame(@nospecialize(exct), enter_idx::Int) = new(exct, enter_idx) end mutable struct InferenceState diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index c549f3f05959e8..97d8bf90c060da 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -2771,7 +2771,7 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s end if contains_is(argtypes_vec, Union{}) - return CallMeta(Const(Union{}), Any, EFFECTS_TOTAL, NoCallInfo()) + return CallMeta(Const(Union{}), Union{}, EFFECTS_TOTAL, NoCallInfo()) end # Run the abstract_call without restricting abstract call @@ -2789,7 +2789,7 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s rt = widenslotwrapper(call.rt) if isa(rt, Const) # output was computed to be constant - return CallMeta(Const(typeof(rt.val)), Any, EFFECTS_TOTAL, info) + return CallMeta(Const(typeof(rt.val)), Union{}, EFFECTS_TOTAL, info) end rt = widenconst(rt) if rt === Bottom || (isconcretetype(rt) && !iskindtype(rt)) diff --git a/src/opaque_closure.c b/src/opaque_closure.c index 8d8698c67ed9a1..7fd6d5a0f86662 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -150,7 +150,7 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet sigtype = jl_argtype_with_function(env, (jl_value_t*)argt); jl_method_instance_t *mi = jl_specializations_get_linfo((jl_method_t*)root, sigtype, jl_emptysvec); - inst = jl_new_codeinst(mi, rt_ub, NULL, NULL, (jl_value_t*)ci, + inst = jl_new_codeinst(mi, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci, 0, meth->primary_world, -1, 0, 0, jl_nothing, 0); jl_mi_cache_insert(mi, inst); diff --git a/test/compiler/EscapeAnalysis/EscapeAnalysis.jl b/test/compiler/EscapeAnalysis/EscapeAnalysis.jl index 7366024329ee6d..d8ea8be21fe07b 100644 --- a/test/compiler/EscapeAnalysis/EscapeAnalysis.jl +++ b/test/compiler/EscapeAnalysis/EscapeAnalysis.jl @@ -70,7 +70,7 @@ function is_load_forwardable(x::EscapeInfo) end @testset "EAUtils" begin - @test code_escapes() do; println("prevent ConstABI"); sin(42); end isa EAUtils.EscapeResult + @test_throws "everything has been constant folded" code_escapes() do; sin(42); end @test code_escapes(sin, (Int,)) isa EAUtils.EscapeResult @test code_escapes(sin, (Int,)) isa EAUtils.EscapeResult end