Skip to content

Commit 81c7220

Browse files
authored
IncrementalCompact: fix display of basic block boundaries. (#47043)
1 parent b9d539d commit 81c7220

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

base/compiler/ssair/show.jl

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -842,9 +842,8 @@ function show_ir(io::IO, ci::CodeInfo, config::IRShowConfig=default_config(ci);
842842
end
843843

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

849848
# First print everything that has already been compacted
850849

@@ -856,27 +855,66 @@ function show_ir(io::IO, compact::IncrementalCompact, config::IRShowConfig=defau
856855
push!(used_compacted, i)
857856
end
858857
end
858+
859+
# while compacting, the end of the active result bb will not have been determined
860+
# (this is done post-hoc by `finish_current_bb!`), so determine it here from scratch.
861+
result_bbs = copy(compact.result_bbs)
862+
if compact.active_result_bb <= length(result_bbs)
863+
# count the total number of nodes we'll add to this block
864+
input_bb_idx = block_for_inst(compact.ir.cfg, compact.idx)
865+
input_bb = compact.ir.cfg.blocks[input_bb_idx]
866+
count = 0
867+
for input_idx in input_bb.stmts.start:input_bb.stmts.stop
868+
pop_new_node! = new_nodes_iter(compact.ir)
869+
while pop_new_node!(input_idx) !== nothing
870+
count += 1
871+
end
872+
end
873+
874+
result_bb = result_bbs[compact.active_result_bb]
875+
result_bbs[compact.active_result_bb] = Core.Compiler.BasicBlock(result_bb,
876+
Core.Compiler.StmtRange(first(result_bb.stmts), last(result_bb.stmts)+count))
877+
end
878+
compact_cfg = CFG(result_bbs, Int[first(result_bbs[i].stmts) for i in 2:length(result_bbs)])
879+
859880
pop_new_node! = new_nodes_iter(compact)
860881
maxssaid = length(compact.result) + Core.Compiler.length(compact.new_new_nodes)
861882
bb_idx = let io = IOContext(io, :maxssaid=>maxssaid)
862-
show_ir_stmts(io, compact, 1:compact.result_idx-1, config, used_compacted, compact_cfg, 1; pop_new_node!)
883+
show_ir_stmts(io, compact, 1:compact.result_idx-1, config, used_compacted,
884+
compact_cfg, 1; pop_new_node!)
863885
end
864886

887+
865888
# Print uncompacted nodes from the original IR
866889

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

897+
# while compacting, the start of the active uncompacted bb will have been overwritten.
898+
# this manifests as a stmt range end that is less than the start, so correct that.
899+
inputs_bbs = copy(cfg.blocks)
900+
for (i, bb) in enumerate(inputs_bbs)
901+
if bb.stmts.stop < bb.stmts.start
902+
inputs_bbs[i] = Core.Compiler.BasicBlock(bb,
903+
Core.Compiler.StmtRange(last(bb.stmts), last(bb.stmts)))
904+
# this is not entirely correct, and will result in the bb starting again,
905+
# but is the best we can do without changing how `finish_current_bb!` works.
906+
end
907+
end
908+
uncompacted_cfg = CFG(inputs_bbs, Int[first(inputs_bbs[i].stmts) for i in 2:length(inputs_bbs)])
909+
873910
pop_new_node! = new_nodes_iter(compact.ir, compact.new_nodes_idx)
874911
maxssaid = length(compact.ir.stmts) + Core.Compiler.length(compact.ir.new_nodes)
875912
let io = IOContext(io, :maxssaid=>maxssaid)
876-
show_ir_stmts(io, compact.ir, compact.idx:length(stmts), config, used_uncompacted, cfg, bb_idx; pop_new_node!)
913+
show_ir_stmts(io, compact.ir, compact.idx:length(stmts), config, used_uncompacted,
914+
uncompacted_cfg, bb_idx; pop_new_node!)
877915
end
878916

879-
finish_show_ir(io, cfg, config)
917+
finish_show_ir(io, uncompacted_cfg, config)
880918
end
881919

882920
function effectbits_letter(effects::Effects, name::Symbol, suffix::Char)

test/show.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,3 +2479,40 @@ end
24792479
ir = Core.Compiler.complete(compact)
24802480
@test lines_shown(compact) == instructions + 1
24812481
end
2482+
2483+
@testset "#46424: IncrementalCompact displays wrong basic-block boundaries" begin
2484+
# get some cfg
2485+
function foo(i)
2486+
j = i+42
2487+
j == 1 ? 1 : 2
2488+
end
2489+
ir = only(Base.code_ircode(foo, (Int,)))[1]
2490+
2491+
# at every point we should be able to observe these three basic blocks
2492+
function verify_display(ir)
2493+
str = sprint(io->show(io, ir))
2494+
@test contains(str, "1 ─ %1 = ")
2495+
@test contains(str, r"2 ─ \s+ return 1")
2496+
@test contains(str, r"3 ─ \s+ return 2")
2497+
end
2498+
verify_display(ir)
2499+
2500+
# insert some instructions
2501+
for i in 1:3
2502+
inst = Core.Compiler.NewInstruction(Expr(:call, :identity, i), Int)
2503+
Core.Compiler.insert_node!(ir, 2, inst)
2504+
end
2505+
2506+
# compact
2507+
compact = Core.Compiler.IncrementalCompact(ir)
2508+
verify_display(compact)
2509+
state = Core.Compiler.iterate(compact)
2510+
while state !== nothing
2511+
verify_display(compact)
2512+
state = Core.Compiler.iterate(compact, state[2])
2513+
end
2514+
2515+
# complete
2516+
ir = Core.Compiler.complete(compact)
2517+
verify_display(ir)
2518+
end

0 commit comments

Comments
 (0)