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.
  • Loading branch information
vtjnash committed Sep 14, 2021
1 parent 8f0b17b commit cb5a5bc
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 @@ -27,31 +27,6 @@ function try_compute_fieldidx_args(typ::DataType, args::Vector{Any})
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 @@ -1209,12 +1184,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 @@ -524,7 +514,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 @@ -586,8 +576,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,
slottypes::Vector{Any})
function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree,
defuses::Vector{SlotInfo}, slottypes::Vector{Any})
code = ir.stmts.inst
cfg = ir.cfg
left = Int[]
Expand Down Expand Up @@ -616,7 +606,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse,
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 @@ -671,9 +661,9 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse,
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 cb5a5bc

Please sign in to comment.