Skip to content

Commit

Permalink
WIP: Semi-concrete IR interpreter
Browse files Browse the repository at this point in the history
Co-authored-by: Ian Atol <[email protected]>
Co-authored-by: Shuhei Kadowaki <[email protected]>
  • Loading branch information
3 people committed Apr 11, 2022
1 parent 0deb326 commit ed737ad
Show file tree
Hide file tree
Showing 17 changed files with 700 additions and 182 deletions.
298 changes: 171 additions & 127 deletions base/compiler/abstractinterpretation.jl

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ include("compiler/methodtable.jl")
include("compiler/inferenceresult.jl")
include("compiler/inferencestate.jl")

include("compiler/ssair/basicblock.jl")
include("compiler/ssair/domtree.jl")
include("compiler/ssair/ir.jl")

include("compiler/typeutils.jl")
include("compiler/typelimits.jl")
include("compiler/typelattice.jl")
Expand All @@ -139,7 +143,7 @@ include("compiler/stmtinfo.jl")

include("compiler/abstractinterpretation.jl")
include("compiler/typeinfer.jl")
include("compiler/optimize.jl") # TODO: break this up further + extract utilities
include("compiler/optimize.jl")

# required for bootstrap
# TODO: find why this is needed and remove it.
Expand Down
55 changes: 31 additions & 24 deletions base/compiler/inferenceresult.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@ function is_forwardable_argtype(@nospecialize x)
isa(x, PartialOpaque)
end

function va_process_argtypes(given_argtypes::Vector{Any}, mi::MethodInstance,
condargs::Union{Vector{Tuple{Int,Int}}, Nothing}=nothing)
isva = mi.def.isva
nargs = Int(mi.def.nargs)
if isva || isvarargtype(given_argtypes[end])
isva_given_argtypes = Vector{Any}(undef, nargs)
for i = 1:(nargs - isva)
isva_given_argtypes[i] = argtype_by_index(given_argtypes, i)
end
if isva
if length(given_argtypes) < nargs && isvarargtype(given_argtypes[end])
last = length(given_argtypes)
else
last = nargs
end
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
# invalidate `Conditional` imposed on varargs
if condargs !== nothing
for (slotid, i) in condargs
if slotid last
isva_given_argtypes[i] = widenconditional(isva_given_argtypes[i])
end
end
end
end
return isva_given_argtypes
end
return given_argtypes
end

# In theory, there could be a `cache` containing a matching `InferenceResult`
# for the provided `linfo` and `given_argtypes`. The purpose of this function is
# to return a valid value for `cache_lookup(linfo, argtypes, cache).argtypes`,
Expand Down Expand Up @@ -55,30 +85,7 @@ function matching_cache_argtypes(
end
given_argtypes[i] = widenconditional(argtype)
end
isva = linfo.def.isva
if isva || isvarargtype(given_argtypes[end])
isva_given_argtypes = Vector{Any}(undef, nargs)
for i = 1:(nargs - isva)
isva_given_argtypes[i] = argtype_by_index(given_argtypes, i)
end
if isva
if length(given_argtypes) < nargs && isvarargtype(given_argtypes[end])
last = length(given_argtypes)
else
last = nargs
end
isva_given_argtypes[nargs] = tuple_tfunc(given_argtypes[last:end])
# invalidate `Conditional` imposed on varargs
if condargs !== nothing
for (slotid, i) in condargs
if slotid last
isva_given_argtypes[i] = widenconditional(isva_given_argtypes[i])
end
end
end
end
given_argtypes = isva_given_argtypes
end
given_argtypes = va_process_argtypes(given_argtypes, linfo, condargs)
@assert length(given_argtypes) == nargs
for i in 1:nargs
given_argtype = given_argtypes[i]
Expand Down
6 changes: 6 additions & 0 deletions base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ function in(idx::Int, bsbmp::BitSetBoundedMinPrioritySet)
return idx in bsbmp.elems
end

function append!(bsbmp::BitSetBoundedMinPrioritySet, itr)
for val in itr
push!(bsbmp, val)
end
end

mutable struct InferenceState
params::InferenceParams
result::InferenceResult # remember where to put the result
Expand Down
3 changes: 2 additions & 1 deletion base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import Core.Compiler: # Core.Compiler specific definitions
isbitstype, isexpr, is_meta_expr_head, println, widenconst, argextype, singleton_type,
fieldcount_noerror, try_compute_field, try_compute_fieldidx, hasintersect, ,
intrinsic_nothrow, array_builtin_common_typecheck, arrayset_typecheck,
setfield!_nothrow, alloc_array_ndims, stmt_effect_free, check_effect_free!
setfield!_nothrow, alloc_array_ndims, stmt_effect_free, check_effect_free!,
SemiConcreteResult

include(x) = _TOP_MOD.include(@__MODULE__, x)
if _TOP_MOD === Core.Compiler
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/ssair/EscapeAnalysis/interprocedural.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Core.Compiler:
call_sig, argtypes_to_type, is_builtin, is_return_type, istopfunction, validate_sparams,
specialize_method, invoke_rewrite

const Linfo = Union{MethodInstance,InferenceResult}
const Linfo = Union{MethodInstance,InferenceResult,SemiConcreteResult}
struct CallInfo
linfos::Vector{Linfo}
nothrow::Bool
Expand Down
4 changes: 1 addition & 3 deletions base/compiler/ssair/driver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ function stmt_effect_free end # imported by EscapeAnalysis
function alloc_array_ndims end # imported by EscapeAnalysis
function try_compute_field end # imported by EscapeAnalysis

include("compiler/ssair/basicblock.jl")
include("compiler/ssair/domtree.jl")
include("compiler/ssair/ir.jl")
include("compiler/ssair/slot2ssa.jl")
include("compiler/ssair/inlining.jl")
include("compiler/ssair/verify.jl")
include("compiler/ssair/legacy.jl")
include("compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl")
include("compiler/ssair/passes.jl")
include("compiler/ssair/irinterp.jl")
11 changes: 11 additions & 0 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,8 @@ function handle_const_call!(
push!(cases, InliningCase(result.mi.specTypes, case))
elseif isa(result, InferenceResult)
handled_all_cases &= handle_inf_result!(result, argtypes, flag, state, cases, true)
elseif isa(result, SemiConcreteResult)
handled_all_cases &= handle_semi_concrete_result!(result, cases, true)
else
@assert result === nothing
handled_all_cases &= handle_match!(match, argtypes, flag, state, cases, true)
Expand Down Expand Up @@ -1334,6 +1336,15 @@ function handle_inf_result!(
return true
end

function handle_semi_concrete_result!(result::SemiConcreteResult, cases::Vector{InliningCase}, allow_abstract::Bool = false)
mi = result.mi
spec_types = mi.specTypes
allow_abstract || isdispatchtuple(spec_types) || return false
validate_sparams(mi.sparam_vals) || return false
push!(cases, InliningCase(spec_types, InliningTodo(mi, result.ir, result.effects)))
return true
end

function const_result_item(result::ConstResult, state::InliningState)
if !isdefined(result, :result) || !is_inlineable_constant(result.result)
return compileable_specialization(state.et, result.mi, result.effects)
Expand Down
11 changes: 9 additions & 2 deletions base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1030,15 +1030,22 @@ function renumber_ssa2!(@nospecialize(stmt), ssanums::Vector{Any}, used_ssas::Ve
end

# Used in inlining before we start compacting - Only works at the CFG level
function kill_edge!(bbs::Vector{BasicBlock}, from::Int, to::Int)
function kill_edge!(bbs::Vector{BasicBlock}, from::Int, to::Int, callback=nothing)
preds, succs = bbs[to].preds, bbs[from].succs
deleteat!(preds, findfirst(x->x === from, preds)::Int)
deleteat!(succs, findfirst(x->x === to, succs)::Int)
if length(preds) == 0
for succ in copy(bbs[to].succs)
kill_edge!(bbs, to, succ)
kill_edge!(bbs, to, succ, callback)
end
end
if callback !== nothing
callback(from, to)
end
end

function kill_edge!(ir::IRCode, from::Int, to::Int, callback=nothing)
kill_edge!(ir.cfg.blocks, from, to, callback)
end

# N.B.: from and to are non-renamed indices
Expand Down
Loading

0 comments on commit ed737ad

Please sign in to comment.