Skip to content

Commit

Permalink
IncrementalCompact: fix display of basic block boundaries. (#47043)
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt authored Oct 4, 2022
1 parent b9d539d commit 81c7220
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 5 deletions.
48 changes: 43 additions & 5 deletions base/compiler/ssair/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,8 @@ function show_ir(io::IO, ci::CodeInfo, config::IRShowConfig=default_config(ci);
end

function show_ir(io::IO, compact::IncrementalCompact, config::IRShowConfig=default_config(compact.ir))
compact_cfg = CFG(compact.result_bbs, Int[first(compact.result_bbs[i].stmts) for i in 2:length(compact.result_bbs)])
cfg = compact.ir.cfg
(_, width) = displaysize(io)


# First print everything that has already been compacted

Expand All @@ -856,27 +855,66 @@ function show_ir(io::IO, compact::IncrementalCompact, config::IRShowConfig=defau
push!(used_compacted, i)
end
end

# while compacting, the end of the active result bb will not have been determined
# (this is done post-hoc by `finish_current_bb!`), so determine it here from scratch.
result_bbs = copy(compact.result_bbs)
if compact.active_result_bb <= length(result_bbs)
# count the total number of nodes we'll add to this block
input_bb_idx = block_for_inst(compact.ir.cfg, compact.idx)
input_bb = compact.ir.cfg.blocks[input_bb_idx]
count = 0
for input_idx in input_bb.stmts.start:input_bb.stmts.stop
pop_new_node! = new_nodes_iter(compact.ir)
while pop_new_node!(input_idx) !== nothing
count += 1
end
end

result_bb = result_bbs[compact.active_result_bb]
result_bbs[compact.active_result_bb] = Core.Compiler.BasicBlock(result_bb,
Core.Compiler.StmtRange(first(result_bb.stmts), last(result_bb.stmts)+count))
end
compact_cfg = CFG(result_bbs, Int[first(result_bbs[i].stmts) for i in 2:length(result_bbs)])

pop_new_node! = new_nodes_iter(compact)
maxssaid = length(compact.result) + Core.Compiler.length(compact.new_new_nodes)
bb_idx = let io = IOContext(io, :maxssaid=>maxssaid)
show_ir_stmts(io, compact, 1:compact.result_idx-1, config, used_compacted, compact_cfg, 1; pop_new_node!)
show_ir_stmts(io, compact, 1:compact.result_idx-1, config, used_compacted,
compact_cfg, 1; pop_new_node!)
end


# Print uncompacted nodes from the original IR

# print a separator
(_, width) = displaysize(io)
stmts = compact.ir.stmts
indent = length(string(length(stmts)))
# config.line_info_preprinter(io, "", compact.idx)
printstyled(io, ""^(width-indent-1), '\n', color=:red)

# while compacting, the start of the active uncompacted bb will have been overwritten.
# this manifests as a stmt range end that is less than the start, so correct that.
inputs_bbs = copy(cfg.blocks)
for (i, bb) in enumerate(inputs_bbs)
if bb.stmts.stop < bb.stmts.start
inputs_bbs[i] = Core.Compiler.BasicBlock(bb,
Core.Compiler.StmtRange(last(bb.stmts), last(bb.stmts)))
# this is not entirely correct, and will result in the bb starting again,
# but is the best we can do without changing how `finish_current_bb!` works.
end
end
uncompacted_cfg = CFG(inputs_bbs, Int[first(inputs_bbs[i].stmts) for i in 2:length(inputs_bbs)])

pop_new_node! = new_nodes_iter(compact.ir, compact.new_nodes_idx)
maxssaid = length(compact.ir.stmts) + Core.Compiler.length(compact.ir.new_nodes)
let io = IOContext(io, :maxssaid=>maxssaid)
show_ir_stmts(io, compact.ir, compact.idx:length(stmts), config, used_uncompacted, cfg, bb_idx; pop_new_node!)
show_ir_stmts(io, compact.ir, compact.idx:length(stmts), config, used_uncompacted,
uncompacted_cfg, bb_idx; pop_new_node!)
end

finish_show_ir(io, cfg, config)
finish_show_ir(io, uncompacted_cfg, config)
end

function effectbits_letter(effects::Effects, name::Symbol, suffix::Char)
Expand Down
37 changes: 37 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2479,3 +2479,40 @@ end
ir = Core.Compiler.complete(compact)
@test lines_shown(compact) == instructions + 1
end

@testset "#46424: IncrementalCompact displays wrong basic-block boundaries" begin
# get some cfg
function foo(i)
j = i+42
j == 1 ? 1 : 2
end
ir = only(Base.code_ircode(foo, (Int,)))[1]

# at every point we should be able to observe these three basic blocks
function verify_display(ir)
str = sprint(io->show(io, ir))
@test contains(str, "1 ─ %1 = ")
@test contains(str, r"2 ─ \s+ return 1")
@test contains(str, r"3 ─ \s+ return 2")
end
verify_display(ir)

# insert some instructions
for i in 1:3
inst = Core.Compiler.NewInstruction(Expr(:call, :identity, i), Int)
Core.Compiler.insert_node!(ir, 2, inst)
end

# compact
compact = Core.Compiler.IncrementalCompact(ir)
verify_display(compact)
state = Core.Compiler.iterate(compact)
while state !== nothing
verify_display(compact)
state = Core.Compiler.iterate(compact, state[2])
end

# complete
ir = Core.Compiler.complete(compact)
verify_display(ir)
end

0 comments on commit 81c7220

Please sign in to comment.