Skip to content

Commit dc71ab2

Browse files
committed
Add a simple pass to copy Exprs that appears multiple times in the AST
These objects make it really hard to mutate the AST correctly since one mutation can be accidentally done at places where it is invalid.
1 parent d8f1977 commit dc71ab2

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

base/inference.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3390,6 +3390,7 @@ function optimize(me::InferenceState)
33903390
# and elide unnecessary allocations
33913391
alloc_elim_pass!(me)
33923392
getfield_elim_pass!(me)
3393+
copy_duplicated_expr_pass!(me)
33933394
# Clean up for `alloc_elim_pass!` and `getfield_elim_pass!`
33943395
void_use_elim_pass!(me)
33953396
filter!(x -> x !== nothing, code)
@@ -6046,6 +6047,36 @@ function replace_getfield!(e::Expr, tupname, vals, field_names, sv::InferenceSta
60466047
end
60476048
end
60486049

6050+
function copy_expr_in_array!(ary, seen)
6051+
for i in 1:length(ary)
6052+
ex = ary[i]
6053+
isa(ex, Expr) || continue
6054+
ex = ex::Expr
6055+
if haskey(seen, ex)
6056+
newex = Expr(ex.head)
6057+
append!(newex.args, ex.args)
6058+
newex.typ = ex.typ
6059+
ary[i] = ex = newex
6060+
# No need to add to `seen`, there's no way there can be another one of the copied
6061+
# version in the AST....
6062+
else
6063+
seen[ex] = nothing
6064+
if haskey(seen, ex.args)
6065+
# Haven't actually seen this happen but it's pretty easy to check
6066+
ex.args = copy(ex.args)
6067+
else
6068+
seen[ex.args] = nothing
6069+
end
6070+
end
6071+
copy_expr_in_array!(ex.args, seen)
6072+
end
6073+
end
6074+
6075+
# Clone expressions that appears multiple times in the code
6076+
function copy_duplicated_expr_pass!(sv::InferenceState)
6077+
copy_expr_in_array!(sv.src.code, ObjectIdDict())
6078+
end
6079+
60496080
# fix label numbers to always equal the statement index of the label
60506081
function reindex_labels!(sv::InferenceState)
60516082
body = sv.src.code

0 commit comments

Comments
 (0)