From eafa1e39bea35cd2e71ff5cb01109da734036001 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 9 Nov 2023 14:17:45 +0900 Subject: [PATCH 1/3] fix up test case for unmatched type param inlining --- base/compiler/ssair/inlining.jl | 9 ++++----- test/compiler/inline.jl | 25 +++++++++++-------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 318b21b09bb16..831133f84ca74 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -1393,8 +1393,7 @@ function compute_inlining_cases(@nospecialize(info::CallInfo), flag::UInt32, sig cases = InliningCase[] argtypes = sig.argtypes local handled_all_cases::Bool = true - local revisit_idx = nothing - local only_method = nothing + local revisit_idx = local only_method = nothing local meth::MethodLookupResult local all_result_count = 0 local joint_effects::Effects = EFFECTS_TOTAL @@ -1410,14 +1409,14 @@ function compute_inlining_cases(@nospecialize(info::CallInfo), flag::UInt32, sig handled_all_cases = false continue else - if length(meth) == 1 && only_method !== false + if length(meth) == 1 && only_method !== missing if only_method === nothing only_method = meth[1].method elseif only_method !== meth[1].method - only_method = false + only_method = missing end else - only_method = false + only_method = missing end end local split_fully_covered::Bool = false diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 2ad18e3374d7f..9e58f23fd755c 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -1675,13 +1675,12 @@ function oc_capture_oc(z) end @test fully_eliminated(oc_capture_oc, (Int,)) +# inlining with unmatched type parameters @eval struct OldVal{T} - x::T (OV::Type{OldVal{T}})() where T = $(Expr(:new, :OV)) end -with_unmatched_typeparam1(x::OldVal{i}) where {i} = i -with_unmatched_typeparam2() = [ Base.donotdelete(OldVal{i}()) for i in 1:10000 ] -function with_unmatched_typeparam3() +@test OldVal{0}() === OldVal{0}.instance +function with_unmatched_typeparam() f(x::OldVal{i}) where {i} = i r = 0 for i = 1:10000 @@ -1689,17 +1688,15 @@ function with_unmatched_typeparam3() end return r end - -@testset "Inlining with unmatched type parameters" begin - let src = code_typed1(with_unmatched_typeparam1, (Any,)) - @test !any(@nospecialize(x) -> isexpr(x, :call) && length(x.args) == 1, src.code) - end - let src = code_typed1(with_unmatched_typeparam2) - @test !any(@nospecialize(x) -> isexpr(x, :call) && length(x.args) == 1, src.code) - end - let src = code_typed1(with_unmatched_typeparam3) - @test !any(@nospecialize(x) -> isexpr(x, :call) && length(x.args) == 1, src.code) +let src = code_typed1(with_unmatched_typeparam) + found = nothing + for x in src.code + if isexpr(x, :call) && length(x.args) == 1 + found = x + break + end end + @test isnothing(found) || (source=src, statement=found) end function twice_sitofp(x::Int, y::Int) From 81ef12a3a82c9845aa525207c63802b4fd91b0ad Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 9 Nov 2023 14:18:06 +0900 Subject: [PATCH 2/3] fixed test case for #43296 --- test/compiler/inference.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 20fdaaf297d82..174218f65b988 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -138,7 +138,7 @@ end Core.Compiler.limit_type_size(Type{Any}, Type, Union{}, 0, 0) == Type{Any} -# issue #43296 #43296 +# issue #43296 struct C43296{t,I} end r43296(b) = r43296(typeof(b)) r43296(::Type) = nothing @@ -149,7 +149,8 @@ f43296(g, :) = h k43296(b, j, :) = l k43296(b, j, ::Nothing) = b i43296(b, j) = k43296(b, j, r43296(j)) -@test only(Base.return_types(i43296, (Int, C43296{C43296{C43296{Val, Tuple}, Tuple}}))) == Int +@test only(Base.return_types(i43296, (Int, C43296{C43296{C43296{Val, Tuple}}}))) <: Int +@test only(Base.return_types(i43296, (Int, C43296{C43296{C43296{Val, <:Tuple}}}))) <: Int abstract type e43296{a, j} <: AbstractArray{a, j} end abstract type b43296{a, j, c, d} <: e43296{a, j} end From 358540cf46c683f3a6881242722f4b610c376a50 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 9 Nov 2023 02:14:31 +0900 Subject: [PATCH 3/3] effects: improve idempotency of effects derived by post-opt analysis Since now effects can be refined by post-opt analysis, `typeinf_edge` should propagate `frame.result.ipo_effects` instead of `frame.ipo_effects`. --- base/compiler/typeinfer.jl | 4 ++-- test/compiler/effects.jl | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 9eef6615521ca..29d3c01d151be 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -537,7 +537,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter) end me.result.valid_worlds = me.valid_worlds me.result.result = bestguess - me.ipo_effects = me.result.ipo_effects = adjust_effects(me) + me.result.ipo_effects = me.ipo_effects = adjust_effects(me) if limited_ret # a parent may be cached still, but not this intermediate work: @@ -856,7 +856,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize update_valid_age!(caller, frame.valid_worlds) isinferred = is_inferred(frame) edge = isinferred ? mi : nothing - effects = isinferred ? frame.ipo_effects : adjust_effects(Effects(), method) # effects are adjusted already within `finish` for ipo_effects + effects = isinferred ? frame.result.ipo_effects : adjust_effects(Effects(), method) # effects are adjusted already within `finish` for ipo_effects # propagate newly inferred source to the inliner, allowing efficient inlining w/o deserialization: # note that this result is cached globally exclusively, we can use this local result destructively volatile_inf_result = isinferred && let inferred_src = result.src diff --git a/test/compiler/effects.jl b/test/compiler/effects.jl index 031e454c10539..ad2c60723adf6 100644 --- a/test/compiler/effects.jl +++ b/test/compiler/effects.jl @@ -1158,3 +1158,17 @@ end issue51837(; openquotechar, newlinechar) end |> !Core.Compiler.is_nothrow @test_throws ArgumentError issue51837(; openquotechar='α', newlinechar='\n') + +# idempotency of effects derived by post-opt analysis +callgetfield(x, f) = getfield(x, f, Base.@_boundscheck) +@test Base.infer_effects(callgetfield, (Some{Any},Symbol)).noub === Core.Compiler.NOUB_IF_NOINBOUNDS +callgetfield1(x, f) = getfield(x, f, Base.@_boundscheck) +callgetfield_simple(x, f) = callgetfield1(x, f) +@test Base.infer_effects(callgetfield_simple, (Some{Any},Symbol)).noub === + Base.infer_effects(callgetfield_simple, (Some{Any},Symbol)).noub === + Core.Compiler.ALWAYS_TRUE +callgetfield2(x, f) = getfield(x, f, Base.@_boundscheck) +callgetfield_inbounds(x, f) = @inbounds callgetfield2(x, f) +@test Base.infer_effects(callgetfield_inbounds, (Some{Any},Symbol)).noub === + Base.infer_effects(callgetfield_inbounds, (Some{Any},Symbol)).noub === + Core.Compiler.ALWAYS_FALSE