Skip to content

Commit

Permalink
inference: respect nospecialize on args [ci skip]
Browse files Browse the repository at this point in the history
This performs badly.
  • Loading branch information
vtjnash committed Jan 14, 2021
1 parent f517fdb commit 8ab7b6b
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 18 deletions.
4 changes: 2 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function iterate end
function Typeof end
ccall(:jl_toplevel_eval_in, Any, (Any, Any),
Core, quote
(f::typeof(Typeof))(x) = ($(_expr(:meta,:nospecialize,:x)); isa(x,Type) ? Type{x} : typeof(x))
(f::typeof(Typeof))(x) = ($(_expr(:meta,:inline)); $(_expr(:meta,:nospecialize,:x)); isa(x,Type) ? Type{x} : typeof(x))
end)


Expand Down Expand Up @@ -436,7 +436,7 @@ end
# simple convert for use by constructors of types in Core
# note that there is no actual conversion defined here,
# so the methods and ccall's in Core aren't permitted to use convert
convert(::Type{Any}, @nospecialize(x)) = x
convert(::Type{Any}, @nospecialize(x)) = (@_inline_meta; x)
convert(::Type{T}, x::T) where {T} = x
cconvert(::Type{T}, x) where {T} = convert(T, x)
unsafe_convert(::Type{T}, x::T) where {T} = x
Expand Down
8 changes: 8 additions & 0 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
add_remark!(interp, sv, "Refusing to infer into `depwarn`")
return Any, false, nothing
end
if method.nospecialize != 0 && isdefined(method, :source)
declared_inline = ccall(:jl_ir_flag_inlineable, Bool, (Any,), method.source)
if !declared_inline
oldsig = sig
sig = get_nospecialize_sig(method, sig, sparams)
# sig === oldsig || println(oldsig, " => ", sig, " of ", method.sig)
end
end
topmost = nothing
# Limit argument type tuple growth of functions:
# look through the parents list to see if there's a call to the same method
Expand Down
19 changes: 18 additions & 1 deletion base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,25 @@ function get_compileable_sig(method::Method, @nospecialize(atypes), sparams::Sim
isa(atypes, DataType) || return nothing
mt = ccall(:jl_method_table_for, Any, (Any,), atypes)
mt === nothing && return nothing
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any),
atypes = ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any),
mt, atypes, sparams, method)
is_compileable = atypes.isdispatchtuple ||
ccall(:jl_isa_compileable_sig, Int32, (Any, Any), atypes, method) != 0
is_compileable || return nothing
return atypes
end

function get_nospecialize_sig(method::Method, @nospecialize(atypes), sparams::SimpleVector)
if atypes isa UnionAll
ua = unwrap_unionall(atypes)
ua isa DataType || return method.sig
atypes = Tuple{Any[rewrap_unionall(ua.parameters[i], atypes) for i = 1:length(ua.parameters)]...}
end
mt = ccall(:jl_method_table_for, Any, (Any,), atypes)
mt === nothing && return method.sig
atypes = ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any),
mt, atypes, sparams, method)
return atypes
end

# eliminate UnionAll vars that might be degenerate due to having identical bounds,
Expand Down
4 changes: 2 additions & 2 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ false
Supertype operator, equivalent to `T2 <: T1`.
"""
(>:)(@nospecialize(a), @nospecialize(b)) = (b <: a)
(>:)(a, b) = (@nospecialize; @_inline_meta; b <: a)

"""
supertype(T::DataType)
Expand Down Expand Up @@ -305,7 +305,7 @@ julia> a ≢ a
false
```
"""
!==(@nospecialize(x), @nospecialize(y)) = !(x === y)
!==(x, y) = (@nospecialize; @_inline_meta; !(x === y))
const = !==

"""
Expand Down
5 changes: 3 additions & 2 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Return the closest common ancestor of `T` and `S`, i.e. the narrowest type from
they both inherit.
"""
typejoin() = Bottom
typejoin(@nospecialize(t)) = t
typejoin(@nospecialize(t)) = (@_pure_meta; t)
typejoin(@nospecialize(t), ts...) = (@_pure_meta; typejoin(t, typejoin(ts...)))
function typejoin(@nospecialize(a), @nospecialize(b))
@_pure_meta
Expand Down Expand Up @@ -146,10 +146,11 @@ either a parent of both types, or a `Union` if appropriate.
Falls back to [`typejoin`](@ref).
"""
function promote_typejoin(@nospecialize(a), @nospecialize(b))
@_inline_meta
c = typejoin(_promote_typesubtract(a), _promote_typesubtract(b))
return Union{a, b, c}::Type
end
_promote_typesubtract(@nospecialize(a)) = typesplit(a, Union{Nothing, Missing})
_promote_typesubtract(@nospecialize(a)) = (@_inline_meta; typesplit(a, Union{Nothing, Missing}))


# Returns length, isfixed
Expand Down
16 changes: 8 additions & 8 deletions base/tuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ _counttuple(::Type) = nothing

## indexing ##

length(@nospecialize t::Tuple) = nfields(t)
length(@nospecialize t::Tuple) = (@_inline_meta; nfields(t))
firstindex(@nospecialize t::Tuple) = 1
lastindex(@nospecialize t::Tuple) = length(t)
size(@nospecialize(t::Tuple), d::Integer) = (d == 1) ? length(t) : throw(ArgumentError("invalid tuple dimension $d"))
axes(@nospecialize t::Tuple) = (OneTo(length(t)),)
@eval getindex(@nospecialize(t::Tuple), i::Int) = getfield(t, i, $(Expr(:boundscheck)))
@eval getindex(@nospecialize(t::Tuple), i::Real) = getfield(t, convert(Int, i), $(Expr(:boundscheck)))
lastindex(@nospecialize t::Tuple) = (@_inline_meta; length(t))
size(@nospecialize(t::Tuple), d::Integer) = (@_inline_meta; (d == 1) ? length(t) : throw(ArgumentError("invalid tuple dimension $d")))
axes(@nospecialize t::Tuple) = (@_inline_meta; (OneTo(length(t)),))
@eval getindex(@nospecialize(t::Tuple), i::Int) = (@_inline_meta; getfield(t, i, $(Expr(:boundscheck))))
@eval getindex(@nospecialize(t::Tuple), i::Real) = (@_inline_meta; getfield(t, convert(Int, i), $(Expr(:boundscheck))))
getindex(t::Tuple, r::AbstractArray{<:Any,1}) = (eltype(t)[t[ri] for ri in r]...,)
getindex(t::Tuple, b::AbstractArray{Bool,1}) = length(b) == length(t) ? getindex(t, findall(b)) : throw(BoundsError(t, b))
getindex(t::Tuple, c::Colon) = t
Expand All @@ -47,8 +47,8 @@ true
```
"""
function setindex(x::Tuple, v, i::Integer)
@boundscheck 1 <= i <= length(x) || throw(BoundsError(x, i))
@_inline_meta
@boundscheck 1 <= i <= length(x) || throw(BoundsError(x, i))
_setindex(v, i, x...)
end

Expand All @@ -66,7 +66,7 @@ function iterate(@nospecialize(t::Tuple), i::Int=1)
return (1 <= i <= length(t)) ? (@inbounds t[i], i + 1) : nothing
end

keys(@nospecialize t::Tuple) = OneTo(length(t))
keys(@nospecialize t::Tuple) = (@_inline_meta; OneTo(length(t)))

prevind(@nospecialize(t::Tuple), i::Integer) = Int(i)-1
nextind(@nospecialize(t::Tuple), i::Integer) = Int(i)+1
Expand Down
4 changes: 1 addition & 3 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2038,10 +2038,8 @@ JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_methtable_t *mt, jl_t
intptr_t nspec = (mt == jl_type_type_mt || mt == jl_nonfunction_mt ? m->nargs + 1 : mt->max_args + 2);
jl_compilation_sig(ti, env, m, nspec, &newparams);
tt = (newparams ? jl_apply_tuple_type(newparams) : ti);
int is_compileable = ((jl_datatype_t*)ti)->isdispatchtuple ||
jl_isa_compileable_sig(tt, m);
JL_GC_POP();
return is_compileable ? (jl_value_t*)tt : jl_nothing;
return (jl_value_t*)tt;
}

// compile-time method lookup
Expand Down

0 comments on commit 8ab7b6b

Please sign in to comment.