From fa83a427821d6ab989800cc579fde8f913b5aeb2 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Thu, 3 May 2018 15:07:14 -0400 Subject: [PATCH 1/7] fix InferenceResult cache lookup for new optimizer --- base/compiler/ssair/inlining2.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index 254977bd99dc1..b57152629651e 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -577,6 +577,7 @@ function analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, end # Handle vararg functions + prevararg_rewritten_atypes = atypes isva = na > 0 && method.isva if isva @assert length(atypes) >= na - 1 @@ -584,8 +585,9 @@ function analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, atypes = Any[atypes[1:(na - 1)]..., va_type] end - # Go see if we already have a pre-inferred result - res = find_inferred(linfo, atypes, sv) + # Go see if we already have a pre-inferred result. Use prevararg_rewritten_atypes + # for the lookup, since that's what inference used when it populated the cache. + res = find_inferred(linfo, prevararg_rewritten_atypes, sv) res === nothing && return nothing if length(res::Tuple) == 1 From 4aeeccf631414e92cfa56ab5355d884ef8c6b587 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 14:19:06 -0400 Subject: [PATCH 2/7] utilize cached vararg type info in new inlining pass --- base/compiler/ssair/inlining2.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index b57152629651e..f26540bf61ece 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -696,7 +696,6 @@ function handle_single_case!(ir, stmt, idx, case, isinvoke, todo) end end - function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv::OptimizationState) # todo = (inline_idx, (isva, isinvoke, isapply, na), method, spvals, inline_linetable, inline_ir, lie) todo = Any[] @@ -763,11 +762,13 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: # As a special case, if we can see the tuple() call, look at it's arguments to find # our types. They can be more precise (e.g. f(Bool, A...) would be lowered as # _apply(f, tuple(Bool)::Tuple{DataType}, A), which might not be precise enough to - # get a good method match. This pattern is used in the array code a bunch. + # get a good method match). This pattern is used in the array code a bunch. if isa(def, SSAValue) && is_tuple_call(ir, ir[def]) for tuparg in ir[def].args[2:end] push!(new_atypes, exprtype(tuparg, ir, ir.mod)) end + elseif (isa(def, Argument) && def === stmt.args[end] && !isempty(sv.result_vargs)) + append!(new_atypes, sv.result_vargs) else append!(new_atypes, typ.parameters) end From e4c90a447957702752da52e8122646e8b5c3b656 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 14:19:33 -0400 Subject: [PATCH 3/7] fix test to work with new optimizer --- base/compiler/ssair/inlining2.jl | 2 +- test/compiler/compiler.jl | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index f26540bf61ece..078ef096c4d9f 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -767,7 +767,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: for tuparg in ir[def].args[2:end] push!(new_atypes, exprtype(tuparg, ir, ir.mod)) end - elseif (isa(def, Argument) && def === stmt.args[end] && !isempty(sv.result_vargs)) + elseif isa(def, Argument) && def === stmt.args[end] && !isempty(sv.result_vargs) append!(new_atypes, sv.result_vargs) else append!(new_atypes, typ.parameters) diff --git a/test/compiler/compiler.jl b/test/compiler/compiler.jl index 7e078f2b2452d..086d6ba2cebc0 100644 --- a/test/compiler/compiler.jl +++ b/test/compiler/compiler.jl @@ -1536,9 +1536,9 @@ x26826 = rand() apply26826(f, args...) = f(args...) -f26826(x) = apply26826(Base.getproperty, Foo26826(1, x), :b) # We use getproperty to drive these tests because it requires constant # propagation in order to lower to a well-inferred getfield call. +f26826(x) = apply26826(Base.getproperty, Foo26826(1, x), :b) @test @inferred(f26826(x26826)) === x26826 @@ -1554,12 +1554,10 @@ g26826(x) = getfield26826(x, :a, :b) # InferenceResult cache properly for varargs methods. typed_code = Core.Compiler.code_typed(f26826, (Float64,))[1].first.code found_well_typed_getfield_call = false -for stmnt in typed_code - if Meta.isexpr(stmnt, :(=)) && Meta.isexpr(stmnt.args[2], :call) - lhs = stmnt.args[2] - if lhs.args[1] == GlobalRef(Base, :getfield) && lhs.typ === Float64 - global found_well_typed_getfield_call = true - end +for stmt in typed_code + lhs = Meta.isexpr(stmt, :(=)) ? stmt.args[2] : stmt + if Meta.isexpr(lhs, :call) && lhs.args[1] == GlobalRef(Base, :getfield) && lhs.typ === Float64 + global found_well_typed_getfield_call = true end end From 6e78ef1be6b45a5260b72fd5ac0d76204ea73333 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 15:19:38 -0400 Subject: [PATCH 4/7] fix predicate for exploiting cached varargs type info --- base/compiler/ssair/inlining2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index 078ef096c4d9f..5b5f1810f8cd1 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -767,7 +767,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: for tuparg in ir[def].args[2:end] push!(new_atypes, exprtype(tuparg, ir, ir.mod)) end - elseif isa(def, Argument) && def === stmt.args[end] && !isempty(sv.result_vargs) + elseif isa(def, Argument) && def === stmt.args[end] && def.n === length(ir.argtypes) && !isempty(sv.result_vargs) append!(new_atypes, sv.result_vargs) else append!(new_atypes, typ.parameters) From 7f13234131307016623230b13d969aae6a113065 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 16:14:17 -0400 Subject: [PATCH 5/7] atypes no longer needs to be modified to match cached types --- base/compiler/ssair/inlining2.jl | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index 5b5f1810f8cd1..73d9a21695de9 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -576,18 +576,7 @@ function analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, return ConstantCase(quoted(linfo.inferred_const), method, Any[methsp...], metharg) end - # Handle vararg functions - prevararg_rewritten_atypes = atypes - isva = na > 0 && method.isva - if isva - @assert length(atypes) >= na - 1 - va_type = tuple_tfunc(Tuple{Any[widenconst(atypes[i]) for i in 1:length(atypes)]...}) - atypes = Any[atypes[1:(na - 1)]..., va_type] - end - - # Go see if we already have a pre-inferred result. Use prevararg_rewritten_atypes - # for the lookup, since that's what inference used when it populated the cache. - res = find_inferred(linfo, prevararg_rewritten_atypes, sv) + res = find_inferred(linfo, atypes, sv) res === nothing && return nothing if length(res::Tuple) == 1 From 254ff3905d8d40fcbb30114fae085d84c87ef308 Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 16:14:27 -0400 Subject: [PATCH 6/7] don't require varargs to be in last position to exploit cached type info --- base/compiler/ssair/inlining2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index 73d9a21695de9..507af92f1cacf 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -756,7 +756,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: for tuparg in ir[def].args[2:end] push!(new_atypes, exprtype(tuparg, ir, ir.mod)) end - elseif isa(def, Argument) && def === stmt.args[end] && def.n === length(ir.argtypes) && !isempty(sv.result_vargs) + elseif isa(def, Argument) && def.n === length(ir.argtypes) && !isempty(sv.result_vargs) append!(new_atypes, sv.result_vargs) else append!(new_atypes, typ.parameters) From 7506dc1c3b89f272aaa7027f4ba30b999f2c760e Mon Sep 17 00:00:00 2001 From: Jarrett Revels Date: Fri, 4 May 2018 21:09:25 -0400 Subject: [PATCH 7/7] restore missing isva boolean --- base/compiler/ssair/inlining2.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/compiler/ssair/inlining2.jl b/base/compiler/ssair/inlining2.jl index 507af92f1cacf..03d904db556d3 100644 --- a/base/compiler/ssair/inlining2.jl +++ b/base/compiler/ssair/inlining2.jl @@ -618,7 +618,8 @@ function analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, #verify_ir(ir2) return InliningTodo(idx, - isva, isinvoke, isapply, na, + na > 0 && method.isva, + isinvoke, isapply, na, method, Any[methsp...], metharg, inline_linetable, ir2, linear_inline_eligible(ir2)) end