decrease max_methods world-splitting setting for some functions#59377
Closed
nsajko wants to merge 10 commits intoJuliaLang:masterfrom
Closed
decrease max_methods world-splitting setting for some functions#59377nsajko wants to merge 10 commits intoJuliaLang:masterfrom
max_methods world-splitting setting for some functions#59377nsajko wants to merge 10 commits intoJuliaLang:masterfrom
Conversation
Member
Author
|
This must be causing tangible inference issues, because the trimming CI fails. However, the logs don't show what the issue is. |
Member
Author
|
Ah, there's a bunch of inference failures in the usual test suite, too. Clearly more work is necessary. |
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 27, 2025
The method return type is known concretely as `OneTo{Int}`, however the
compiler can't tell because there are too many methods matching
`length(::Array)`, over the world-splitting threshold, `max_methods`.
Cross-reference PR JuliaLang#57627, which might help here in another way by
decreasing the number of unnecessary methods, however merging that PR
would also cause regressions if world-splitting is not disabled first
for `length` (xref PR JuliaLang#59377).
Fix that by asserting the return type of the `length` call as `Int`.
The `typeassert` should improve abstract return type inference, and
consequently make the sysimage more resistant to invalidation.
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 27, 2025
The method return type is known concretely as `OneTo{Int}`, however the
compiler can't tell because there are too many methods matching
`length(::Array)`, over the world-splitting threshold, `max_methods`.
Cross-reference WIP PR JuliaLang#57627, which might help here in another way by
decreasing the number of unnecessary methods, however merging that PR
would also cause regressions if world-splitting is not disabled first
for `length` (xref WIP PR JuliaLang#59377).
Fix that by asserting the return type of the `length` call as `Int`.
The `typeassert` should improve abstract return type inference, and
consequently make the sysimage more resistant to invalidation.
f9ddf54 to
a47559f
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods`, such as PRs: * JuliaLang#59091 * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 28, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Aug 29, 2025
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
a563401 to
e7c44cc
Compare
Member
Author
|
This now temporarily includes the commit from PR #59421, however I expect that one will be merged before this one will be considered. |
Member
Author
|
The only test failure is curious:
CI log link: The test on line 287 here is the one that fails: julia/test/boundscheck_exec.jl Lines 267 to 289 in 3396562 Perhaps a compiler bug? |
e7c44cc to
78499ab
Compare
This was referenced Jan 24, 2026
nsajko
added a commit
to nsajko/julia
that referenced
this pull request
Jan 25, 2026
* Introducing new types and methods for a callable can invalidate already compiled method instances of a function for which world-splitting is enabled (`max_methods`). * Invalidation of sysimage or package precompiled code worsens latency due to requiring recompilation. * Lowering the `max_methods` setting for a function often causes inference issues for existing code that is not completely type-stable (which is a lot of code). In many cases this is easy to fix by avoiding method proliferation, such as by merging some methods and introducing branching into the merged method. This PR aims to fix the latter issue for some `Tuple`-related methods of some functions where decreasing `max_methods` might be interesting. Seeing as branching was deliberately avoided in the bodies of many of these methods, I opted for the approach of introducing local functions which preserve the dispatch logic as before, without branching. Thus there should be no regressions, except perhaps because of changed inlining costs. This PR is a prerequisite for PRs which try to decrease `max_methods` for select functions, such as PR: * JuliaLang#59377
388a7c6 to
31cd591
Compare
As noted by simeonschaub on the original issue JuliaLang#41489, this only used to work by accident anyway.
3ff5e67 to
ff224cc
Compare
A function which is meant to have methods added to it by users should have a small `max_methods` value, as world-splitting just leads to unnecessary invalidation in that case, in the context of the package ecosystem, where users are allowed to add arbitrarily many methods to such functions. xref PR JuliaLang#57884 xref PR JuliaLang#58788 xref PR JuliaLang#58829 xref PR JuliaLang#59091
ff224cc to
6b81847
Compare
Some of these lines still need to be adjusted to `max_methods = 2`, if the function requires a method for the bottom type. Some of these lines need to be deleted outright, as not all of these functions are intended to allow package authors to add methods to them.
Delete each line corresponding to a function which is not supposed to have methods added to it by users or by package authors.
A function which takes a type argument and requires a method for the bottom type may reasonably require a `max_methods` value greater than one.
Member
Author
|
Giving up on this, bootstrapping concerns make this too difficult. Someone else feel free to take over. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP, not ready for review.
A function which is meant to have methods added to it by users should have a small
max_methodsvalue, as world-splitting just leads to unnecessary invalidation in that case, in the context of the package ecosystem, where users are allowed to add arbitrarily many methods to such functions.xref PR #57884
xref PR #58788
xref PR #58829
xref PR #59091