Skip to content

Commit c6a090f

Browse files
authored
Merge pull request #42180 from JuliaLang/avi/backport-1.7
release: backport complicated compiler changes
2 parents c85012a + 93f40a0 commit c6a090f

File tree

14 files changed

+268
-208
lines changed

14 files changed

+268
-208
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 176 additions & 128 deletions
Large diffs are not rendered by default.

base/compiler/inferenceresult.jl

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,35 @@ end
1313
# for the provided `linfo` and `given_argtypes`. The purpose of this function is
1414
# to return a valid value for `cache_lookup(linfo, argtypes, cache).argtypes`,
1515
# so that we can construct cache-correct `InferenceResult`s in the first place.
16-
function matching_cache_argtypes(linfo::MethodInstance, given_argtypes::Vector, va_override)
16+
function matching_cache_argtypes(linfo::MethodInstance, given_argtypes::Vector, va_override::Bool)
1717
@assert isa(linfo.def, Method) # ensure the next line works
1818
nargs::Int = linfo.def.nargs
19-
@assert length(given_argtypes) >= (nargs - 1)
2019
given_argtypes = anymap(widenconditional, given_argtypes)
21-
if va_override || linfo.def.isva
20+
isva = va_override || linfo.def.isva
21+
if isva || isvarargtype(given_argtypes[end])
2222
isva_given_argtypes = Vector{Any}(undef, nargs)
23-
for i = 1:(nargs - 1)
23+
for i = 1:(nargs - isva)
2424
isva_given_argtypes[i] = argtype_by_index(given_argtypes, i)
2525
end
26-
if length(given_argtypes) >= nargs || !isvarargtype(given_argtypes[end])
27-
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[nargs:end])
28-
else
29-
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[end:end])
26+
if isva
27+
if length(given_argtypes) < nargs && isvarargtype(given_argtypes[end])
28+
last = length(given_argtypes)
29+
else
30+
last = nargs
31+
end
32+
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
3033
end
3134
given_argtypes = isva_given_argtypes
3235
end
36+
@assert length(given_argtypes) == nargs
3337
cache_argtypes, overridden_by_const = matching_cache_argtypes(linfo, nothing, va_override)
34-
if nargs === length(given_argtypes)
35-
for i in 1:nargs
36-
given_argtype = given_argtypes[i]
37-
cache_argtype = cache_argtypes[i]
38-
if !is_argtype_match(given_argtype, cache_argtype, overridden_by_const[i])
39-
# prefer the argtype we were given over the one computed from `linfo`
40-
cache_argtypes[i] = given_argtype
41-
overridden_by_const[i] = true
42-
end
38+
for i in 1:nargs
39+
given_argtype = given_argtypes[i]
40+
cache_argtype = cache_argtypes[i]
41+
if !is_argtype_match(given_argtype, cache_argtype, overridden_by_const[i])
42+
# prefer the argtype we were given over the one computed from `linfo`
43+
cache_argtypes[i] = given_argtype
44+
overridden_by_const[i] = true
4345
end
4446
end
4547
return cache_argtypes, overridden_by_const

base/compiler/inferencestate.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function sptypes_from_meth_instance(linfo::MethodInstance)
265265
while temp isa UnionAll
266266
temp = temp.body
267267
end
268-
sigtypes = temp.parameters
268+
sigtypes = (temp::DataType).parameters
269269
for j = 1:length(sigtypes)
270270
tj = sigtypes[j]
271271
if isType(tj) && tj.parameters[1] === Pi

base/compiler/optimize.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,11 @@ function stmt_affects_purity(@nospecialize(stmt), ir)
196196
return true
197197
end
198198

199-
# Convert IRCode back to CodeInfo and compute inlining cost and sideeffects
199+
# compute inlining cost and sideeffects
200200
function finish(interp::AbstractInterpreter, opt::OptimizationState, params::OptimizationParams, ir::IRCode, @nospecialize(result))
201-
def = opt.linfo.def
202-
nargs = Int(opt.nargs) - 1
201+
(; src, nargs, linfo) = opt
202+
(; def, specTypes) = linfo
203+
nargs = Int(nargs) - 1
203204

204205
force_noinline = _any(@nospecialize(x) -> isexpr(x, :meta) && x.args[1] === :noinline, ir.meta)
205206

@@ -221,7 +222,7 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, params::Opt
221222
end
222223
end
223224
if proven_pure
224-
for fl in opt.src.slotflags
225+
for fl in src.slotflags
225226
if (fl & SLOT_USEDUNDEF) != 0
226227
proven_pure = false
227228
break
@@ -230,7 +231,7 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, params::Opt
230231
end
231232
end
232233
if proven_pure
233-
opt.src.pure = true
234+
src.pure = true
234235
end
235236

236237
if proven_pure
@@ -243,7 +244,7 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, params::Opt
243244
if !(isa(result, Const) && !is_inlineable_constant(result.val))
244245
opt.const_api = true
245246
end
246-
force_noinline || (opt.src.inlineable = true)
247+
force_noinline || (src.inlineable = true)
247248
end
248249
end
249250

@@ -252,7 +253,7 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, params::Opt
252253
# determine and cache inlineability
253254
union_penalties = false
254255
if !force_noinline
255-
sig = unwrap_unionall(opt.linfo.specTypes)
256+
sig = unwrap_unionall(specTypes)
256257
if isa(sig, DataType) && sig.name === Tuple.name
257258
for P in sig.parameters
258259
P = unwrap_unionall(P)
@@ -264,25 +265,25 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState, params::Opt
264265
else
265266
force_noinline = true
266267
end
267-
if !opt.src.inlineable && result === Union{}
268+
if !src.inlineable && result === Union{}
268269
force_noinline = true
269270
end
270271
end
271272
if force_noinline
272-
opt.src.inlineable = false
273+
src.inlineable = false
273274
elseif isa(def, Method)
274-
if opt.src.inlineable && isdispatchtuple(opt.linfo.specTypes)
275+
if src.inlineable && isdispatchtuple(specTypes)
275276
# obey @inline declaration if a dispatch barrier would not help
276277
else
277278
bonus = 0
278279
if result Tuple && !isconcretetype(widenconst(result))
279280
bonus = params.inline_tupleret_bonus
280281
end
281-
if opt.src.inlineable
282+
if src.inlineable
282283
# For functions declared @inline, increase the cost threshold 20x
283284
bonus += params.inline_cost_threshold*19
284285
end
285-
opt.src.inlineable = isinlineable(def, opt, params, union_penalties, bonus)
286+
src.inlineable = isinlineable(def, opt, params, union_penalties, bonus)
286287
end
287288
end
288289

base/compiler/ssair/inlining.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,10 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
313313
push!(linetable, LineInfoNode(entry.module, entry.method, entry.file, entry.line,
314314
(entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at)))
315315
end
316-
nargs_def = item.mi.def.nargs
317-
isva = nargs_def > 0 && item.mi.def.isva
316+
(; def, sparam_vals) = item.mi
317+
nargs_def = def.nargs::Int32
318+
isva = nargs_def > 0 && def.isva
319+
sig = def.sig
318320
if isva
319321
vararg = mk_tuplecall!(compact, argexprs[nargs_def:end], compact.result[idx][:line])
320322
argexprs = Any[argexprs[1:(nargs_def - 1)]..., vararg]
@@ -347,7 +349,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
347349
# face of rename_arguments! mutating in place - should figure out
348350
# something better eventually.
349351
inline_compact[idx′] = nothing
350-
stmt′ = ssa_substitute!(idx′, stmt′, argexprs, item.mi.def.sig, item.mi.sparam_vals, linetable_offset, boundscheck_idx, compact)
352+
stmt′ = ssa_substitute!(idx′, stmt′, argexprs, sig, sparam_vals, linetable_offset, boundscheck_idx, compact)
351353
if isa(stmt′, ReturnNode)
352354
isa(stmt′.val, SSAValue) && (compact.used_ssas[stmt′.val.id] += 1)
353355
return_value = SSAValue(idx′)
@@ -374,7 +376,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
374376
inline_compact = IncrementalCompact(compact, spec.ir, compact.result_idx)
375377
for ((_, idx′), stmt′) in inline_compact
376378
inline_compact[idx′] = nothing
377-
stmt′ = ssa_substitute!(idx′, stmt′, argexprs, item.mi.def.sig, item.mi.sparam_vals, linetable_offset, boundscheck_idx, compact)
379+
stmt′ = ssa_substitute!(idx′, stmt′, argexprs, sig, sparam_vals, linetable_offset, boundscheck_idx, compact)
378380
if isa(stmt′, ReturnNode)
379381
if isdefined(stmt′, :val)
380382
val = stmt′.val
@@ -709,9 +711,8 @@ function compileable_specialization(et::Union{EdgeTracker, Nothing}, match::Meth
709711
return mi
710712
end
711713

712-
function compileable_specialization(et::Union{EdgeTracker, Nothing}, result::InferenceResult)
713-
mi = specialize_method(result.linfo.def::Method, result.linfo.specTypes,
714-
result.linfo.sparam_vals, false, true)
714+
function compileable_specialization(et::Union{EdgeTracker, Nothing}, (; linfo)::InferenceResult)
715+
mi = specialize_method(linfo.def::Method, linfo.specTypes, linfo.sparam_vals, false, true)
715716
mi !== nothing && et !== nothing && push!(et, mi::MethodInstance)
716717
return mi
717718
end
@@ -1065,9 +1066,9 @@ function inline_invoke!(ir::IRCode, idx::Int, sig::Signature, (; match, result):
10651066
pushfirst!(atypes, atype0)
10661067

10671068
if isa(result, InferenceResult)
1068-
item = InliningTodo(result, atypes, calltype)
1069-
validate_sparams(item.mi.sparam_vals) || return nothing
1070-
if argtypes_to_type(atypes) <: item.mi.def.sig
1069+
(; mi) = item = InliningTodo(result, atypes, calltype)
1070+
validate_sparams(mi.sparam_vals) || return nothing
1071+
if argtypes_to_type(atypes) <: mi.def.sig
10711072
state.mi_cache !== nothing && (item = resolve_todo(item, state))
10721073
handle_single_case!(ir, stmt, idx, item, true, todo)
10731074
return nothing
@@ -1195,7 +1196,7 @@ function analyze_single_call!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::Int
11951196
for i in 1:length(infos)
11961197
info = infos[i]
11971198
meth = info.results
1198-
if meth === missing || meth.ambig
1199+
if meth.ambig
11991200
# Too many applicable methods
12001201
# Or there is a (partial?) ambiguity
12011202
too_many = true
@@ -1213,19 +1214,20 @@ function analyze_single_call!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::Int
12131214
only_method = false
12141215
end
12151216
for match in meth
1216-
signature_union = Union{signature_union, match.spec_types}
1217-
if !isdispatchtuple(match.spec_types)
1217+
spec_types = match.spec_types
1218+
signature_union = Union{signature_union, spec_types}
1219+
if !isdispatchtuple(spec_types)
12181220
fully_covered = false
12191221
continue
12201222
end
12211223
case = analyze_method!(match, sig.atypes, state, calltype)
12221224
if case === nothing
12231225
fully_covered = false
12241226
continue
1225-
elseif _any(p->p[1] === match.spec_types, cases)
1227+
elseif _any(p->p[1] === spec_types, cases)
12261228
continue
12271229
end
1228-
push!(cases, Pair{Any,Any}(match.spec_types, case))
1230+
push!(cases, Pair{Any,Any}(spec_types, case))
12291231
end
12301232
end
12311233

base/compiler/ssair/legacy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function replace_code_newstyle!(ci::CodeInfo, ir::IRCode, nargs::Int)
4747
for metanode in ir.meta
4848
push!(ci.code, metanode)
4949
push!(ci.codelocs, 1)
50-
push!(ci.ssavaluetypes, Any)
50+
push!(ci.ssavaluetypes::Vector{Any}, Any)
5151
push!(ci.ssaflags, 0x00)
5252
end
5353
# Translate BB Edges to statement edges

base/compiler/ssair/passes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ function type_lift_pass!(ir::IRCode)
10641064
if haskey(processed, id)
10651065
val = processed[id]
10661066
else
1067-
push!(worklist, (id, up_id, new_phi, i))
1067+
push!(worklist, (id, up_id, new_phi::SSAValue, i))
10681068
continue
10691069
end
10701070
else

base/compiler/ssair/slot2ssa.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse, narg
871871
changed = false
872872
for new_idx in type_refine_phi
873873
node = new_nodes.stmts[new_idx]
874-
new_typ = recompute_type(node[:inst], ci, ir, ir.sptypes, slottypes)
874+
new_typ = recompute_type(node[:inst]::Union{PhiNode,PhiCNode}, ci, ir, ir.sptypes, slottypes)
875875
if !(node[:type] new_typ) || !(new_typ node[:type])
876876
node[:type] = new_typ
877877
changed = true

base/compiler/stmtinfo.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ to re-consult the method table. This info is illegal on any statement that is
99
not a call to a generic function.
1010
"""
1111
struct MethodMatchInfo
12-
results::Union{Missing, MethodLookupResult}
12+
results::MethodLookupResult
1313
end
1414

1515
"""

base/compiler/tfuncs.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,7 +1627,7 @@ function builtin_tfunction(interp::AbstractInterpreter, @nospecialize(f), argtyp
16271627
if length(argtypes) - 1 == tf[2]
16281628
argtypes = argtypes[1:end-1]
16291629
else
1630-
vatype = argtypes[end]
1630+
vatype = argtypes[end]::Core.TypeofVararg
16311631
argtypes = argtypes[1:end-1]
16321632
while length(argtypes) < tf[1]
16331633
push!(argtypes, unwrapva(vatype))
@@ -1733,7 +1733,7 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s
17331733
aft = argtypes[2]
17341734
if isa(aft, Const) || (isType(aft) && !has_free_typevars(aft)) ||
17351735
(isconcretetype(aft) && !(aft <: Builtin))
1736-
af_argtype = isa(tt, Const) ? tt.val : tt.parameters[1]
1736+
af_argtype = isa(tt, Const) ? tt.val : (tt::DataType).parameters[1]
17371737
if isa(af_argtype, DataType) && af_argtype <: Tuple
17381738
argtypes_vec = Any[aft, af_argtype.parameters...]
17391739
if contains_is(argtypes_vec, Union{})

0 commit comments

Comments
 (0)