Skip to content

Commit 9d4565b

Browse files
authored
a few compiler improvements (#36176)
- improve fieldtype_nothrow for vararg tuple types - remove UnionAll construction code from tuple_type_head - add specializations to avoid some common generated functions
1 parent 98e678f commit 9d4565b

File tree

5 files changed

+41
-10
lines changed

5 files changed

+41
-10
lines changed

base/compiler/tfuncs.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,12 +876,12 @@ function _fieldtype_nothrow(@nospecialize(s), exact::Bool, name::Const)
876876
isa(fld, Int) || return false
877877
ftypes = datatype_fieldtypes(u)
878878
nf = length(ftypes)
879-
(fld >= 1 && fld <= nf) || return false
880879
if u.name === Tuple.name && fld >= nf && isvarargtype(ftypes[nf])
881-
# The length of the tuple will be determined at runtime, we can't say
882-
# anything
883-
return false
880+
# If we don't know the exact type, the length of the tuple will be determined
881+
# at runtime and we can't say anything.
882+
return exact
884883
end
884+
(fld >= 1 && fld <= nf) || return false
885885
return true
886886
end
887887

base/essentials.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ ERROR: ArgumentError: Cannot call tail on an empty tuple.
205205
tail(x::Tuple) = argtail(x...)
206206
tail(::Tuple{}) = throw(ArgumentError("Cannot call tail on an empty tuple."))
207207

208-
tuple_type_head(T::Type) = (@_pure_meta; fieldtype(T::Type{<:Tuple}, 1))
208+
tuple_type_head(T::Type) = (@_pure_meta; fieldtype(T, 1))
209209

210210
function tuple_type_tail(T::Type)
211211
@_pure_meta

base/multidimensional.jl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,7 @@ function _unsafe_getindex(::IndexStyle, A::AbstractArray, I::Vararg{Union{Real,
758758
return dest
759759
end
760760

761-
# Always index with the exactly indices provided.
762-
@generated function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Vararg{Union{Real, AbstractArray}, N}) where N
761+
function _generate_unsafe_getindex!_body(N::Int)
763762
quote
764763
@_inline_meta
765764
D = eachindex(dest)
@@ -776,6 +775,20 @@ end
776775
end
777776
end
778777

778+
# Always index with the exactly indices provided.
779+
@generated function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Vararg{Union{Real, AbstractArray}, N}) where N
780+
_generate_unsafe_getindex!_body(N)
781+
end
782+
783+
# manually written-out specializations for 1 and 2 arguments to save compile time
784+
@eval function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Vararg{Union{Real, AbstractArray},1})
785+
$(_generate_unsafe_getindex!_body(1))
786+
end
787+
788+
@eval function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Vararg{Union{Real, AbstractArray},2})
789+
$(_generate_unsafe_getindex!_body(2))
790+
end
791+
779792
@noinline throw_checksize_error(A, sz) = throw(DimensionMismatch("output array is the wrong size; expected $sz, got $(size(A))"))
780793

781794
## setindex! ##
@@ -786,8 +799,7 @@ function _setindex!(l::IndexStyle, A::AbstractArray, x, I::Union{Real, AbstractA
786799
A
787800
end
788801

789-
@generated function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Union{Real,AbstractArray}...)
790-
N = length(I)
802+
function _generate_unsafe_setindex!_body(N::Int)
791803
quote
792804
x′ = unalias(A, x)
793805
@nexprs $N d->(I_d = unalias(A, I[d]))
@@ -806,6 +818,18 @@ end
806818
end
807819
end
808820

821+
@generated function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Vararg{Union{Real,AbstractArray}, N}) where N
822+
_generate_unsafe_setindex!_body(N)
823+
end
824+
825+
@eval function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Vararg{Union{Real,AbstractArray},1})
826+
$(_generate_unsafe_setindex!_body(1))
827+
end
828+
829+
@eval function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Vararg{Union{Real,AbstractArray},2})
830+
$(_generate_unsafe_setindex!_body(2))
831+
end
832+
809833
diff(a::AbstractVector) = diff(a, dims=1)
810834

811835
"""

base/namedtuple.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ function merge(a::NamedTuple{an}, b::NamedTuple{bn}) where {an, bn}
248248
end
249249
end
250250

251-
merge(a::NamedTuple{()}, b::NamedTuple) = b
251+
merge(a::NamedTuple, b::NamedTuple{()}) = a
252+
merge(a::NamedTuple{()}, b::NamedTuple{()}) = a
253+
merge(a::NamedTuple{()}, b::NamedTuple) = b
252254

253255
merge(a::NamedTuple, b::Iterators.Pairs{<:Any,<:Any,<:Any,<:NamedTuple}) = merge(a, b.data)
254256

@@ -320,6 +322,8 @@ function structdiff(a::NamedTuple{an}, b::Union{NamedTuple{bn}, Type{NamedTuple{
320322
end
321323
end
322324

325+
structdiff(a::NamedTuple{an}, b::Union{NamedTuple{an}, Type{NamedTuple{an}}}) where {an} = (;)
326+
323327
"""
324328
setindex(nt::NamedTuple, val, key::Symbol)
325329

test/compiler/inference.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,9 @@ let fieldtype_tfunc = Core.Compiler.fieldtype_tfunc,
655655
@test fieldtype_nothrow(Union{Type{Base.RefValue{<:Real}}, Type{Base.RefValue{Any}}}, Const(:x))
656656
@test fieldtype_nothrow(Const(Union{Base.RefValue{<:Real}, Base.RefValue{Any}}), Const(:x))
657657
@test fieldtype_nothrow(Type{Union{Base.RefValue{T}, Base.RefValue{Any}}} where {T<:Real}, Const(:x))
658+
@test fieldtype_nothrow(Type{Tuple{Vararg{Int}}}, Const(1))
659+
@test fieldtype_nothrow(Type{Tuple{Vararg{Int}}}, Const(42))
660+
@test !fieldtype_nothrow(Type{<:Tuple{Vararg{Int}}}, Const(1))
658661
end
659662

660663
# issue #11480

0 commit comments

Comments
 (0)