Skip to content

Commit b799cf4

Browse files
yhlsvchuravy
authored andcommitted
Make domtree construction take Vector{BasicBlock} as input instead of CFG
This is in anticipation of domtrees being added to CFGs.
1 parent a5f5e8a commit b799cf4

File tree

6 files changed

+51
-51
lines changed

6 files changed

+51
-51
lines changed

base/compiler/ssair/domtree.jl

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ function DFS!(D::DFSTree, blocks::Vector{BasicBlock})
144144
to_visit[end] = (current_node_bb, parent_pre, true)
145145

146146
# Push children to the stack
147-
for succ_bb in cfg.blocks[current_node_bb].succs
147+
for succ_bb in blocks[current_node_bb].succs
148148
push!(to_visit, (succ_bb, pre_num, false))
149149
end
150150

@@ -200,11 +200,11 @@ function DomTree()
200200
return DomTree(DFSTree(0), SNCAData[], BBNumber[], DomTreeNode[])
201201
end
202202

203-
function construct_domtree(cfg::CFG)
204-
return update_domtree!(cfg, DomTree(), true, 0)
203+
function construct_domtree(blocks::Vector{BasicBlock})
204+
return update_domtree!(blocks, DomTree(), true, 0)
205205
end
206206

207-
function update_domtree!(cfg::CFG, domtree::DomTree,
207+
function update_domtree!(blocks::Vector{BasicBlock}, domtree::DomTree,
208208
recompute_dfs::Bool, max_pre::PreNumber)
209209
if recompute_dfs
210210
DFS!(domtree.dfs_tree, blocks)
@@ -214,7 +214,7 @@ function update_domtree!(cfg::CFG, domtree::DomTree,
214214
max_pre = length(domtree.dfs_tree)
215215
end
216216

217-
SNCA!(domtree, cfg, max_pre)
217+
SNCA!(domtree, blocks, max_pre)
218218
compute_domtree_nodes!(domtree)
219219
return domtree
220220
end
@@ -249,11 +249,11 @@ pseudocode in [LG05] is not entirely accurate. The best way to understand
249249
what's happening is to read [LT79], then the description of SLT in [LG05]
250250
(warning: inconsistent notation), then the description of Semi-NCA.
251251
"""
252-
function SNCA!(domtree::DomTree, cfg::CFG, max_pre::PreNumber)
252+
function SNCA!(domtree::DomTree, blocks::Vector{BasicBlock}, max_pre::PreNumber)
253253
D = domtree.dfs_tree
254254
state = domtree.snca_state
255255
# There may be more blocks than are reachable in the DFS / dominator tree
256-
n_blocks = length(cfg.blocks)
256+
n_blocks = length(blocks)
257257
n_nodes = length(D)
258258

259259
# `label` is initialized to the identity mapping (though the paper doesn't
@@ -275,7 +275,7 @@ function SNCA!(domtree::DomTree, cfg::CFG, max_pre::PreNumber)
275275
# worst we'll discover it below). Save a memory reference here.
276276
semi_w = typemax(PreNumber)
277277
last_linked = PreNumber(w + 1)
278-
for v cfg.blocks[D.from_pre[w]].preds
278+
for v blocks[D.from_pre[w]].preds
279279
# For the purpose of the domtree, ignore virtual predecessors into
280280
# catch blocks.
281281
v == 0 && continue
@@ -373,8 +373,8 @@ function snca_compress_worklist!(
373373
end
374374
end
375375

376-
"Given an updated CFG, update the given dominator tree with an inserted edge."
377-
function domtree_insert_edge!(domtree::DomTree, cfg::CFG,
376+
"Given updated blocks, update the given dominator tree with an inserted edge."
377+
function domtree_insert_edge!(domtree::DomTree, blocks::Vector{BasicBlock},
378378
from::BBNumber, to::BBNumber)
379379
# Implements Section 3.1 of [GI16]
380380
dt = domtree.dfs_tree
@@ -385,23 +385,23 @@ function domtree_insert_edge!(domtree::DomTree, cfg::CFG,
385385
if to_pre == 0 || (from_pre < to_pre && from_post < to_post)
386386
# The DFS tree is invalidated by the edge insertion, so run from
387387
# scratch
388-
update_domtree!(cfg, domtree, true, 0)
388+
update_domtree!(blocks, domtree, true, 0)
389389
else
390390
# DFS tree is still valid, so update only affected nodes
391-
update_domtree!(cfg, domtree, false, to_pre)
391+
update_domtree!(blocks, domtree, false, to_pre)
392392
end
393393

394394
return domtree
395395
end
396396

397-
"Given an updated CFG, update the given dominator tree with a deleted edge."
398-
function domtree_delete_edge!(domtree::DomTree, cfg::CFG,
397+
"Given updated blocks, update the given dominator tree with a deleted edge."
398+
function domtree_delete_edge!(domtree::DomTree, blocks::Vector{BasicBlock},
399399
from::BBNumber, to::BBNumber)
400400
# Implements Section 3.1 of [GI16]
401401
if is_parent(domtree.dfs_tree, from, to)
402402
# The `from` block is the parent of the `to` block in the DFS tree, so
403403
# deleting the edge invalidates the DFS tree, so start from scratch
404-
update_domtree!(cfg, domtree, true, 0)
404+
update_domtree!(blocks, domtree, true, 0)
405405
elseif on_semidominator_path(domtree, from, to)
406406
# Recompute semidominators for blocks with preorder number up to that
407407
# of `to` block. Semidominators for blocks with preorder number greater
@@ -410,7 +410,7 @@ function domtree_delete_edge!(domtree::DomTree, cfg::CFG,
410410
# `to` would be lower than those of these blocks, and `to` is not their
411411
# parent in the DFS tree).
412412
to_pre = domtree.dfs_tree.to_pre[to]
413-
update_domtree!(cfg, domtree, false, to_pre)
413+
update_domtree!(blocks, domtree, false, to_pre)
414414
end
415415
# Otherwise, dominator tree is not affected
416416

@@ -490,19 +490,19 @@ function iterate(doms::DominatedBlocks, state::Nothing=nothing)
490490
return (bb, nothing)
491491
end
492492

493-
function naive_idoms(cfg::CFG)
494-
nblocks = length(cfg.blocks)
493+
function naive_idoms(blocks::Vector{BasicBlock})
494+
nblocks = length(blocks)
495495
# The extra +1 helps us detect unreachable blocks below
496496
dom_all = BitSet(1:nblocks+1)
497497
dominators = BitSet[n == 1 ? BitSet(1) : copy(dom_all) for n = 1:nblocks]
498498
changed = true
499499
while changed
500500
changed = false
501501
for n = 2:nblocks
502-
if isempty(cfg.blocks[n].preds)
502+
if isempty(blocks[n].preds)
503503
continue
504504
end
505-
firstp, rest = Iterators.peel(Iterators.filter(p->p != 0, cfg.blocks[n].preds))
505+
firstp, rest = Iterators.peel(Iterators.filter(p->p != 0, blocks[n].preds))
506506
new_doms = copy(dominators[firstp])
507507
for p in rest
508508
intersect!(new_doms, dominators[p])

base/compiler/ssair/driver.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ end
111111

112112
function slot2reg(ir::IRCode, ci::CodeInfo, nargs::Int, sv::OptimizationState)
113113
# need `ci` for the slot metadata, IR for the code
114-
@timeit "domtree 1" domtree = construct_domtree(ir.cfg)
114+
@timeit "domtree 1" domtree = construct_domtree(ir.cfg.blocks)
115115
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.inst)
116116
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, nargs, sv.sptypes, sv.slottypes) # consumes `ir`
117117
return ir

base/compiler/ssair/passes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ function getfield_elim_pass!(ir::IRCode)
728728
# IR. This needs to be after we iterate through the IR with
729729
# `IncrementalCompact` because removing dead blocks can invalidate the
730730
# domtree.
731-
@timeit "domtree 2" domtree = construct_domtree(ir.cfg)
731+
@timeit "domtree 2" domtree = construct_domtree(ir.cfg.blocks)
732732

733733
# Now go through any mutable structs and see which ones we can eliminate
734734
for (idx, (intermediaries, defuse)) in defuses

base/compiler/ssair/verify.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function verify_ir(ir::IRCode, print::Bool=true)
6666
# Verify CFG
6767
last_end = 0
6868
# Verify statements
69-
domtree = construct_domtree(ir.cfg)
69+
domtree = construct_domtree(ir.cfg.blocks)
7070
for (idx, block) in pairs(ir.cfg.blocks)
7171
if first(block.stmts) != last_end + 1
7272
#ranges = [(idx,first(bb.stmts),last(bb.stmts)) for (idx, bb) in pairs(ir.cfg.blocks)]

test/compiler/irpasses.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ let m = Meta.@lower 1 + 1
3434
src.ssaflags = fill(Int32(0), nstmts)
3535
ir = Core.Compiler.inflate_ir(src)
3636
Core.Compiler.verify_ir(ir)
37-
domtree = Core.Compiler.construct_domtree(ir.cfg)
37+
domtree = Core.Compiler.construct_domtree(ir.cfg.blocks)
3838
ir = Core.Compiler.domsort_ssa!(ir, domtree)
3939
Core.Compiler.verify_ir(ir)
4040
phi = ir.stmts.inst[3]
@@ -62,7 +62,7 @@ let m = Meta.@lower 1 + 1
6262
src.ssaflags = fill(Int32(0), nstmts)
6363
ir = Core.Compiler.inflate_ir(src)
6464
Core.Compiler.verify_ir(ir)
65-
domtree = Core.Compiler.construct_domtree(ir.cfg)
65+
domtree = Core.Compiler.construct_domtree(ir.cfg.blocks)
6666
ir = Core.Compiler.domsort_ssa!(ir, domtree)
6767
Core.Compiler.verify_ir(ir)
6868
end

test/compiler/ssair.jl

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ let cfg = CFG(BasicBlock[
6767
make_bb([2, 3] , [5] ),
6868
make_bb([2, 4] , [] ),
6969
], Int[])
70-
dfs = Compiler.DFS(cfg)
70+
dfs = Compiler.DFS(cfg.blocks)
7171
@test dfs.from_pre[dfs.to_parent_pre[dfs.to_pre[5]]] == 4
72-
let correct_idoms = Compiler.naive_idoms(cfg)
73-
@test Compiler.construct_domtree(cfg).idoms_bb == correct_idoms
72+
let correct_idoms = Compiler.naive_idoms(cfg.blocks)
73+
@test Compiler.construct_domtree(cfg.blocks).idoms_bb == correct_idoms
7474
# For completeness, reverse the order of pred/succ in the CFG and verify
7575
# the answer doesn't change (it does change the which node is chosen
7676
# as the semi-dominator, since it changes the DFS numbering).
@@ -81,7 +81,7 @@ let cfg = CFG(BasicBlock[
8181
c && (blocks[4] = make_bb(reverse(blocks[4].preds), blocks[4].succs))
8282
d && (blocks[5] = make_bb(reverse(blocks[5].preds), blocks[5].succs))
8383
cfg′ = CFG(blocks, cfg.index)
84-
@test Compiler.construct_domtree(cfg′).idoms_bb == correct_idoms
84+
@test Compiler.construct_domtree(cfg′.blocks).idoms_bb == correct_idoms
8585
end
8686
end
8787
end
@@ -265,53 +265,53 @@ let cfg = CFG(BasicBlock[
265265
make_bb([2, 6], []),
266266
make_bb([4], [5, 3]),
267267
], Int[])
268-
domtree = Compiler.construct_domtree(cfg)
268+
domtree = Compiler.construct_domtree(cfg.blocks)
269269
@test domtree.dfs_tree.to_pre == [1, 2, 4, 5, 3, 6]
270-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
270+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
271271

272272
# Test removal of edge between a parent and child in the DFS tree, which
273273
# should trigger complete recomputation of domtree (first case in algorithm
274274
# for removing edge from domtree dynamically)
275275
Compiler.cfg_delete_edge!(cfg, 2, 5)
276-
Compiler.domtree_delete_edge!(domtree, cfg, 2, 5)
277-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 6, 4]
276+
Compiler.domtree_delete_edge!(domtree, cfg.blocks, 2, 5)
277+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 6, 4]
278278
# Add edge back (testing first case for insertion)
279279
Compiler.cfg_insert_edge!(cfg, 2, 5)
280-
Compiler.domtree_insert_edge!(domtree, cfg, 2, 5)
281-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
280+
Compiler.domtree_insert_edge!(domtree, cfg.blocks, 2, 5)
281+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
282282

283283
# Test second case in algorithm for removing edges from domtree, in which
284284
# `from` is on a semidominator path from the semidominator of `to` to `to`
285285
Compiler.cfg_delete_edge!(cfg, 6, 5)
286-
Compiler.domtree_delete_edge!(domtree, cfg, 6, 5)
287-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 2, 4]
286+
Compiler.domtree_delete_edge!(domtree, cfg.blocks, 6, 5)
287+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 2, 4]
288288
# Add edge back (testing second case for insertion)
289289
Compiler.cfg_insert_edge!(cfg, 6, 5)
290-
Compiler.domtree_insert_edge!(domtree, cfg, 6, 5)
291-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
290+
Compiler.domtree_insert_edge!(domtree, cfg.blocks, 6, 5)
291+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
292292

293293
# Test last case for removing edges, in which edge does not satisfy either
294294
# of the above conditions
295295
Compiler.cfg_delete_edge!(cfg, 6, 3)
296-
Compiler.domtree_delete_edge!(domtree, cfg, 6, 3)
297-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
296+
Compiler.domtree_delete_edge!(domtree, cfg.blocks, 6, 3)
297+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
298298
# Add edge back (testing second case for insertion)
299299
Compiler.cfg_insert_edge!(cfg, 6, 3)
300-
Compiler.domtree_insert_edge!(domtree, cfg, 6, 3)
301-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
300+
Compiler.domtree_insert_edge!(domtree, cfg.blocks, 6, 3)
301+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
302302

303303
# Try removing all edges from root
304304
Compiler.cfg_delete_edge!(cfg, 1, 2)
305-
Compiler.domtree_delete_edge!(domtree, cfg, 1, 2)
306-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 0, 1, 3, 6, 4]
305+
Compiler.domtree_delete_edge!(domtree, cfg.blocks, 1, 2)
306+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 0, 1, 3, 6, 4]
307307
Compiler.cfg_delete_edge!(cfg, 1, 3)
308-
Compiler.domtree_delete_edge!(domtree, cfg, 1, 3)
309-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 0, 0, 0, 0, 0]
308+
Compiler.domtree_delete_edge!(domtree, cfg.blocks, 1, 3)
309+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 0, 0, 0, 0, 0]
310310
# Add edges back
311311
Compiler.cfg_insert_edge!(cfg, 1, 2)
312-
Compiler.domtree_insert_edge!(domtree, cfg, 1, 2)
313-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 0, 0, 2, 0]
312+
Compiler.domtree_insert_edge!(domtree, cfg.blocks, 1, 2)
313+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 0, 0, 2, 0]
314314
Compiler.cfg_insert_edge!(cfg, 1, 3)
315-
Compiler.domtree_insert_edge!(domtree, cfg, 1, 3)
316-
@test domtree.idoms_bb == Compiler.naive_idoms(cfg) == [0, 1, 1, 3, 1, 4]
315+
Compiler.domtree_insert_edge!(domtree, cfg.blocks, 1, 3)
316+
@test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4]
317317
end

0 commit comments

Comments
 (0)