From 62a4a002d0ef92711e40bac08e84f27b9848bb58 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 20 Apr 2022 14:19:46 -0400 Subject: [PATCH 1/3] propagate inlining metadata to keyword sorter methods --- src/ast.scm | 4 ++++ src/julia-syntax.scm | 1 + 2 files changed, 5 insertions(+) diff --git a/src/ast.scm b/src/ast.scm index 0f69638fdb52e..c6f924b045189 100644 --- a/src/ast.scm +++ b/src/ast.scm @@ -523,6 +523,10 @@ (and (if one (length= e 3) (length> e 2)) (eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize)))) +(define (inline-meta? e) + (and (length= e 2) + (eq? (car e) 'meta) (memq (cadr e) '(inline noinline)))) + (define (if-generated? e) (and (length= e 4) (eq? (car e) 'if) (equal? (cadr e) '(generated)))) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 4024d25c2e9ec..793180bdb7084 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -562,6 +562,7 @@ ,(if (any kwarg? pargl) (gensy) UNUSED) (call (core kwftype) ,ftype)) ,kw ,@pargl ,@vararg) `(block + ,@(filter inline-meta? prologue) ,@(let ((lnns (filter linenum? prologue))) (if (pair? lnns) (list (car lnns)) From 12d48b25a7ce0e45dffa69fbe3b009cc9fc6d32c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Tue, 5 Jul 2022 14:22:57 +0900 Subject: [PATCH 2/3] propagate other method metadata as well --- src/ast.scm | 17 ++++++++++++++--- src/julia-syntax.scm | 4 +++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ast.scm b/src/ast.scm index c6f924b045189..bbb2180a8a92f 100644 --- a/src/ast.scm +++ b/src/ast.scm @@ -523,9 +523,20 @@ (and (if one (length= e 3) (length> e 2)) (eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize)))) -(define (inline-meta? e) - (and (length= e 2) - (eq? (car e) 'meta) (memq (cadr e) '(inline noinline)))) +(define (meta? e) + (and (length> e 1) (eq? (car e) 'meta))) + +(define (method-meta-sym? x) + (memq x '(inline noinline aggressive_constprop no_constprop propagate_inbounds))) + +(define (propagate-method-meta e) + `(meta ,@(filter (lambda (x) + (or (method-meta-sym? x) + (and (pair? x) (eq? (car x) 'purity)))) + (cdr e)))) + +(define (argwide-nospecialize-meta? e) + (and (length= e 2) (eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize)))) (define (if-generated? e) (and (length= e 4) (eq? (car e) 'if) (equal? (cadr e) '(generated)))) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 793180bdb7084..8af1bc8b80d23 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -562,7 +562,9 @@ ,(if (any kwarg? pargl) (gensy) UNUSED) (call (core kwftype) ,ftype)) ,kw ,@pargl ,@vararg) `(block - ,@(filter inline-meta? prologue) + ;; propagate method metadata to keyword sorter + ,@(map propagate-method-meta (filter meta? prologue)) + ,@(filter argwide-nospecialize-meta? prologue) ,@(let ((lnns (filter linenum? prologue))) (if (pair? lnns) (list (car lnns)) From 48707d36882304356c52c3771dfe5ed3028f258e Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Tue, 5 Jul 2022 14:39:06 +0900 Subject: [PATCH 3/3] test metadata propagation to keyword sorter --- base/compiler/abstractinterpretation.jl | 5 ++- base/compiler/utilities.jl | 14 ++++++++ test/compiler/inline.jl | 46 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 5aa7669c3a3a9..581f8226a3829 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -799,8 +799,7 @@ function const_prop_enabled(interp::AbstractInterpreter, sv::InferenceState, mat add_remark!(interp, sv, "[constprop] Disabled by parameter") return false end - method = match.method - if method.constprop == 0x02 + if is_no_constprop(match.method) add_remark!(interp, sv, "[constprop] Disabled by method parameter") return false end @@ -1003,7 +1002,7 @@ function is_all_overridden((; fargs, argtypes)::ArgInfo, sv::InferenceState) end function force_const_prop(interp::AbstractInterpreter, @nospecialize(f), method::Method) - return method.constprop == 0x01 || + return is_aggressive_constprop(method) || InferenceParams(interp).aggressive_constant_propagation || istopfunction(f, :getproperty) || istopfunction(f, :setproperty!) diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 7ef006f244aa6..82748669e4387 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -209,6 +209,20 @@ function specialize_method(match::MethodMatch; kwargs...) return specialize_method(match.method, match.spec_types, match.sparams; kwargs...) end +""" + is_aggressive_constprop(method::Union{Method,CodeInfo}) -> Bool + +Check if `method` is declared as `Base.@constprop :aggressive`. +""" +is_aggressive_constprop(method::Union{Method,CodeInfo}) = method.constprop == 0x01 + +""" + is_no_constprop(method::Union{Method,CodeInfo}) -> Bool + +Check if `method` is declared as `Base.@constprop :none`. +""" +is_no_constprop(method::Union{Method,CodeInfo}) = method.constprop == 0x02 + ######### # types # ######### diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 94331da6a7d03..a11fdbd2b6203 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -1402,3 +1402,49 @@ end end end end + +# https://github.com/JuliaLang/julia/issues/45050 +@testset "propagate :meta annotations to keyword sorter methods" begin + # @inline, @noinline, @constprop + let @inline f(::Any; x::Int=1) = 2x + @test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source) + @test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source) + end + let @noinline f(::Any; x::Int=1) = 2x + @test !ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source) + @test !ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source) + end + let Base.@constprop :aggressive f(::Any; x::Int=1) = 2x + @test Core.Compiler.is_aggressive_constprop(only(methods(f))) + @test Core.Compiler.is_aggressive_constprop(only(methods(Core.kwfunc(f)))) + end + let Base.@constprop :none f(::Any; x::Int=1) = 2x + @test Core.Compiler.is_no_constprop(only(methods(f))) + @test Core.Compiler.is_no_constprop(only(methods(Core.kwfunc(f)))) + end + # @nospecialize + let f(@nospecialize(A::Any); x::Int=1) = 2x + @test only(methods(f)).nospecialize == 1 + @test only(methods(Core.kwfunc(f))).nospecialize == 4 + end + let f(::Any; x::Int=1) = (@nospecialize; 2x) + @test only(methods(f)).nospecialize == -1 + @test only(methods(Core.kwfunc(f))).nospecialize == -1 + end + # Base.@assume_effects + let Base.@assume_effects :notaskstate f(::Any; x::Int=1) = 2x + @test Core.Compiler.decode_effects_override(only(methods(f)).purity).notaskstate + @test Core.Compiler.decode_effects_override(only(methods(Core.kwfunc(f))).purity).notaskstate + end + # propagate multiple metadata also + let @inline Base.@assume_effects :notaskstate Base.@constprop :aggressive f(::Any; x::Int=1) = (@nospecialize; 2x) + @test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source) + @test Core.Compiler.is_aggressive_constprop(only(methods(f))) + @test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source) + @test Core.Compiler.is_aggressive_constprop(only(methods(Core.kwfunc(f)))) + @test only(methods(f)).nospecialize == -1 + @test only(methods(Core.kwfunc(f))).nospecialize == -1 + @test Core.Compiler.decode_effects_override(only(methods(f)).purity).notaskstate + @test Core.Compiler.decode_effects_override(only(methods(Core.kwfunc(f))).purity).notaskstate + end +end