Skip to content

Commit

Permalink
Make child list construction more efficient for ASTs
Browse files Browse the repository at this point in the history
Rather than forcing construction of individual `SyntaxTree`s and
splatting of SyntaxList into such trees, collect children into a single
SyntaxList directly. This is basically doing our own lowering of
_apply_iterate where we happen to know the concrete type of the list of
arguments.
  • Loading branch information
c42f committed Dec 21, 2024
1 parent 2a8eb6e commit 1766242
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
40 changes: 35 additions & 5 deletions src/ast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@ _unpack_srcref(graph, srcref::SyntaxTree) = _node_id(graph, srcref)
_unpack_srcref(graph, srcref::Tuple) = _node_ids(graph, srcref...)
_unpack_srcref(graph, srcref) = srcref

function _push_nodeid!(graph::SyntaxGraph, ids::Vector{NodeId}, val)
push!(ids, _node_id(graph, val))
end
function _push_nodeid!(graph::SyntaxGraph, ids::Vector{NodeId}, val::Nothing)
nothing
end
function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals)
for v in vals
_push_nodeid!(graph, ids, v)
end
end
function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals::SyntaxList)
check_compatible_graph(graph, vals)
append!(ids, vals.ids)
end

function makeleaf(graph::SyntaxGraph, srcref, proto; attrs...)
id = newnode!(graph)
ex = SyntaxTree(graph, id)
Expand All @@ -177,17 +193,20 @@ function makeleaf(graph::SyntaxGraph, srcref, proto; attrs...)
return ex
end

function makenode(graph::SyntaxGraph, srcref, proto, children...; attrs...)
function _makenode(graph::SyntaxGraph, srcref, proto, children; attrs...)
id = newnode!(graph)
setchildren!(graph, id, _node_ids(graph, children...))
setchildren!(graph, id, children)
ex = SyntaxTree(graph, id)
copy_attrs!(ex, proto, true)
setattr!(graph, id; source=_unpack_srcref(graph, srcref), attrs...)
return SyntaxTree(graph, id)
end
function _makenode(ctx, srcref, proto, children; attrs...)
_makenode(syntax_graph(ctx), srcref, proto, children; attrs...)
end

function makenode(ctx, srcref, proto, children...; attrs...)
makenode(syntax_graph(ctx), srcref, proto, children...; attrs...)
_makenode(ctx, srcref, proto, _node_ids(syntax_graph(ctx), children...); attrs...)
end

function makeleaf(ctx, srcref, proto; kws...)
Expand Down Expand Up @@ -335,9 +354,20 @@ function _expand_ast_tree(ctx, srcref, tree)
push!(flatargs, a)
end
end
children_ex = :(let child_ids = Vector{NodeId}(), graph = syntax_graph($ctx)
end)
child_stmts = children_ex.args[2].args
for a in flatargs[2:end]
child = _expand_ast_tree(ctx, srcref, a)
if Meta.isexpr(child, :(...))
push!(child_stmts, :(_append_nodeids!(graph, child_ids, $(child.args[1]))))
else
push!(child_stmts, :(_push_nodeid!(graph, child_ids, $child)))
end
end
push!(child_stmts, :(child_ids))
_match_kind(srcref, flatargs[1]) do kind, srcref, kws
children = map(a->_expand_ast_tree(ctx, srcref, a), flatargs[2:end])
:(makenode($ctx, $srcref, $kind, $(children...), $(kws...)))
:(_makenode($ctx, $srcref, $kind, $children_ex; $(kws...)))
end
elseif Meta.isexpr(tree, :(:=))
lhs = tree.args[1]
Expand Down
13 changes: 7 additions & 6 deletions src/linear_ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function compile_leave_handler(ctx, srcref, src_tokens, dest_tokens)
jump_ok = n == 0 || (n <= length(src_tokens) && dest_tokens[n].var_id == src_tokens[n].var_id)
jump_ok || throw(LoweringError(srcref, "Attempt to jump into try block"))
if n < length(src_tokens)
@ast ctx srcref [K"leave" src_tokens[n+1:end]]
@ast ctx srcref [K"leave" src_tokens[n+1:end]...]
else
nothing
end
Expand Down Expand Up @@ -959,11 +959,12 @@ function compile_lambda(outer_ctx, ex)
end
# @info "" @ast ctx ex [K"block" ctx.code]
code = renumber_body(ctx, ctx.code, slot_rewrites)
makenode(ctx, ex, K"code_info",
makenode(ctx, ex[1], K"block", code),
is_toplevel_thunk=ex.is_toplevel_thunk,
slots=slots
)
@ast ctx ex [K"code_info"(is_toplevel_thunk=ex.is_toplevel_thunk,
slots=slots)
[K"block"(ex[3])
code...
]
]
end

"""
Expand Down
2 changes: 1 addition & 1 deletion src/macro_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function collect_unquoted!(ctx, unquoted, ex, depth)
end

function expand_quote(ctx, ex)
unquoted = SyntaxTree[]
unquoted = SyntaxList(ctx)
collect_unquoted!(ctx, unquoted, ex, 0)
# Unlike user-defined macro expansion, we don't call append_sourceref for
# the entire expression produced by `quote` expansion. We could, but it
Expand Down
2 changes: 1 addition & 1 deletion test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ macro ast_(tree)
quote
graph = _ast_test_graph()
srcref = _source_node(graph, $(QuoteNode(__source__)))
$(JuliaLowering._expand_ast_tree(:graph, :srcref, tree))
@ast graph srcref $tree
end
end

Expand Down

0 comments on commit 1766242

Please sign in to comment.