Skip to content

Commit

Permalink
IncrementalCompact: Don't corrupt CFG when finishing early
Browse files Browse the repository at this point in the history
Finishing an IncrementalComapact before iterating the whole underlying
IRCode is not something that we really do in base, or at least not in
places other than a basic block boundary. However, it can be useful
for downstream consumers, so make it work anyway. Also create a
separate test file for IncrementalCompact tests (of which we really
should have more) and move one existing test.
  • Loading branch information
Keno committed Apr 29, 2024
1 parent 96866cb commit 9b401ba
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 26 deletions.
10 changes: 6 additions & 4 deletions base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2064,9 +2064,11 @@ function non_dce_finish!(compact::IncrementalCompact)
result_idx = compact.result_idx
resize!(compact.result, result_idx - 1)
just_fixup!(compact)
bb = compact.cfg_transform.result_bbs[end]
compact.cfg_transform.result_bbs[end] = BasicBlock(bb,
StmtRange(first(bb.stmts), result_idx-1))
if !did_just_finish_bb(compact)
# Finish the bb now
finish_current_bb!(compact, 0)
end
result_bbs = resize!(compact.cfg_transform.result_bbs, compact.active_result_bb-1)
compact.renamed_new_nodes = true
nothing
end
Expand All @@ -2078,7 +2080,7 @@ function finish(compact::IncrementalCompact)
end

function complete(compact::IncrementalCompact)
result_bbs = resize!(compact.cfg_transform.result_bbs, compact.active_result_bb-1)
result_bbs = compact.cfg_transform.result_bbs
cfg = CFG(result_bbs, Int[first(result_bbs[i].stmts) for i in 2:length(result_bbs)])
if should_check_ssa_counts()
oracle_check(compact)
Expand Down
2 changes: 1 addition & 1 deletion test/choosetests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ function choosetests(choices = [])
# do subarray before sparse but after linalg
filtertests!(tests, "subarray")
filtertests!(tests, "compiler", [
"compiler/datastructures", "compiler/inference", "compiler/effects",
"compiler/datastructures", "compiler/inference", "compiler/effects", "compiler/compact",
"compiler/validation", "compiler/ssair", "compiler/irpasses", "compiler/tarjan",
"compiler/codegen", "compiler/inline", "compiler/contextual", "compiler/invalidation",
"compiler/AbstractInterpreter", "compiler/EscapeAnalysis/EscapeAnalysis"])
Expand Down
37 changes: 37 additions & 0 deletions test/compiler/compact.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Core.Compiler: IncrementalCompact, insert_node_here!, finish,
NewInstruction, verify_ir, ReturnNode, SSAValue

foo_test_function(i) = i == 1 ? 1 : 2

@testset "IncrementalCompact statefulness" begin
ir = only(Base.code_ircode(foo_test_function, (Int,)))[1]
compact = IncrementalCompact(ir)

# set up first iterator
x = Core.Compiler.iterate(compact)
x = Core.Compiler.iterate(compact, x[2])

# set up second iterator
x = Core.Compiler.iterate(compact)

# consume remainder
while x !== nothing
x = Core.Compiler.iterate(compact, x[2])
end

ir = finish(compact)
@test Core.Compiler.verify_ir(ir) === nothing
end

# Test early finish of IncrementalCompact
@testset "IncrementalCompact early finish" begin
ir = only(Base.code_ircode(foo_test_function, (Int,)))[1]
compact = IncrementalCompact(ir)

insert_node_here!(compact, NewInstruction(ReturnNode(1), Union{}, ir[SSAValue(1)][:line]))
new_ir = finish(compact)
# TODO: Should IncrementalCompact be doing this internally?
empty!(new_ir.cfg.blocks[1].succs)
verify_ir(new_ir)
@test length(new_ir.cfg.blocks) == 1
end
21 changes: 0 additions & 21 deletions test/compiler/ssair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -589,27 +589,6 @@ end
@test show(devnull, ir) === nothing
end

@testset "IncrementalCompact statefulness" begin
foo(i) = i == 1 ? 1 : 2
ir = only(Base.code_ircode(foo, (Int,)))[1]
compact = Core.Compiler.IncrementalCompact(ir)

# set up first iterator
x = Core.Compiler.iterate(compact)
x = Core.Compiler.iterate(compact, x[2])

# set up second iterator
x = Core.Compiler.iterate(compact)

# consume remainder
while x !== nothing
x = Core.Compiler.iterate(compact, x[2])
end

ir = Core.Compiler.complete(compact)
@test Core.Compiler.verify_ir(ir) === nothing
end

# insert_node! operations
# =======================

Expand Down

0 comments on commit 9b401ba

Please sign in to comment.