Skip to content

Commit a034aa1

Browse files
authored
domtree: Optimize DFS! allocations (JuliaLang#52880)
Since `DFS!` is a decent fraction of the work for updating the domtree, this should be a noticeable improvement to semi-concrete eval for very large functions. Profiling downstream shows a lot of time spent `push!`ing into the worklist and creating temporary arrays.
1 parent 8a69745 commit a034aa1

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

base/compiler/ssair/domtree.jl

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,25 @@ struct DFSTree
8282
# (preorder number -> preorder number)
8383
# Storing it this way saves a few lookups in the snca_compress! algorithm
8484
to_parent_pre::Vector{PreNumber}
85+
86+
_worklist::Vector{Tuple{BBNumber, PreNumber, Bool}}
8587
end
8688

8789
function DFSTree(n_blocks::Int)
8890
return DFSTree(zeros(PreNumber, n_blocks),
8991
Vector{BBNumber}(undef, n_blocks),
9092
zeros(PostNumber, n_blocks),
9193
Vector{BBNumber}(undef, n_blocks),
92-
zeros(PreNumber, n_blocks))
94+
zeros(PreNumber, n_blocks),
95+
Vector{Tuple{BBNumber, PreNumber, Bool}}())
9396
end
9497

9598
copy(D::DFSTree) = DFSTree(copy(D.to_pre),
9699
copy(D.from_pre),
97100
copy(D.to_post),
98101
copy(D.from_post),
99-
copy(D.to_parent_pre))
102+
copy(D.to_parent_pre),
103+
copy(D._worklist))
100104

101105
function copy!(dst::DFSTree, src::DFSTree)
102106
copy!(dst.to_pre, src.to_pre)
@@ -106,17 +110,26 @@ function copy!(dst::DFSTree, src::DFSTree)
106110
copy!(dst.to_parent_pre, src.to_parent_pre)
107111
return dst
108112
end
113+
function resize!(D::DFSTree, n::Integer)
114+
resize!(D.to_pre, n)
115+
resize!(D.from_pre, n)
116+
resize!(D.to_post, n)
117+
resize!(D.from_post, n)
118+
resize!(D.to_parent_pre, n)
119+
end
109120

110121
length(D::DFSTree) = length(D.from_pre)
111122

112123
function DFS!(D::DFSTree, blocks::Vector{BasicBlock}, is_post_dominator::Bool)
113-
copy!(D, DFSTree(length(blocks)))
124+
resize!(D, length(blocks))
125+
fill!(D.to_pre, 0)
126+
to_visit = D._worklist # always starts empty
114127
if is_post_dominator
115128
# TODO: We're using -1 as the virtual exit node here. Would it make
116129
# sense to actually have a real BB for the exit always?
117-
to_visit = Tuple{BBNumber, PreNumber, Bool}[(-1, 0, false)]
130+
push!(to_visit, (-1, 0, false))
118131
else
119-
to_visit = Tuple{BBNumber, PreNumber, Bool}[(1, 0, false)]
132+
push!(to_visit, (1, 0, false))
120133
end
121134
pre_num = is_post_dominator ? 0 : 1
122135
post_num = 1

0 commit comments

Comments
 (0)