Skip to content

Commit 5905386

Browse files
committed
WIP: Semi-concrete IR interpreter
1 parent 28f58e7 commit 5905386

File tree

17 files changed

+695
-175
lines changed

17 files changed

+695
-175
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 154 additions & 117 deletions
Large diffs are not rendered by default.

base/compiler/compiler.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ include("compiler/methodtable.jl")
131131
include("compiler/inferenceresult.jl")
132132
include("compiler/inferencestate.jl")
133133

134+
include("compiler/ssair/basicblock.jl")
135+
include("compiler/ssair/domtree.jl")
136+
include("compiler/ssair/ir.jl")
137+
134138
include("compiler/typeutils.jl")
135139
include("compiler/typelimits.jl")
136140
include("compiler/typelattice.jl")
@@ -139,7 +143,7 @@ include("compiler/stmtinfo.jl")
139143

140144
include("compiler/abstractinterpretation.jl")
141145
include("compiler/typeinfer.jl")
142-
include("compiler/optimize.jl") # TODO: break this up further + extract utilities
146+
include("compiler/optimize.jl")
143147

144148
# required for bootstrap
145149
# TODO: find why this is needed and remove it.

base/compiler/inferenceresult.jl

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,36 @@ function is_forwardable_argtype(@nospecialize x)
1616
isa(x, PartialOpaque)
1717
end
1818

19+
function va_process_argtypes(given_argtypes::Vector{Any}, mi::MethodInstance,
20+
condargs::Union{Vector{Tuple{Int,Int}}, Nothing}=nothing)
21+
isva = mi.def.isva
22+
nargs = Int(mi.def.nargs)
23+
if isva || isvarargtype(given_argtypes[end])
24+
isva_given_argtypes = Vector{Any}(undef, nargs)
25+
for i = 1:(nargs - isva)
26+
isva_given_argtypes[i] = argtype_by_index(given_argtypes, i)
27+
end
28+
if isva
29+
if length(given_argtypes) < nargs && isvarargtype(given_argtypes[end])
30+
last = length(given_argtypes)
31+
else
32+
last = nargs
33+
end
34+
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
35+
# invalidate `Conditional` imposed on varargs
36+
if condargs !== nothing
37+
for (slotid, i) in condargs
38+
if slotid last
39+
isva_given_argtypes[i] = widenconditional(isva_given_argtypes[i])
40+
end
41+
end
42+
end
43+
end
44+
return isva_given_argtypes
45+
end
46+
return given_argtypes
47+
end
48+
1949
# In theory, there could be a `cache` containing a matching `InferenceResult`
2050
# for the provided `linfo` and `given_argtypes`. The purpose of this function is
2151
# to return a valid value for `cache_lookup(linfo, argtypes, cache).argtypes`,
@@ -55,30 +85,7 @@ function matching_cache_argtypes(
5585
end
5686
given_argtypes[i] = widenconditional(argtype)
5787
end
58-
isva = linfo.def.isva
59-
if isva || isvarargtype(given_argtypes[end])
60-
isva_given_argtypes = Vector{Any}(undef, nargs)
61-
for i = 1:(nargs - isva)
62-
isva_given_argtypes[i] = argtype_by_index(given_argtypes, i)
63-
end
64-
if isva
65-
if length(given_argtypes) < nargs && isvarargtype(given_argtypes[end])
66-
last = length(given_argtypes)
67-
else
68-
last = nargs
69-
end
70-
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
71-
# invalidate `Conditional` imposed on varargs
72-
if condargs !== nothing
73-
for (slotid, i) in condargs
74-
if slotid last
75-
isva_given_argtypes[i] = widenconditional(isva_given_argtypes[i])
76-
end
77-
end
78-
end
79-
end
80-
given_argtypes = isva_given_argtypes
81-
end
88+
given_argtypes = va_process_argtypes(given_argtypes, linfo, condargs)
8289
@assert length(given_argtypes) == nargs
8390
for i in 1:nargs
8491
given_argtype = given_argtypes[i]

base/compiler/inferencestate.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ function in(idx::Int, bsbmp::BitSetBoundedMinPrioritySet)
8282
return idx in bsbmp.elems
8383
end
8484

85+
function append!(bsbmp::BitSetBoundedMinPrioritySet, itr)
86+
for val in itr
87+
push!(bsbmp, val)
88+
end
89+
end
90+
8591
mutable struct InferenceState
8692
params::InferenceParams
8793
result::InferenceResult # remember where to put the result

base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import Core.Compiler: # Core.Compiler specific definitions
3131
isbitstype, isexpr, is_meta_expr_head, println, widenconst, argextype, singleton_type,
3232
fieldcount_noerror, try_compute_field, try_compute_fieldidx, hasintersect, ,
3333
intrinsic_nothrow, array_builtin_common_typecheck, arrayset_typecheck,
34-
setfield!_nothrow, alloc_array_ndims, stmt_effect_free, check_effect_free!
34+
setfield!_nothrow, alloc_array_ndims, stmt_effect_free, check_effect_free!,
35+
SemiConcreteResult
3536

3637
include(x) = _TOP_MOD.include(@__MODULE__, x)
3738
if _TOP_MOD === Core.Compiler

base/compiler/ssair/EscapeAnalysis/interprocedural.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Core.Compiler:
66
call_sig, argtypes_to_type, is_builtin, is_return_type, istopfunction, validate_sparams,
77
specialize_method, invoke_rewrite
88

9-
const Linfo = Union{MethodInstance,InferenceResult}
9+
const Linfo = Union{MethodInstance,InferenceResult,SemiConcreteResult}
1010
struct CallInfo
1111
linfos::Vector{Linfo}
1212
nothrow::Bool

base/compiler/ssair/driver.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ function stmt_effect_free end # imported by EscapeAnalysis
1313
function alloc_array_ndims end # imported by EscapeAnalysis
1414
function try_compute_field end # imported by EscapeAnalysis
1515

16-
include("compiler/ssair/basicblock.jl")
17-
include("compiler/ssair/domtree.jl")
18-
include("compiler/ssair/ir.jl")
1916
include("compiler/ssair/slot2ssa.jl")
2017
include("compiler/ssair/inlining.jl")
2118
include("compiler/ssair/verify.jl")
2219
include("compiler/ssair/legacy.jl")
2320
include("compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl")
2421
include("compiler/ssair/passes.jl")
22+
include("compiler/ssair/irinterp.jl")

base/compiler/ssair/inlining.jl

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,8 @@ function handle_const_call!(
12811281
push!(cases, InliningCase(result.mi.specTypes, case))
12821282
elseif isa(result, InferenceResult)
12831283
handled_all_cases &= handle_inf_result!(result, argtypes, flag, state, cases)
1284+
elseif isa(result, SemiConcreteResult)
1285+
handled_all_cases &= handle_semi_concrete_result!(result, cases)
12841286
else
12851287
@assert result === nothing
12861288
handled_all_cases &= handle_match!(match, argtypes, flag, state, cases)
@@ -1294,8 +1296,13 @@ function handle_const_call!(
12941296
if length(cases) == 0
12951297
length(results) == 1 || return nothing
12961298
result = results[1]
1297-
isa(result, InferenceResult) || return nothing
1298-
handle_inf_result!(result, argtypes, flag, state, cases, true) || return nothing
1299+
if isa(result, InferenceResult)
1300+
handle_inf_result!(result, argtypes, flag, state, cases, true) || return nothing
1301+
elseif isa(result, SemiConcreteResult)
1302+
handle_semi_concrete_result!(result, cases) || return nothing
1303+
else
1304+
return nothing
1305+
end
12991306
spec_types = cases[1].sig
13001307
any_covers_full = handled_all_cases = atype <: spec_types
13011308
end
@@ -1328,6 +1335,15 @@ function handle_inf_result!(
13281335
return true
13291336
end
13301337

1338+
function handle_semi_concrete_result!(result::SemiConcreteResult, cases::Vector{InliningCase}, allow_abstract::Bool = false)
1339+
mi = result.mi
1340+
spec_types = mi.specTypes
1341+
allow_abstract || isdispatchtuple(spec_types) || return false
1342+
validate_sparams(mi.sparam_vals) || return false
1343+
push!(cases, InliningCase(spec_types, InliningTodo(mi, result.ir, result.effects)))
1344+
return true
1345+
end
1346+
13311347
function const_result_item(result::ConstResult, state::InliningState)
13321348
if !isdefined(result, :result) || !is_inlineable_constant(result.result)
13331349
return compileable_specialization(state.et, result.mi, EFFECTS_TOTAL)

base/compiler/ssair/ir.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,15 +1030,22 @@ function renumber_ssa2!(@nospecialize(stmt), ssanums::Vector{Any}, used_ssas::Ve
10301030
end
10311031

10321032
# Used in inlining before we start compacting - Only works at the CFG level
1033-
function kill_edge!(bbs::Vector{BasicBlock}, from::Int, to::Int)
1033+
function kill_edge!(bbs::Vector{BasicBlock}, from::Int, to::Int, callback=nothing)
10341034
preds, succs = bbs[to].preds, bbs[from].succs
10351035
deleteat!(preds, findfirst(x->x === from, preds)::Int)
10361036
deleteat!(succs, findfirst(x->x === to, succs)::Int)
10371037
if length(preds) == 0
10381038
for succ in copy(bbs[to].succs)
1039-
kill_edge!(bbs, to, succ)
1039+
kill_edge!(bbs, to, succ, callback)
10401040
end
10411041
end
1042+
if callback !== nothing
1043+
callback(from, to)
1044+
end
1045+
end
1046+
1047+
function kill_edge!(ir::IRCode, from::Int, to::Int, callback=nothing)
1048+
kill_edge!(ir.cfg.blocks, from, to, callback)
10421049
end
10431050

10441051
# N.B.: from and to are non-renamed indices

0 commit comments

Comments
 (0)