Skip to content

Commit 7e16e14

Browse files
gbaralditopolarity
authored andcommitted
Add 0 predecessor to entry basic block and handle it in inlining (#58683)
(cherry picked from commit da00451)
1 parent e35e82b commit 7e16e14

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
@@ -818,3 +818,23 @@ let cl = Int32[32, 1, 1, 1000, 240, 230]
818818
cl2 = ccall(:jl_uncompress_codelocs, Any, (Any, Int), str, 2)
819819
@test cl == cl2
820820
end
821+
822+
#57153 check that the CFG has a #0 block predecessor and that we don't fail to compile code that observes that
823+
function _worker_task57153()
824+
while true
825+
r = let
826+
try
827+
if @noinline rand(Bool)
828+
return nothing
829+
end
830+
q, m
831+
finally
832+
missing
833+
end
834+
end
835+
r[1]::Bool
836+
end
837+
end
838+
let ir = Base.code_ircode(_worker_task57153, (), optimize_until="CC: COMPACT_2")[1].first
839+
@test findfirst(x->x==0, ir.cfg.blocks[1].preds) !== nothing
840+
end

0 commit comments

Comments
 (0)