Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions Compiler/src/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
block = block_for_inst(ir, idx)
inline_into_block!(state, block)

if !isempty(inlinee_cfg.blocks[1].preds)
if length(inlinee_cfg.blocks[1].preds) > 1
need_split_before = true
else
@assert inlinee_cfg.blocks[1].preds[1] == 0
end

last_block_idx = last(state.cfg.blocks[block].stmts)
if false # TODO: ((idx+1) == last_block_idx && isa(ir[SSAValue(last_block_idx)], GotoNode))
need_split = false
Expand Down Expand Up @@ -166,12 +167,18 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
end
new_block_range = (length(state.new_cfg_blocks)-length(inlinee_cfg.blocks)+1):length(state.new_cfg_blocks)

# Fixup the edges of the newely added blocks
# Fixup the edges of the newly added blocks
for (old_block, new_block) in enumerate(bb_rename_range)
if old_block != 1 || need_split_before
p = state.new_cfg_blocks[new_block].preds
let bb_rename_range = bb_rename_range
map!(p, p) do old_pred_block
# the meaning of predecessor 0 depends on the block we encounter it:
# - in the first block, it represents the function entry and so needs to be re-mapped
if old_block == 1 && old_pred_block == 0
return first(bb_rename_range) - 1
end
# - elsewhere, it represents external control-flow from a caught exception which is un-affected by inlining
return old_pred_block == 0 ? 0 : bb_rename_range[old_pred_block]
end
end
Expand All @@ -186,10 +193,6 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
end
end

if need_split_before
push!(state.new_cfg_blocks[first(bb_rename_range)].preds, first(bb_rename_range)-1)
end

any_edges = false
for (old_block, new_block) in enumerate(bb_rename_range)
if (length(state.new_cfg_blocks[new_block].succs) == 0)
Expand Down Expand Up @@ -399,7 +402,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
else
bb_offset, post_bb_id = popfirst!(todo_bbs)
# This implements the need_split_before flag above
need_split_before = !isempty(item.ir.cfg.blocks[1].preds)
need_split_before = length(item.ir.cfg.blocks[1].preds) > 1
if need_split_before
finish_current_bb!(compact, 0)
end
Expand Down
3 changes: 3 additions & 0 deletions Compiler/src/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ function compute_basic_blocks(stmts::Vector{Any})
end
# Compute successors/predecessors
for (num, b) in enumerate(blocks)
if b.stmts.start == 1
push!(b.preds, 0) # the entry block has a virtual predecessor
end
terminator = stmts[last(b.stmts)]
if isa(terminator, ReturnNode)
# return never has any successors
Expand Down
20 changes: 20 additions & 0 deletions Compiler/test/ssair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -825,3 +825,23 @@ end

@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = "nonexisting pass name")
@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = typemax(Int))

#57153 check that the CFG has a #0 block predecessor and that we don't fail to compile code that observes that
function _worker_task57153()
while true
r = let
try
if @noinline rand(Bool)
return nothing
end
q, m
finally
missing
end
end
r[1]::Bool
end
end
let ir = Base.code_ircode(_worker_task57153, (), optimize_until="CC: COMPACT_2")[1].first
@test findfirst(x->x==0, ir.cfg.blocks[1].preds) !== nothing
end