From 1b5fcf870b99ffccfc8fa8bfefa7a11fccaacbab Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 31 Dec 2022 18:56:55 +0000 Subject: [PATCH 1/2] Hook up effect modeling for `TypeVar` and `UnionAll` We already had effect modeling for `_typevar`, which `TypeVar` should just defer to. Add a simple model for `UnionAll` as well, though in the future we can add the Vararg case also. --- base/compiler/abstractinterpretation.jl | 23 ++++++++++++++--------- base/compiler/tfuncs.jl | 1 + 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index c3dfc0eeb22d2..e23cd696a2444 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1834,35 +1834,38 @@ end function abstract_call_unionall(argtypes::Vector{Any}) if length(argtypes) == 3 canconst = true + a2 = argtypes[2] a3 = argtypes[3] + nothrow = a2 โŠ‘ TypeVar && ( + a3 โŠ‘ Type || + a3 โŠ‘ TypeVar) if isa(a3, Const) body = a3.val elseif isType(a3) body = a3.parameters[1] canconst = false else - return Any + return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) end if !isa(body, Type) && !isa(body, TypeVar) - return Any + return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) end if has_free_typevars(body) - a2 = argtypes[2] if isa(a2, Const) tv = a2.val elseif isa(a2, PartialTypeVar) tv = a2.tv canconst = false else - return Any + return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) end - !isa(tv, TypeVar) && return Any + !isa(tv, TypeVar) && return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) body = UnionAll(tv, body) end ret = canconst ? Const(body) : Type{body} - return ret + return CallMeta(ret, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) end - return Any + return CallMeta(Any, EFFECTS_UNKNOWN, NoCallInfo()) end function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, si::StmtInfo, sv::InferenceState) @@ -1974,9 +1977,11 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), elseif la == 3 ub_var = argtypes[3] end - return CallMeta(typevar_tfunc(๐•ƒแตข, n, lb_var, ub_var), EFFECTS_UNKNOWN, NoCallInfo()) + pT = typevar_tfunc(๐•ƒแตข, n, lb_var, ub_var) + return CallMeta(pT, + builtin_effects(๐•ƒแตข, Core._typevar, Any[n, lb_var, ub_var], pT), NoCallInfo()) elseif f === UnionAll - return CallMeta(abstract_call_unionall(argtypes), EFFECTS_UNKNOWN, NoCallInfo()) + return abstract_call_unionall(argtypes) elseif f === Tuple && la == 2 aty = argtypes[2] ty = isvarargtype(aty) ? unwrapva(aty) : widenconst(aty) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index ad24636add1a4..78df7fa0b865a 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -2117,6 +2117,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[ typeassert, typeof, compilerbarrier, + Core._typevar ] const _ARGMEM_BUILTINS = Any[ From 9aa83e78f05dd9e21f7a5325a1e05030dc9a6fe9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 1 Jan 2023 11:22:44 -0500 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> --- base/compiler/abstractinterpretation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index e23cd696a2444..6cf40748ca6f3 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1848,7 +1848,7 @@ function abstract_call_unionall(argtypes::Vector{Any}) return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow), NoCallInfo()) end if !isa(body, Type) && !isa(body, TypeVar) - return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) + return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) end if has_free_typevars(body) if isa(a2, Const) @@ -1857,9 +1857,9 @@ function abstract_call_unionall(argtypes::Vector{Any}) tv = a2.tv canconst = false else - return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) + return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) end - !isa(tv, TypeVar) && return CallMeta(Any, Effects(EFFECTS_TOTAL; nothrow=false), NoCallInfo()) + !isa(tv, TypeVar) && return CallMeta(Any, EFFECTS_THROWS, NoCallInfo()) body = UnionAll(tv, body) end ret = canconst ? Const(body) : Type{body}