Skip to content

Commit 59bd6f3

Browse files
committed
reduce the impact of generated functions on getindex inference
1 parent ef3fe27 commit 59bd6f3

File tree

2 files changed

+15
-24
lines changed

2 files changed

+15
-24
lines changed

base/inference.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ function abstract_call_method(method::Method, f::ANY, sig::ANY, sparams::SimpleV
15351535
sigtuple = unwrap_unionall(sig)::DataType
15361536

15371537
tm = _topmod(sv)
1538-
if !istopfunction(tm, f, :promote_typeof)
1538+
if !istopfunction(tm, f, :promote_typeof) && !istopfunction(tm, f, :getindex)
15391539
# limit argument type tuple growth
15401540
msig = unwrap_unionall(method.sig)
15411541
lsig = length(msig.parameters)

base/multidimensional.jl

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -435,13 +435,9 @@ getindex(t::Tuple, i::CartesianIndex{1}) = getindex(t, i.I[1])
435435
# These are not defined on directly on getindex to avoid
436436
# ambiguities for AbstractArray subtypes. See the note in abstractarray.jl
437437

438-
@generated function _getindex(l::IndexStyle, A::AbstractArray, I::Union{Real, AbstractArray}...)
439-
N = length(I)
440-
quote
441-
@_inline_meta
442-
@boundscheck checkbounds(A, I...)
443-
_unsafe_getindex(l, _maybe_reshape(l, A, I...), I...)
444-
end
438+
@inline function _getindex(l::IndexStyle, A::AbstractArray, I::Union{Real, AbstractArray}...)
439+
@boundscheck checkbounds(A, I...)
440+
return _unsafe_getindex(l, _maybe_reshape(l, A, I...), I...)
445441
end
446442
# But we can speed up IndexCartesian arrays by reshaping them to the appropriate dimensionality:
447443
_maybe_reshape(::IndexLinear, A::AbstractArray, I...) = A
@@ -450,31 +446,26 @@ _maybe_reshape(::IndexCartesian, A::AbstractVector, I...) = A
450446
@inline __maybe_reshape(A::AbstractArray{T,N}, ::NTuple{N,Any}) where {T,N} = A
451447
@inline __maybe_reshape(A::AbstractArray, ::NTuple{N,Any}) where {N} = reshape(A, Val{N})
452448

453-
@generated function _unsafe_getindex(::IndexStyle, A::AbstractArray, I::Union{Real, AbstractArray}...)
454-
N = length(I)
455-
quote
456-
# This is specifically not inlined to prevent exessive allocations in type unstable code
457-
@nexprs $N d->(I_d = I[d])
458-
shape = @ncall $N index_shape I
459-
dest = similar(A, shape)
460-
map(unsafe_length, indices(dest)) == map(unsafe_length, shape) || throw_checksize_error(dest, shape)
461-
@ncall $N _unsafe_getindex! dest A I
462-
end
449+
function _unsafe_getindex(::IndexStyle, A::AbstractArray, I::Vararg{Union{Real, AbstractArray}, N}) where N
450+
# This is specifically not inlined to prevent exessive allocations in type unstable code
451+
shape = index_shape(I...)
452+
dest = similar(A, shape)
453+
map(unsafe_length, indices(dest)) == map(unsafe_length, shape) || throw_checksize_error(dest, shape)
454+
_unsafe_getindex!(dest, A, I...) # usually a generated function, don't allow it to impact inference result
455+
return dest
463456
end
464457

465458
# Always index with the exactly indices provided.
466-
@generated function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Union{Real, AbstractArray}...)
467-
N = length(I)
459+
@generated function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Vararg{Union{Real, AbstractArray}, N}) where N
468460
quote
469-
$(Expr(:meta, :inline))
470-
@nexprs $N d->(J_d = I[d])
461+
@_inline_meta
471462
D = eachindex(dest)
472463
Ds = start(D)
473-
@inbounds @nloops $N j d->J_d begin
464+
@inbounds @nloops $N j d->I[d] begin
474465
d, Ds = next(D, Ds)
475466
dest[d] = @ncall $N getindex src j
476467
end
477-
dest
468+
return dest
478469
end
479470
end
480471

0 commit comments

Comments
 (0)