1
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2
2
3
+ " Represents a Basic Block, in the DomTree"
3
4
struct DomTreeNode
5
+ # How deep we are in the DomTree
4
6
level:: Int
7
+ # The BB indices in the CFG for all Basic Blocks we immediately dominate
5
8
children:: Vector{Int}
6
9
end
7
10
DomTreeNode () = DomTreeNode (1 , Vector {Int} ())
8
11
12
+ " Data structure that encodes which basic block dominates which."
9
13
struct DomTree
14
+ # Which basic block immediately dominates each basic block (ordered by BB indices)
15
+ # Note: this is the inverse of the nodes, children field
10
16
idoms:: Vector{Int}
17
+
18
+ # The nodes in the tree (ordered by BB indices)
11
19
nodes:: Vector{DomTreeNode}
12
20
end
13
21
14
22
"""
15
- Checks if bb1 dominates bb2
23
+ Checks if bb1 dominates bb2.
24
+ bb1 and bb2 are indexes into the CFG blocks.
25
+ bb1 dominates bb2 if the only way to enter bb2 is via bb1.
26
+ (Other blocks may be in between, e.g bb1->bbX->bb2).
16
27
"""
17
28
function dominates (domtree:: DomTree , bb1:: Int , bb2:: Int )
18
29
bb1 == bb2 && return true
@@ -38,11 +49,13 @@ function update_level!(domtree::Vector{DomTreeNode}, node::Int, level::Int)
38
49
end
39
50
end
40
51
52
+ " Iterable data structure that walks though all dominated blocks"
41
53
struct DominatedBlocks
42
54
domtree:: DomTree
43
55
worklist:: Vector{Int}
44
56
end
45
57
58
+ " Returns an iterator that walks through all blocks dominated by the basic block at index `root`"
46
59
function dominated (domtree:: DomTree , root:: Int )
47
60
doms = DominatedBlocks (domtree, Vector {Int} ())
48
61
push! (doms. worklist, root)
@@ -222,7 +235,7 @@ begin
222
235
v:: DFSNumber , last_linked:: DFSNumber )
223
236
# TODO : There is a smarter way to do this
224
237
u = ancestors[v]
225
- worklist = Tuple{Int, Int }[(u,v)]
238
+ worklist = Tuple{DFSNumber, DFSNumber }[(u,v)]
226
239
@assert u < v
227
240
while ! isempty (worklist)
228
241
u, v = last (worklist)
@@ -241,6 +254,11 @@ begin
241
254
end
242
255
243
256
"""
257
+ SNCA(cfg::CFG)
258
+
259
+ Determines a map from basic blocks to the block which immediately dominate them.
260
+ Expressed as indexes into `cfg.blocks`.
261
+
244
262
The main Semi-NCA algrithm. Matches Figure 2.8 in [LG05].
245
263
Note that the pseudocode in [LG05] is not entirely accurate.
246
264
The best way to understand what's happening is to read [LT79], then the
@@ -253,7 +271,7 @@ begin
253
271
# the paper doesn't make that clear). The rational for this is Lemma
254
272
# 2.4 in [LG05] (i.e. Theorem 4 in ). Note however, that we don't
255
273
# ever look at `semi` until it is fully initialized, so we could leave
256
- # it unitialized here if we wanted to.
274
+ # it uninitialized here if we wanted to.
257
275
state = Node[ Node (typemax (DFSNumber), w) for w in preorder (D) ]
258
276
# Initialize idoms to parents. Note that while idoms are eventually
259
277
# BB indexed, we keep it DFS indexed until a final post-processing
@@ -302,6 +320,7 @@ begin
302
320
end
303
321
idoms_dfs[v] = idom
304
322
end
323
+ # Reexpress the idom relationship in BB indexing
305
324
idoms_bb = Int[ (i == 1 || D. reverse[i] == 0 ) ? 0 : D. numbering[idoms_dfs[D. reverse[i]]] for i = 1 : length (cfg. blocks) ]
306
325
idoms_bb
307
326
end
0 commit comments