Skip to content

Commit e5d6d0f

Browse files
committed
lattice overhaul step 3: simplify tmerge
1 parent b96af1f commit e5d6d0f

File tree

14 files changed

+302
-277
lines changed

14 files changed

+302
-277
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
9494
if const_result !== nothing
9595
any_const_result = true
9696
end
97-
this_rt = tmerge(this_rt, rt)
97+
this_rt = this_rt rt
9898
if bail_out_call(interp, this_rt, sv)
9999
break
100100
end
@@ -139,16 +139,16 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
139139
this_rt = widenconditional(this_rt)
140140
@assert !isConditional(this_conditional) "invalid lattice element returned from inter-procedural context"
141141
seen += 1
142-
rettype = tmerge(rettype, this_rt)
142+
rettype = rettype this_rt
143143
if this_conditional !==&& is_lattice_bool(rettype) && fargs !== nothing
144144
if conditionals === nothing
145145
conditionals = LatticeElement[⊥ for _ in 1:length(argtypes)],
146146
LatticeElement[⊥ for _ in 1:length(argtypes)]
147147
end
148148
for i = 1:length(argtypes)
149149
cnd = conditional_argtype(this_conditional, sig, argtypes, i)
150-
conditionals[1][i] = tmerge(conditionals[1][i], cnd.vtype)
151-
conditionals[2][i] = tmerge(conditionals[2][i], cnd.elsetype)
150+
conditionals[1][i] = conditionals[1][i] cnd.vtype
151+
conditionals[2][i] = conditionals[2][i] cnd.elsetype
152152
end
153153
end
154154
if bail_out_call(interp, rettype, sv)
@@ -290,7 +290,7 @@ In such cases `maybecondinfo` should be either of:
290290
- `maybecondinfo::Tuple{Vector{Any},Vector{Any}}`: precomputed argument type refinement information
291291
- method call signature tuple type
292292
When we deal with multiple `MethodMatch`es, it's better to precompute `maybecondinfo` by
293-
`tmerge`ing argument signature type of each method call.
293+
`⊔`-joining argument signature type of each method call.
294294
"""
295295
function from_interprocedural!(rt::LatticeElement, sv::InferenceState, arginfo::ArgInfo, @nospecialize(maybecondinfo))
296296
rt = collect_limitations!(rt, sv)
@@ -916,7 +916,7 @@ function precise_container_type(interp::AbstractInterpreter, itft::LatticeElemen
916916
tps = (t::DataType).parameters
917917
_all(valid_as_lattice, tps) || continue
918918
for j in 1:ltp
919-
result[j] = tmerge(result[j], rewrap_unionall(tps[j], tti0))
919+
result[j] = result[j] NativeType(rewrap_unionall(tps[j], tti0))
920920
end
921921
end
922922
return result, nothing
@@ -1019,9 +1019,9 @@ function abstract_iteration(interp::AbstractInterpreter, itft::LatticeElement, i
10191019
end
10201020
break
10211021
end
1022-
valtype0 = tmerge(valtype0, nounion.parameters[1])
1022+
valtype0 = valtype0 NativeType(nounion.parameters[1])
10231023
valtype = widenconst(valtype0)
1024-
statetype0 = tmerge(statetype0, nounion.parameters[2])
1024+
statetype0 = statetype0 NativeType(nounion.parameters[2])
10251025
statetype = widenconst(statetype0)
10261026
stateordonet = abstract_call_known(interp, iteratef, ArgInfo(nothing, LatticeElement[Const(iteratef), itertype, statetype0]), sv).rt
10271027
stateordonet_widened = widenconst(stateordonet)
@@ -1067,14 +1067,14 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Argtypes, sv::Inf
10671067
cti = cti_info[1]::Argtypes
10681068
info = cti_info[2]::MaybeAbstractIterationInfo
10691069
# We can't represent a repeating sequence of the same types,
1070-
# so tmerge everything together to get one type that represents
1070+
# so ⊔-join everything together to get one type that represents
10711071
# everything.
10721072
argt = cti[end]
10731073
if isVararg(argt)
10741074
argt = NativeType(unwrapva(vararg(argt)))
10751075
end
10761076
for i in 1:(length(cti)-1)
1077-
argt = tmerge(argt, cti[i])
1077+
argt = argt cti[i]
10781078
end
10791079
cti = LatticeElement[NativeType(Vararg{widenconst(argt)})]
10801080
end
@@ -1083,12 +1083,13 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Argtypes, sv::Inf
10831083
end
10841084
for j = 1:length(ctypes)
10851085
ct = ctypes[j]::Vector{LatticeElement}
1086-
if isVararg(ct[end])
1086+
ctend = ct[end]
1087+
if isVararg(ctend)
10871088
# This is vararg, we're not gonna be able to do any inling,
10881089
# drop the info
10891090
info = nothing
1090-
tail = tuple_tail_elem(ct[end], cti)
1091-
push!(ctypes´, push!(ct[1:(end - 1)], tail))
1091+
tail = tuple_tail_elem(unwrapva(vararg(ctend)), anymap(vawidenconst, cti))
1092+
push!(ctypes´, push!(ct[1:(end - 1)], NativeType(tail)))
10921093
else
10931094
push!(ctypes´, append!(ct[:], cti))
10941095
end
@@ -1106,15 +1107,17 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Argtypes, sv::Inf
11061107
lct = length(ct)
11071108
# truncate argument list at the first Vararg
11081109
for i = 1:lct-1
1109-
if isVararg(ct[i])
1110-
ct[i] = tuple_tail_elem(ct[i], ct[(i+1):lct])
1110+
cti = ct[i]
1111+
if isVararg(cti)
1112+
tail = tuple_tail_elem(vararg(cti), Any[vawidenconst(ct[j]) for j = (i+1):lct]) # TODO (lattice overhaul) we want to unwrapva(vararg(cti)) ?
1113+
ct[i] = NativeType(tail)
11111114
resize!(ct, i)
11121115
break
11131116
end
11141117
end
11151118
call = abstract_call(interp, ArgInfo(nothing, ct), sv, max_methods)
11161119
push!(retinfos, ApplyCallInfo(call.info, arginfo))
1117-
res = tmerge(res, call.rt)
1120+
res = res call.rt
11181121
if bail_out_apply(interp, res, sv)
11191122
if i != length(ctypes)
11201123
# No point carrying forward the info, we're not gonna inline it anyway
@@ -1128,6 +1131,8 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Argtypes, sv::Inf
11281131
return CallMeta(res, retinfo)
11291132
end
11301133

1134+
vawidenconst(t::LatticeElement) = isVararg(t) ? vararg(t) : widenconst(t)
1135+
11311136
function is_method_pure(method::Method, @nospecialize(sig), sparams::SimpleVector)
11321137
if isdefined(method, :generator)
11331138
method.generator.expand_early || return false
@@ -1201,7 +1206,7 @@ function abstract_call_builtin(
12011206
if isa(b, SlotNumber) && cnd.slot_id == slot_id(b)
12021207
ty = (cnd.elsetype ty ? cnd.elsetype : (ty widenconst(cnd.elsetype)))
12031208
end
1204-
return tmerge(tx, ty)
1209+
return tx ty
12051210
end
12061211
end
12071212
end
@@ -1288,13 +1293,13 @@ function abstract_call_builtin(
12881293
cnd = isdefined_tfunc(ty, fld)
12891294
if isConst(cnd)
12901295
if constant(cnd)::Bool
1291-
vtype = tmerge(vtype, ty)
1296+
vtype = vtype ty
12921297
else
1293-
elsetype = tmerge(elsetype, ty)
1298+
elsetype = elsetype ty
12941299
end
12951300
else
1296-
vtype = tmerge(vtype, ty)
1297-
elsetype = tmerge(elsetype, ty)
1301+
vtype = vtype ty
1302+
elsetype = elsetype ty
12981303
end
12991304
end
13001305
return Conditional(a.id, vtype, elsetype)
@@ -1653,7 +1658,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
16531658
if isa(e, PhiNode)
16541659
rt =
16551660
for val in e.values
1656-
rt = tmerge(rt, abstract_eval_special_value(interp, val, vtypes, sv))
1661+
rt = rt abstract_eval_special_value(interp, val, vtypes, sv)
16571662
end
16581663
return rt
16591664
end
@@ -1691,7 +1696,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
16911696
end
16921697
if !anyrefine
16931698
anyrefine = has_nontrivial_const_info(at) || # constant information
1694-
at ft # just a type-level information, but more precise than the declared type
1699+
at ft # just a type-level information, but more precise than the declared type
16951700
end
16961701
ats[i-1] = at
16971702
end
@@ -1830,7 +1835,7 @@ end
18301835
function widenreturn(rt::LatticeElement, bestguess::LatticeElement, nslots::Int, slottypes::Argtypes, changes::VarTable)
18311836
if !(bestguess Bool) || unwraptype(bestguess) === Bool
18321837
# give up inter-procedural constraint back-propagation
1833-
# when tmerge would widen the result anyways (as an optimization)
1838+
# when would widen the result anyways (as an optimization)
18341839
rt = widenconditional(rt)
18351840
else
18361841
if isConditional(rt)
@@ -1988,7 +1993,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
19881993
bestguess = frame.bestguess
19891994
rt = abstract_eval_value(interp, stmt.val, changes, frame)
19901995
rt = widenreturn(rt, bestguess, nslots, slottypes, changes)
1991-
# narrow representation of bestguess slightly to prepare for tmerge with rt
1996+
# narrow representation of bestguess slightly to prepare for with rt
19921997
if isInterConditional(rt) && isConst(bestguess)
19931998
let cnd = interconditional(rt)
19941999
slot_id = cnd.slot_id
@@ -2008,9 +2013,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
20082013
if !isempty(frame.limitations)
20092014
rt = LimitedAccuracy(rt, copy(frame.limitations))
20102015
end
2011-
if tchanged(rt, bestguess)
2016+
if bestguess rt
20122017
# new (wider) return type for frame
2013-
bestguess = tmerge(bestguess, rt)
2018+
bestguess = bestguess rt
20142019
# TODO: if isInterConditional(bestguess) && !interesting(bestguess); bestguess = widenconditional(bestguess); end
20152020
frame.bestguess = bestguess
20162021
for (caller, caller_pc) in frame.cycle_backedges

base/compiler/inferencestate.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ function record_ssa_assign(ssa_id::Int, new::LatticeElement, frame::InferenceSta
322322
if old === NOT_FOUND || !(new old)
323323
# typically, we expect that old ⊑ new (that output information only
324324
# gets less precise with worse input information), but to actually
325-
# guarantee convergence we need to use tmerge here to ensure that is true
326-
ssavaluetypes[ssa_id] = old === NOT_FOUND ? new : tmerge(old, new)
325+
# guarantee convergence we need to use here to ensure that is true
326+
ssavaluetypes[ssa_id] = old === NOT_FOUND ? new : old new
327327
W = frame.ip
328328
s = frame.stmt_types
329329
for r in frame.ssavalue_uses[ssa_id]

base/compiler/ssair/inlining.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,9 +1042,9 @@ function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), sta
10421042
ub, exact = instanceof_tfunc(ubt)
10431043
exact || return
10441044
# Narrow opaque closure type
1045-
newT = widenconst(tmerge(lb, info.unspec.rt) ub)
1045+
newT = typeintersect(typemerge(lb, widenconst(info.unspec.rt)), ub)
10461046
if newT !== ub
1047-
# N.B.: Narrowing the ub requires a backdge on the mi whose type
1047+
# N.B.: Narrowing the ub requires a backedge on the mi whose type
10481048
# information we're using, since a change in that function may
10491049
# invalidate ub result.
10501050
stmt.args[4] = newT

base/compiler/ssair/passes.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe
271271
# path, with a different type constraint. We may have
272272
# to redo some work here with the wider typeconstraint
273273
push!(worklist_defs, new_def)
274-
push!(worklist_constraints, unwraptype(tmerge(new_constraint, visited_constraints[new_def])))
274+
push!(worklist_constraints, typemerge(new_constraint, visited_constraints[new_def]))
275275
end
276276
continue
277277
end
@@ -468,8 +468,6 @@ function walk_to_def(compact::IncrementalCompact, @nospecialize(leaf))
468468
return Pair{Any, Any}(def, leaf)
469469
end
470470

471-
make_MaybeUndef(@nospecialize(typ)) = isa(typ, MaybeUndef) ? typ : MaybeUndef(typ)
472-
473471
"""
474472
lift_comparison!(compact::IncrementalCompact, idx::Int, stmt::Expr)
475473

base/compiler/ssair/slot2ssa.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ function recompute_type(node::Union{PhiNode, PhiCNode}, ci::CodeInfo, ir::IRCode
592592
while isDelayedTyp(typ)
593593
typ = types(ir)[getDelayedTyp(typ).phi::NewSSAValue]
594594
end
595-
new_typ = tmerge(new_typ, was_maybe_undef ? MaybeUndef(typ) : typ)
595+
new_typ = new_typ (was_maybe_undef ? MaybeUndef(typ) : typ)
596596
end
597597
return new_typ
598598
end
@@ -735,7 +735,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree,
735735
if isDelayedTyp(typ)
736736
push!(type_refine_phi, ssaval.id)
737737
end
738-
new_typ = isDelayedTyp(typ) ?: tmerge(old_entry[:type], typ)
738+
new_typ = isDelayedTyp(typ) ?: (old_entry[:type] typ)
739739
old_entry[:type] = new_typ
740740
old_entry[:inst] = node
741741
incoming_vals[slot] = ssaval
@@ -869,7 +869,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree,
869869
while isDelayedTyp(typ)
870870
typ = types(ir)[getDelayedTyp(typ).phi::NewSSAValue]
871871
end
872-
new_typ = tmerge(new_typ, typ)
872+
new_typ = new_typ typ
873873
end
874874
node[:type] = new_typ
875875
end

base/compiler/tfuncs.jl

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ function ifelse_tfunc(cnd::LatticeElement, x::LatticeElement, y::LatticeElement)
233233
elseif !(Bool cnd)
234234
return
235235
end
236-
return tmerge(x, y)
236+
return x y
237237
end
238238
add_tfunc(Core.ifelse, 3, 3, ifelse_tfunc, 1)
239239

@@ -318,8 +318,7 @@ function isdefined_tfunc(arg1::LatticeElement, sym::LatticeElement)
318318
end
319319
end
320320
elseif isa(a1, Union)
321-
return tmerge(isdefined_tfunc(NativeType(a1.a), sym),
322-
isdefined_tfunc(NativeType(a1.b), sym))
321+
return isdefined_tfunc(NativeType(a1.a), sym) isdefined_tfunc(NativeType(a1.b), sym)
323322
end
324323
return LBool
325324
end
@@ -391,8 +390,7 @@ function _sizeof_tfunc(@nospecialize x#=::Type=#)
391390
isconstType(x) && return _const_sizeof(x.parameters[1])
392391
xu = unwrap_unionall(x)
393392
if isa(xu, Union)
394-
return tmerge(_sizeof_tfunc(rewrap_unionall(xu.a, x)),
395-
_sizeof_tfunc(rewrap_unionall(xu.b, x)))
393+
return _sizeof_tfunc(rewrap_unionall(xu.a, x)) _sizeof_tfunc(rewrap_unionall(xu.b, x))
396394
end
397395
# Core.sizeof operates on either a type or a value. First check which
398396
# case we're in.
@@ -433,7 +431,7 @@ function _nfields_tfunc(@nospecialize(x#=::Type=#))
433431
na === LInt && return na
434432
nb = _nfields_tfunc(x.b)
435433
nb === LInt && return nb
436-
return tmerge(na, nb)
434+
return na nb
437435
end
438436
return LInt
439437
end
@@ -874,8 +872,8 @@ end
874872
function __getfield_tfunc(@nospecialize(s0#=::Type=#), name::LatticeElement, setfield::Bool)
875873
s = unwrap_unionall(s0)
876874
if isa(s, Union)
877-
return tmerge(__getfield_tfunc(rewrap_unionall(s.a, s0), name, setfield),
878-
__getfield_tfunc(rewrap_unionall(s.b, s0), name, setfield))
875+
return __getfield_tfunc(rewrap_unionall(s.a, s0), name, setfield)
876+
__getfield_tfunc(rewrap_unionall(s.b, s0), name, setfield)
879877
end
880878
isa(s, DataType) || return
881879
isabstracttype(s) && return
@@ -924,7 +922,7 @@ function __getfield_tfunc(@nospecialize(s0#=::Type=#), name::LatticeElement, set
924922
for i in 1:nf
925923
_ft = ftypes[i]
926924
setfield && isconst(s, i) && continue
927-
t = tmerge(t, NativeType(rewrap_unionall(unwrapva(_ft), s0)))
925+
t = t NativeType(rewrap_unionall(unwrapva(_ft), s0))
928926
t ===&& break
929927
end
930928
return t
@@ -1150,8 +1148,8 @@ function fieldtype_tfunc(s0::LatticeElement, name::LatticeElement)
11501148

11511149
su = unwrap_unionall(s)
11521150
if isa(su, Union)
1153-
return tmerge(fieldtype_tfunc(NativeType(rewrap_unionall(su.a, s)), name),
1154-
fieldtype_tfunc(NativeType(rewrap_unionall(su.b, s)), name))
1151+
return fieldtype_tfunc(NativeType(rewrap_unionall(su.a, s)), name)
1152+
fieldtype_tfunc(NativeType(rewrap_unionall(su.b, s)), name)
11551153
end
11561154

11571155
s, exact = instanceof_tfunc(s0)
@@ -1221,7 +1219,7 @@ function _fieldtype_tfunc(@nospecialize(s#=::Type=#), exact::Bool, name::Lattice
12211219
else
12221220
ft1 = Const(ft1)
12231221
end
1224-
t = tmerge(t, ft1)
1222+
t = t ft1
12251223
t ===&& break
12261224
end
12271225
return t

0 commit comments

Comments
 (0)