Skip to content

Commit 37fd41e

Browse files
authored
NFC cosmetic cleanup for compiler code (#45706)
* clean up `abstract_call_method` interface * tidy up `abstract_call_opaque_closure` interface * miscellaneous improvements
1 parent 30e8204 commit 37fd41e

File tree

4 files changed

+48
-53
lines changed

4 files changed

+48
-53
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,16 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
125125
splitsigs = switchtupleunion(sig)
126126
for sig_n in splitsigs
127127
result = abstract_call_method(interp, method, sig_n, svec(), multiple_matches, sv)
128-
rt = result.rt
129-
edge = result.edge
128+
(; rt, edge, effects) = result
130129
edge !== nothing && push!(edges, edge)
131130
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
132131
this_arginfo = ArgInfo(fargs, this_argtypes)
133132
const_call_result = abstract_call_method_with_const_args(interp, result,
134133
f, this_arginfo, match, sv)
135-
effects = result.edge_effects
136134
const_result = nothing
137135
if const_call_result !== nothing
138-
const_rt = const_call_result.rt
139-
if const_rt rt
140-
rt = const_rt
136+
if const_call_result.rt rt
137+
rt = const_call_result.rt
141138
(; effects, const_result) = const_call_result
142139
end
143140
end
@@ -167,17 +164,16 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
167164
end
168165

169166
result = abstract_call_method(interp, method, sig, match.sparams, multiple_matches, sv)
170-
this_conditional = ignorelimited(result.rt)
171-
this_rt = widenwrappedconditional(result.rt)
172-
edge = result.edge
167+
(; rt, edge, effects) = result
168+
this_conditional = ignorelimited(rt)
169+
this_rt = widenwrappedconditional(rt)
173170
edge !== nothing && push!(edges, edge)
174171
# try constant propagation with argtypes for this match
175172
# this is in preparation for inlining, or improving the return result
176173
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
177174
this_arginfo = ArgInfo(fargs, this_argtypes)
178175
const_call_result = abstract_call_method_with_const_args(interp, result,
179176
f, this_arginfo, match, sv)
180-
effects = result.edge_effects
181177
const_result = nothing
182178
if const_call_result !== nothing
183179
this_const_conditional = ignorelimited(const_call_result.rt)
@@ -606,7 +602,8 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
606602
sparams = recomputed[2]::SimpleVector
607603
end
608604

609-
(; rt, edge, edge_effects) = typeinf_edge(interp, method, sig, sparams, sv)
605+
(; rt, edge, effects) = typeinf_edge(interp, method, sig, sparams, sv)
606+
610607
if edge === nothing
611608
edgecycle = edgelimited = true
612609
end
@@ -615,16 +612,17 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
615612
# may have been tainted due to recursion at this point even if it's overridden
616613
if is_effect_overridden(sv, :terminates_globally)
617614
# this frame is known to terminate
618-
edge_effects = Effects(edge_effects, terminates=ALWAYS_TRUE)
615+
effects = Effects(effects, terminates=ALWAYS_TRUE)
619616
elseif is_effect_overridden(method, :terminates_globally)
620617
# this edge is known to terminate
621-
edge_effects = Effects(edge_effects; terminates=ALWAYS_TRUE)
618+
effects = Effects(effects; terminates=ALWAYS_TRUE)
622619
elseif edgecycle
623620
# Some sort of recursion was detected. Even if we did not limit types,
624621
# we cannot guarantee that the call will terminate
625-
edge_effects = Effects(edge_effects; terminates=TRISTATE_UNKNOWN)
622+
effects = Effects(effects; terminates=TRISTATE_UNKNOWN)
626623
end
627-
return MethodCallResult(rt, edgecycle, edgelimited, edge, edge_effects)
624+
625+
return MethodCallResult(rt, edgecycle, edgelimited, edge, effects)
628626
end
629627

630628
function edge_matches_sv(frame::InferenceState, method::Method, @nospecialize(sig), sparams::SimpleVector, hardlimit::Bool, sv::InferenceState)
@@ -700,13 +698,13 @@ struct MethodCallResult
700698
edgecycle::Bool
701699
edgelimited::Bool
702700
edge::Union{Nothing,MethodInstance}
703-
edge_effects::Effects
701+
effects::Effects
704702
function MethodCallResult(@nospecialize(rt),
705703
edgecycle::Bool,
706704
edgelimited::Bool,
707705
edge::Union{Nothing,MethodInstance},
708-
edge_effects::Effects)
709-
return new(rt, edgecycle, edgelimited, edge, edge_effects)
706+
effects::Effects)
707+
return new(rt, edgecycle, edgelimited, edge, effects)
710708
end
711709
end
712710

@@ -751,10 +749,10 @@ function concrete_eval_eligible(interp::AbstractInterpreter,
751749
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
752750
# disable concrete-evaluation if this function call is tainted by some overlayed
753751
# method since currently there is no direct way to execute overlayed methods
754-
isoverlayed(method_table(interp)) && !is_nonoverlayed(result.edge_effects) && return false
752+
isoverlayed(method_table(interp)) && !is_nonoverlayed(result.effects) && return false
755753
return f !== nothing &&
756754
result.edge !== nothing &&
757-
is_foldable(result.edge_effects) &&
755+
is_foldable(result.effects) &&
758756
is_all_const_arg(arginfo)
759757
end
760758

@@ -785,7 +783,7 @@ function concrete_eval_call(interp::AbstractInterpreter,
785783
Core._call_in_world_total(world, f, args...)
786784
catch
787785
# The evaulation threw. By :consistent-cy, we're guaranteed this would have happened at runtime
788-
return ConstCallResults(Union{}, ConcreteResult(result.edge::MethodInstance, result.edge_effects), result.edge_effects)
786+
return ConstCallResults(Union{}, ConcreteResult(result.edge::MethodInstance, result.effects), result.effects)
789787
end
790788
if is_inlineable_constant(value) || call_result_unused(sv)
791789
# If the constant is not inlineable, still do the const-prop, since the
@@ -929,7 +927,7 @@ function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodC
929927
return false
930928
else
931929
if isa(rt, Const)
932-
if result.edge_effects.nothrow !== ALWAYS_TRUE
930+
if result.effects.nothrow !== ALWAYS_TRUE
933931
# Could still be improved to Bottom (or at least could see the effects improved)
934932
return true
935933
end
@@ -1596,8 +1594,8 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
15961594
method = match.method
15971595
tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
15981596
ti = tienv[1]; env = tienv[2]::SimpleVector
1599-
(; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv)
1600-
effects = result.edge_effects
1597+
result = abstract_call_method(interp, method, ti, env, false, sv)
1598+
(; rt, edge, effects) = result
16011599
edge !== nothing && add_backedge!(edge::MethodInstance, sv)
16021600
match = MethodMatch(ti, env, method, argtype <: method.sig)
16031601
res = nothing
@@ -1746,9 +1744,11 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
17461744
return abstract_call_gf_by_type(interp, f, arginfo, atype, sv, max_methods)
17471745
end
17481746

1749-
function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::PartialOpaque, arginfo::ArgInfo, sv::InferenceState)
1747+
function abstract_call_opaque_closure(interp::AbstractInterpreter,
1748+
closure::PartialOpaque, arginfo::ArgInfo, sv::InferenceState, check::Bool=true)
17501749
sig = argtypes_to_type(arginfo.argtypes)
1751-
(; rt, edge, edge_effects) = result = abstract_call_method(interp, closure.source, sig, Core.svec(), false, sv)
1750+
result = abstract_call_method(interp, closure.source, sig, Core.svec(), false, sv)
1751+
(; rt, edge, effects) = result
17521752
edge !== nothing && add_backedge!(edge, sv)
17531753
tt = closure.typ
17541754
sigT = (unwrap_unionall(tt)::DataType).parameters[1]
@@ -1759,12 +1759,21 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part
17591759
nothing, arginfo, match, sv)
17601760
if const_call_result !== nothing
17611761
if const_call_result.rt rt
1762-
(; rt, const_result) = const_call_result
1762+
(; rt, effects, const_result) = const_call_result
17631763
end
17641764
end
17651765
end
17661766
info = OpaqueClosureCallInfo(match, const_result)
1767-
return CallMeta(from_interprocedural!(rt, sv, arginfo, match.spec_types), edge_effects, info)
1767+
if check # analyze implicit type asserts on argument and return type
1768+
ftt = closure.typ
1769+
(aty, rty) = (unwrap_unionall(ftt)::DataType).parameters
1770+
rty = rewrap_unionall(rty isa TypeVar ? rty.lb : rty, ftt)
1771+
if !(rt rty && tuple_tfunc(arginfo.argtypes[2:end]) rewrap_unionall(aty, ftt))
1772+
effects = Effects(effects; nothrow=TRISTATE_UNKNOWN)
1773+
end
1774+
end
1775+
rt = from_interprocedural!(rt, sv, arginfo, match.spec_types)
1776+
return CallMeta(rt, effects, info)
17681777
end
17691778

17701779
function most_general_argtypes(closure::PartialOpaque)
@@ -1786,22 +1795,8 @@ function abstract_call(interp::AbstractInterpreter, arginfo::ArgInfo,
17861795
if isa(ft, PartialOpaque)
17871796
newargtypes = copy(argtypes)
17881797
newargtypes[1] = ft.env
1789-
body_call = abstract_call_opaque_closure(interp, ft, ArgInfo(arginfo.fargs, newargtypes), sv)
1790-
# Analyze implicit type asserts on argument and return type
1791-
ftt = ft.typ
1792-
(at, rt) = (unwrap_unionall(ftt)::DataType).parameters
1793-
if isa(rt, TypeVar)
1794-
rt = rewrap_unionall(rt.lb, ftt)
1795-
else
1796-
rt = rewrap_unionall(rt, ftt)
1797-
end
1798-
nothrow = body_call.rt rt
1799-
if nothrow
1800-
nothrow = tuple_tfunc(newargtypes[2:end]) rewrap_unionall(at, ftt)
1801-
end
1802-
return CallMeta(body_call.rt, Effects(body_call.effects,
1803-
nothrow = nothrow ? TRISTATE_UNKNOWN : body_call.effects.nothrow),
1804-
body_call.info)
1798+
return abstract_call_opaque_closure(interp,
1799+
ft, ArgInfo(arginfo.fargs, newargtypes), sv, #=check=#true)
18051800
elseif (uft = unwrap_unionall(widenconst(ft)); isa(uft, DataType) && uft.name === typename(Core.OpaqueClosure))
18061801
return CallMeta(rewrap_unionall((uft::DataType).parameters[2], widenconst(ft)), Effects(), false)
18071802
elseif f === nothing
@@ -2027,7 +2022,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
20272022
argtypes = most_general_argtypes(t)
20282023
pushfirst!(argtypes, t.env)
20292024
callinfo = abstract_call_opaque_closure(interp, t,
2030-
ArgInfo(nothing, argtypes), sv)
2025+
ArgInfo(nothing, argtypes), sv, #=check=#false)
20312026
sv.stmt_info[sv.currpc] = OpaqueClosureCreateInfo(callinfo)
20322027
end
20332028
end

base/compiler/typeinfer.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -840,11 +840,11 @@ ipo_effects(code::CodeInstance) = decode_effects(code.ipo_purity_bits)
840840
struct EdgeCallResult
841841
rt #::Type
842842
edge::Union{Nothing,MethodInstance}
843-
edge_effects::Effects
843+
effects::Effects
844844
function EdgeCallResult(@nospecialize(rt),
845845
edge::Union{Nothing,MethodInstance},
846-
edge_effects::Effects)
847-
return new(rt, edge, edge_effects)
846+
effects::Effects)
847+
return new(rt, edge, effects)
848848
end
849849
end
850850

base/compiler/utilities.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function normalize_typevars(method::Method, @nospecialize(atype), sparams::Simpl
184184
sp_ = ccall(:jl_type_intersection_with_env, Any, (Any, Any), at2, method.sig)::SimpleVector
185185
sparams = sp_[2]::SimpleVector
186186
end
187-
return atype, sparams
187+
return Pair{Any,SimpleVector}(atype, sparams)
188188
end
189189

190190
# get a handle to the unique specialization object representing a particular instantiation of a call

base/reflection.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,10 +1108,10 @@ const SLOT_USED = 0x8
11081108
ast_slotflag(@nospecialize(code), i) = ccall(:jl_ir_slotflag, UInt8, (Any, Csize_t), code, i - 1)
11091109

11101110
"""
1111-
may_invoke_generator(method, atype, sparams)
1111+
may_invoke_generator(method, atype, sparams) -> Bool
11121112
11131113
Computes whether or not we may invoke the generator for the given `method` on
1114-
the given atype and sparams. For correctness, all generated function are
1114+
the given `atype` and `sparams`. For correctness, all generated function are
11151115
required to return monotonic answers. However, since we don't expect users to
11161116
be able to successfully implement this criterion, we only call generated
11171117
functions on concrete types. The one exception to this is that we allow calling
@@ -1122,8 +1122,8 @@ computes whether we are in either of these cases.
11221122
Unlike normal functions, the compilation heuristics still can't generate good dispatch
11231123
in some cases, but this may still allow inference not to fall over in some limited cases.
11241124
"""
1125-
function may_invoke_generator(method::MethodInstance)
1126-
return may_invoke_generator(method.def::Method, method.specTypes, method.sparam_vals)
1125+
function may_invoke_generator(mi::MethodInstance)
1126+
return may_invoke_generator(mi.def::Method, mi.specTypes, mi.sparam_vals)
11271127
end
11281128
function may_invoke_generator(method::Method, @nospecialize(atype), sparams::SimpleVector)
11291129
# If we have complete information, we may always call the generator

0 commit comments

Comments
 (0)