diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 98ae3486e59ee..22bc1cf046d98 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -17,7 +17,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), arginfo::ArgInfo, si::StmtInfo, @nospecialize(atype), sv::AbsIntState, max_methods::Int) ๐•ƒโ‚š, ๐•ƒแตข = ipo_lattice(interp), typeinf_lattice(interp) - โŠ‘โ‚š = โŠ‘(๐•ƒโ‚š) + โŠ‘โ‚š, โŠ”โ‚š, โŠ”แตข = partialorder(๐•ƒโ‚š), join(๐•ƒโ‚š), join(๐•ƒแตข) if !should_infer_this_call(interp, sv) add_remark!(interp, sv, "Skipped call in throw block") # At this point we are guaranteed to end up throwing on this path, @@ -37,7 +37,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), (; valid_worlds, applicable, info) = matches update_valid_age!(sv, valid_worlds) napplicable = length(applicable) - rettype = excttype = Bottom + rettype = exctype = Bottom edges = MethodInstance[] conditionals = nothing # keeps refinement information of call argument types when the return type is boolean seen = 0 # number of signatures actually inferred @@ -96,8 +96,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), const_results[i] = const_result end edge === nothing || push!(edges, edge) - this_rt = tmerge(this_rt, rt) - this_exct = tmerge(this_exct, exct) + this_rt = this_rt โŠ”โ‚š rt + this_exct = this_exct โŠ”โ‚š exct if bail_out_call(interp, this_rt, sv) break end @@ -156,8 +156,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end @assert !(this_conditional isa Conditional || this_rt isa MustAlias) "invalid lattice element returned from inter-procedural context" seen += 1 - rettype = tmerge(๐•ƒโ‚š, rettype, this_rt) - excttype = tmerge(๐•ƒโ‚š, excttype, this_exct) + rettype = rettype โŠ”โ‚š this_rt + exctype = exctype โŠ”โ‚š this_exct if has_conditional(๐•ƒโ‚š, sv) && this_conditional !== Bottom && is_lattice_bool(๐•ƒโ‚š, rettype) && fargs !== nothing if conditionals === nothing conditionals = Any[Bottom for _ in 1:length(argtypes)], @@ -165,8 +165,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end for i = 1:length(argtypes) cnd = conditional_argtype(๐•ƒแตข, this_conditional, sig, argtypes, i) - conditionals[1][i] = tmerge(๐•ƒแตข, conditionals[1][i], cnd.thentype) - conditionals[2][i] = tmerge(๐•ƒแตข, conditionals[2][i], cnd.elsetype) + conditionals[1][i] = conditionals[1][i] โŠ”แตข cnd.thentype + conditionals[2][i] = conditionals[2][i] โŠ”แตข cnd.elsetype end end if bail_out_call(interp, InferenceLoopState(sig, rettype, all_effects), sv) @@ -182,14 +182,14 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), if seen โ‰  napplicable # there is unanalyzed candidate, widen type and effects to the top - rettype = excttype = Any + rettype = exctype = Any all_effects = Effects() else if (matches isa MethodMatches ? (!matches.fullmatch || any_ambig(matches)) : (!all(matches.fullmatches) || any_ambig(matches))) # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature. all_effects = Effects(all_effects; nothrow=false) - excttype = tmerge(๐•ƒโ‚š, excttype, MethodError) + exctype = exctype โŠ”โ‚š MethodError end if sv isa InferenceState && fargs !== nothing slotrefinements = collect_slot_refinements(๐•ƒแตข, applicable, argtypes, fargs, sv) @@ -240,7 +240,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end end - return CallMeta(rettype, excttype, all_effects, info, slotrefinements) + return CallMeta(rettype, exctype, all_effects, info, slotrefinements) end struct FailedMethodMatch @@ -367,7 +367,7 @@ function from_interprocedural!(interp::AbstractInterpreter, @nospecialize(rt), s arginfo::ArgInfo, @nospecialize(maybecondinfo)) rt = collect_limitations!(rt, sv) if isa(rt, InterMustAlias) - rt = from_intermustalias(rt, arginfo, sv) + rt = from_intermustalias(typeinf_lattice(interp), rt, arginfo, sv) elseif is_lattice_bool(ipo_lattice(interp), rt) if maybecondinfo === nothing rt = widenconditional(rt) @@ -387,12 +387,13 @@ function collect_limitations!(@nospecialize(typ), sv::InferenceState) return typ end -function from_intermustalias(rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState) +function from_intermustalias(๐•ƒแตข::AbstractLattice, rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState) fargs = arginfo.fargs if fargs !== nothing && 1 โ‰ค rt.slot โ‰ค length(fargs) arg = ssa_def_slot(fargs[rt.slot], sv) if isa(arg, SlotNumber) argtyp = widenslotwrapper(arginfo.argtypes[rt.slot]) + โŠ‘ = partialorder(๐•ƒแตข) if rt.vartyp โŠ‘ argtyp return MustAlias(arg, rt.vartyp, rt.fldidx, rt.fldtyp) else @@ -412,6 +413,7 @@ function from_interconditional(๐•ƒแตข::AbstractLattice, @nospecialize(rt), sv:: alias = nothing thentype = elsetype = Any condval = maybe_extract_const_bool(rt) + โŠ‘, โ‹ค, โŠ“ = partialorder(๐•ƒแตข), strictneqpartialorder(๐•ƒแตข), meet(๐•ƒแตข) for i in 1:length(fargs) # find the first argument which supports refinement, # and intersect all equivalent arguments with it @@ -447,24 +449,24 @@ function from_interconditional(๐•ƒแตข::AbstractLattice, @nospecialize(rt), sv:: end if condval === false thentype = Bottom - elseif โŠ‘(๐•ƒแตข, new_thentype, thentype) + elseif new_thentype โŠ‘ thentype thentype = new_thentype else - thentype = tmeet(๐•ƒแตข, thentype, widenconst(new_thentype)) + thentype = thentype โŠ“ widenconst(new_thentype) end if condval === true elsetype = Bottom - elseif โŠ‘(๐•ƒแตข, new_elsetype, elsetype) + elseif new_elsetype โŠ‘ elsetype elsetype = new_elsetype else - elsetype = tmeet(๐•ƒแตข, elsetype, widenconst(new_elsetype)) + elsetype = elsetype โŠ“ widenconst(new_elsetype) end - if (slot > 0 || condval !== false) && โ‹ค(๐•ƒแตข, thentype, old) + if (slot > 0 || condval !== false) && thentype โ‹ค old slot = id if !(arg isa SlotNumber) && argtyp isa MustAlias alias = argtyp end - elseif (slot > 0 || condval !== true) && โ‹ค(๐•ƒแตข, elsetype, old) + elseif (slot > 0 || condval !== true) && elsetype โ‹ค old slot = id if !(arg isa SlotNumber) && argtyp isa MustAlias alias = argtyp @@ -1368,7 +1370,6 @@ function matching_cache_argtypes(๐•ƒ::AbstractLattice, mi::MethodInstance, given_argtypes = Vector{Any}(undef, length(argtypes)) def = mi.def::Method nargs = Int(def.nargs) - local condargs = nothing for i in 1:length(argtypes) argtype = argtypes[i] # forward `Conditional` if it conveys a constraint on any other argument @@ -1385,10 +1386,6 @@ function matching_cache_argtypes(๐•ƒ::AbstractLattice, mi::MethodInstance, # TODO bail out here immediately rather than just propagating Bottom ? given_argtypes[i] = Bottom else - if condargs === nothing - condargs = Tuple{Int,Int}[] - end - push!(condargs, (slotid, i)) given_argtypes[i] = Conditional(slotid, thentype, elsetype) end continue