-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
inference: improve inference of indexing into union of tuples #39296
Conversation
Is there a way to fix this more generally? For example, in cases like below:
|
The precision of return type of tuple indexing really relies on constant propagation, but when an argument is union of tuples, call signature will be split and constant prop' won't happen, and so inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR special cases some of tuple indexing methods (`getindex(::Tuple)` and `indexed_iterate(::Tuple)`) and forces constant propagation to happen even when their argument is union of tuples, by converting it to tuple of unions.
We need to enable constant prop' for union split signatures to fix this in general. |
Right, is that possible? |
yeah, later I'll make another PR doing that as an alternative for this PR (but its latency impact should be examined carefully) |
The precision of inference on certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for union signatures (with "non-Bottom" results) - adds special cases for some functions (see `force_constant_prop'`) so that we keep inferring on them even after the return type from non-constant analysis has grown to `Any`, since constant analysis can improve the result later on The added test cases will should showcase the cases where the inference result could be improved by that. --- Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time master (26a721b) ```bash Sysimage built. Summary: Total ─────── 57.320450 seconds Base: ─────── 24.371516 seconds 42.518% Stdlibs: ──── 32.947400 seconds 57.4793% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1379/1379 Precompilation complete. Summary: Total ─────── 101.325866 seconds Generation ── 74.901320 seconds 73.9212% Execution ─── 26.424546 seconds 26.0788% LINK usr/lib/julia/sys.dylib ``` this PR ```bash Sysimage built. Summary: Total ─────── 58.387562 seconds Base: ─────── 24.403206 seconds 41.7952% Stdlibs: ──── 33.982657 seconds 58.2019% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 99.659102 seconds Generation ── 73.983763 seconds 74.2368% Execution ─── 25.675339 seconds 25.7632% LINK usr/lib/julia/sys.dylib ``` > first time to plot master (26a721b) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- This PR is an alternative for JuliaLang#39296, closes JuliaLang#39296.
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for union signatures (with "non-Bottom" results) - adds special cases for some functions (see `force_constant_prop'`) so that we keep inferring on them even after the return type from non-constant analysis has grown to `Any`, since constant analysis can improve the result later on The added test cases will should showcase the cases where the inference result could be improved by that. --- Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (26a721b) ```bash Sysimage built. Summary: Total ─────── 57.320450 seconds Base: ─────── 24.371516 seconds 42.518% Stdlibs: ──── 32.947400 seconds 57.4793% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1379/1379 Precompilation complete. Summary: Total ─────── 101.325866 seconds Generation ── 74.901320 seconds 73.9212% Execution ─── 26.424546 seconds 26.0788% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Sysimage built. Summary: Total ─────── 58.387562 seconds Base: ─────── 24.403206 seconds 41.7952% Stdlibs: ──── 33.982657 seconds 58.2019% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 99.659102 seconds Generation ── 73.983763 seconds 74.2368% Execution ─── 25.675339 seconds 25.7632% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (26a721b) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- NOTE: this PR is an alternative for JuliaLang#39296
Done: #39305 |
Yay! |
Will be superceded by #39305 |
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
…9305) The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes #37610 - some part of this code was taken from #37637 - this PR is originally supposed to be alternative and more generalized version of #39296
…liaLang#39305) The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
…liaLang#39305) The inference precision of certain functions really relies on constant propagation, but currently constant prop' won't happen when a call signature is union split and so sometimes inference ends up looser return type: e.g. ```julia julia> Base.return_types((Union{Tuple{Int,Nothing},Tuple{Int,Missing}},)) do t a, b = t a # I expected a::Int, but a::Union{Missing,Nothing,Int} end |> first Union{Missing, Nothing, Int64} ``` This PR: - enables constant prop' for each union signatures, by calling `abstract_call_method_with_const_args` just after each `abstract_call_method` - refactor `abstract_call_method_with_const_args` into two separate parts, 1.) heuristics to decide whether to do constant prop', 2.) try constant propagation The added test cases will should showcase the cases where the inference result could be improved by that. --- I've not seen notable regression in latency with this PR. Here is a sample benchmark of the impact of this PR on latency, from which I guess this PR is acceptable ? > build time: master (caeacef) ```bash Sysimage built. Summary: Total ─────── 61.615938 seconds Base: ─────── 26.575732 seconds 43.1313% Stdlibs: ──── 35.038024 seconds 56.8652% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1378/1378 Precompilation complete. Summary: Total ─────── 116.417013 seconds Generation ── 81.077365 seconds 69.6439% Execution ─── 35.339648 seconds 30.3561% LINK usr/lib/julia/sys.dylib ``` > build time: this PR ```bash Stdlibs total ──── 34.077962 seconds Sysimage built. Summary: Total ─────── 61.804573 seconds Base: ─────── 27.724077 seconds 44.8576% Stdlibs: ──── 34.077962 seconds 55.1383% JULIA usr/lib/julia/sys-o.a Generating REPL precompile statements... 30/30 Executing precompile statements... 1362/1362 Precompilation complete. Summary: Total ─────── 111.262672 seconds Generation ── 83.535305 seconds 75.0794% Execution ─── 27.727367 seconds 24.9206% LINK usr/lib/julia/sys.dylib ``` > first time to plot: master (caeacef) ```julia julia> using Plots; @time plot(rand(10,3)) 3.614168 seconds (5.47 M allocations: 324.564 MiB, 5.73% gc time, 53.02% compilation time) ``` > first time to plot: this PR ```julia julia> using Plots; @time plot(rand(10,3)) 3.557919 seconds (5.53 M allocations: 328.812 MiB, 2.89% gc time, 51.94% compilation time) ``` --- - fixes JuliaLang#37610 - some part of this code was taken from JuliaLang#37637 - this PR is originally supposed to be alternative and more generalized version of JuliaLang#39296
The precision of return type of tuple indexing really relies on constant
propagation, but when an argument is union of tuples, call signature
will be split and constant prop' won't happen, and so inference ends up
looser return type: e.g.
This PR special cases some of tuple indexing methods
(
getindex(::Tuple)
andindexed_iterate(::Tuple)
) and forces constantpropagation to happen even when their argument is union of tuples,
by converting it to tuple of unions.
The diff certainly looks a bit odd; is there a better way to address this ?