diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 128ce4d21968e..dbe55e2757c0c 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -593,14 +593,20 @@ function rewrite_apply_exprargs!(ir::IRCode, idx::Int, argexprs::Vector{Any}, at def_atypes = sv.result_vargs else def_atypes = Any[] - for p in widenconst(atypes[i]).parameters - if isa(p, DataType) && isdefined(p, :instance) - # replace singleton types with their equivalent Const object - p = Const(p.instance) - elseif isconstType(p) - p = Const(p.parameters[1]) + if isa(atypes[i], Const) + for p in atypes[i].val + push!(def_atypes, Const(p)) + end + else + for p in widenconst(atypes[i]).parameters + if isa(p, DataType) && isdefined(p, :instance) + # replace singleton types with their equivalent Const object + p = Const(p.instance) + elseif isconstType(p) + p = Const(p.parameters[1]) + end + push!(def_atypes, p) end - push!(def_atypes, p) end end # now push flattened types into new_atypes and getfield exprs into new_argexprs diff --git a/test/inline.jl b/test/inline.jl index 621e1cf6e47c9..04cb23d9626d9 100644 --- a/test/inline.jl +++ b/test/inline.jl @@ -160,3 +160,40 @@ function f_ifelse(x) end # 2 for now because the compiler leaves a GotoNode around @test_broken length(code_typed(f_ifelse, (String,))[1][1].code) <= 2 + +# Test that inlining of _apply properly hits the inference cache +@noinline cprop_inline_foo1() = (1, 1) +@noinline cprop_inline_foo2() = (2, 2) +function cprop_inline_bar(x...) + if x === (1, 1, 1, 1) + return x + else + # What you put here doesn't really matter, + # the point is to prevent inlining when + # x is not known to be (1, 1, 1, 1) + println(stdout, "Hello") + println(stdout, "World") + println(stdout, "Hello") + println(stdout, "World") + println(stdout, "Hello") + println(stdout, "World") + println(stdout, "Hello") + println(stdout, "World") + println(stdout, "Hello") + println(stdout, "World") + println(stdout, "Hello") + println(stdout, "World") + return x + end + x +end + +function cprop_inline_baz1() + return cprop_inline_bar(cprop_inline_foo1()..., cprop_inline_foo1()...) +end +@test length(code_typed(cprop_inline_baz1, ())[1][1].code) == 1 + +function cprop_inline_baz2() + return cprop_inline_bar(cprop_inline_foo2()..., cprop_inline_foo2()...) +end +@test length(code_typed(cprop_inline_baz2, ())[1][1].code) == 2