From a153feaa0b167520d6e42d1aa03d224ec0064a7c Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 4 Jan 2019 12:53:25 -0500 Subject: [PATCH] optimize identity splat of a tuple, `(t...,)` (#30571) --- base/compiler/ssair/inlining.jl | 6 ++++++ src/builtins.c | 3 +++ test/compiler/inline.jl | 3 +++ 3 files changed, 12 insertions(+) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 418afe10fcb46..1b7cbebac5caa 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -837,6 +837,12 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: # Independent of whether we can inline, the above analysis allows us to rewrite # this apply call to a regular call ft = atypes[2] + if length(atypes) == 3 && ft isa Const && ft.val === Core.tuple && atypes[3] ⊑ Tuple + # rewrite `((t::Tuple)...,)` to `t` + ir.stmts[idx] = stmt.args[3] + ok = false + break + end stmt.args, atypes = rewrite_apply_exprargs!(ir, idx, stmt.args, atypes, sv) ok = !has_free_typevars(ft) ok || break diff --git a/src/builtins.c b/src/builtins.c index 4f5938a17e574..1f67eb0e7202d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -462,6 +462,9 @@ JL_CALLABLE(jl_f__apply) return (jl_value_t*)t; } } + else if (f == jl_builtin_tuple && jl_is_tuple(args[1])) { + return args[1]; + } } size_t n=0, i, j; for(i=1; i < nargs; i++) { diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 47d770977f016..c7e55ac19fe03 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -217,3 +217,6 @@ function f_div(x, y) return x end @test length(code_typed(f_div, (Int, Int))[1][1].code) > 1 + +f_identity_splat(t) = (t...,) +@test length(code_typed(f_identity_splat, (Tuple{Int,Int},))[1][1].code) == 1