Skip to content

Commit

Permalink
Ensure to_index inlines by separating the n-ary version
Browse files Browse the repository at this point in the history
This separates the n-ary version of to_index to to_indexes. Recursive definitions with tuples don't inline like recursive splatted arguments.
  • Loading branch information
mbauman committed Jun 27, 2015
1 parent 756517b commit 3a4d466
Show file tree
Hide file tree
Showing 7 changed files with 17 additions and 19 deletions.
8 changes: 4 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,12 @@ function _getindex(::LinearFast, A::AbstractArray, I::Real...)
@_inline_meta
# We must check bounds for sub2ind; so we can then call unsafe_getindex
checkbounds(A, I...)
unsafe_getindex(A, sub2ind(size(A), to_index(I)...))
unsafe_getindex(A, sub2ind(size(A), to_indexes(I...)...))
end
_unsafe_getindex(::LinearFast, A::AbstractArray, I::Int) = (@_inline_meta; getindex(A, I))
function _unsafe_getindex(::LinearFast, A::AbstractArray, I::Real...)
@_inline_meta
unsafe_getindex(A, sub2ind(size(A), to_index(I)...))
unsafe_getindex(A, sub2ind(size(A), to_indexes(I...)...))
end

# LinearSlow Scalar indexing
Expand Down Expand Up @@ -530,12 +530,12 @@ function _setindex!(::LinearFast, A::AbstractArray, v, I::Real...)
@_inline_meta
# We must check bounds for sub2ind; so we can then call unsafe_setindex!
checkbounds(A, I...)
unsafe_setindex!(A, v, sub2ind(size(A), to_index(I)...))
unsafe_setindex!(A, v, sub2ind(size(A), to_indexes(I...)...))
end
_unsafe_setindex!(::LinearFast, A::AbstractArray, v, I::Int) = (@_inline_meta; setindex!(A, v, I))
function _unsafe_setindex!(::LinearFast, A::AbstractArray, v, I::Real...)
@_inline_meta
unsafe_setindex!(A, v, sub2ind(size(A), to_index(I)...))
unsafe_setindex!(A, v, sub2ind(size(A), to_indexes(I...)...))
end

# LinearSlow Scalar indexing
Expand Down
8 changes: 4 additions & 4 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,13 @@ getindex(A::Array, i1::Real) = arrayref(A, to_index(i1))
getindex(A::Array, i1::Real, i2::Real) = arrayref(A, to_index(i1), to_index(i2))
getindex(A::Array, i1::Real, i2::Real, i3::Real) = arrayref(A, to_index(i1), to_index(i2), to_index(i3))
getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real) = arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4))
getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_index(I)...)
getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_indexes(I...)...)

unsafe_getindex(A::Array, i1::Real) = @inbounds return arrayref(A, to_index(i1))
unsafe_getindex(A::Array, i1::Real, i2::Real) = @inbounds return arrayref(A, to_index(i1), to_index(i2))
unsafe_getindex(A::Array, i1::Real, i2::Real, i3::Real) = @inbounds return arrayref(A, to_index(i1), to_index(i2), to_index(i3))
unsafe_getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real) = @inbounds return arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4))
unsafe_getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = @inbounds return arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_index(I)...)
unsafe_getindex(A::Array, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = @inbounds return arrayref(A, to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_indexes(I...)...)

# Faster contiguous indexing using copy! for UnitRange and Colon
getindex(A::Array, I::UnitRange{Int}) = (checkbounds(A, I); unsafe_getindex(A, I))
Expand Down Expand Up @@ -331,13 +331,13 @@ setindex!{T}(A::Array{T}, x, i1::Real) = arrayset(A, convert(T,x), to_index(i1))
setindex!{T}(A::Array{T}, x, i1::Real, i2::Real) = arrayset(A, convert(T,x), to_index(i1), to_index(i2))
setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real) = arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3))
setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real) = arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4))
setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_index(I)...)
setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_indexes(I...)...)

unsafe_setindex!{T}(A::Array{T}, x, i1::Real) = @inbounds return arrayset(A, convert(T,x), to_index(i1))
unsafe_setindex!{T}(A::Array{T}, x, i1::Real, i2::Real) = @inbounds return arrayset(A, convert(T,x), to_index(i1), to_index(i2))
unsafe_setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real) = @inbounds return arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3))
unsafe_setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real) = @inbounds return arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4))
unsafe_setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = @inbounds return arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_index(I)...)
unsafe_setindex!{T}(A::Array{T}, x, i1::Real, i2::Real, i3::Real, i4::Real, I::Real...) = @inbounds return arrayset(A, convert(T,x), to_index(i1), to_index(i2), to_index(i3), to_index(i4), to_indexes(I...)...)

# These are redundant with the abstract fallbacks but needed for bootstrap
function setindex!(A::Array, x, I::AbstractVector{Int})
Expand Down
2 changes: 1 addition & 1 deletion base/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ endof(c::Char) = 1
getindex(c::Char) = c
getindex(c::Char, i::Integer) = i == 1 ? c : throw(BoundsError())
getindex(c::Char, I::Integer...) = all(EqX(1), I) ? c : throw(BoundsError())
getindex(c::Char, I::Real...) = getindex(c, to_index(I)...)
getindex(c::Char, I::Real...) = getindex(c, to_indexes(I...)...)
first(c::Char) = c
last(c::Char) = c
eltype(c::Char) = Char
Expand Down
2 changes: 1 addition & 1 deletion base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ _iterable(v) = repeated(v)
_unsafe_setindex!(l, A, x, J...)
end
@inline function _unsafe_setindex!(l::LinearIndexing, A::AbstractArray, x, J::Union{Real,AbstractVector,Colon}...)
_unsafe_batchsetindex!(l, A, _iterable(x), to_index(J)...)
_unsafe_batchsetindex!(l, A, _iterable(x), to_indexes(J...)...)
end

# While setindex! with one array argument doesn't mean anything special, it is
Expand Down
2 changes: 1 addition & 1 deletion base/number.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ endof(x::Number) = 1
getindex(x::Number) = x
getindex(x::Number, i::Integer) = i == 1 ? x : throw(BoundsError())
getindex(x::Number, I::Integer...) = all([i == 1 for i in I]) ? x : throw(BoundsError())
getindex(x::Number, I::Real...) = getindex(x, to_index(I)...)
getindex(x::Number, I::Real...) = getindex(x, to_indexes(I...)...)
unsafe_getindex(x::Real, i::Real) = x
first(x::Number) = x
last(x::Number) = x
Expand Down
10 changes: 4 additions & 6 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,12 @@ to_index(c::Colon) = c
to_index(I::AbstractArray{Bool}) = find(I)
to_index(A::AbstractArray{Int}) = A
to_index{T<:Integer}(A::AbstractArray{T}) = [to_index(x) for x in A]
to_index(i1, i2) = to_index(i1), to_index(i2)
to_index(i1, i2, i3) = to_index(i1), to_index(i2), to_index(i3)
to_index(i1, i2, i3, i4) = to_index(i1), to_index(i2), to_index(i3), to_index(i4)
to_index(I...) = to_index(I)
to_index(I::Tuple{}) = ()
to_index(I::Tuple) = (to_index(I[1]), to_index(tail(I))...)
to_index(i) = error("invalid index: $i")

to_indexes() = ()
to_indexes(i1) = (to_index(i1),)
to_indexes(i1, I...) = (to_index(i1), to_indexes(I...)...)

# Addition/subtraction of ranges
for f in (:+, :-)
@eval begin
Expand Down
4 changes: 2 additions & 2 deletions base/subarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,9 @@ end
# Indexing with non-scalars. For now, this returns a copy, but changing that
# is just a matter of deleting the explicit call to copy.
getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::ViewIndex...) = copy(sub(V, I...))
getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::Union{Real, AbstractVector, Colon}...) = getindex(V, to_index(I)...)
getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::Union{Real, AbstractVector, Colon}...) = getindex(V, to_indexes(I...)...)
unsafe_getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::ViewIndex...) = copy(sub_unsafe(V, I))
unsafe_getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::Union{Real, AbstractVector, Colon}...) = unsafe_getindex(V, to_index(I)...)
unsafe_getindex{T,N,P,IV}(V::SubArray{T,N,P,IV}, I::Union{Real, AbstractVector, Colon}...) = unsafe_getindex(V, to_indexes(I...)...)

# Nonscalar setindex! falls back to the AbstractArray versions

Expand Down

0 comments on commit 3a4d466

Please sign in to comment.