Skip to content

Commit

Permalink
inference: remove code that relies upon inferring the output type
Browse files Browse the repository at this point in the history
Recursing into inference may be unreliable during inference.

(cherry picked from commit cb5a5bc)
  • Loading branch information
vtjnash authored and KristofferC committed Sep 15, 2021
1 parent 54590dc commit dd4c574
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 49 deletions.
2 changes: 1 addition & 1 deletion base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function inline_into_block!(state::CFGInliningState, block::Int)
new_range = state.first_bb+1:block
l = length(state.new_cfg_blocks)
state.bb_rename[new_range] = (l+1:l+length(new_range))
append!(state.new_cfg_blocks, map(copy, state.cfg.blocks[new_range]))
append!(state.new_cfg_blocks, (copy(block) for block in state.cfg.blocks[new_range]))
push!(state.merged_orig_blocks, last(new_range))
end
state.first_bb = block
Expand Down
29 changes: 2 additions & 27 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,6 @@ function try_compute_fieldidx_expr(@nospecialize(typ), @nospecialize(use_expr))
return try_compute_fieldidx(typ, field)
end

function lift_defuse(cfg::CFG, ssa::SSADefUse)
# We remove from `uses` any block where all uses are dominated
# by a def. This prevents insertion of dead phi nodes at the top
# of such a block if that block happens to be in a loop
ordered = Tuple{Int, Int, Bool}[(x, block_for_inst(cfg, x), true) for x in ssa.uses]
for x in ssa.defs
push!(ordered, (x, block_for_inst(cfg, x), false))
end
ordered = sort(ordered, by=x->x[1])
bb_defs = Int[]
bb_uses = Int[]
last_bb = last_def_bb = 0
for (_, bb, is_use) in ordered
if bb != last_bb && is_use
push!(bb_uses, bb)
end
last_bb = bb
if last_def_bb != bb && !is_use
push!(bb_defs, bb)
last_def_bb = bb
end
end
SSADefUse(bb_uses, bb_defs, Int[])
end

function find_curblock(domtree::DomTree, allblocks::Vector{Int}, curblock::Int)
# TODO: This can be much faster by looking at current level and only
# searching for those blocks in a sorted order
Expand Down Expand Up @@ -1205,12 +1180,12 @@ function cfg_simplify!(ir::IRCode)
# Compute (renamed) successors and predecessors given (renamed) block
function compute_succs(i)
orig_bb = follow_merged_succ(result_bbs[i])
return map(i -> bb_rename_succ[i], bbs[orig_bb].succs)
return Int[bb_rename_succ[i] for i in bbs[orig_bb].succs]
end
function compute_preds(i)
orig_bb = result_bbs[i]
preds = bbs[orig_bb].preds
return map(pred -> bb_rename_pred[pred], preds)
return Int[bb_rename_pred[pred] for pred in preds]
end

BasicBlock[
Expand Down
7 changes: 4 additions & 3 deletions base/compiler/ssair/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,15 @@ show_unquoted(io::IO, val::Argument, indent::Int, prec::Int) = show_unquoted(io,

show_unquoted(io::IO, stmt::PhiNode, indent::Int, ::Int) = show_unquoted_phinode(io, stmt, indent, "%")
function show_unquoted_phinode(io::IO, stmt::PhiNode, indent::Int, prefix::String)
args = map(1:length(stmt.edges)) do i
args = String[let
e = stmt.edges[i]
v = !isassigned(stmt.values, i) ? "#undef" :
sprint() do io′
show_unquoted(io′, stmt.values[i], indent)
end
return "$prefix$e => $v"
end
"$prefix$e => $v"
end for i in 1:length(stmt.edges)
]
print(io, "φ ", '(')
join(io, args, ", ")
print(io, ')')
Expand Down
22 changes: 6 additions & 16 deletions base/compiler/ssair/slot2ssa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@ function scan_entry!(result::Vector{SlotInfo}, idx::Int, @nospecialize(stmt))
end


function lift_defuse(cfg::CFG, defuse)
map(defuse) do slot
SlotInfo(
Int[block_for_inst(cfg, x) for x in slot.defs],
Int[block_for_inst(cfg, x) for x in slot.uses],
slot.any_newvar
)
end
end

function scan_slot_def_use(nargs::Int, ci::CodeInfo, code::Vector{Any})
nslots = length(ci.slotflags)
result = SlotInfo[SlotInfo() for i = 1:nslots]
Expand Down Expand Up @@ -523,7 +513,7 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree)
return new_ir
end

function compute_live_ins(cfg::CFG, defuse)
function compute_live_ins(cfg::CFG, defuse #=::Union{SlotInfo,SSADefUse}=#)
# We remove from `uses` any block where all uses are dominated
# by a def. This prevents insertion of dead phi nodes at the top
# of such a block if that block happens to be in a loop
Expand Down Expand Up @@ -585,8 +575,8 @@ function recompute_type(node::Union{PhiNode, PhiCNode}, ci::CodeInfo, ir::IRCode
return new_typ
end

function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse, nargs::Int,
slottypes::Vector{Any})
function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree,
defuses::Vector{SlotInfo}, nargs::Int, slottypes::Vector{Any})
code = ir.stmts.inst
cfg = ir.cfg
left = Int[]
Expand Down Expand Up @@ -615,7 +605,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse, narg
for (_, exc) in catch_entry_blocks
phicnodes[exc] = Vector{Tuple{SlotNumber, NewSSAValue, PhiCNode}}()
end
@timeit "idf" for (idx, slot) in Iterators.enumerate(defuse)
@timeit "idf" for (idx, slot) in Iterators.enumerate(defuses)
# No uses => no need for phi nodes
isempty(slot.uses) && continue
# TODO: Restore this optimization
Expand Down Expand Up @@ -670,9 +660,9 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse, narg
end
# Perform SSA renaming
initial_incoming_vals = Any[
if 0 in defuse[x].defs
if 0 in defuses[x].defs
Argument(x)
elseif !defuse[x].any_newvar
elseif !defuses[x].any_newvar
undef_token
else
SSAValue(-2)
Expand Down
5 changes: 3 additions & 2 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,14 +493,15 @@ static void reset_mt_caches(jl_methtable_t *mt, void *env)


jl_function_t *jl_typeinf_func = NULL;
size_t jl_typeinf_world = 0;
size_t jl_typeinf_world = 1;

JL_DLLEXPORT void jl_set_typeinf_func(jl_value_t *f)
{
size_t newfunc = jl_typeinf_world == 1 && jl_typeinf_func == NULL;
jl_typeinf_func = (jl_function_t*)f;
jl_typeinf_world = jl_get_tls_world_age();
++jl_world_counter; // make type-inference the only thing in this world
if (jl_typeinf_world == 0) {
if (0 && newfunc) {
// give type inference a chance to see all of these
// TODO: also reinfer if max_world != ~(size_t)0
jl_array_t *unspec = jl_alloc_vec_any(0);
Expand Down

0 comments on commit dd4c574

Please sign in to comment.