Skip to content

Commit 1ae12df

Browse files
authored
Merge 247a4b5 into 17445fe
2 parents 17445fe + 247a4b5 commit 1ae12df

File tree

4 files changed

+42
-66
lines changed

4 files changed

+42
-66
lines changed

base/compiler/optimize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ end
647647
function refine_effects!(interp::AbstractInterpreter, sv::PostOptAnalysisState)
648648
if !is_effect_free(sv.result.ipo_effects) && sv.all_effect_free && !isempty(sv.ea_analysis_pending)
649649
ir = sv.ir
650-
nargs = length(ir.argtypes)
650+
nargs = let def = sv.result.linfo.def; isa(def, Method) ? Int(def.nargs) : 0; end
651651
estate = EscapeAnalysis.analyze_escapes(ir, nargs, optimizer_lattice(interp), GetNativeEscapeCache(interp))
652652
argescapes = EscapeAnalysis.ArgEscapeCache(estate)
653653
stack_analysis_result!(sv.result, argescapes)

base/compiler/ssair/inlining.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,6 @@ function handle_finalizer_call!(ir::IRCode, idx::Int, stmt::Expr, info::Finalize
15971597
push!(stmt.args, item1.invoke)
15981598
elseif isa(item1, ConstantCase)
15991599
push!(stmt.args, nothing)
1600-
push!(stmt.args, item1.val)
16011600
end
16021601
end
16031602
return nothing

base/compiler/ssair/passes.jl

Lines changed: 41 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,10 +1564,12 @@ end
15641564

15651565
is_nothrow(ir::IRCode, ssa::SSAValue) = has_flag(ir[ssa], IR_FLAG_NOTHROW)
15661566

1567-
function reachable_blocks(cfg::CFG, from_bb::Int, to_bb::Union{Nothing,Int} = nothing)
1567+
function reachable_blocks(cfg::CFG, from_bb::Int, to_bb::Int)
15681568
worklist = Int[from_bb]
15691569
visited = BitSet(from_bb)
1570-
if to_bb !== nothing
1570+
if to_bb == from_bb
1571+
return visited
1572+
else
15711573
push!(visited, to_bb)
15721574
end
15731575
function visit!(bb::Int)
@@ -1582,100 +1584,78 @@ function reachable_blocks(cfg::CFG, from_bb::Int, to_bb::Union{Nothing,Int} = no
15821584
return visited
15831585
end
15841586

1585-
function try_resolve_finalizer!(ir::IRCode, idx::Int, finalizer_idx::Int, defuse::SSADefUse,
1587+
function try_resolve_finalizer!(ir::IRCode, alloc_idx::Int, finalizer_idx::Int, defuse::SSADefUse,
15861588
inlining::InliningState, lazydomtree::LazyDomtree,
15871589
lazypostdomtree::LazyPostDomtree, @nospecialize(info::CallInfo))
15881590
# For now, require that:
15891591
# 1. The allocation dominates the finalizer registration
1590-
# 2. The finalizer registration dominates all uses reachable from the
1591-
# finalizer registration.
1592-
# 3. The insertion block for the finalizer is the post-dominator of all
1593-
# uses and the finalizer registration block. The insertion block must
1594-
# be dominated by the finalizer registration block.
1595-
# 4. The path from the finalizer registration to the finalizer inlining
1592+
# 2. The insertion block for the finalizer is the post-dominator of all
1593+
# uses (including the finalizer registration).
1594+
# 3. The path from the finalizer registration to the finalizer inlining
15961595
# location is nothrow
15971596
#
1598-
# TODO: We could relax item 3, by inlining the finalizer multiple times.
1597+
# TODO: We could relax the check 2, by inlining the finalizer multiple times.
15991598

16001599
# Check #1: The allocation dominates the finalizer registration
16011600
domtree = get!(lazydomtree)
16021601
finalizer_bb = block_for_inst(ir, finalizer_idx)
1603-
alloc_bb = block_for_inst(ir, idx)
1602+
alloc_bb = block_for_inst(ir, alloc_idx)
16041603
dominates(domtree, alloc_bb, finalizer_bb) || return nothing
16051604

1606-
bb_insert_block::Int = finalizer_bb
1607-
bb_insert_idx::Union{Int,Nothing} = finalizer_idx
1608-
function note_block_use!(usebb::Int, useidx::Int)
1609-
new_bb_insert_block = nearest_common_dominator(get!(lazypostdomtree),
1610-
bb_insert_block, usebb)
1611-
if new_bb_insert_block == bb_insert_block && bb_insert_idx !== nothing
1612-
bb_insert_idx = max(bb_insert_idx::Int, useidx)
1613-
elseif new_bb_insert_block == usebb
1614-
bb_insert_idx = useidx
1605+
# Check #2: The insertion block for the finalizer is the post-dominator of all uses
1606+
insert_bb::Int = finalizer_bb
1607+
insert_idx::Union{Int,Nothing} = finalizer_idx
1608+
function note_defuse!(x::Union{Int,SSAUse})
1609+
defuse_idx = x isa SSAUse ? x.idx : x
1610+
defuse_idx == finalizer_idx && return nothing
1611+
defuse_bb = block_for_inst(ir, defuse_idx)
1612+
new_insert_bb = nearest_common_dominator(get!(lazypostdomtree),
1613+
insert_bb, defuse_bb)
1614+
if new_insert_bb == insert_bb && insert_idx !== nothing
1615+
insert_idx = max(insert_idx::Int, defuse_idx)
1616+
elseif new_insert_bb == defuse_bb
1617+
insert_idx = defuse_idx
16151618
else
1616-
bb_insert_idx = nothing
1619+
insert_idx = nothing
16171620
end
1618-
bb_insert_block = new_bb_insert_block
1621+
insert_bb = new_insert_bb
16191622
nothing
16201623
end
1621-
1622-
# Collect all reachable blocks between the finalizer registration and the
1623-
# insertion point
1624-
blocks = reachable_blocks(ir.cfg, finalizer_bb, alloc_bb)
1625-
1626-
# Check #2
1627-
function check_defuse(x::Union{Int,SSAUse})
1628-
duidx = x isa SSAUse ? x.idx : x
1629-
duidx == finalizer_idx && return true
1630-
bb = block_for_inst(ir, duidx)
1631-
# Not reachable from finalizer registration - we're ok
1632-
bb blocks && return true
1633-
note_block_use!(bb, duidx)
1634-
if dominates(domtree, finalizer_bb, bb)
1635-
return true
1636-
else
1637-
return false
1638-
end
1639-
end
1640-
all(check_defuse, defuse.uses) || return nothing
1641-
all(check_defuse, defuse.defs) || return nothing
1642-
bb_insert_block != 0 || return nothing # verify post-dominator of all uses exists
1643-
1644-
# Check #3
1645-
dominates(domtree, finalizer_bb, bb_insert_block) || return nothing
1624+
foreach(note_defuse!, defuse.uses)
1625+
foreach(note_defuse!, defuse.defs)
1626+
insert_bb != 0 || return nothing # verify post-dominator of all uses exists
16461627

16471628
if !OptimizationParams(inlining.interp).assume_fatal_throw
16481629
# Collect all reachable blocks between the finalizer registration and the
16491630
# insertion point
1650-
blocks = finalizer_bb == bb_insert_block ? Int[finalizer_bb] :
1651-
reachable_blocks(ir.cfg, finalizer_bb, bb_insert_block)
1631+
blocks = reachable_blocks(ir.cfg, finalizer_bb, insert_bb)
16521632

1653-
# Check #4
1654-
function check_range_nothrow(ir::IRCode, s::Int, e::Int)
1633+
# Check #3
1634+
function check_range_nothrow(s::Int, e::Int)
16551635
return all(s:e) do sidx::Int
16561636
sidx == finalizer_idx && return true
1657-
sidx == idx && return true
1637+
sidx == alloc_idx && return true
16581638
return is_nothrow(ir, SSAValue(sidx))
16591639
end
16601640
end
16611641
for bb in blocks
16621642
range = ir.cfg.blocks[bb].stmts
16631643
s, e = first(range), last(range)
1664-
if bb == bb_insert_block
1665-
bb_insert_idx === nothing && continue
1666-
e = bb_insert_idx
1644+
if bb == insert_bb
1645+
insert_idx === nothing && continue
1646+
e = insert_idx
16671647
end
16681648
if bb == finalizer_bb
16691649
s = finalizer_idx
16701650
end
1671-
check_range_nothrow(ir, s, e) || return nothing
1651+
check_range_nothrow(s, e) || return nothing
16721652
end
16731653
end
16741654

16751655
# Ok, legality check complete. Figure out the exact statement where we're
16761656
# going to inline the finalizer.
1677-
loc = bb_insert_idx === nothing ? first(ir.cfg.blocks[bb_insert_block].stmts) : bb_insert_idx::Int
1678-
attach_after = bb_insert_idx !== nothing
1657+
loc = insert_idx === nothing ? first(ir.cfg.blocks[insert_bb].stmts) : insert_idx::Int
1658+
attach_after = insert_idx !== nothing
16791659

16801660
finalizer_stmt = ir[SSAValue(finalizer_idx)][:stmt]
16811661
argexprs = Any[finalizer_stmt.args[2], finalizer_stmt.args[3]]
@@ -1702,11 +1682,10 @@ function try_resolve_finalizer!(ir::IRCode, idx::Int, finalizer_idx::Int, defuse
17021682
return nothing
17031683
end
17041684

1705-
function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse}}, used_ssas::Vector{Int}, lazydomtree::LazyDomtree, inlining::Union{Nothing, InliningState})
1685+
function sroa_mutables!(ir::IRCode, defuses::IdDict{Int,Tuple{SPCSet,SSADefUse}}, used_ssas::Vector{Int}, lazydomtree::LazyDomtree, inlining::Union{Nothing,InliningState})
17061686
𝕃ₒ = inlining === nothing ? SimpleInferenceLattice.instance : optimizer_lattice(inlining.interp)
17071687
lazypostdomtree = LazyPostDomtree(ir)
17081688
for (defidx, (intermediaries, defuse)) in defuses
1709-
intermediaries = collect(intermediaries)
17101689
# Check if there are any uses we did not account for. If so, the variable
17111690
# escapes and we cannot eliminate the allocation. This works, because we're guaranteed
17121691
# not to include any intermediaries that have dead uses. As a result, missing uses will only ever
@@ -1906,7 +1885,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse
19061885
end
19071886
end
19081887

1909-
function form_new_preserves(origex::Expr, intermediates::Vector{Int}, new_preserves::Vector{Any})
1888+
function form_new_preserves(origex::Expr, intermediaries::Union{Vector{Int},SPCSet}, new_preserves::Vector{Any})
19101889
newex = Expr(:foreigncall)
19111890
nccallargs = length(origex.args[3]::SimpleVector)
19121891
for i in 1:(6+nccallargs-1)
@@ -1915,7 +1894,7 @@ function form_new_preserves(origex::Expr, intermediates::Vector{Int}, new_preser
19151894
for i in (6+nccallargs):length(origex.args)
19161895
x = origex.args[i]
19171896
# don't need to preserve intermediaries
1918-
if isa(x, SSAValue) && x.id in intermediates
1897+
if isa(x, SSAValue) && x.id in intermediaries
19191898
continue
19201899
end
19211900
push!(newex.args, x)

test/compiler/inline.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,7 +1570,6 @@ let
15701570
@test get_finalization_count() == 1000
15711571
end
15721572

1573-
15741573
function cfg_finalization7(io)
15751574
for i = -999:1000
15761575
o = DoAllocWithField(0)
@@ -1597,7 +1596,6 @@ let
15971596
@test get_finalization_count() == 1000
15981597
end
15991598

1600-
16011599
# optimize `[push!|pushfirst!](::Vector{Any}, x...)`
16021600
@testset "optimize `$f(::Vector{Any}, x...)`" for f = Any[push!, pushfirst!]
16031601
@eval begin

0 commit comments

Comments
 (0)