~ninjin/julia-nix

cb5a5bcef970d70799cd0dff127fc09bf67ebf11 — Jameson Nash 2 years ago 8f0b17b
inference: remove code that relies upon inferring the output type

Recursing into inference may be unreliable during inference.
M base/compiler/ssair/inlining.jl => base/compiler/ssair/inlining.jl +1 -1
@@ 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

M base/compiler/ssair/passes.jl => base/compiler/ssair/passes.jl +2 -27
@@ 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


@@ 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[

M base/compiler/ssair/show.jl => base/compiler/ssair/show.jl +4 -3
@@ 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, ')')

M base/compiler/ssair/slot2ssa.jl => base/compiler/ssair/slot2ssa.jl +6 -16
@@ 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]


@@ 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


@@ 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[]


@@ 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


@@ 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)

M src/gf.c => src/gf.c +3 -2
@@ 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);