Skip to content

Commit c0224d5

Browse files
authored
Optimize copy of Expr (#37439)
* Remove allocation of extra `[]` * Remove all dynamic dispatch * `@inbounds` array access
1 parent 1378bb6 commit c0224d5

File tree

1 file changed

+25
-23
lines changed

1 file changed

+25
-23
lines changed

base/expr.jl

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,36 @@ end
3131

3232
## expressions ##
3333

34-
function copy(e::Expr)
35-
n = Expr(e.head)
36-
n.args = copy_exprargs(e.args)
37-
return n
38-
end
34+
copy(e::Expr) = exprarray(e.head, copy_exprargs(e.args))
3935

4036
# copy parts of an AST that the compiler mutates
41-
copy_exprs(@nospecialize(x)) = x
42-
copy_exprs(x::Expr) = copy(x)
43-
function copy_exprs(x::PhiNode)
44-
new_values = Vector{Any}(undef, length(x.values))
45-
for i = 1:length(x.values)
46-
isassigned(x.values, i) || continue
47-
new_values[i] = copy_exprs(x.values[i])
48-
end
49-
return PhiNode(copy(x.edges), new_values)
50-
end
51-
function copy_exprs(x::PhiCNode)
52-
new_values = Vector{Any}(undef, length(x.values))
53-
for i = 1:length(x.values)
54-
isassigned(x.values, i) || continue
55-
new_values[i] = copy_exprs(x.values[i])
37+
function copy_exprs(@nospecialize(x))
38+
if isa(x, Expr)
39+
return copy(x)
40+
elseif isa(x, PhiNode)
41+
values = x.values
42+
nvalues = length(values)
43+
new_values = Vector{Any}(undef, nvalues)
44+
@inbounds for i = 1:nvalues
45+
isassigned(values, i) || continue
46+
new_values[i] = copy_exprs(values[i])
47+
end
48+
return PhiNode(copy(x.edges), new_values)
49+
elseif isa(x, PhiCNode)
50+
values = x.values
51+
nvalues = length(values)
52+
new_values = Vector{Any}(undef, nvalues)
53+
@inbounds for i = 1:nvalues
54+
isassigned(values, i) || continue
55+
new_values[i] = copy_exprs(values[i])
56+
end
57+
return PhiCNode(new_values)
5658
end
57-
return PhiCNode(new_values)
59+
return x
5860
end
59-
copy_exprargs(x::Array{Any,1}) = Any[copy_exprs(x[i]) for i in 1:length(x)]
61+
copy_exprargs(x::Array{Any,1}) = Any[copy_exprs(@inbounds x[i]) for i in 1:length(x)]
6062

61-
exprarray(head, args::Array{Any,1}) = (ex = Expr(head); ex.args = args; ex)
63+
@eval exprarray(head::Symbol, arg::Array{Any,1}) = $(Expr(:new, :Expr, :head, :arg))
6264

6365
# create copies of the CodeInfo definition, and any mutable fields
6466
function copy(c::CodeInfo)

0 commit comments

Comments
 (0)