Skip to content

Commit 9edac22

Browse files
propagate method metadata to keyword sorter methods (#45041)
Co-authored-by: Shuhei Kadowaki <[email protected]>
1 parent c1750f2 commit 9edac22

File tree

5 files changed

+80
-3
lines changed

5 files changed

+80
-3
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,7 @@ function const_prop_enabled(interp::AbstractInterpreter, sv::InferenceState, mat
827827
add_remark!(interp, sv, "[constprop] Disabled by parameter")
828828
return false
829829
end
830-
method = match.method
831-
if method.constprop == 0x02
830+
if is_no_constprop(match.method)
832831
add_remark!(interp, sv, "[constprop] Disabled by method parameter")
833832
return false
834833
end
@@ -1028,7 +1027,7 @@ function is_all_overridden((; fargs, argtypes)::ArgInfo, sv::InferenceState)
10281027
end
10291028

10301029
function force_const_prop(interp::AbstractInterpreter, @nospecialize(f), method::Method)
1031-
return method.constprop == 0x01 ||
1030+
return is_aggressive_constprop(method) ||
10321031
InferenceParams(interp).aggressive_constant_propagation ||
10331032
istopfunction(f, :getproperty) ||
10341033
istopfunction(f, :setproperty!)

base/compiler/utilities.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ function specialize_method(match::MethodMatch; kwargs...)
209209
return specialize_method(match.method, match.spec_types, match.sparams; kwargs...)
210210
end
211211

212+
"""
213+
is_aggressive_constprop(method::Union{Method,CodeInfo}) -> Bool
214+
215+
Check if `method` is declared as `Base.@constprop :aggressive`.
216+
"""
217+
is_aggressive_constprop(method::Union{Method,CodeInfo}) = method.constprop == 0x01
218+
219+
"""
220+
is_no_constprop(method::Union{Method,CodeInfo}) -> Bool
221+
222+
Check if `method` is declared as `Base.@constprop :none`.
223+
"""
224+
is_no_constprop(method::Union{Method,CodeInfo}) = method.constprop == 0x02
225+
212226
#########
213227
# types #
214228
#########

src/ast.scm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,21 @@
523523
(and (if one (length= e 3) (length> e 2))
524524
(eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize))))
525525

526+
(define (meta? e)
527+
(and (length> e 1) (eq? (car e) 'meta)))
528+
529+
(define (method-meta-sym? x)
530+
(memq x '(inline noinline aggressive_constprop no_constprop propagate_inbounds)))
531+
532+
(define (propagate-method-meta e)
533+
`(meta ,@(filter (lambda (x)
534+
(or (method-meta-sym? x)
535+
(and (pair? x) (eq? (car x) 'purity))))
536+
(cdr e))))
537+
538+
(define (argwide-nospecialize-meta? e)
539+
(and (length= e 2) (eq? (car e) 'meta) (memq (cadr e) '(nospecialize specialize))))
540+
526541
(define (if-generated? e)
527542
(and (length= e 4) (eq? (car e) 'if) (equal? (cadr e) '(generated))))
528543

src/julia-syntax.scm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@
562562
,(if (any kwarg? pargl) (gensy) UNUSED)
563563
(call (core kwftype) ,ftype)) ,kw ,@pargl ,@vararg)
564564
`(block
565+
;; propagate method metadata to keyword sorter
566+
,@(map propagate-method-meta (filter meta? prologue))
567+
,@(filter argwide-nospecialize-meta? prologue)
565568
,@(let ((lnns (filter linenum? prologue)))
566569
(if (pair? lnns)
567570
(list (car lnns))

test/compiler/inline.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,3 +1402,49 @@ end
14021402
end
14031403
end
14041404
end
1405+
1406+
# https://github.com/JuliaLang/julia/issues/45050
1407+
@testset "propagate :meta annotations to keyword sorter methods" begin
1408+
# @inline, @noinline, @constprop
1409+
let @inline f(::Any; x::Int=1) = 2x
1410+
@test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source)
1411+
@test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source)
1412+
end
1413+
let @noinline f(::Any; x::Int=1) = 2x
1414+
@test !ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source)
1415+
@test !ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source)
1416+
end
1417+
let Base.@constprop :aggressive f(::Any; x::Int=1) = 2x
1418+
@test Core.Compiler.is_aggressive_constprop(only(methods(f)))
1419+
@test Core.Compiler.is_aggressive_constprop(only(methods(Core.kwfunc(f))))
1420+
end
1421+
let Base.@constprop :none f(::Any; x::Int=1) = 2x
1422+
@test Core.Compiler.is_no_constprop(only(methods(f)))
1423+
@test Core.Compiler.is_no_constprop(only(methods(Core.kwfunc(f))))
1424+
end
1425+
# @nospecialize
1426+
let f(@nospecialize(A::Any); x::Int=1) = 2x
1427+
@test only(methods(f)).nospecialize == 1
1428+
@test only(methods(Core.kwfunc(f))).nospecialize == 4
1429+
end
1430+
let f(::Any; x::Int=1) = (@nospecialize; 2x)
1431+
@test only(methods(f)).nospecialize == -1
1432+
@test only(methods(Core.kwfunc(f))).nospecialize == -1
1433+
end
1434+
# Base.@assume_effects
1435+
let Base.@assume_effects :notaskstate f(::Any; x::Int=1) = 2x
1436+
@test Core.Compiler.decode_effects_override(only(methods(f)).purity).notaskstate
1437+
@test Core.Compiler.decode_effects_override(only(methods(Core.kwfunc(f))).purity).notaskstate
1438+
end
1439+
# propagate multiple metadata also
1440+
let @inline Base.@assume_effects :notaskstate Base.@constprop :aggressive f(::Any; x::Int=1) = (@nospecialize; 2x)
1441+
@test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(f)).source)
1442+
@test Core.Compiler.is_aggressive_constprop(only(methods(f)))
1443+
@test ccall(:jl_ir_flag_inlineable, Bool, (Any,), only(methods(Core.kwfunc(f))).source)
1444+
@test Core.Compiler.is_aggressive_constprop(only(methods(Core.kwfunc(f))))
1445+
@test only(methods(f)).nospecialize == -1
1446+
@test only(methods(Core.kwfunc(f))).nospecialize == -1
1447+
@test Core.Compiler.decode_effects_override(only(methods(f)).purity).notaskstate
1448+
@test Core.Compiler.decode_effects_override(only(methods(Core.kwfunc(f))).purity).notaskstate
1449+
end
1450+
end

0 commit comments

Comments
 (0)