Skip to content
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

Fully drop _tuple_any and improve type-based offset axes check. #45260

Merged
merged 7 commits into from
Aug 10, 2022

Conversation

N5N3
Copy link
Member

@N5N3 N5N3 commented May 10, 2022

Base._tuple_any is only used in Base.has_offset_axes.
After #44063, we have a similar method _any_tuple, which should be functionally consistent for offset axes check.
This PR fully removes _tuple_any, and make Base.has_offset_axes call _any_tuple.
(Ideally, we'd better call public api any instead. But our compiler fails to fold some check as a const.)

This PR also omits some axes call in has_offset_axes by checking indices/parent's axes rather than self's axes.
This helps #44040 a little.

Test added.

@N5N3 N5N3 force-pushed the remove_tuple_any branch 3 times, most recently from 8c42ee9 to 8dd18c3 Compare May 11, 2022 02:35
@N5N3
Copy link
Member Author

N5N3 commented May 11, 2022

#45230 invalidated the optimization introduced in #40358.
ba0939f recovers it and defines some “cheap” firstindex for StepRange{T,T}. (We could extend them once we land #45236)
The const-folding test for range has been added in 8dd18c3.

@N5N3 N5N3 requested a review from vtjnash May 11, 2022 06:06
test/compiler/inline.jl Outdated Show resolved Hide resolved
@N5N3 N5N3 force-pushed the remove_tuple_any branch 2 times, most recently from 9d37b62 to 8a02e52 Compare May 11, 2022 13:36
base/range.jl Outdated
@@ -687,6 +687,13 @@ step_hp(r::AbstractRange) = step(r)

axes(r::AbstractRange) = (oneto(length(r)),)

# Needed to ensure `has_offset_axes` can constant-fold.
has_offset_axes(::StepRange) = false
let baseints = Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let baseints = Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128}
let baseints = BitInteger

Copy link
Member Author

Choose a reason for hiding this comment

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

BitInteger is defined later in int.jl. Maybe we can replace it with Union{bigints, smallints}

base/range.jl Outdated
has_offset_axes(::StepRange) = false
let baseints = Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128}
global firstindex
firstindex(::StepRange{T,<:baseints}) where {T<:baseints} = sizeof(T) < sizeof(Int) ? 1 : one(T)
Copy link
Member

Choose a reason for hiding this comment

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

T might be a Union and not have a size?

Copy link
Member Author

@N5N3 N5N3 May 12, 2022

Choose a reason for hiding this comment

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

Well, we should use sizeof(first(r)) instead.
The new length has similar problem.
To make sure the result is correct, we'd better split L694 into:

firstindex(r::StepRange{<:bigints,<:BitInteger}) = one(last(r)-first(r))
firstindex(::StepRange{<:smallints,<:BitInteger}) = 1

base/range.jl Outdated Show resolved Hide resolved
@@ -799,7 +806,7 @@ let smallints = (Int === Int64 ?
function length(r::OrdinalRange{<:smallints})
s = step(r)
isempty(r) && return 0
return div(Int(last(r)) - Int(first(r)), s) + 1
return Int(div(Int(last(r)) - Int(first(r)), s)) + 1
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure it is legal to cast this to an Int? This seems highly unrelated to the commit message

Copy link
Member Author

@N5N3 N5N3 May 12, 2022

Choose a reason for hiding this comment

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

This is for length(::StepRange{Int8,Int128}). Without this, we'll return a Int128 for non-empty r.
I believe it's safe as we convert the div result rather than step s. Int should be enough to represent the length

test/abstractarray.jl Outdated Show resolved Hide resolved
test/abstractarray.jl Outdated Show resolved Hide resolved
test/abstractarray.jl Outdated Show resolved Hide resolved
test/abstractarray.jl Outdated Show resolved Hide resolved
test/ranges.jl Outdated Show resolved Hide resolved
test/ranges.jl Outdated Show resolved Hide resolved
base/abstractarray.jl Outdated Show resolved Hide resolved
@N5N3 N5N3 force-pushed the remove_tuple_any branch 3 times, most recently from 987a9b0 to ab36599 Compare May 17, 2022 09:28
N5N3 and others added 7 commits July 25, 2022 21:18
`_any_tuple` should be functionally consistent. (And has no bootstrap problem.)
This avoid some unneeded `axes` call, thus more possible be folded by the compiler.
And define `firstindex` accordingly.

Co-Authored-By: Jameson Nash <[email protected]>
@vtjnash vtjnash merged commit f345923 into JuliaLang:master Aug 10, 2022
@N5N3 N5N3 deleted the remove_tuple_any branch August 11, 2022 03:48
ffucci pushed a commit to ffucci/julia that referenced this pull request Aug 11, 2022
* Follow up to JuliaLang#45236 (make `length(::StepRange{Int8,Int128})` type-stable)
* Fully drop `_tuple_any` (unneeded now)
* Make sure `has_offset_axes(::StepRange)` could be const folded.
  And define some "cheap" `firstindex`
* Do offset axes check on `A`'s parent rather than itself.
  This avoid some unneeded `axes` call, thus more possible be folded by the compiler.

Co-authored-by: Jameson Nash <[email protected]>
pcjentsch pushed a commit to pcjentsch/julia that referenced this pull request Aug 18, 2022
* Follow up to JuliaLang#45236 (make `length(::StepRange{Int8,Int128})` type-stable)
* Fully drop `_tuple_any` (unneeded now)
* Make sure `has_offset_axes(::StepRange)` could be const folded.
  And define some "cheap" `firstindex`
* Do offset axes check on `A`'s parent rather than itself.
  This avoid some unneeded `axes` call, thus more possible be folded by the compiler.

Co-authored-by: Jameson Nash <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants