Skip to content

Commit

Permalink
wip: domination analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Nov 23, 2021
1 parent 8b62a59 commit 31f9725
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions src/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ end
# analysis
# ========

const FieldDef = Pair{Int,Any}
const FieldInfo = IdSet{FieldDef}
const FieldsInfo = Vector{FieldInfo}
struct UnintializedField end

"""
x::EscapeLattice
Expand Down Expand Up @@ -186,7 +191,7 @@ struct EscapeLattice
ReturnEscape::Bool
ThrownEscape::Bool
EscapeSites::BitSet
FieldSets::Union{Vector{IdSet{Any}},Bool}
FieldSets::Union{FieldsInfo,Bool}
# TODO: ArgEscape::Int

function EscapeLattice(Analyzed::Bool,
Expand Down Expand Up @@ -297,7 +302,7 @@ x::EscapeLattice ⊑ y::EscapeLattice = begin
if isa(yf, Bool)
yf === false && return false
else
xf, yf = xf::Vector{IdSet{Any}}, yf::Vector{IdSet{Any}}
xf, yf = xf::FieldsInfo, yf::FieldsInfo
xn, yn = length(xf), length(yf)
xn > yn && return false
for i in 1:xn
Expand Down Expand Up @@ -331,10 +336,10 @@ x::EscapeLattice ⊔ y::EscapeLattice = begin
elseif yf === false
FieldSets = xf
else
xf, yf = xf::Vector{IdSet{Any}}, yf::Vector{IdSet{Any}}
xf, yf = xf::FieldsInfo, yf::FieldsInfo
xn, yn = length(xf), length(yf)
nmax, nmin = max(xn, yn), min(xn, yn)
FieldSets = Vector{IdSet{Any}}(undef, nmax)
FieldSets = FieldsInfo(undef, nmax)
for i in 1:nmax
if i > nmax
FieldSets[i] = (xn > yn ? xf : yf)[i]
Expand Down Expand Up @@ -752,7 +757,7 @@ function escape_new!(ir::IRCode, pc::Int, args::Vector{Any},
if info == NotAnalyzed()
info = NoEscape()
end
newinfo = add_fieldsets(info, ir.stmts[pc][:type], args)
newinfo = add_fieldsets(info, ir.stmts[pc][:type], pc, args)
add_escape_change!(SSAValue(pc), ir, newinfo, changes)

# propagate the escape information of this object to all its fields as well
Expand All @@ -762,22 +767,23 @@ function escape_new!(ir::IRCode, pc::Int, args::Vector{Any},
end
end

function add_fieldsets(info::EscapeLattice, @nospecialize(typ), args::Vector{Any})
function add_fieldsets(info::EscapeLattice, @nospecialize(typ), pc::Int, args::Vector{Any})
FieldSets = info.FieldSets
nfields = fieldcount_noerror(typ)
if isa(FieldSets, Bool) && !FieldSets
if nfields === nothing
# abstract type, can't propagate
FieldSets = true
else
FieldSets = IdSet{Any}[IdSet{Any}() for _ in 1:nfields]
FieldSets = FieldInfo[FieldInfo() for _ in 1:nfields]
end
end
if !isa(FieldSets, Bool)
@assert nfields == length(FieldSets)
for i in 2:length(args)
i-1 > nfields::Int && break # see https://github.com/JuliaLang/julia/issues/43146
push!(FieldSets[i-1], args[i])
nargs = length(args)
for i in 1:nfields
val = nargs < i+1 ? UnintializedField() : args[i+1]
push!(FieldSets[i], FieldDef(pc, val))
end
end
return EscapeLattice(info, FieldSets)
Expand Down Expand Up @@ -837,16 +843,7 @@ function escape_builtin!(::typeof(typeassert), ir::IRCode, pc::Int, args::Vector
end

function escape_builtin!(::typeof(tuple), ir::IRCode, pc::Int, args::Vector{Any}, state::EscapeState, changes::Changes)
info = state.ssavalues[pc]
if info == NotAnalyzed()
info = NoEscape()
end
tupleinfo = add_fieldsets(info, ir.stmts[pc][:type], args)
add_escape_change!(SSAValue(pc), ir, tupleinfo, changes)
# propagate the escape information of this object to all its fields as well,
for i in 2:length(args)
add_escape_change!(args[i], ir, ignore_fieldsets(info), changes)
end
escape_new!(ir, pc, args, state, changes)
end

function escape_builtin!(::typeof(getfield), ir::IRCode, pc::Int, args::Vector{Any}, state::EscapeState, changes::Changes)
Expand Down Expand Up @@ -881,14 +878,14 @@ function escape_builtin!(::typeof(getfield), ir::IRCode, pc::Int, args::Vector{A
fidx = nothing
end
if fidx !== nothing
for x in FieldSets[fidx]
for (_, x) in FieldSets[fidx]
add_escape_change!(x, ir, info, changes)
add_alias_change!(x, SSAValue(pc), ir, changes)
end
else
# when the field can't be known precisely,
# propagate this escape information to all the fields conservatively
for FieldSet in FieldSets, x in FieldSet
for FieldSet in FieldSets, (_, x) in FieldSet
add_escape_change!(x, ir, info, changes)
add_alias_change!(x, SSAValue(pc), ir, changes)
end
Expand Down Expand Up @@ -939,7 +936,7 @@ function escape_builtin!(::typeof(setfield!), ir::IRCode, pc::Int, args::Vector{
else
nfields = fieldcount_noerror(typ)
if nfields !== nothing
FieldSets = IdSet{Any}[IdSet{Any}() for _ in 1:nfields]
FieldSets = FieldInfo[FieldInfo() for _ in 1:nfields]
@goto add_field
else
# fields aren't known precisely
Expand All @@ -955,12 +952,12 @@ function escape_builtin!(::typeof(setfield!), ir::IRCode, pc::Int, args::Vector{
fidx = nothing
end
if fidx !== nothing
push!(FieldSets[fidx], val)
push!(FieldSets[fidx], FieldDef(pc, val))
else
# when the field can't be known precisely,
# add this alias information to all the field sets conservatively
for FieldSet in FieldSets
push!(FieldSet, val)
push!(FieldSet, FieldDef(pc, val))
end
end
# update `obj`'s escape information with the new field sets
Expand Down

0 comments on commit 31f9725

Please sign in to comment.