Skip to content

Commit da00451

Browse files
authored
Add 0 predecessor to entry basic block and handle it in inlining (#58683)
1 parent cdb158b commit da00451

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

Compiler/src/ssair/inlining.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,11 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
126126
block = block_for_inst(ir, idx)
127127
inline_into_block!(state, block)
128128

129-
if !isempty(inlinee_cfg.blocks[1].preds)
129+
if length(inlinee_cfg.blocks[1].preds) > 1
130130
need_split_before = true
131+
else
132+
@assert inlinee_cfg.blocks[1].preds[1] == 0
131133
end
132-
133134
last_block_idx = last(state.cfg.blocks[block].stmts)
134135
if false # TODO: ((idx+1) == last_block_idx && isa(ir[SSAValue(last_block_idx)], GotoNode))
135136
need_split = false
@@ -166,12 +167,18 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
166167
end
167168
new_block_range = (length(state.new_cfg_blocks)-length(inlinee_cfg.blocks)+1):length(state.new_cfg_blocks)
168169

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

189-
if need_split_before
190-
push!(state.new_cfg_blocks[first(bb_rename_range)].preds, first(bb_rename_range)-1)
191-
end
192-
193196
any_edges = false
194197
for (old_block, new_block) in enumerate(bb_rename_range)
195198
if (length(state.new_cfg_blocks[new_block].succs) == 0)
@@ -399,7 +402,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
399402
else
400403
bb_offset, post_bb_id = popfirst!(todo_bbs)
401404
# This implements the need_split_before flag above
402-
need_split_before = !isempty(item.ir.cfg.blocks[1].preds)
405+
need_split_before = length(item.ir.cfg.blocks[1].preds) > 1
403406
if need_split_before
404407
finish_current_bb!(compact, 0)
405408
end

Compiler/src/ssair/ir.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ function compute_basic_blocks(stmts::Vector{Any})
105105
end
106106
# Compute successors/predecessors
107107
for (num, b) in enumerate(blocks)
108+
if b.stmts.start == 1
109+
push!(b.preds, 0) # the entry block has a virtual predecessor
110+
end
108111
terminator = stmts[last(b.stmts)]
109112
if isa(terminator, ReturnNode)
110113
# return never has any successors

Compiler/test/ssair.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,3 +825,23 @@ end
825825

826826
@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = "nonexisting pass name")
827827
@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = typemax(Int))
828+
829+
#57153 check that the CFG has a #0 block predecessor and that we don't fail to compile code that observes that
830+
function _worker_task57153()
831+
while true
832+
r = let
833+
try
834+
if @noinline rand(Bool)
835+
return nothing
836+
end
837+
q, m
838+
finally
839+
missing
840+
end
841+
end
842+
r[1]::Bool
843+
end
844+
end
845+
let ir = Base.code_ircode(_worker_task57153, (), optimize_until="CC: COMPACT_2")[1].first
846+
@test findfirst(x->x==0, ir.cfg.blocks[1].preds) !== nothing
847+
end

0 commit comments

Comments
 (0)