Skip to content

Commit 5e5416a

Browse files
topolarityaviatesk
andauthored
slot2ssa: remove TypedSlot (#50943)
Dependent on #50924 . This removes the last remaining usage of `TypedSlot`. As a bonus, this evicts all of the "tmerge" type-iteration that was being done in slot2ssa. --------- Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
1 parent 4ac6b05 commit 5e5416a

File tree

12 files changed

+169
-284
lines changed

12 files changed

+169
-284
lines changed

β€Žbase/compiler/inferencestate.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ mutable struct InferenceState
229229

230230
#= results =#
231231
result::InferenceResult # remember where to put the result
232+
unreachable::BitSet # statements that were found to be statically unreachable
232233
valid_worlds::WorldRange
233234
bestguess #::Type
234235
ipo_effects::Effects
@@ -278,6 +279,7 @@ mutable struct InferenceState
278279
end
279280
src.ssavaluetypes = ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ]
280281

282+
unreachable = BitSet()
281283
pclimitations = IdSet{InferenceState}()
282284
limitations = IdSet{InferenceState}()
283285
cycle_backedges = Vector{Tuple{InferenceState,Int}}()
@@ -306,7 +308,7 @@ mutable struct InferenceState
306308
linfo, world, mod, sptypes, slottypes, src, cfg, method_info,
307309
currbb, currpc, ip, handler_at, ssavalue_uses, bb_vartables, ssavaluetypes, stmt_edges, stmt_info,
308310
pclimitations, limitations, cycle_backedges, callers_in_cycle, dont_work_on_me, parent,
309-
result, valid_worlds, bestguess, ipo_effects,
311+
result, unreachable, valid_worlds, bestguess, ipo_effects,
310312
restrict_abstract_call_sites, cached, insert_coverage,
311313
interp)
312314
end

β€Žbase/compiler/optimize.jl

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,15 @@ mutable struct OptimizationState{Interp<:AbstractInterpreter}
130130
slottypes::Vector{Any}
131131
inlining::InliningState{Interp}
132132
cfg::CFG
133+
unreachable::BitSet
134+
bb_vartables::Vector{Union{Nothing,VarTable}}
133135
insert_coverage::Bool
134136
end
135137
function OptimizationState(sv::InferenceState, interp::AbstractInterpreter)
136138
inlining = InliningState(sv, interp)
137139
return OptimizationState(sv.linfo, sv.src, nothing, sv.stmt_info, sv.mod,
138-
sv.sptypes, sv.slottypes, inlining, sv.cfg, sv.insert_coverage)
140+
sv.sptypes, sv.slottypes, inlining, sv.cfg,
141+
sv.unreachable, sv.bb_vartables, sv.insert_coverage)
139142
end
140143
function OptimizationState(linfo::MethodInstance, src::CodeInfo, interp::AbstractInterpreter)
141144
# prepare src for running optimization passes if it isn't already
@@ -159,7 +162,15 @@ function OptimizationState(linfo::MethodInstance, src::CodeInfo, interp::Abstrac
159162
# This method is mostly used for unit testing the optimizer
160163
inlining = InliningState(interp)
161164
cfg = compute_basic_blocks(src.code)
162-
return OptimizationState(linfo, src, nothing, stmt_info, mod, sptypes, slottypes, inlining, cfg, false)
165+
unreachable = BitSet()
166+
bb_vartables = Union{VarTable,Nothing}[]
167+
for block = 1:length(cfg.blocks)
168+
push!(bb_vartables, VarState[
169+
VarState(slottypes[slot], src.slotflags[slot] & SLOT_USEDUNDEF != 0)
170+
for slot = 1:nslots
171+
])
172+
end
173+
return OptimizationState(linfo, src, nothing, stmt_info, mod, sptypes, slottypes, inlining, cfg, unreachable, bb_vartables, false)
163174
end
164175
function OptimizationState(linfo::MethodInstance, interp::AbstractInterpreter)
165176
world = get_world_counter(interp)
@@ -168,7 +179,6 @@ function OptimizationState(linfo::MethodInstance, interp::AbstractInterpreter)
168179
return OptimizationState(linfo, src, interp)
169180
end
170181

171-
172182
include("compiler/ssair/driver.jl")
173183

174184
function ir_to_codeinf!(opt::OptimizationState)
@@ -328,7 +338,7 @@ function stmt_effect_flags(𝕃ₒ::AbstractLattice, @nospecialize(stmt), @nospe
328338
return (false, false, false)
329339
end
330340
end
331-
isa(stmt, UnoptSlot) && error("unexpected IR elements")
341+
isa(stmt, SlotNumber) && error("unexpected IR elements")
332342
return (true, true, true)
333343
end
334344

@@ -363,8 +373,6 @@ function argextype(
363373
@assert false
364374
elseif isa(x, SlotNumber)
365375
return slottypes[x.id]
366-
elseif isa(x, TypedSlot)
367-
return x.typ
368376
elseif isa(x, SSAValue)
369377
return abstract_eval_ssavalue(x, src)
370378
elseif isa(x, Argument)
@@ -523,12 +531,39 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
523531
linetable = collect(LineInfoNode, linetable::Vector{Any})::Vector{LineInfoNode}
524532
end
525533

534+
# Update control-flow to reflect any unreachable branches.
535+
ssavaluetypes = ci.ssavaluetypes::Vector{Any}
536+
code = copy_exprargs(ci.code)
537+
for i = 1:length(code)
538+
expr = code[i]
539+
if !(i in sv.unreachable) && isa(expr, GotoIfNot)
540+
# Replace this live GotoIfNot with:
541+
# - no-op if :nothrow and the branch target is unreachable
542+
# - cond if :nothrow and both targets are unreachable
543+
# - typeassert if must-throw
544+
if widenconst(argextype(expr.cond, ci, sv.sptypes)) === Bool
545+
block = block_for_inst(sv.cfg, i)
546+
if i + 1 in sv.unreachable
547+
cfg_delete_edge!(sv.cfg, block, block + 1)
548+
expr = GotoNode(expr.dest)
549+
elseif expr.dest in sv.unreachable
550+
cfg_delete_edge!(sv.cfg, block, block_for_inst(sv.cfg, expr.dest))
551+
expr = nothing
552+
end
553+
elseif ssavaluetypes[i] === Bottom
554+
block = block_for_inst(sv.cfg, i)
555+
cfg_delete_edge!(sv.cfg, block, block + 1)
556+
cfg_delete_edge!(sv.cfg, block, block_for_inst(sv.cfg, expr.dest))
557+
expr = Expr(:call, Core.typeassert, expr.cond, Bool)
558+
end
559+
code[i] = expr
560+
end
561+
end
562+
526563
# Go through and add an unreachable node after every
527564
# Union{} call. Then reindex labels.
528-
code = copy_exprargs(ci.code)
529565
stmtinfo = sv.stmt_info
530566
codelocs = ci.codelocs
531-
ssavaluetypes = ci.ssavaluetypes::Vector{Any}
532567
ssaflags = ci.ssaflags
533568
meta = Expr[]
534569
idx = 1
@@ -562,8 +597,8 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
562597
idx += 1
563598
prevloc = codeloc
564599
end
565-
if ssavaluetypes[idx] === Union{} && !(code[idx] isa Core.Const)
566-
# Type inference should have converted any must-throw terminators to an equivalent w/o control-flow edges
600+
if ssavaluetypes[idx] === Union{} && !(oldidx in sv.unreachable)
601+
# We should have converted any must-throw terminators to an equivalent w/o control-flow edges
567602
@assert !isterminator(code[idx])
568603

569604
block = block_for_inst(sv.cfg, oldidx)
@@ -589,8 +624,8 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
589624

590625
# Verify that type-inference did its job
591626
if JLOptions().debug_level == 2
592-
for i = (idx + 1):(block_end - 1)
593-
@assert (code[i] isa Core.Const) || is_meta_expr(code[i])
627+
for i = (oldidx + 1):last(sv.cfg.blocks[block].stmts)
628+
@assert i in sv.unreachable
594629
end
595630
end
596631

@@ -659,7 +694,7 @@ function slot2reg(ir::IRCode, ci::CodeInfo, sv::OptimizationState)
659694
@timeit "domtree 1" domtree = construct_domtree(ir.cfg.blocks)
660695
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.stmt)
661696
𝕃ₒ = optimizer_lattice(sv.inlining.interp)
662-
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, sv.slottypes, 𝕃ₒ) # consumes `ir`
697+
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, sv, domtree, defuse_insts, 𝕃ₒ) # consumes `ir`
663698
# NOTE now we have converted `ir` to the SSA form and eliminated slots
664699
# let's resize `argtypes` now and remove unnecessary types for the eliminated slots
665700
resize!(ir.argtypes, nargs)
@@ -888,10 +923,7 @@ function renumber_ir_elements!(body::Vector{Any}, ssachangemap::Vector{Int}, lab
888923
end
889924

890925
function renumber_cfg_stmts!(cfg::CFG, blockchangemap::Vector{Int})
891-
any_change = cumsum_ssamap!(blockchangemap)
892-
any_change || return
893-
894-
last_end = 0
926+
cumsum_ssamap!(blockchangemap) || return
895927
for i = 1:length(cfg.blocks)
896928
old_range = cfg.blocks[i].stmts
897929
new_range = StmtRange(first(old_range) + ((i > 1) ? blockchangemap[i - 1] : 0),

β€Žbase/compiler/ssair/show.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ function print_stmt(io::IO, idx::Int, @nospecialize(stmt), used::BitSet, maxleng
7575
show_unquoted_phinode(io, stmt, indent, "#")
7676
elseif stmt isa GotoIfNot
7777
show_unquoted_gotoifnot(io, stmt, indent, "#")
78-
elseif stmt isa TypedSlot
79-
# call `show` with the type set to Any so it will not be shown, since
80-
# we will show the type ourselves.
81-
show_unquoted(io, SlotNumber(stmt.id), indent, show_type ? prec_decl : 0)
8278
# everything else in the IR, defer to the generic AST printer
8379
else
8480
show_unquoted(io, stmt, indent, show_type ? prec_decl : 0)

0 commit comments

Comments
Β (0)