Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize more tuple splatting independent of length when possible #35930

Merged
merged 1 commit into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,26 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Optimizatio
if arg_start > length(atypes)
return nothing
end
ft = atypes[arg_start]
if ft isa Const && ft.val === Core.tuple
# if one argument is a tuple already, and the rest are empty, we can just return it
# e.g. rewrite `((t::Tuple)...,)` to `t`
nonempty_idx = 0
for i = (arg_start + 1):length(atypes)
ti = atypes[i]
ti ⊑ Tuple{} && continue
if ti ⊑ Tuple && nonempty_idx == 0
nonempty_idx = i
continue
end
nonempty_idx = 0
break
end
if nonempty_idx != 0
ir.stmts[idx] = stmt.args[nonempty_idx]
return nothing
end
end
# Try to figure out the signature of the function being called
# and if rewrite_apply_exprargs can deal with this form
for i = (arg_start + 1):length(atypes)
Expand All @@ -905,12 +925,6 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Optimizatio
end
# Independent of whether we can inline, the above analysis allows us to rewrite
# this apply call to a regular call
ft = atypes[arg_start]
if length(atypes) == arg_start+1 && ft isa Const && ft.val === Core.tuple && atypes[arg_start+1] ⊑ Tuple
# rewrite `((t::Tuple)...,)` to `t`
ir.stmts[idx] = stmt.args[arg_start+1]
return nothing
end
stmt.args, atypes = rewrite_apply_exprargs!(ir, idx, stmt.args, atypes, arg_start)
has_free_typevars(ft) && return nothing
f = singleton_type(ft)
Expand Down
5 changes: 5 additions & 0 deletions test/compiler/inline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ end
f_identity_splat(t) = (t...,)
@test length(code_typed(f_identity_splat, (Tuple{Int,Int},))[1][1].code) == 1

# splatting one tuple into (,) plus zero or more empties should reduce
# this pattern appears for example in `fill_to_length`
f_splat_with_empties(t) = (()..., t..., ()..., ()...)
@test length(code_typed(f_splat_with_empties, (NTuple{200,UInt8},))[1][1].code) == 1

# check that <: can be fully eliminated
struct SomeArbitraryStruct; end
function f_subtype()
Expand Down