Skip to content

Compiler: walk_to_defs, collect_leaves: specialize for predecessors #57859

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

nsajko
Copy link
Contributor

@nsajko nsajko commented Mar 22, 2025

Should make the code less vulnerable to invalidation.

@nsajko nsajko added invalidations backport 1.12 Change should be backported to release-1.12 labels Mar 22, 2025
@nsajko
Copy link
Contributor Author

nsajko commented Mar 22, 2025

The invalidation count on loading TypeDomainNaturalNumbers v7.0.0 drops from 741 to 722. I haven't been able to get a nice diff, but these three method instances are some of those that are not invalidated on the PR branch:

{   
    "method_instance": {
        "method": "walk_to_defs(compact::Compiler.IncrementalCompact, defssa, typeconstraint, predecessors, 𝕃ₒ::Compiler.AbstractLattice) @ Compiler ../usr/share/julia/Compiler/src/ssair/passes.jl:274",
        "method_instance": "MethodInstance for Compiler.walk_to_defs(::Compiler.IncrementalCompact, ::Any, ::Any, ::Function, ::Compiler.PartialsLattice{Compiler.ConstsLattice})"
    },
    "children": [
        {   
            "method_instance": {
                "method": "collect_leaves(compact::Compiler.IncrementalCompact, val, typeconstraint, 𝕃ₒ::Compiler.AbstractLattice, predecessors) @ Compiler ../usr/share/julia/Compiler/src/ssair/passes.jl:185",
                "method_instance": "MethodInstance for Compiler.collect_leaves(::Compiler.IncrementalCompact, ::Any, ::Any, ::Compiler.PartialsLattice{Compiler.ConstsLattice}, ::Function)"
            },
            "children": [
                {   
                    "method_instance": {
                        "method": "lift_keyvalue_get!(compact::Compiler.IncrementalCompact, idx::Int64, stmt::Expr, 𝕃ₒ::Compiler.AbstractLattice) @ Compiler ../usr/share/julia/Compiler/src/ssair/passes.jl:981",
                        "method_instance": "MethodInstance for Compiler.lift_keyvalue_get!(::Compiler.IncrementalCompact, ::Int64, ::Expr, ::Compiler.PartialsLattice{Compiler.ConstsLattice})"
                    }
                }
            ]
        }
    ]
}

Data:

This was referenced Mar 22, 2025
@KristofferC
Copy link
Member

KristofferC commented Mar 25, 2025

There is another length(values) a few lines above. Is that also not problematic?

(fast fingered the close button)

@KristofferC KristofferC reopened this Mar 25, 2025
Copy link
Member

@topolarity topolarity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proper fix here to my eyes is that this should be specializing on the type of predecessors, so that values is then a well-inferred type

@vtjnash
Copy link
Member

vtjnash commented Mar 26, 2025

Looks like it is an argument, so that should be written , predecessors::P, ...) where P

@nsajko nsajko changed the title Compiler: walk_to_defs: type assert Int before calling : Compiler: walk_to_defs: specialize for the type of predecessors Mar 27, 2025
@nsajko nsajko force-pushed the Compiler_ssair_passes_type_assert_Int_before_Colon branch from a3273a6 to 71a9406 Compare March 27, 2025 07:31
@nsajko
Copy link
Contributor Author

nsajko commented Mar 27, 2025

The proper fix here to my eyes is that this should be specializing on the type of predecessors

Just tried doing that while getting rid of the type assert. It gets rid of two additional invalidations, but sadly reintroduces the invalidations that were eliminated by the type assert.

I say merge this as-is, it's probably best to keep these PRs minimal to ease backporting or reverts if necessary.

The invalidations fixed by the current version of this PR:

{
    "method_instance": {
        "method": "isempty(r::StepRange) @ Base range.jl:685",
        "method_instance": "MethodInstance for isempty(::StepRange{Tuple{LineNumberNode, Expr}})"
    },
    "children": [
        {
            "method_instance": {
                "method": "iterate(r::OrdinalRange) @ Base range.jl:917",
                "method_instance": "MethodInstance for iterate(::OrdinalRange{Tuple{LineNumberNode, Expr}})"
            },
            "children": [
                {
                    "method_instance": {
                        "method": "Vector{T}(r::AbstractRange{T}) where T @ Base range.jl:1395",
                        "method_instance": "MethodInstance for Vector{Tuple{LineNumberNode, Expr}}(::AbstractRange{Tuple{LineNumberNode, Expr}})"
                    },
                    "children": [
                    ]
                }
            ]
        }
    ]
}

@topolarity
Copy link
Member

Just tried doing that while getting rid of the type assert. It gets rid of two additional invalidations, but sadly reintroduces the invalidations that were eliminated by the type assert.

Thanks for checking! It looks like collect_leaves probably also needs the same specialization trick

@nsajko nsajko changed the title Compiler: walk_to_defs: specialize for the type of predecessors Compiler: walk_to_defs, collect_leaves: specialize for predecessors Mar 27, 2025
@nsajko nsajko force-pushed the Compiler_ssair_passes_type_assert_Int_before_Colon branch from f3bda2e to 25e13c5 Compare March 27, 2025 13:16
@nsajko
Copy link
Contributor Author

nsajko commented Mar 27, 2025

With the current version of this PR, the unique invalidation count when running the MWE below drops from 627 to 610. The diff happens to be very ugly, so I'm not pasting any individual wins.

MWE:

struct S <: Integer end
function Base.zero(::S) end
function Base.one(::S) end
let int_types = (Bool, Int8, UInt8, Int16, UInt16, Int, UInt, BigInt),
    bin_ops = (+, *)
    for int_type  int_types
        T = Symbol(int_type)
        @eval begin
            function S(::$T) end
            function Base.$T(::S) end
            function Base.promote_rule(::Type{$T}, ::Type{S}) end
            function Base.promote_rule(::Type{S}, ::Type{$T}) end
        end
        for bin_op  bin_ops
            op = Symbol(bin_op)
            @eval begin
                function Base.$op(::$T, ::S) end
                function Base.$op(::S, ::$T) end
            end
        end
    end
end

Data on each invalidation:

@vtjnash vtjnash added the merge me PR is reviewed. Merge when all tests are passing label Mar 27, 2025
Copy link
Member

@topolarity topolarity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@topolarity topolarity merged commit d9441ac into JuliaLang:master Mar 27, 2025
8 checks passed
@nsajko nsajko deleted the Compiler_ssair_passes_type_assert_Int_before_Colon branch March 27, 2025 18:35
@nsajko nsajko removed the merge me PR is reviewed. Merge when all tests are passing label Mar 27, 2025
KristofferC pushed a commit that referenced this pull request Mar 31, 2025
…ssors` (#57859)

Should make the code less vulnerable to invalidation.

(cherry picked from commit d9441ac)
@KristofferC KristofferC mentioned this pull request Mar 31, 2025
36 tasks
KristofferC pushed a commit that referenced this pull request Mar 31, 2025
…ssors` (#57859)

Should make the code less vulnerable to invalidation.

(cherry picked from commit d9441ac)
@KristofferC KristofferC mentioned this pull request Apr 4, 2025
51 tasks
@KristofferC KristofferC removed the backport 1.12 Change should be backported to release-1.12 label Apr 9, 2025
serenity4 pushed a commit to serenity4/julia that referenced this pull request May 1, 2025
…ssors` (JuliaLang#57859)

Should make the code less vulnerable to invalidation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants