Skip to content

Commit 456198f

Browse files
vtjnashtkelman
authored andcommitted
improve inference of methods with Type{leaftype} parameters
(cherry picked from commit 15e7369) ref #21771 remove many unneeded pure annotations Removing actually may enable inference to get a sharper result, since it is no longer being directed to ignore backedges and correctness assumptions Replaces pure annotations in promotion with inline (cherry picked from commit 76a30fb) handling Base printing of Expr.typ fields not containing a Type this allows printing of the Exprs flowing through inference (which might instead have the field set to something like a Const object) (cherry picked from commit f97d9e8) apply_type on Type{T} is valid whenever T is valid removes performance bug added by 0292c42 (cherry picked from commit 8ee2e06)
1 parent bc9c8a8 commit 456198f

File tree

7 files changed

+46
-33
lines changed

7 files changed

+46
-33
lines changed

base/inference.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ mutable struct InferenceState
219219
if isa(atyp, DataType) && isdefined(atyp, :instance)
220220
# replace singleton types with their equivalent Const object
221221
atyp = Const(atyp.instance)
222+
elseif isconstType(atyp)
223+
atype = Const(atyp.parameters[1])
222224
else
223225
atyp = rewrap_unionall(atyp, linfo.specTypes)
224226
end
@@ -996,7 +998,7 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
996998
ai = args[i]
997999
if isType(ai)
9981000
aip1 = ai.parameters[1]
999-
canconst &= isleaftype(aip1)
1001+
canconst &= !has_free_typevars(aip1)
10001002
push!(tparams, aip1)
10011003
elseif isa(ai, Const) && (isa(ai.val, Type) || isa(ai.val, TypeVar) || valid_tparam(ai.val))
10021004
push!(tparams, ai.val)
@@ -1773,6 +1775,10 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
17731775
else
17741776
return Any
17751777
end
1778+
if !isa(body, Type) && !isa(body, TypeVar)
1779+
return Any
1780+
end
1781+
has_free_typevars(body) || return body
17761782
if isa(argtypes[2], Const)
17771783
tv = argtypes[2].val
17781784
elseif isa(argtypes[2], PartialTypeVar)
@@ -1783,9 +1789,6 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
17831789
return Any
17841790
end
17851791
!isa(tv, TypeVar) && return Any
1786-
if !isa(body, Type) && !isa(body, TypeVar)
1787-
return Any
1788-
end
17891792
theunion = UnionAll(tv, body)
17901793
ret = canconst ? abstract_eval_constant(theunion) : Type{theunion}
17911794
return ret
@@ -1853,8 +1856,8 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
18531856
t = pure_eval_call(f, argtypes, atype, sv)
18541857
t !== false && return t
18551858

1856-
if istopfunction(tm, f, :promote_type) || istopfunction(tm, f, :typejoin)
1857-
return Type
1859+
if istopfunction(tm, f, :typejoin) || f === return_type
1860+
return Type # don't try to infer these function edges directly -- it won't actually come up with anything useful
18581861
elseif length(argtypes) == 2 && istopfunction(tm, f, :typename)
18591862
return typename_static(argtypes[2])
18601863
end

base/linalg/uniformscaling.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
import Base: copy, ctranspose, getindex, show, transpose, one, zero, inv,
4-
@_pure_meta, hcat, vcat, hvcat
4+
hcat, vcat, hvcat
55
import Base.LinAlg: SingularException
66

77
struct UniformScaling{T<:Number}
@@ -201,7 +201,7 @@ promote_to_arrays(n,k, ::Type{T}, A, B, C) where {T} =
201201
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays_(n[k+2], T, C))
202202
promote_to_arrays(n,k, ::Type{T}, A, B, Cs...) where {T} =
203203
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays(n,k+2, T, Cs...)...)
204-
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling}}}) = (@_pure_meta; Matrix)
204+
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling}}}) = Matrix
205205

206206
for (f,dim,name) in ((:hcat,1,"rows"), (:vcat,2,"cols"))
207207
@eval begin

base/promotion.jl

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,14 @@ end
122122

123123
## promotion mechanism ##
124124

125-
promote_type() = (@_pure_meta; Bottom)
126-
promote_type(T) = (@_pure_meta; T)
127-
promote_type(T, S, U, V...) = (@_pure_meta; promote_type(T, promote_type(S, U, V...)))
125+
promote_type() = Bottom
126+
promote_type(T) = T
127+
promote_type(T, S, U, V...) = (@_inline_meta; promote_type(T, promote_type(S, U, V...)))
128128

129-
promote_type(::Type{Bottom}, ::Type{Bottom}) = (@_pure_meta; Bottom)
130-
promote_type(::Type{T}, ::Type{T}) where {T} = (@_pure_meta; T)
131-
promote_type(::Type{T}, ::Type{Bottom}) where {T} = (@_pure_meta; T)
132-
promote_type(::Type{Bottom}, ::Type{T}) where {T} = (@_pure_meta; T)
129+
promote_type(::Type{Bottom}, ::Type{Bottom}) = Bottom
130+
promote_type(::Type{T}, ::Type{T}) where {T} = T
131+
promote_type(::Type{T}, ::Type{Bottom}) where {T} = T
132+
promote_type(::Type{Bottom}, ::Type{T}) where {T} = T
133133

134134
"""
135135
promote_type(type1, type2)
@@ -152,7 +152,7 @@ BigFloat
152152
```
153153
"""
154154
function promote_type(::Type{T}, ::Type{S}) where {T,S}
155-
@_pure_meta
155+
@_inline_meta
156156
# Try promote_rule in both orders. Typically only one is defined,
157157
# and there is a fallback returning Bottom below, so the common case is
158158
# promote_type(T, S) =>
@@ -161,26 +161,29 @@ function promote_type(::Type{T}, ::Type{S}) where {T,S}
161161
promote_result(T, S, promote_rule(T,S), promote_rule(S,T))
162162
end
163163

164-
promote_rule(T, S) = (@_pure_meta; Bottom)
164+
promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom
165165

166-
promote_result(t,s,T,S) = (@_pure_meta; promote_type(T,S))
166+
promote_result(::Type{<:Any},::Type{<:Any},::Type{T},::Type{S}) where {T,S} = (@_inline_meta; promote_type(T,S))
167167
# If no promote_rule is defined, both directions give Bottom. In that
168168
# case use typejoin on the original types instead.
169-
promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@_pure_meta; typejoin(T, S))
169+
promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@_inline_meta; typejoin(T, S))
170170

171171
promote() = ()
172172
promote(x) = (x,)
173173
function promote(x::T, y::S) where {T,S}
174+
@_inline_meta
174175
(convert(promote_type(T,S),x), convert(promote_type(T,S),y))
175176
end
176-
promote_typeof(x) = (@_pure_meta; typeof(x))
177-
promote_typeof(x, xs...) = (@_pure_meta; promote_type(typeof(x), promote_typeof(xs...)))
177+
promote_typeof(x) = typeof(x)
178+
promote_typeof(x, xs...) = (@_inline_meta; promote_type(typeof(x), promote_typeof(xs...)))
178179
function promote(x, y, z)
180+
@_inline_meta
179181
(convert(promote_typeof(x,y,z), x),
180182
convert(promote_typeof(x,y,z), y),
181183
convert(promote_typeof(x,y,z), z))
182184
end
183185
function promote(x, y, zs...)
186+
@_inline_meta
184187
(convert(promote_typeof(x,y,zs...), x),
185188
convert(promote_typeof(x,y,zs...), y),
186189
convert(Tuple{Vararg{promote_typeof(x,y,zs...)}}, zs)...)
@@ -195,16 +198,16 @@ end
195198
# happens, and +(promote(x,y)...) is called again, causing a stack
196199
# overflow.
197200
function promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T<:Number,S<:Number}
198-
@_pure_meta
201+
@_inline_meta
199202
promote_to_supertype(T, S, typejoin(T,S))
200203
end
201204

202205
# promote numeric types T and S to typejoin(T,S) if T<:S or S<:T
203206
# for example this makes promote_type(Integer,Real) == Real without
204207
# promoting arbitrary pairs of numeric types to Number.
205-
promote_to_supertype(::Type{T}, ::Type{T}, ::Type{T}) where {T<:Number} = (@_pure_meta; T)
206-
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{T}) where {T<:Number,S<:Number} = (@_pure_meta; T)
207-
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{S}) where {T<:Number,S<:Number} = (@_pure_meta; S)
208+
promote_to_supertype(::Type{T}, ::Type{T}, ::Type{T}) where {T<:Number} = (@_inline_meta; T)
209+
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{T}) where {T<:Number,S<:Number} = (@_inline_meta; T)
210+
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{S}) where {T<:Number,S<:Number} = (@_inline_meta; S)
208211
promote_to_supertype(::Type{T}, ::Type{S}, ::Type) where {T<:Number,S<:Number} =
209212
error("no promotion exists for ", T, " and ", S)
210213

@@ -304,15 +307,15 @@ minmax(x::Real, y::Real) = minmax(promote(x, y)...)
304307
# "Promotion" that takes a function into account and tries to preserve
305308
# non-concrete types. These are meant to be used mainly by elementwise
306309
# operations, so it is advised against overriding them
307-
_default_type(T::Type) = (@_pure_meta; T)
310+
_default_type(T::Type) = (@_inline_meta; T)
308311

309312
if isdefined(Core, :Inference)
310313
const _return_type = Core.Inference.return_type
311314
else
312315
_return_type(f::ANY, t::ANY) = Any
313316
end
314317

315-
promote_op(::Any...) = (@_pure_meta; Any)
318+
promote_op(::Any...) = (@_inline_meta; Any)
316319
function promote_op{S}(f, ::Type{S})
317320
@_inline_meta
318321
T = _return_type(f, Tuple{_default_type(S)})

base/show.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ typeemphasize(io::IO) = get(io, :TYPEEMPHASIZE, false) === true
512512

513513
const indent_width = 4
514514

515-
function show_expr_type(io::IO, ty, emph)
515+
function show_expr_type(io::IO, ty::ANY, emph::Bool)
516516
if ty === Function
517517
print(io, "::F")
518518
elseif ty === Core.IntrinsicFunction
@@ -617,7 +617,7 @@ function show_unquoted(io::IO, ex::Slot, ::Int, ::Int)
617617
if isa(slottypes, Array) && slotid <= length(slottypes::Array)
618618
slottype = slottypes[slotid]
619619
# The Slot in assignment can somehow have an Any type
620-
if slottype <: typ
620+
if isa(slottype, Type) && isa(typ, Type) && slottype <: typ
621621
typ = slottype
622622
end
623623
end

base/sparse/abstractsparse.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ issparse(S::LinAlg.UnitLowerTriangular{<:Any,<:AbstractSparseMatrix}) = true
2020
issparse(S::UpperTriangular{<:Any,<:AbstractSparseMatrix}) = true
2121
issparse(S::LinAlg.UnitUpperTriangular{<:Any,<:AbstractSparseMatrix}) = true
2222

23-
indtype(S::AbstractSparseArray{<:Any,Ti}) where {Ti} = (Base.@_pure_meta; Ti)
23+
indtype(S::AbstractSparseArray{<:Any,Ti}) where {Ti} = Ti

base/sparse/sparsevector.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Common definitions
44

5-
import Base: scalarmax, scalarmin, sort, find, findnz, @_pure_meta
5+
import Base: scalarmax, scalarmin, sort, find, findnz
66
import Base.LinAlg: promote_to_array_type, promote_to_arrays_
77

88
### The SparseVector
@@ -962,8 +962,8 @@ function hvcat(rows::Tuple{Vararg{Int}}, X::_SparseConcatGroup...)
962962
end
963963

964964
# make sure UniformScaling objects are converted to sparse matrices for concatenation
965-
promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}}) = (@_pure_meta; SparseMatrixCSC)
966-
promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = (@_pure_meta; Matrix)
965+
promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}}) = SparseMatrixCSC
966+
promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = Matrix
967967
promote_to_arrays_(n::Int, ::Type{SparseMatrixCSC}, J::UniformScaling) = sparse(J, n, n)
968968

969969
# Concatenations strictly involving un/annotated dense matrices/vectors should yield dense arrays

test/inference.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,3 +828,10 @@ end
828828
end
829829
@test length(code_typed(test_20902, (), optimize = false)) == 1
830830
@test length(code_typed(test_20902, (), optimize = false)) == 1
831+
832+
# normalization of arguments with constant Types as parameters
833+
g21771(T) = T
834+
f21771(::Val{U}) where {U} = Tuple{g21771(U)}
835+
@test @inferred(f21771(Val{Int}())) === Tuple{Int}
836+
@test @inferred(f21771(Val{Union{}}())) === Tuple{Union{}}
837+
@test @inferred(f21771(Val{Integer}())) === Tuple{Integer}

0 commit comments

Comments
 (0)