Skip to content

Commit 723ed65

Browse files
committed
lattice overhaul: clean up
1 parent 661fe42 commit 723ed65

File tree

22 files changed

+167
-188
lines changed

22 files changed

+167
-188
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ call_result_unused(frame::InferenceState) =
1919
isexpr(frame.src.code[frame.currpc], :call) && isempty(frame.ssavalue_uses[frame.currpc])
2020

2121
function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
22-
fargs::Union{Nothing,Vector{Any}}, argtypes::Vector{AbstractLattice}, @nospecialize(atype),
22+
fargs::Union{Nothing,Vector{Any}}, argtypes::Lattices, @nospecialize(atype),
2323
sv::InferenceState, max_methods::Int = InferenceParams(interp).MAX_METHODS)
2424
if sv.params.unoptimize_throw_blocks && is_stmt_throw_block(get_curr_ssaflag(sv))
2525
add_remark!(interp, sv, "Skipped call in throw block")
@@ -238,26 +238,26 @@ end
238238

239239
struct UnionSplitMethodMatches
240240
applicable::Vector{Any}
241-
applicable_argtypes::Vector{Vector{AbstractLattice}}
241+
applicable_argtypes::Vector{Lattices}
242242
info::UnionSplitInfo
243243
valid_worlds::WorldRange
244244
mts::Vector{Core.MethodTable}
245245
fullmatches::Vector{Bool}
246246
end
247247

248-
function find_matching_methods(argtypes::Vector{AbstractLattice}, @nospecialize(atype), method_table::MethodTableView,
248+
function find_matching_methods(argtypes::Lattices, @nospecialize(atype), method_table::MethodTableView,
249249
union_split::Int, max_methods::Int)
250250
# NOTE this is valid as far as any "constant" lattice element doesn't represent `Union` type
251251
if 1 < unionsplitcost(argtypes) <= union_split
252252
split_argtypes = switchtupleunion(argtypes)
253253
infos = MethodMatchInfo[]
254254
applicable = Any[]
255-
applicable_argtypes = Vector{AbstractLattice}[] # arrays like `argtypes`, including constants, for each match
255+
applicable_argtypes = Lattices[] # arrays like `argtypes`, including constants, for each match
256256
valid_worlds = WorldRange()
257257
mts = Core.MethodTable[]
258258
fullmatches = Bool[]
259259
for i in 1:length(split_argtypes)
260-
arg_n = split_argtypes[i]::Vector{AbstractLattice}
260+
arg_n = split_argtypes[i]::Lattices
261261
sig_n = argtypes_to_type(arg_n)
262262
mt = ccall(:jl_method_table_for, Any, (Any,), sig_n)
263263
mt === nothing && return FailedMethodMatch("Could not identify method table for call")
@@ -517,7 +517,7 @@ struct MethodCallResult
517517
end
518518

519519
function abstract_call_method_with_const_args(interp::AbstractInterpreter, result::MethodCallResult,
520-
@nospecialize(f), argtypes::Vector{AbstractLattice}, match::MethodMatch,
520+
@nospecialize(f), argtypes::Lattices, match::MethodMatch,
521521
sv::InferenceState, va_override::Bool)
522522
mi = maybe_get_const_prop_profitable(interp, result, f, argtypes, match, sv)
523523
mi === nothing && return nothing
@@ -559,7 +559,7 @@ end
559559
# if there's a possibility we could get a better result (hopefully without doing too much work)
560560
# returns `MethodInstance` with constant arguments, returns nothing otherwise
561561
function maybe_get_const_prop_profitable(interp::AbstractInterpreter, result::MethodCallResult,
562-
@nospecialize(f), argtypes::Vector{AbstractLattice}, match::MethodMatch,
562+
@nospecialize(f), argtypes::Lattices, match::MethodMatch,
563563
sv::InferenceState)
564564
if !InferenceParams(interp).ipo_constant_propagation
565565
add_remark!(interp, sv, "[constprop] Disabled by parameter")
@@ -621,7 +621,7 @@ end
621621
end
622622

623623
# see if propagating constants may be worthwhile
624-
function const_prop_argument_heuristic(interp::AbstractInterpreter, argtypes::Vector{AbstractLattice})
624+
function const_prop_argument_heuristic(interp::AbstractInterpreter, argtypes::Lattices)
625625
for a in argtypes
626626
a = widenconditional(a)
627627
if has_nontrivial_const_info(a) && is_const_prop_profitable_arg(a)
@@ -650,7 +650,7 @@ end
650650
return improvable_via_constant_propagation(rettype)
651651
end
652652

653-
function is_allconst(argtypes::Vector{AbstractLattice})
653+
function is_allconst(argtypes::Lattices)
654654
for a in argtypes
655655
a = widenconditional(a)
656656
if !isConst(a) && !isconstType(widenconst(a)) && !isPartialStruct(a) && !isPartialOpaque(a)
@@ -667,7 +667,7 @@ function force_const_prop(interp::AbstractInterpreter, @nospecialize(f), method:
667667
istopfunction(f, :setproperty!)
668668
end
669669

670-
function const_prop_function_heuristic(interp::AbstractInterpreter, @nospecialize(f), argtypes::Vector{AbstractLattice}, nargs::Int, allconst::Bool)
670+
function const_prop_function_heuristic(interp::AbstractInterpreter, @nospecialize(f), argtypes::Lattices, nargs::Int, allconst::Bool)
671671
if nargs > 1
672672
if istopfunction(f, :getindex) || istopfunction(f, :setindex!)
673673
arrty = unwraptype(argtypes[2])
@@ -709,7 +709,7 @@ end
709709
# result anyway.
710710
function const_prop_methodinstance_heuristic(
711711
interp::AbstractInterpreter, match::MethodMatch, mi::MethodInstance,
712-
argtypes::Vector{AbstractLattice}, sv::InferenceState)
712+
argtypes::Lattices, sv::InferenceState)
713713
method = match.method
714714
if method.is_for_opaque_closure
715715
# Not inlining an opaque closure can be very expensive, so be generous
@@ -920,7 +920,7 @@ end
920920
end
921921

922922
# do apply(af, fargs...), where af is a function value
923-
function abstract_apply(interp::AbstractInterpreter, argtypes::Vector{AbstractLattice}, sv::InferenceState,
923+
function abstract_apply(interp::AbstractInterpreter, argtypes::Lattices, sv::InferenceState,
924924
max_methods::Int = InferenceParams(interp).MAX_METHODS)
925925
itft = argtype_by_index(argtypes, 2)
926926
aft = argtype_by_index(argtypes, 3)
@@ -1030,7 +1030,7 @@ function is_method_pure(method::Method, @nospecialize(sig), sparams::SimpleVecto
10301030
end
10311031
is_method_pure(match::MethodMatch) = is_method_pure(match.method, match.spec_types, match.sparams)
10321032

1033-
function pure_eval_call(@nospecialize(f), argtypes::Vector{AbstractLattice})
1033+
function pure_eval_call(@nospecialize(f), argtypes::Lattices)
10341034
for i = 2:length(argtypes)
10351035
a = widenconditional(argtypes[i])
10361036
if !(isConst(a) || isconstType(widenconst(a)))
@@ -1047,7 +1047,7 @@ function pure_eval_call(@nospecialize(f), argtypes::Vector{AbstractLattice})
10471047
end
10481048
end
10491049

1050-
function argtype_by_index(argtypes::Vector{AbstractLattice}, i::Int)
1050+
function argtype_by_index(argtypes::Lattices, i::Int)
10511051
n = length(argtypes)
10521052
na = unwraptype(argtypes[n])
10531053
if isvarargtype(na)
@@ -1057,7 +1057,7 @@ function argtype_by_index(argtypes::Vector{AbstractLattice}, i::Int)
10571057
end
10581058
end
10591059

1060-
function argtype_tail(argtypes::Vector{AbstractLattice}, i::Int)
1060+
function argtype_tail(argtypes::Lattices, i::Int)
10611061
n = length(argtypes)
10621062
if isvarargtype(unwraptype(argtypes[n])) && i > n
10631063
i = n
@@ -1066,7 +1066,7 @@ function argtype_tail(argtypes::Vector{AbstractLattice}, i::Int)
10661066
end
10671067

10681068
@latticeop ret function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, fargs::Union{Nothing,Vector{Any}},
1069-
argtypes::Vector{AbstractLattice}, sv::InferenceState, max_methods::Int)
1069+
argtypes::Lattices, sv::InferenceState, max_methods::Int)
10701070
@nospecialize f
10711071
la = length(argtypes)
10721072
if f === ifelse && fargs isa Vector{Any} && la == 4
@@ -1167,7 +1167,7 @@ end
11671167
return isa(rt, TypeVar) ? NativeType(rt.ub) : TypeLattice(rt)
11681168
end
11691169

1170-
@latticeop ret function abstract_call_unionall(argtypes::Vector{AbstractLattice})
1170+
@latticeop ret function abstract_call_unionall(argtypes::Lattices)
11711171
if length(argtypes) == 3
11721172
canconst = true
11731173
a3 = argtypes[3]
@@ -1201,7 +1201,7 @@ end
12011201
return
12021202
end
12031203

1204-
function abstract_invoke(interp::AbstractInterpreter, argtypes::Vector{AbstractLattice}, sv::InferenceState)
1204+
function abstract_invoke(interp::AbstractInterpreter, argtypes::Lattices, sv::InferenceState)
12051205
ft′ = argtype_by_index(argtypes, 2)
12061206
ft = widenconst(ft′)
12071207
ft === Bottom && return CallMeta(⊥, false)
@@ -1248,7 +1248,7 @@ end
12481248

12491249
# call where the function is known exactly
12501250
function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
1251-
fargs::Union{Nothing,Vector{Any}}, argtypes::Vector{AbstractLattice},
1251+
fargs::Union{Nothing,Vector{Any}}, argtypes::Lattices,
12521252
sv::InferenceState,
12531253
max_methods::Int = InferenceParams(interp).MAX_METHODS)
12541254

@@ -1344,7 +1344,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
13441344
return abstract_call_gf_by_type(interp, f, fargs, argtypes, atype, sv, max_methods)
13451345
end
13461346

1347-
function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::PartialOpaque, argtypes::Vector{AbstractLattice}, sv::InferenceState)
1347+
function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::PartialOpaque, argtypes::Lattices, sv::InferenceState)
13481348
pushfirst!(argtypes, TypeLattice(closure.env))
13491349
sig = argtypes_to_type(argtypes)
13501350
(; rt, edge) = result = abstract_call_method(interp, closure.source, sig, Core.svec(), false, sv)
@@ -1376,7 +1376,7 @@ function most_general_argtypes(closure::PartialOpaque)
13761376
end
13771377

13781378
# call where the function is any lattice element
1379-
function abstract_call(interp::AbstractInterpreter, fargs::Union{Nothing,Vector{Any}}, argtypes::Vector{AbstractLattice},
1379+
function abstract_call(interp::AbstractInterpreter, fargs::Union{Nothing,Vector{Any}}, argtypes::Lattices,
13801380
sv::InferenceState, max_methods::Int = InferenceParams(interp).MAX_METHODS)
13811381
#print("call ", e.args[1], argtypes, "\n\n")
13821382
ft = argtypes[1]
@@ -1489,7 +1489,7 @@ end
14891489

14901490
function collect_argtypes(interp::AbstractInterpreter, ea::Vector{Any}, vtypes::VarTable, sv::InferenceState)
14911491
n = length(ea)
1492-
argtypes = Vector{AbstractLattice}(undef, n)
1492+
argtypes = Lattices(undef, n)
14931493
@inbounds for i = 1:n
14941494
ai = abstract_eval_value(interp, ea[i], vtypes, sv)
14951495
if ai ===
@@ -1677,7 +1677,7 @@ end
16771677
return typ
16781678
end
16791679

1680-
@latticeop op function widenreturn(@nospecialize(rt), @nospecialize(bestguess), nslots::Int, slottypes::Vector{AbstractLattice}, changes::VarTable)
1680+
@latticeop op function widenreturn(@nospecialize(rt), @nospecialize(bestguess), nslots::Int, slottypes::Lattices, changes::VarTable)
16811681
if !(bestguess Bool) || unwraptype(bestguess) === Bool
16821682
# give up inter-procedural constraint back-propagation
16831683
# when tmerge would widen the result anyways (as an optimization)
@@ -1992,7 +1992,7 @@ end
19921992
return changes
19931993
end
19941994

1995-
@latticeop op function bool_rt_to_conditional(@nospecialize(rt), slottypes::Vector{AbstractLattice}, state::VarTable, slot_id::Int)
1995+
@latticeop op function bool_rt_to_conditional(@nospecialize(rt), slottypes::Lattices, state::VarTable, slot_id::Int)
19961996
old = slottypes[slot_id]
19971997
new = widenconditional(state[slot_id].typ) # avoid nested conditional
19981998
if new old && !(old new)

base/compiler/compiler.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ abstract type _AbstractLattice end
117117
const AbstractLattice = Union{
118118
TypeofVararg,
119119
_AbstractLattice}
120+
const Lattices = Vector{AbstractLattice}
120121

121122
macro latticeop(mode, def)
122123
@assert is_function_def(def)
@@ -138,7 +139,7 @@ macro latticeop(mode, def)
138139
end
139140
return esc(Expr(def.head, sig, body))
140141
end
141-
anymap(f::Function, a::Vector{AbstractLattice}) = Any[ f(a[i]) for i in 1:length(a) ]
142+
anymap(f::Function, a::Lattices) = Any[ f(a[i]) for i in 1:length(a) ]
142143

143144
include("compiler/cicache.jl")
144145
include("compiler/types.jl")

base/compiler/inferenceresult.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ 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{AbstractLattice}, va_override::Bool)
16+
function matching_cache_argtypes(linfo::MethodInstance, given_argtypes::Lattices, va_override::Bool)
1717
@assert isa(linfo.def, Method) # ensure the next line works
1818
nargs::Int = linfo.def.nargs
1919
given_argtypes = AbstractLattice[widenconditional(a) for a in given_argtypes]
@@ -56,7 +56,7 @@ function most_general_argtypes(method::Union{Method, Nothing}, @nospecialize(spe
5656
# For opaque closure, the closure environment is processed elsewhere
5757
nargs -= 1
5858
end
59-
cache_argtypes = Vector{AbstractLattice}(undef, nargs)
59+
cache_argtypes = Lattices(undef, nargs)
6060
# First, if we're dealing with a varargs method, then we set the last element of `args`
6161
# to the appropriate `Tuple` type or `PartialStruct` instance.
6262
if !toplevel && isva
@@ -141,7 +141,7 @@ function matching_cache_argtypes(linfo::MethodInstance, ::Nothing, va_override::
141141
return cache_argtypes, falses(length(cache_argtypes))
142142
end
143143

144-
function cache_lookup(linfo::MethodInstance, given_argtypes::Vector{AbstractLattice}, cache::Vector{InferenceResult})
144+
function cache_lookup(linfo::MethodInstance, given_argtypes::Lattices, cache::Vector{InferenceResult})
145145
method = linfo.def::Method
146146
nargs::Int = method.nargs
147147
method.isva && (nargs -= 1)

base/compiler/inferencestate.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ mutable struct InferenceState
2424
params::InferenceParams
2525
result::InferenceResult # remember where to put the result
2626
linfo::MethodInstance
27-
sptypes::Vector{AbstractLattice} # types of static parameter
28-
slottypes::Vector{AbstractLattice}
27+
sptypes::Lattices # types of static parameter
28+
slottypes::Lattices
2929
mod::Module
3030
currpc::LineNum
3131
pclimitations::IdSet{InferenceState} # causes of precision restrictions (LimitedAccuracy) on currpc ssavalue
@@ -79,7 +79,7 @@ mutable struct InferenceState
7979
sp = sptypes_from_meth_instance(linfo::MethodInstance)
8080

8181
nssavalues = src.ssavaluetypes::Int
82-
# NOTE we can't initialize `src.ssavaluetypes` as `Vector{AbstractLattice}` to avoid
82+
# NOTE we can't initialize `src.ssavaluetypes` as `Lattices` to avoid
8383
# an allocation within `ir_to_codeinf!(src)` where we widen all ssavaluetypes to native Julia types
8484
src.ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ]
8585
stmt_info = Any[ nothing for i = 1:length(code) ]
@@ -93,7 +93,7 @@ mutable struct InferenceState
9393
argtypes = result.argtypes
9494
nargs = length(argtypes)
9595
s_argtypes = VarTable(undef, nslots)
96-
slottypes = Vector{AbstractLattice}(undef, nslots)
96+
slottypes = Lattices(undef, nslots)
9797
for i in 1:nslots
9898
at = (i > nargs) ?: TypeLattice(argtypes[i])
9999
s_argtypes[i] = VarState(at, i > nargs)

base/compiler/optimize.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct InliningState{S <: Union{EdgeTracker, Nothing}, T, I<:AbstractInterpreter
2929
end
3030

3131
function inlining_policy(interp::AbstractInterpreter, @nospecialize(src), stmt_flag::UInt8,
32-
mi::MethodInstance, argtypes::Vector{AbstractLattice})
32+
mi::MethodInstance, argtypes::Lattices)
3333
if isa(src, CodeInfo) || isa(src, Vector{UInt8})
3434
src_inferred = ccall(:jl_ir_flag_inferred, Bool, (Any,), src)
3535
src_inlineable = is_stmt_inline(stmt_flag) || ccall(:jl_ir_flag_inlineable, Bool, (Any,), src)
@@ -63,8 +63,8 @@ mutable struct OptimizationState
6363
ir::Union{Nothing, IRCode}
6464
stmt_info::Vector{Any}
6565
mod::Module
66-
sptypes::Vector{AbstractLattice} # static parameters
67-
slottypes::Vector{AbstractLattice}
66+
sptypes::Lattices # static parameters
67+
slottypes::Lattices
6868
const_api::Bool
6969
inlining::InliningState
7070
function OptimizationState(frame::InferenceState, params::OptimizationParams, interp::AbstractInterpreter)
@@ -395,7 +395,7 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, sv::
395395
end
396396
strip_trailing_junk!(ci, code, stmtinfo)
397397
cfg = compute_basic_blocks(code)
398-
types = AbstractLattice[]
398+
types = Lattices()
399399
stmts = InstructionStream(code, types, stmtinfo, codelocs, ssaflags)
400400
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable::Union{Vector{LineInfoNode},Vector{Any}}), sv.slottypes, meta, sv.sptypes)
401401
return ir
@@ -447,8 +447,8 @@ plus_saturate(x::Int, y::Int) = max(x, y, x+y)
447447
# known return type
448448
isknowntype(@nospecialize T) = (T === ⊥) || isConst(T) || isconcretetype(widenconst(T))
449449

450-
function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptypes::Vector{AbstractLattice},
451-
slottypes::Vector{AbstractLattice}, union_penalties::Bool,
450+
function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptypes::Lattices,
451+
slottypes::Lattices, union_penalties::Bool,
452452
params::OptimizationParams, error_path::Bool = false)
453453
head = ex.head
454454
if is_meta_expr_head(head)
@@ -539,8 +539,8 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp
539539
return 0
540540
end
541541

542-
function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{CodeInfo, IRCode}, sptypes::Vector{AbstractLattice},
543-
slottypes::Vector{AbstractLattice}, union_penalties::Bool, params::OptimizationParams)
542+
function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{CodeInfo, IRCode}, sptypes::Lattices,
543+
slottypes::Lattices, union_penalties::Bool, params::OptimizationParams)
544544
thiscost = 0
545545
dst(tgt) = isa(src, IRCode) ? first(src.cfg.blocks[tgt].stmts) : tgt
546546
if stmt isa Expr
@@ -569,7 +569,7 @@ function inline_worthy(ir::IRCode,
569569
return true
570570
end
571571

572-
function statement_costs!(cost::Vector{Int}, body::Vector{Any}, src::Union{CodeInfo, IRCode}, sptypes::Vector{AbstractLattice}, unionpenalties::Bool, params::OptimizationParams)
572+
function statement_costs!(cost::Vector{Int}, body::Vector{Any}, src::Union{CodeInfo, IRCode}, sptypes::Lattices, unionpenalties::Bool, params::OptimizationParams)
573573
maxcost = 0
574574
for line = 1:length(body)
575575
stmt = body[line]
@@ -584,7 +584,7 @@ function statement_costs!(cost::Vector{Int}, body::Vector{Any}, src::Union{CodeI
584584
return maxcost
585585
end
586586

587-
function is_known_call(e::Expr, @nospecialize(func), src, sptypes::Vector{AbstractLattice}, slottypes::Vector{AbstractLattice} = empty_slottypes)
587+
function is_known_call(e::Expr, @nospecialize(func), src, sptypes::Lattices, slottypes::Lattices = empty_slottypes)
588588
if e.head !== :call
589589
return false
590590
end

0 commit comments

Comments
 (0)