Skip to content

Commit

Permalink
Fix bug when inlining pending nodes
Browse files Browse the repository at this point in the history
While working on IR, we give pending nodes SSA ids after the main
body of the function, and then we drop them in place during compaction.
Inlining was using thse IDs to try to determine which basic block
we're currently inlining into, but for pending blocks it was looking
at the raw ID rather than the insertion position, corrupting the CFG.

Fixes #37555
Fixes #37182
  • Loading branch information
Keno committed Sep 17, 2020
1 parent 2bd31a0 commit c2eef6a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
14 changes: 7 additions & 7 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ function inline_into_block!(state::CFGInliningState, block::Int)
return
end

function cfg_inline_item!(idx::Int, spec::ResolvedInliningSpec, state::CFGInliningState, from_unionsplit::Bool=false)
function cfg_inline_item!(ir::IRCode, idx::Int, spec::ResolvedInliningSpec, state::CFGInliningState, from_unionsplit::Bool=false)
inlinee_cfg = spec.ir.cfg
# Figure out if we need to split the BB
need_split_before = false
need_split = true
block = block_for_inst(state.cfg, idx)
block = block_for_inst(ir, idx)
inline_into_block!(state, block)

if !isempty(inlinee_cfg.blocks[1].preds)
Expand Down Expand Up @@ -206,8 +206,8 @@ function cfg_inline_item!(idx::Int, spec::ResolvedInliningSpec, state::CFGInlini
end
end

function cfg_inline_unionsplit!(idx::Int, item::UnionSplit, state::CFGInliningState)
block = block_for_inst(state.cfg, idx)
function cfg_inline_unionsplit!(ir::IRCode, idx::Int, item::UnionSplit, state::CFGInliningState)
block = block_for_inst(ir, idx)
inline_into_block!(state, block)
from_bbs = Int[]
delete!(state.split_targets, length(state.new_cfg_blocks))
Expand All @@ -223,7 +223,7 @@ function cfg_inline_unionsplit!(idx::Int, item::UnionSplit, state::CFGInliningSt
if isa(case, InliningTodo)
spec = case.spec::ResolvedInliningSpec
if !spec.linear_inline_eligible
cfg_inline_item!(idx, spec, state, true)
cfg_inline_item!(ir, idx, spec, state, true)
end
end
bb = length(state.new_cfg_blocks)
Expand Down Expand Up @@ -501,13 +501,13 @@ function batch_inline!(todo::Vector{Pair{Int, Any}}, ir::IRCode, linetable::Vect
state = CFGInliningState(ir)
for (idx, item) in todo
if isa(item, UnionSplit)
cfg_inline_unionsplit!(idx, item::UnionSplit, state)
cfg_inline_unionsplit!(ir, idx, item::UnionSplit, state)
else
item = item::InliningTodo
spec = item.spec::ResolvedInliningSpec
# A linear inline does not modify the CFG
spec.linear_inline_eligible && continue
cfg_inline_item!(idx, spec, state, false)
cfg_inline_item!(ir, idx, spec, state, false)
end
end
finish_cfg_inline!(state)
Expand Down
7 changes: 7 additions & 0 deletions base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ struct IRCode
copy(ir.linetable), copy(ir.cfg), copy(ir.new_nodes), copy(ir.meta))
end

function block_for_inst(ir::IRCode, inst::Int)
if inst > length(ir.stmts)
inst = ir.new_nodes.info[inst - length(ir.stmts)].pos
end
block_for_inst(ir.cfg, inst)
end

function getindex(x::IRCode, s::SSAValue)
if s.id <= length(x.stmts)
return x.stmts[s.id][:inst]
Expand Down

0 comments on commit c2eef6a

Please sign in to comment.