WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 6c75e91

Browse files
authored
[JuliaLowering] Tidy up node creation functions (JuliaLang#60191)
We currently use keyword arguments as arbitrary key-value pairs in a number of places, which I've realized isn't really how they're intended to be used. This change fixes this and reduces the JuliaLowering package image size by about 20% on my machine from `26.910 MiB -> 21.701 MiB`, or when compiled into sysbase.dylib, `+55MB -> +45MB`. Unfortunately no change to precompile time as I had hoped, but I figured this is worth doing anyway. Lowering performance looks unchanged. I've just used `Vector{Pair}` or explicit `setattr` calls, but let me know if there's a better way of doing this. Also let me know if you have a reason for the difference in size when compiled into Base---I don't think I'm accidentally producing two copies, but you never know.
1 parent 44ecbcf commit 6c75e91

File tree

14 files changed

+176
-164
lines changed

14 files changed

+176
-164
lines changed

JuliaLowering/src/ast.jl

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -126,48 +126,53 @@ function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals::SyntaxL
126126
append!(ids, vals.ids)
127127
end
128128

129-
function makeleaf(graph::SyntaxGraph, srcref, proto; attrs...)
129+
# TODO: "proto", if SyntaxTree, is rarely different from srcref. reorganize to:
130+
# newnode/newleaf(ctx, srcref, k::Kind[, attrs])
131+
# makenode/makeleaf(ctx, old::SyntaxTree[, attrs])
132+
133+
function makeleaf(graph::SyntaxGraph, srcref, proto::Union{Kind, SyntaxTree})
130134
id = newnode!(graph)
131135
ex = SyntaxTree(graph, id)
132136
copy_attrs!(ex, proto, true)
133-
setattr!(graph, id; source=_unpack_srcref(graph, srcref), attrs...)
137+
ex.source = _unpack_srcref(graph, srcref)
134138
return ex
135139
end
136140

137-
function _makenode(graph::SyntaxGraph, srcref, proto, children; attrs...)
138-
id = newnode!(graph)
139-
setchildren!(graph, id, children)
140-
ex = SyntaxTree(graph, id)
141-
copy_attrs!(ex, proto, true)
142-
setattr!(graph, id; source=_unpack_srcref(graph, srcref), attrs...)
143-
return SyntaxTree(graph, id)
144-
end
145-
function _makenode(ctx, srcref, proto, children; attrs...)
146-
_makenode(syntax_graph(ctx), srcref, proto, children; attrs...)
141+
function makeleaf(ctx::AbstractLoweringContext, srcref, proto)
142+
makeleaf(syntax_graph(ctx), srcref, proto)
147143
end
148144

149-
function makenode(ctx, srcref, proto, children...; attrs...)
150-
_makenode(ctx, srcref, proto, _node_ids(syntax_graph(ctx), children...); attrs...)
145+
function makeleaf(ctx, srcref, proto, @nospecialize(attrs::AbstractVector))
146+
graph = syntax_graph(ctx)
147+
ex = makeleaf(graph, srcref, proto)
148+
for (k, v) in attrs
149+
setattr!(graph, ex._id, k, v)
150+
end
151+
return ex
151152
end
152153

153-
function makeleaf(ctx, srcref, proto; kws...)
154-
makeleaf(syntax_graph(ctx), srcref, proto; kws...)
154+
function makenode(ctx, srcref, proto, children, attrs=nothing)
155+
graph = syntax_graph(ctx)
156+
ex = isnothing(attrs) ? makeleaf(graph, srcref, proto) :
157+
makeleaf(graph, srcref, proto, attrs)
158+
setchildren!(graph, ex._id, children isa SyntaxList ? children.ids : children)
159+
return ex
155160
end
156161

157-
function makeleaf(ctx, srcref, k::Kind, value; kws...)
158-
graph = syntax_graph(ctx)
162+
function newleaf(ctx, srcref, k::Kind, @nospecialize(value))
163+
leaf = makeleaf(ctx, srcref, k)
159164
if k == K"Identifier" || k == K"core" || k == K"top" || k == K"Symbol" ||
160165
k == K"globalref" || k == K"Placeholder" ||
161166
k == K"StrMacroName" || k == K"CmdMacroName"
162-
makeleaf(graph, srcref, k; name_val=value, kws...)
167+
setattr!(leaf._graph, leaf._id, :name_val, value)
163168
elseif k == K"BindingId"
164-
makeleaf(graph, srcref, k; var_id=value, kws...)
169+
setattr!(leaf._graph, leaf._id, :var_id, value)
165170
elseif k == K"label"
166-
makeleaf(graph, srcref, k; id=value, kws...)
171+
setattr!(leaf._graph, leaf._id, :id, value)
167172
elseif k == K"symbolic_label"
168-
makeleaf(graph, srcref, k; name_val=value, kws...)
173+
setattr!(leaf._graph, leaf._id, :name_val, value)
169174
elseif k in KSet"TOMBSTONE SourceLocation latestworld latestworld_if_toplevel"
170-
makeleaf(graph, srcref, k; kws...)
175+
# no attributes
171176
else
172177
val = k == K"Integer" ? convert(Int, value) :
173178
k == K"Float" ? convert(Float64, value) :
@@ -177,8 +182,9 @@ function makeleaf(ctx, srcref, k::Kind, value; kws...)
177182
k == K"Bool" ? value :
178183
k == K"VERSION" ? value :
179184
error("Unexpected leaf kind `$k`")
180-
makeleaf(graph, srcref, k; value=val, kws...)
185+
setattr!(leaf._graph, leaf._id, :value, val)
181186
end
187+
leaf
182188
end
183189

184190
# TODO: Replace this with makeleaf variant?
@@ -192,7 +198,7 @@ end
192198

193199
# Convenience functions to create leaf nodes referring to identifiers within
194200
# the Core and Top modules.
195-
core_ref(ctx, ex, name) = makeleaf(ctx, ex, K"core", name)
201+
core_ref(ctx, ex, name) = newleaf(ctx, ex, K"core", name)
196202
svec_type(ctx, ex) = core_ref(ctx, ex, "svec")
197203
nothing_(ctx, ex) = core_ref(ctx, ex, "nothing")
198204

@@ -202,7 +208,7 @@ top_ref(ctx, ex, name) = makeleaf(ctx, ex, K"top", name)
202208
# Return (variable, assignment_node)
203209
function assign_tmp(ctx::AbstractLoweringContext, ex, name="tmp")
204210
var = ssavar(ctx, ex, name)
205-
assign_var = makenode(ctx, ex, K"=", var, ex)
211+
assign_var = makenode(ctx, ex, K"=", NodeId[var._id, ex._id])
206212
var, assign_var
207213
end
208214

@@ -211,7 +217,7 @@ function emit_assign_tmp(stmts::SyntaxList, ctx, ex, name="tmp")
211217
return ex
212218
end
213219
var = ssavar(ctx, ex, name)
214-
push!(stmts, makenode(ctx, ex, K"=", var, ex))
220+
push!(stmts, makenode(ctx, ex, K"=", NodeId[var._id, ex._id]))
215221
var
216222
end
217223

@@ -225,31 +231,38 @@ function _match_srcref(ex)
225231
end
226232
end
227233

228-
function _match_kind(f::Function, srcref, ex)
234+
function _kw_to_pair(ex)
235+
if ex isa Expr && ex.head === :kw && ex.args[1] isa Symbol
236+
(QuoteNode(ex.args[1]), esc(ex.args[2]))
237+
elseif ex isa Symbol
238+
(QuoteNode(ex), esc(ex))
239+
else
240+
@assert false "invalid keyword form in @ast $ex"
241+
end
242+
end
243+
244+
function _match_kind(srcref, ex)
229245
kws = []
230246
if Meta.isexpr(ex, :call)
231247
kind = esc(ex.args[1])
232248
args = ex.args[2:end]
233249
if Meta.isexpr(args[1], :parameters)
234-
kws = map(esc, args[1].args)
250+
kws = map(_kw_to_pair, args[1].args)
235251
popfirst!(args)
236252
end
237253
while length(args) >= 1 && Meta.isexpr(args[end], :kw)
238-
pushfirst!(kws, esc(pop!(args)))
254+
pushfirst!(kws, _kw_to_pair(pop!(args)))
239255
end
240256
if length(args) == 1
241257
srcref_tmp = gensym("srcref")
242-
return quote
243-
$srcref_tmp = $(_match_srcref(args[1]))
244-
$(f(kind, srcref_tmp, kws))
245-
end
258+
return (kind, _match_srcref(args[1]), kws)
246259
elseif length(args) > 1
247260
error("Unexpected: extra srcref argument in `$ex`?")
248261
end
249262
else
250263
kind = esc(ex)
251264
end
252-
f(kind, srcref, kws)
265+
return (kind, srcref, kws)
253266
end
254267

255268
function _expand_ast_tree(ctx, srcref, tree)
@@ -262,8 +275,12 @@ function _expand_ast_tree(ctx, srcref, tree)
262275
val = nothing
263276
kindspec = tree.args[1]
264277
end
265-
_match_kind(srcref, kindspec) do kind, srcref, kws
266-
:(makeleaf($ctx, $srcref, $kind, $(val), $(kws...)))
278+
let (kind, srcref, kws) = _match_kind(srcref, kindspec)
279+
n = :(newleaf($ctx, $srcref, $kind, $val))
280+
for (attr, val) in kws
281+
n = :(setattr!($n, $attr, $val))
282+
end
283+
n
267284
end
268285
elseif Meta.isexpr(tree, :call) && tree.args[1] === :(=>)
269286
# Leaf node with copied attributes
@@ -292,8 +309,12 @@ function _expand_ast_tree(ctx, srcref, tree)
292309
end
293310
end
294311
push!(child_stmts, :(child_ids))
295-
_match_kind(srcref, flatargs[1]) do kind, srcref, kws
296-
:(_makenode($ctx, $srcref, $kind, $children_ex; $(kws...)))
312+
let (kind, srcref, kws) = _match_kind(srcref, flatargs[1])
313+
n = :(makenode($ctx, $srcref, $kind, $children_ex))
314+
for (attr, val) in kws
315+
n = :(setattr!($n, $attr, $val))
316+
end
317+
n
297318
end
298319
elseif Meta.isexpr(tree, :(:=))
299320
lhs = tree.args[1]
@@ -389,17 +410,17 @@ end
389410

390411
function copy_attrs!(dest, head::Union{Kind,JuliaSyntax.SyntaxHead}, all=false)
391412
if all
392-
sethead!(dest._graph, dest._id, head)
413+
setattr!(dest._graph, dest._id, :kind, kind(head))
414+
!(head isa Kind) && setattr!(dest._graph, dest._id, :syntax_flags, flags(head))
393415
end
394416
end
395417

396-
function mapchildren(f::Function, ctx, ex::SyntaxTree, do_map_child::Function;
397-
extra_attrs...)
418+
function mapchildren(f::Function, ctx, ex::SyntaxTree, do_map_child::Function)
398419
if is_leaf(ex)
399420
return ex
400421
end
401422
orig_children = children(ex)
402-
cs = isempty(extra_attrs) ? nothing : SyntaxList(ctx)
423+
cs = nothing
403424
for (i,e) in enumerate(orig_children)
404425
newchild = do_map_child(i) ? f(e) : e
405426
if isnothing(cs)
@@ -418,14 +439,12 @@ function mapchildren(f::Function, ctx, ex::SyntaxTree, do_map_child::Function;
418439
return ex
419440
end
420441
cs::SyntaxList
421-
ex2 = makenode(ctx, ex, head(ex), cs)
422-
copy_attrs!(ex2, ex)
423-
setattr!(ex2; extra_attrs...)
442+
ex2 = makenode(ctx, ex, ex, cs)
424443
return ex2
425444
end
426445

427-
function mapchildren(f::Function, ctx, ex::SyntaxTree, mapped_children::AbstractVector{<:Integer};
428-
extra_attrs...)
446+
function mapchildren(f::Function, ctx, ex::SyntaxTree,
447+
mapped_children::AbstractVector{<:Integer})
429448
j = Ref(firstindex(mapped_children))
430449
function do_map_child(i)
431450
ind = j[]
@@ -436,11 +455,11 @@ function mapchildren(f::Function, ctx, ex::SyntaxTree, mapped_children::Abstract
436455
false
437456
end
438457
end
439-
mapchildren(f, ctx, ex, do_map_child; extra_attrs...)
458+
mapchildren(f, ctx, ex, do_map_child)
440459
end
441460

442-
function mapchildren(f::Function, ctx, ex::SyntaxTree; extra_attrs...)
443-
mapchildren(f, ctx, ex, i->true; extra_attrs...)
461+
function mapchildren(f::Function, ctx, ex::SyntaxTree)
462+
mapchildren(f, ctx, ex, i->true)
444463
end
445464

446465

@@ -477,7 +496,7 @@ function _copy_ast(graph2::SyntaxGraph, graph1::SyntaxGraph,
477496
src1
478497
end
479498
copy_attrs!(SyntaxTree(graph2, id2), SyntaxTree(graph1, id1), true)
480-
setattr!(graph2, id2; source=src2)
499+
setattr!(graph2, id2, :source, src2)
481500
if !is_leaf(graph1, id1)
482501
cs = NodeId[]
483502
for cid in children(graph1, id1)
@@ -491,20 +510,19 @@ end
491510
#-------------------------------------------------------------------------------
492511
function set_scope_layer(ctx, ex, layer_id, force)
493512
k = kind(ex)
494-
scope_layer = force ? layer_id : get(ex, :scope_layer, layer_id)
495-
if k == K"module" || k == K"toplevel" || k == K"inert"
496-
makenode(ctx, ex, ex, children(ex);
497-
scope_layer=scope_layer)
513+
new_layer = force ? layer_id : get(ex, :scope_layer, layer_id)
514+
515+
ex2 = if k == K"module" || k == K"toplevel" || k == K"inert"
516+
makenode(ctx, ex, ex, children(ex))
498517
elseif k == K"."
499-
makenode(ctx, ex, ex, set_scope_layer(ctx, ex[1], layer_id, force), ex[2],
500-
scope_layer=scope_layer)
518+
children = NodeId[set_scope_layer(ctx, ex[1], layer_id, force), ex[2]]
519+
makenode(ctx, ex, ex, children)
501520
elseif !is_leaf(ex)
502-
mapchildren(e->set_scope_layer(ctx, e, layer_id, force), ctx, ex;
503-
scope_layer=scope_layer)
521+
mapchildren(e->set_scope_layer(ctx, e, layer_id, force), ctx, ex)
504522
else
505-
makeleaf(ctx, ex, ex;
506-
scope_layer=scope_layer)
523+
makeleaf(ctx, ex, ex)
507524
end
525+
setattr!(ex2, :scope_layer, new_layer)
508526
end
509527

510528
"""
@@ -513,7 +531,7 @@ end
513531
Copy `ex`, adopting the scope layer of `ref`.
514532
"""
515533
function adopt_scope(ex::SyntaxTree, scope_layer::LayerId)
516-
set_scope_layer(ex, ex, scope_layer, true)
534+
set_scope_layer(ex._graph, ex, scope_layer, true)
517535
end
518536

519537
function adopt_scope(ex::SyntaxTree, layer::ScopeLayer)
@@ -539,19 +557,17 @@ end
539557
# the middle of a pass.
540558
const CompileHints = Base.ImmutableDict{Symbol,Any}
541559

542-
function setmeta!(ex::SyntaxTree; kws...)
543-
@assert length(kws) == 1 # todo relax later ?
544-
key = first(keys(kws))
545-
value = first(values(kws))
560+
function setmeta!(ex::SyntaxTree, key::Symbol, @nospecialize(val))
546561
meta = begin
547562
m = get(ex, :meta, nothing)
548-
isnothing(m) ? CompileHints(key, value) : CompileHints(m, key, value)
563+
isnothing(m) ? CompileHints(key, val) : CompileHints(m, key, val)
549564
end
550-
setattr!(ex; meta=meta)
565+
setattr!(ex, :meta, meta)
551566
ex
552567
end
553568

554-
setmeta(ex::SyntaxTree; kws...) = setmeta!(copy_node(ex); kws...)
569+
setmeta(ex::SyntaxTree, k::Symbol, @nospecialize(v)) =
570+
setmeta!(copy_node(ex), k, v)
555571

556572
function getmeta(ex::SyntaxTree, name::Symbol, default)
557573
meta = get(ex, :meta, nothing)

JuliaLowering/src/bindings.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,16 @@ end
151151

152152
# Create a new SSA binding
153153
function ssavar(ctx::AbstractLoweringContext, srcref, name="tmp")
154-
nameref = makeleaf(ctx, srcref, K"Identifier", name_val=name)
154+
nameref = makeleaf(ctx, srcref, K"Identifier")
155+
nameref.name_val = name
155156
new_binding(ctx, nameref, name, :local; is_ssa=true, is_internal=true)
156157
end
157158

158159
# Create a new local mutable binding or lambda argument
159160
function new_local_binding(ctx::AbstractLoweringContext, srcref, name; kind=:local, kws...)
160161
@assert kind === :local || kind === :argument
161-
nameref = makeleaf(ctx, srcref, K"Identifier", name_val=name)
162+
nameref = makeleaf(ctx, srcref, K"Identifier")
163+
nameref.name_val = name
162164
ex = new_binding(ctx, nameref, name, kind; is_internal=true, kws...)
163165
lbindings = current_lambda_bindings(ctx)
164166
if !isnothing(lbindings)
@@ -168,7 +170,8 @@ function new_local_binding(ctx::AbstractLoweringContext, srcref, name; kind=:loc
168170
end
169171

170172
function new_global_binding(ctx::AbstractLoweringContext, srcref, name, mod; kws...)
171-
nameref = makeleaf(ctx, srcref, K"Identifier", name_val=name)
173+
nameref = makeleaf(ctx, srcref, K"Identifier")
174+
nameref.name_val = name
172175
new_binding(ctx, nameref, name, :global; is_internal=true, mod=mod, kws...)
173176
end
174177

JuliaLowering/src/closure_conversion.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ function closure_convert_lambda(ctx, ex)
593593
push!(lambda_children, _convert_closures(ctx2, ex[4]))
594594
end
595595

596-
lam = makenode(ctx, ex, ex, lambda_children; lambda_bindings=lambda_bindings)
596+
lam = makenode(ctx, ex, ex, lambda_children, [:lambda_bindings=>lambda_bindings])
597597
if !isnothing(interpolations) && !isempty(interpolations)
598598
@ast ctx ex [K"call"
599599
replace_captured_locals!::K"Value"

0 commit comments

Comments
 (0)