From 5c7e81d51fa258a1000685f62004d1f58c83f47d Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 18 May 2020 14:11:08 -0400 Subject: [PATCH] optimize more tuple splatting independent of length when possible --- base/compiler/ssair/inlining.jl | 26 ++++++++++++++++++++------ test/compiler/inline.jl | 5 +++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 7c42385f28a98..2acead5985078 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -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) @@ -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) diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 1ff068ae76e7e..0fa46b4554a61 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -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()