Skip to content

Commit 983598a

Browse files
authored
remove isva field from OpaqueClosure (#44008)
Instead allow specifying an argument tuple type separately.
1 parent 2db86f2 commit 983598a

21 files changed

+210
-176
lines changed

base/boot.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ eval(Core, :(CodeInstance(mi::MethodInstance, @nospecialize(rettype), @nospecial
424424
mi, rettype, inferred_const, inferred, const_flags, min_world, max_world, ipo_effects, effects, relocatability)))
425425
eval(Core, :(Const(@nospecialize(v)) = $(Expr(:new, :Const, :v))))
426426
eval(Core, :(PartialStruct(@nospecialize(typ), fields::Array{Any, 1}) = $(Expr(:new, :PartialStruct, :typ, :fields))))
427-
eval(Core, :(PartialOpaque(@nospecialize(typ), @nospecialize(env), isva::Bool, parent::MethodInstance, source::Method) = $(Expr(:new, :PartialOpaque, :typ, :env, :isva, :parent, :source))))
427+
eval(Core, :(PartialOpaque(@nospecialize(typ), @nospecialize(env), parent::MethodInstance, source::Method) = $(Expr(:new, :PartialOpaque, :typ, :env, :parent, :source))))
428428
eval(Core, :(InterConditional(slot::Int, @nospecialize(vtype), @nospecialize(elsetype)) = $(Expr(:new, :InterConditional, :slot, :vtype, :elsetype))))
429429
eval(Core, :(MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) =
430430
$(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers))))

base/compiler/abstractinterpretation.jl

+9-9
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
9999
end
100100
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
101101
this_arginfo = ArgInfo(fargs, this_argtypes)
102-
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv, false)
102+
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
103103
effects = result.edge_effects
104104
if const_result !== nothing
105105
(;rt, effects, const_result) = const_result
@@ -138,7 +138,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
138138
# this is in preparation for inlining, or improving the return result
139139
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
140140
this_arginfo = ArgInfo(fargs, this_argtypes)
141-
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv, false)
141+
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
142142
effects = result.edge_effects
143143
if const_result !== nothing
144144
this_rt = const_result.rt
@@ -667,7 +667,7 @@ end
667667

668668
function abstract_call_method_with_const_args(interp::AbstractInterpreter, result::MethodCallResult,
669669
@nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
670-
sv::InferenceState, va_override::Bool)
670+
sv::InferenceState)
671671
if !const_prop_enabled(interp, sv, match)
672672
return nothing
673673
end
@@ -705,7 +705,7 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter, resul
705705
return nothing
706706
end
707707
end
708-
inf_result = InferenceResult(mi, (arginfo, sv), va_override)
708+
inf_result = InferenceResult(mi, (arginfo, sv))
709709
if !any(inf_result.overridden_by_const)
710710
add_remark!(interp, sv, "[constprop] Could not handle constant info in matching_cache_argtypes")
711711
return nothing
@@ -1457,7 +1457,7 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
14571457
# t, a = ti.parameters[i], argtypes′[i]
14581458
# argtypes′[i] = t ⊑ a ? t : a
14591459
# end
1460-
const_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv, false)
1460+
const_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv)
14611461
if const_result !== nothing
14621462
(;rt, const_result) = const_result
14631463
end
@@ -1603,7 +1603,7 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part
16031603
const_result = nothing
16041604
if !result.edgecycle
16051605
const_result = abstract_call_method_with_const_args(interp, result, nothing,
1606-
arginfo, match, sv, closure.isva)
1606+
arginfo, match, sv)
16071607
if const_result !== nothing
16081608
(;rt, const_result) = const_result
16091609
end
@@ -1619,7 +1619,7 @@ function most_general_argtypes(closure::PartialOpaque)
16191619
if !isa(argt, DataType) || argt.name !== typename(Tuple)
16201620
argt = Tuple
16211621
end
1622-
return most_general_argtypes(closure.source, argt, closure.isva, false)
1622+
return most_general_argtypes(closure.source, argt, false)
16231623
end
16241624

16251625
# call where the function is any lattice element
@@ -1843,14 +1843,14 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
18431843
elseif ehead === :new_opaque_closure
18441844
tristate_merge!(sv, Effects()) # TODO
18451845
t = Union{}
1846-
if length(e.args) >= 5
1846+
if length(e.args) >= 4
18471847
ea = e.args
18481848
argtypes = collect_argtypes(interp, ea, vtypes, sv)
18491849
if argtypes === nothing
18501850
t = Bottom
18511851
else
18521852
t = _opaque_closure_tfunc(argtypes[1], argtypes[2], argtypes[3],
1853-
argtypes[4], argtypes[5], argtypes[6:end], sv.linfo)
1853+
argtypes[4], argtypes[5:end], sv.linfo)
18541854
if isa(t, PartialOpaque)
18551855
# Infer this now so that the specialization is available to
18561856
# optimization.

base/compiler/inferenceresult.jl

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ end
2121
# to return a valid value for `cache_lookup(linfo, argtypes, cache).argtypes`,
2222
# so that we can construct cache-correct `InferenceResult`s in the first place.
2323
function matching_cache_argtypes(
24-
linfo::MethodInstance, (arginfo, sv)#=::Tuple{ArgInfo,InferenceState}=#, va_override::Bool)
24+
linfo::MethodInstance, (arginfo, sv)#=::Tuple{ArgInfo,InferenceState}=#)
2525
(; fargs, argtypes) = arginfo
2626
@assert isa(linfo.def, Method) # ensure the next line works
2727
nargs::Int = linfo.def.nargs
28-
cache_argtypes, overridden_by_const = matching_cache_argtypes(linfo, nothing, va_override)
28+
cache_argtypes, overridden_by_const = matching_cache_argtypes(linfo, nothing)
2929
given_argtypes = Vector{Any}(undef, length(argtypes))
3030
local condargs = nothing
3131
for i in 1:length(argtypes)
@@ -55,7 +55,7 @@ function matching_cache_argtypes(
5555
end
5656
given_argtypes[i] = widenconditional(argtype)
5757
end
58-
isva = va_override || linfo.def.isva
58+
isva = linfo.def.isva
5959
if isva || isvarargtype(given_argtypes[end])
6060
isva_given_argtypes = Vector{Any}(undef, nargs)
6161
for i = 1:(nargs - isva)
@@ -93,8 +93,9 @@ function matching_cache_argtypes(
9393
end
9494

9595
function most_general_argtypes(method::Union{Method, Nothing}, @nospecialize(specTypes),
96-
isva::Bool, withfirst::Bool = true)
96+
withfirst::Bool = true)
9797
toplevel = method === nothing
98+
isva = !toplevel && method.isva
9899
linfo_argtypes = Any[(unwrap_unionall(specTypes)::DataType).parameters...]
99100
nargs::Int = toplevel ? 0 : method.nargs
100101
if !withfirst
@@ -192,10 +193,9 @@ function elim_free_typevars(@nospecialize t)
192193
end
193194
end
194195

195-
function matching_cache_argtypes(linfo::MethodInstance, ::Nothing, va_override::Bool)
196+
function matching_cache_argtypes(linfo::MethodInstance, ::Nothing)
196197
mthd = isa(linfo.def, Method) ? linfo.def::Method : nothing
197-
cache_argtypes = most_general_argtypes(mthd, linfo.specTypes,
198-
va_override || (isa(mthd, Method) ? mthd.isva : false))
198+
cache_argtypes = most_general_argtypes(mthd, linfo.specTypes)
199199
return cache_argtypes, falses(length(cache_argtypes))
200200
end
201201

base/compiler/optimize.jl

+5-6
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,15 @@ function stmt_effect_free(@nospecialize(stmt), @nospecialize(rt), src::Union{IRC
235235
elseif head === :foreigncall
236236
return foreigncall_effect_free(stmt, src)
237237
elseif head === :new_opaque_closure
238-
length(args) < 5 && return false
238+
length(args) < 4 && return false
239239
typ = argextype(args[1], src)
240240
typ, isexact = instanceof_tfunc(typ)
241241
isexact || return false
242242
typ Tuple || return false
243-
isva = argextype(args[2], src)
244-
rt_lb = argextype(args[3], src)
245-
rt_ub = argextype(args[4], src)
246-
src = argextype(args[5], src)
247-
if !(isva Bool && rt_lb Type && rt_ub Type && src Method)
243+
rt_lb = argextype(args[2], src)
244+
rt_ub = argextype(args[3], src)
245+
src = argextype(args[4], src)
246+
if !(rt_lb Type && rt_ub Type && src Method)
248247
return false
249248
end
250249
return true

base/compiler/ssair/inlining.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -1056,10 +1056,10 @@ end
10561056

10571057
function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), state::InliningState)
10581058
if isa(info, OpaqueClosureCreateInfo)
1059-
lbt = argextype(stmt.args[3], ir)
1059+
lbt = argextype(stmt.args[2], ir)
10601060
lb, exact = instanceof_tfunc(lbt)
10611061
exact || return
1062-
ubt = argextype(stmt.args[4], ir)
1062+
ubt = argextype(stmt.args[3], ir)
10631063
ub, exact = instanceof_tfunc(ubt)
10641064
exact || return
10651065
# Narrow opaque closure type
@@ -1068,7 +1068,7 @@ function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), sta
10681068
# N.B.: Narrowing the ub requires a backdge on the mi whose type
10691069
# information we're using, since a change in that function may
10701070
# invalidate ub result.
1071-
stmt.args[4] = newT
1071+
stmt.args[3] = newT
10721072
end
10731073
end
10741074
end

base/compiler/ssair/legacy.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
function inflate_ir(ci::CodeInfo, linfo::MethodInstance)
44
sptypes = sptypes_from_meth_instance(linfo)
55
if ci.inferred
6-
argtypes, _ = matching_cache_argtypes(linfo, nothing, false)
6+
argtypes, _ = matching_cache_argtypes(linfo, nothing)
77
else
88
argtypes = Any[ Any for i = 1:length(ci.slotflags) ]
99
end

base/compiler/ssair/passes.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ function lift_leaves(compact::IncrementalCompact,
393393
ocleaf = simple_walk(compact, ocleaf)
394394
end
395395
ocdef, _ = walk_to_def(compact, ocleaf)
396-
if isexpr(ocdef, :new_opaque_closure) && isa(field, Int) && 1 field length(ocdef.args)-5
397-
lift_arg!(compact, leaf, cache_key, ocdef, 5+field, lifted_leaves)
396+
if isexpr(ocdef, :new_opaque_closure) && isa(field, Int) && 1 field length(ocdef.args)-4
397+
lift_arg!(compact, leaf, cache_key, ocdef, 4+field, lifted_leaves)
398398
continue
399399
end
400400
return nothing

base/compiler/tfuncs.jl

+3-5
Original file line numberDiff line numberDiff line change
@@ -1580,9 +1580,8 @@ function array_elmtype(@nospecialize ary)
15801580
return Any
15811581
end
15821582

1583-
function _opaque_closure_tfunc(@nospecialize(arg), @nospecialize(isva),
1584-
@nospecialize(lb), @nospecialize(ub), @nospecialize(source), env::Vector{Any},
1585-
linfo::MethodInstance)
1583+
function _opaque_closure_tfunc(@nospecialize(arg), @nospecialize(lb), @nospecialize(ub),
1584+
@nospecialize(source), env::Vector{Any}, linfo::MethodInstance)
15861585

15871586
argt, argt_exact = instanceof_tfunc(arg)
15881587
lbt, lb_exact = instanceof_tfunc(lb)
@@ -1596,9 +1595,8 @@ function _opaque_closure_tfunc(@nospecialize(arg), @nospecialize(isva),
15961595
t = lbt == ubt ? t{ubt} : (t{T} where lbt <: T <: ubt)
15971596

15981597
(isa(source, Const) && isa(source.val, Method)) || return t
1599-
(isa(isva, Const) && isa(isva.val, Bool)) || return t
16001598

1601-
return PartialOpaque(t, tuple_tfunc(env), isva.val, linfo, source.val)
1599+
return PartialOpaque(t, tuple_tfunc(env), linfo, source.val)
16021600
end
16031601

16041602
# whether getindex for the elements can potentially throw UndefRef

base/compiler/typelimits.jl

+1-2
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,11 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
428428
end
429429
if isa(typea, PartialOpaque) && isa(typeb, PartialOpaque) && widenconst(typea) == widenconst(typeb)
430430
if !(typea.source === typeb.source &&
431-
typea.isva === typeb.isva &&
432431
typea.parent === typeb.parent)
433432
return widenconst(typea)
434433
end
435434
return PartialOpaque(typea.typ, tmerge(typea.env, typeb.env),
436-
typea.isva, typea.parent, typea.source)
435+
typea.parent, typea.source)
437436
end
438437
# no special type-inference lattice, join the types
439438
typea, typeb = widenconst(typea), widenconst(typeb)

base/compiler/types.jl

+2-3
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,8 @@ mutable struct InferenceResult
126126
ipo_effects::Effects # if inference is finished
127127
effects::Effects # if optimization is finished
128128
function InferenceResult(linfo::MethodInstance,
129-
arginfo#=::Union{Nothing,Tuple{ArgInfo,InferenceState}}=# = nothing,
130-
va_override::Bool = false)
131-
argtypes, overridden_by_const = matching_cache_argtypes(linfo, arginfo, va_override)
129+
arginfo#=::Union{Nothing,Tuple{ArgInfo,InferenceState}}=# = nothing)
130+
argtypes, overridden_by_const = matching_cache_argtypes(linfo, arginfo)
132131
return new(linfo, argtypes, overridden_by_const, Any, nothing, WorldRange(), Effects(), Effects())
133132
end
134133
end

base/opaque_closure.jl

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
"""
4-
@opaque (args...) -> body
4+
@opaque ([type, ]args...) -> body
55
66
Marks a given closure as "opaque". Opaque closures capture the
77
world age of their creation (as opposed to their invocation).
@@ -10,9 +10,17 @@ list, but trades off against the ability to inline opaque
1010
closures at the call site, if their creation is not statically
1111
visible.
1212
13+
An argument tuple type (`type`) may optionally be specified, to
14+
specify allowed argument types in a more flexible way. In particular,
15+
the argument type may be fixed length even if the function is variadic.
16+
1317
!!! warning
1418
This interface is experimental and subject to change or removal without notice.
1519
"""
1620
macro opaque(ex)
1721
esc(Expr(:opaque_closure, ex))
1822
end
23+
24+
macro opaque(ty, ex)
25+
esc(Expr(:opaque_closure, ty, ex))
26+
end

0 commit comments

Comments
 (0)