Skip to content

Commit 520b382

Browse files
committed
lattice overhaul step 3: clean up implementations
1 parent 4baf148 commit 520b382

File tree

16 files changed

+1022
-1010
lines changed

16 files changed

+1022
-1010
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 71 additions & 73 deletions
Large diffs are not rendered by default.

base/compiler/compiler.jl

Lines changed: 11 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ include("ordering.jl")
105105
using .Order
106106
include("sort.jl")
107107
using .Sort
108+
# required by sort/sort! functions
109+
function extrema(x::Array)
110+
isempty(x) && throw(ArgumentError("collection must be non-empty"))
111+
vmin = vmax = x[1]
112+
for i in 2:length(x)
113+
xi = x[i]
114+
vmax = max(vmax, xi)
115+
vmin = min(vmin, xi)
116+
end
117+
return vmin, vmax
118+
end
108119

109120
# We don't include some.jl, but this definition is still useful.
110121
something(x::Nothing, y...) = something(y...)
@@ -138,78 +149,6 @@ include("compiler/abstractinterpretation.jl")
138149
include("compiler/typeinfer.jl")
139150
include("compiler/optimize.jl") # TODO: break this up further + extract utilities
140151

141-
# required for bootstrap
142-
# TODO: find why this is needed and remove it.
143-
function extrema(x::Array)
144-
isempty(x) && throw(ArgumentError("collection must be non-empty"))
145-
vmin = vmax = x[1]
146-
for i in 2:length(x)
147-
xi = x[i]
148-
vmax = max(vmax, xi)
149-
vmin = min(vmin, xi)
150-
end
151-
return vmin, vmax
152-
end
153-
154-
# function show(io::IO, xs::Vector)
155-
# print(io, eltype(xs), '[')
156-
# show_itr(io, xs)
157-
# print(io, ']')
158-
# end
159-
# function show(io::IO, xs::Tuple)
160-
# print(io, '(')
161-
# show_itr(io, xs)
162-
# print(io, ')')
163-
# end
164-
# function show_itr(io::IO, xs)
165-
# n = length(xs)
166-
# for i in 1:n
167-
# show(io, xs[i])
168-
# i == n || print(io, ", ")
169-
# end
170-
# end
171-
# function show(io::IO, typ′::LatticeElement)
172-
# function name(x)
173-
# if isLimitedAccuracy(typ′)
174-
# return (nameof(x), '′',)
175-
# else
176-
# return (nameof(x),)
177-
# end
178-
# end
179-
# typ = ignorelimited(typ′)
180-
# if isConditional(typ)
181-
# show(io, conditional(typ))
182-
# elseif isConst(typ)
183-
# print(io, name(Const)..., '(', constant(typ), ')')
184-
# elseif isPartialStruct(typ)
185-
# print(io, name(PartialStruct)..., '(', widenconst(typ), ", [")
186-
# n = length(partialfields(typ))
187-
# for i in 1:n
188-
# show(io, partialfields(typ)[i])
189-
# i == n || print(io, ", ")
190-
# end
191-
# print(io, "])")
192-
# elseif isPartialTypeVar(typ)
193-
# print(io, name(PartialTypeVar)..., '(')
194-
# show(io, typ.partialtypevar.tv)
195-
# print(io, ')')
196-
# else
197-
# print(io, name(NativeType)..., '(', widenconst(typ), ')')
198-
# end
199-
# end
200-
# function show(io::IO, typ::ConditionalInfo)
201-
# if typ === __NULL_CONDITIONAL__
202-
# return print(io, "__NULL_CONDITIONAL__")
203-
# end
204-
# print(io, nameof(Conditional), '(')
205-
# show(io, typ.var)
206-
# print(io, ", ")
207-
# show(io, typ.vtype)
208-
# print(io, ", ")
209-
# show(io, typ.elsetype)
210-
# print(io, ')')
211-
# end
212-
213152
include("compiler/bootstrap.jl")
214153
ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel)
215154

base/compiler/inferenceresult.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ function matching_cache_argtypes(
3737
if slotid !== nothing
3838
# using union-split signature, we may be able to narrow down `Conditional`
3939
sigt = widenconst(slotid > nargs ? argtypes[slotid] : cache_argtypes[slotid])
40-
vtype = tmeet(cnd.vtype, sigt)
41-
elsetype = tmeet(cnd.elsetype, sigt)
40+
vtype = cnd.vtype sigt
41+
elsetype = cnd.elsetype sigt
4242
if vtype === Bottom && elsetype === Bottom
4343
# we accidentally proved this method match is impossible
4444
# TODO bail out here immediately rather than just propagating Bottom ?
@@ -67,7 +67,7 @@ function matching_cache_argtypes(
6767
else
6868
last = nargs
6969
end
70-
isva_given_argtypes[nargs] = LatticeElement(tuple_tfunc(given_argtypes[last:end]))
70+
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
7171
# invalidate `Conditional` imposed on varargs
7272
if condargs !== nothing
7373
for (slotid, i) in condargs
@@ -166,13 +166,13 @@ function most_general_argtypes(method::Union{Method, Nothing}, @nospecialize(spe
166166
elseif isconstType(atyp)
167167
atyp = Const(atyp.parameters[1])
168168
else
169-
atyp = elim_free_typevars(rewrap_unionall(atyp, specTypes))
169+
atyp = NativeType(elim_free_typevars(rewrap_unionall(atyp, specTypes)))
170170
end
171171
i == n && (lastatype = atyp)
172-
cache_argtypes[i] = LatticeElement(atyp)
172+
cache_argtypes[i] = atyp
173173
end
174174
for i = (tail_index + 1):nargs
175-
cache_argtypes[i] = LatticeElement(lastatype)
175+
cache_argtypes[i] = lastatype
176176
end
177177
else
178178
@assert nargs == 0 "invalid specialization of method" # wrong number of arguments
@@ -219,7 +219,7 @@ function cache_lookup(linfo::MethodInstance, given_argtypes::Argtypes, cache::Ve
219219
end
220220
end
221221
if method.isva && cache_match
222-
cache_match = is_argtype_match(LatticeElement(tuple_tfunc(anymap(unwraptype, given_argtypes[(nargs + 1):end]))),
222+
cache_match = is_argtype_match(tuple_tfunc(given_argtypes[(nargs + 1):end]),
223223
cache_argtypes[end],
224224
cache_overridden_by_const[end])
225225
end

base/compiler/optimize.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ function stmt_effect_free(@nospecialize(stmt), @nospecialize(rt), src::Union{IRC
223223
rt ===&& return false
224224
return _builtin_nothrow(f, LatticeElement[argextype(args[i], src) for i = 2:length(args)], rt)
225225
elseif head === :new
226-
typ = unwraptype(argextype(args[1], src))
226+
typ = argextype(args[1], src)
227227
# `Expr(:new)` of unknown type could raise arbitrary TypeError.
228228
typ, isexact = instanceof_tfunc(typ)
229229
isexact || return false
@@ -240,7 +240,7 @@ function stmt_effect_free(@nospecialize(stmt), @nospecialize(rt), src::Union{IRC
240240
return foreigncall_effect_free(stmt, src)
241241
elseif head === :new_opaque_closure
242242
length(args) < 5 && return false
243-
typ = unwraptype(argextype(args[1], src))
243+
typ = argextype(args[1], src)
244244
typ, isexact = instanceof_tfunc(typ)
245245
isexact || return false
246246
typ Tuple || return false
@@ -350,7 +350,7 @@ function argextype(
350350
if x.head === :static_parameter
351351
return sptypes[x.args[1]::Int]
352352
elseif x.head === :boundscheck
353-
return NativeType(Bool)
353+
return LBool
354354
elseif x.head === :copyast
355355
return argextype(x.args[1], src, sptypes, slottypes)
356356
end
@@ -543,7 +543,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
543543
# insert a side-effect instruction before the current instruction in the same basic block
544544
insert!(code, idx, Expr(:code_coverage_effect))
545545
insert!(codelocs, idx, codeloc)
546-
insert!(ssavaluetypes, idx, NativeType(Nothing))
546+
insert!(ssavaluetypes, idx, LNothing)
547547
insert!(stmtinfo, idx, nothing)
548548
insert!(ssaflags, idx, IR_FLAG_NULL)
549549
changemap[oldidx] += 1
@@ -631,9 +631,8 @@ intrinsic_effect_free_if_nothrow(f) = f === Intrinsics.pointerref ||
631631
# saturating sum (inputs are nonnegative), prevents overflow with typemax(Int) below
632632
plus_saturate(x::Int, y::Int) = max(x, y, x+y)
633633

634-
# TODO (lattice overhaul) T::LatticeElement
635634
# known return type
636-
isknowntype(@nospecialize T) = (T === ⊥) || isConst(T) || isconcretetype(widenconst(T))
635+
isknowntype(T::LatticeElement) = (T === ⊥) || isConst(T) || isconcretetype(widenconst(T))
637636

638637
function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptypes::Argtypes,
639638
union_penalties::Bool, params::OptimizationParams, error_path::Bool = false)

base/compiler/ssair/inlining.jl

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
330330
push!(linetable, newentry)
331331
end
332332
if coverage && spec.ir.stmts[1][:line] + linetable_offset != topline
333-
insert_node_here!(compact, NewInstruction(Expr(:code_coverage_effect), Nothing, topline))
333+
insert_node_here!(compact, NewInstruction(Expr(:code_coverage_effect), LNothing, topline))
334334
end
335335
if def.isva
336336
nargs_def = Int(def.nargs::Int32)
@@ -400,7 +400,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
400400
inline_compact.result[idx′][:type] =
401401
argextype(val, isa(val, Expr) ? compact : inline_compact)
402402
insert_node_here!(inline_compact, NewInstruction(GotoNode(post_bb_id),
403-
Any, compact.result[idx′][:line]),
403+
, compact.result[idx′][:line]),
404404
true)
405405
push!(pn.values, SSAValue(idx′))
406406
else
@@ -443,11 +443,11 @@ function fix_va_argexprs!(compact::IncrementalCompact,
443443
argexprs::Vector{Any}, nargs_def::Int, line_idx::Int32)
444444
newargexprs = argexprs[1:(nargs_def-1)]
445445
tuple_call = Expr(:call, TOP_TUPLE)
446-
tuple_typs = Any[]
446+
tuple_typs = LatticeElement[]
447447
for i in nargs_def:length(argexprs)
448448
arg = argexprs[i]
449449
push!(tuple_call.args, arg)
450-
push!(tuple_typs, unwraptype(argextype(arg, compact)))
450+
push!(tuple_typs, argextype(arg, compact))
451451
end
452452
tuple_typ = tuple_tfunc(tuple_typs)
453453
push!(newargexprs, insert_node_here!(compact, NewInstruction(tuple_call, tuple_typ, line_idx)))
@@ -480,15 +480,15 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
480480
a <: m && continue
481481
# Generate isa check
482482
isa_expr = Expr(:call, isa, argexprs[i], m)
483-
ssa = insert_node_here!(compact, NewInstruction(isa_expr, Bool, line))
483+
ssa = insert_node_here!(compact, NewInstruction(isa_expr, LBool, line))
484484
if cond === true
485485
cond = ssa
486486
else
487487
and_expr = Expr(:call, and_int, cond, ssa)
488-
cond = insert_node_here!(compact, NewInstruction(and_expr, Bool, line))
488+
cond = insert_node_here!(compact, NewInstruction(and_expr, LBool, line))
489489
end
490490
end
491-
insert_node_here!(compact, NewInstruction(GotoIfNot(cond, next_cond_bb), Union{}, line))
491+
insert_node_here!(compact, NewInstruction(GotoIfNot(cond, next_cond_bb), , line))
492492
bb = next_cond_bb - 1
493493
finish_current_bb!(compact, 0)
494494
argexprs′ = argexprs
@@ -500,7 +500,7 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
500500
a, m = aparams[i], mparams[i]
501501
if !(a <: m)
502502
argexprs′[i] = insert_node_here!(compact,
503-
NewInstruction(PiNode(argex, m), m, line))
503+
NewInstruction(PiNode(argex, m), NativeType(m), line))
504504
end
505505
end
506506
end
@@ -517,25 +517,25 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
517517
push!(pn.edges, bb)
518518
push!(pn.values, val)
519519
insert_node_here!(compact,
520-
NewInstruction(GotoNode(join_bb), Union{}, line))
520+
NewInstruction(GotoNode(join_bb), , line))
521521
else
522522
insert_node_here!(compact,
523-
NewInstruction(ReturnNode(), Union{}, line))
523+
NewInstruction(ReturnNode(), , line))
524524
end
525525
finish_current_bb!(compact, 0)
526526
end
527527
bb += 1
528528
# We're now in the fall through block, decide what to do
529529
if fully_covered
530530
e = Expr(:call, GlobalRef(Core, :throw), FATAL_TYPE_BOUND_ERROR)
531-
insert_node_here!(compact, NewInstruction(e, Union{}, line))
532-
insert_node_here!(compact, NewInstruction(ReturnNode(), Union{}, line))
531+
insert_node_here!(compact, NewInstruction(e, , line))
532+
insert_node_here!(compact, NewInstruction(ReturnNode(), , line))
533533
finish_current_bb!(compact, 0)
534534
else
535535
ssa = insert_node_here!(compact, NewInstruction(stmt, typ, line))
536536
push!(pn.edges, bb)
537537
push!(pn.values, ssa)
538-
insert_node_here!(compact, NewInstruction(GotoNode(join_bb), Union{}, line))
538+
insert_node_here!(compact, NewInstruction(GotoNode(join_bb), , line))
539539
finish_current_bb!(compact, 0)
540540
end
541541

@@ -642,7 +642,7 @@ function rewrite_apply_exprargs!(
642642
if thisarginfo === nothing
643643
if isPartialStruct(def_type)
644644
# def_type.typ <: Tuple is assumed
645-
def_argtypes = LatticeElement[LatticeElement(t) for t in partialfields(def_type)]
645+
def_argtypes = partialfields(def_type)
646646
else
647647
def_argtypes = LatticeElement[]
648648
if isConst(def_type) # && isa(constant(def_type), Union{Tuple, SimpleVector}) is implied
@@ -699,15 +699,15 @@ function rewrite_apply_exprargs!(
699699
new_sig, istate, todo)
700700
end
701701
if i != length(thisarginfo.each)
702-
valT = getfield_tfunc(unwraptype(call.rt), Const(1))
702+
valT = getfield_tfunc(call.rt, Const(1))
703703
val_extracted = insert_node!(ir, idx, NewInstruction(
704704
Expr(:call, GlobalRef(Core, :getfield), state1, 1),
705705
valT))
706706
push!(new_argexprs, val_extracted)
707-
push!(new_argtypes, LatticeElement(valT))
707+
push!(new_argtypes, valT)
708708
state_extracted = insert_node!(ir, idx, NewInstruction(
709709
Expr(:call, GlobalRef(Core, :getfield), state1, 2),
710-
getfield_tfunc(unwraptype(call.rt), Const(2))))
710+
getfield_tfunc(call.rt, Const(2))))
711711
state = Core.svec(state_extracted)
712712
end
713713
end
@@ -892,19 +892,19 @@ function is_valid_type_for_apply_rewrite(typ::LatticeElement, params::Optimizati
892892
end
893893

894894
function inline_splatnew!(ir::IRCode, idx::Int, stmt::Expr, rt::LatticeElement)
895-
nf = nfields_tfunc(unwraptype(rt))
895+
nf = nfields_tfunc(rt)
896896
if isConst(nf)
897897
eargs = stmt.args
898898
tup = eargs[2]
899899
tt = argextype(tup, ir)
900-
tnf = nfields_tfunc(unwraptype(tt))
900+
tnf = nfields_tfunc(tt)
901901
# TODO: hoisting this constant(tnf) === constant(nf) check into codegen
902902
# would enable us to almost always do this transform
903903
if isConst(tnf) && constant(tnf) === constant(nf)
904904
n = constant(tnf)::Int
905905
new_argexprs = Any[eargs[1]]
906906
for j = 1:n
907-
atype = getfield_tfunc(unwraptype(tt), Const(j))
907+
atype = getfield_tfunc(tt, Const(j))
908908
new_call = Expr(:call, Core.getfield, tup, j)
909909
new_argexpr = insert_node!(ir, idx, NewInstruction(new_call, atype))
910910
push!(new_argexprs, new_argexpr)
@@ -1036,14 +1036,14 @@ end
10361036
function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), state::InliningState)
10371037
if isa(info, OpaqueClosureCreateInfo)
10381038
lbt = argextype(stmt.args[3], ir)
1039-
lb, exact = instanceof_tfunc(unwraptype(lbt))
1039+
lb, exact = instanceof_tfunc(lbt)
10401040
exact || return
10411041
ubt = argextype(stmt.args[4], ir)
1042-
ub, exact = instanceof_tfunc(unwraptype(ubt))
1042+
ub, exact = instanceof_tfunc(ubt)
10431043
exact || return
10441044
# Narrow opaque closure type
1045-
newT = widenconst(tmeet(tmerge(lb, info.unspec.rt), ub))
1046-
if newT != ub
1045+
newT = widenconst(tmerge(lb, info.unspec.rt) ub)
1046+
if newT !== ub
10471047
# N.B.: Narrowing the ub requires a backdge on the mi whose type
10481048
# information we're using, since a change in that function may
10491049
# invalidate ub result.
@@ -1434,7 +1434,7 @@ function late_inline_special_case!(
14341434
return SomeCase(quoted(constant(type)))
14351435
end
14361436
cmp_call = Expr(:call, GlobalRef(Core, :(===)), stmt.args[2], stmt.args[3])
1437-
cmp_call_ssa = insert_node!(ir, idx, effect_free(NewInstruction(cmp_call, Bool)))
1437+
cmp_call_ssa = insert_node!(ir, idx, effect_free(NewInstruction(cmp_call, LBool)))
14381438
not_call = Expr(:call, GlobalRef(Core.Intrinsics, :not_int), cmp_call_ssa)
14391439
return SomeCase(not_call)
14401440
elseif isinlining && length(argtypes) == 3 && istopfunction(f, :(>:))

base/compiler/ssair/ir.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,17 @@ struct NewInstruction
166166
# Don't bother redoing so on insertion.
167167
effect_free_computed::Bool
168168

169-
function NewInstruction(@nospecialize(stmt), @nospecialize(type), @nospecialize(info),
169+
function NewInstruction(@nospecialize(stmt), type::LatticeElement, @nospecialize(info),
170170
line::Union{Int32, Nothing}, flag::UInt8, effect_free_computed::Bool)
171171
if isa(type, Type)
172172
type = NativeType(type)
173173
end
174174
return new(stmt, type, info, line, flag, effect_free_computed)
175175
end
176176
end
177-
NewInstruction(@nospecialize(stmt), @nospecialize(type)) =
177+
NewInstruction(@nospecialize(stmt), type::LatticeElement) =
178178
NewInstruction(stmt, type, nothing)
179-
NewInstruction(@nospecialize(stmt), @nospecialize(type), line::Union{Nothing, Int32}) =
179+
NewInstruction(@nospecialize(stmt), type::LatticeElement, line::Union{Nothing, Int32}) =
180180
NewInstruction(stmt, type, nothing, line, IR_FLAG_NULL, false)
181181

182182
effect_free(inst::NewInstruction) =
@@ -1163,7 +1163,7 @@ function finish_current_bb!(compact::IncrementalCompact, active_bb, old_result_i
11631163
if unreachable
11641164
node[:inst], node[:type], node[:line] = ReturnNode(), ⊥, 0
11651165
else
1166-
node[:inst], node[:type], node[:line] = nothing, NativeType(Nothing), 0
1166+
node[:inst], node[:type], node[:line] = nothing, LNothing, 0
11671167
end
11681168
compact.result_idx = old_result_idx + 1
11691169
elseif compact.cfg_transforms_enabled && compact.result_idx - 1 == first(bb.stmts)

0 commit comments

Comments
 (0)