Skip to content

Commit

Permalink
Merge pull request #22779 from JuliaLang/jn/isa_tfunc_bugfix
Browse files Browse the repository at this point in the history
fix isa tfunc for type kinds
  • Loading branch information
JeffBezanson authored Jul 12, 2017
2 parents d1d1caa + cd959a2 commit 7c31c41
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
34 changes: 19 additions & 15 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -378,19 +378,21 @@ isType(t::ANY) = isa(t, DataType) && (t::DataType).name === _Type_name
# true if Type is inlineable as constant (is a singleton)
isconstType(t::ANY) = isType(t) && (isleaftype(t.parameters[1]) || t.parameters[1] === Union{})

iskindtype(t::ANY) = (t === DataType || t === UnionAll || t === Union || t === typeof(Bottom))

const IInf = typemax(Int) # integer infinity
const n_ifunc = reinterpret(Int32,arraylen)+1
const t_ifunc = Array{Tuple{Int,Int,Any},1}(n_ifunc)
const t_ifunc_cost = Array{Int,1}(n_ifunc)
const t_ffunc_key = Array{Function,1}(0)
const t_ffunc_val = Array{Tuple{Int,Int,Any},1}(0)
const t_ffunc_cost = Array{Int,1}(0)
const n_ifunc = reinterpret(Int32, arraylen) + 1
const t_ifunc = Array{Tuple{Int, Int, Any}, 1}(n_ifunc)
const t_ifunc_cost = Array{Int, 1}(n_ifunc)
const t_ffunc_key = Array{Any, 1}(0)
const t_ffunc_val = Array{Tuple{Int, Int, Any}, 1}(0)
const t_ffunc_cost = Array{Int, 1}(0)
function add_tfunc(f::IntrinsicFunction, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
idx = reinterpret(Int32,f)+1
idx = reinterpret(Int32, f) + 1
t_ifunc[idx] = (minarg, maxarg, tfunc)
t_ifunc_cost[idx] = cost
end
function add_tfunc(f::Function, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
function add_tfunc(#=@nospecialize::Builtin=# f::Function, minarg::Int, maxarg::Int, tfunc::ANY, cost::Int)
push!(t_ffunc_key, f)
push!(t_ffunc_val, (minarg, maxarg, tfunc))
push!(t_ffunc_cost, cost)
Expand Down Expand Up @@ -711,7 +713,7 @@ add_tfunc(isa, 2, 2,
if t !== Any && !has_free_typevars(t)
if v t
return Const(true)
elseif isa(v, Const) || isa(v, Conditional) || isleaftype(v)
elseif isa(v, Const) || isa(v, Conditional) || (isleaftype(v) && !iskindtype(v))
return Const(false)
end
end
Expand Down Expand Up @@ -1501,20 +1503,20 @@ function builtin_tfunction(f::ANY, argtypes::Array{Any,1},
end
if isa(f, IntrinsicFunction)
iidx = Int(reinterpret(Int32, f::IntrinsicFunction)) + 1
if !isassigned(t_ifunc, iidx)
# unknown/unhandled intrinsic (most fall in this category since most return an unboxed value)
if iidx < 0 || iidx > length(t_ifunc)
# invalid intrinsic
return Any
end
tf = t_ifunc[iidx]
else
fidx = findfirst(t_ffunc_key, f::Function)
fidx = findfirst(t_ffunc_key, f)
if fidx == 0
# unknown/unhandled builtin or anonymous function
# unknown/unhandled builtin function
return Any
end
tf = t_ffunc_val[fidx]
end
tf = tf::Tuple{Real, Real, Any}
tf = tf::Tuple{Int, Int, Any}
if !(tf[1] <= length(argtypes) <= tf[2])
# wrong # of args
return Bottom
Expand Down Expand Up @@ -4640,7 +4642,7 @@ function statement_cost(ex::Expr, src::CodeInfo, mod::Module, params::InferenceP
elseif f == Main.Core.arrayref
return plus_saturate(argcost, isknowntype(ex.typ) ? 4 : params.inline_nonleaf_penalty)
end
fidx = findfirst(t_ffunc_key, f::Function)
fidx = findfirst(t_ffunc_key, f)
if fidx == 0
# unknown/unhandled builtin or anonymous function
# Use the generic cost of a direct function call
Expand Down Expand Up @@ -5906,6 +5908,8 @@ let fs = Any[typeinf_ext, typeinf, typeinf_edge, occurs_outside_getfield, pure_e
if isassigned(t_ifunc, i)
x = t_ifunc[i]
push!(fs, x[3])
else
println(STDERR, "WARNING: tfunc missing for ", reinterpret(IntrinsicFunction, Int32(i)))
end
end
for f in fs
Expand Down
35 changes: 34 additions & 1 deletion test/inference.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

# tests for Core.Inference correctness and precision
import Core.Inference: Const, Conditional,

# issue 9770
@noinline x9770() = false
Expand Down Expand Up @@ -877,7 +878,7 @@ let f(x) = isdefined(x, :NonExistentField) ? 1 : ""
@test Base.return_types(f, (Complex64,)) == Any[String]
@test Union{Int,String} <: Base.return_types(f, (AbstractArray,))[1]
end
import Core.Inference: Const, isdefined_tfunc,
import Core.Inference: isdefined_tfunc
@test isdefined_tfunc(Complex64, Const(())) === Union{}
@test isdefined_tfunc(Complex64, Const(1)) === Const(true)
@test isdefined_tfunc(Complex64, Const(2)) === Const(true)
Expand Down Expand Up @@ -1049,3 +1050,35 @@ end
@test find_core_sizeof_call(first(@code_typed sizeof_constvec()).code)
push!(constvec, 10)
@test @inferred(sizeof_constvec()) == sizeof(Int) * 4

let isa_tfunc = Core.Inference.t_ffunc_val[
findfirst(Core.Inference.t_ffunc_key, isa)][3]
@test isa_tfunc(Array, Const(AbstractArray)) === Const(true)
@test isa_tfunc(Array, Type{AbstractArray}) === Const(true)
@test isa_tfunc(Array, Type{AbstractArray{Int}}) == Bool
@test isa_tfunc(Array{Real}, Type{AbstractArray{Int}}) === Bool # could be improved
@test isa_tfunc(Array{Real, 2}, Const(AbstractArray{Real, 2})) === Const(true)
@test isa_tfunc(Array{Real, 2}, Const(AbstractArray{Int, 2})) === Const(false)
@test isa_tfunc(DataType, Int) === Bool # could be improved
@test isa_tfunc(DataType, Const(Type{Int})) === Bool
@test isa_tfunc(DataType, Const(Type{Array})) === Bool
@test isa_tfunc(UnionAll, Const(Type{Int})) === Bool # could be improved
@test isa_tfunc(UnionAll, Const(Type{Array})) === Bool
@test isa_tfunc(Union, Const(Union{Float32, Float64})) === Bool
@test isa_tfunc(Union, Type{Union}) === Const(true)
@test isa_tfunc(typeof(Union{}), Const(Int)) === Bool # any result is ok
@test isa_tfunc(typeof(Union{}), Const(Union{})) === Bool # could be improved
@test isa_tfunc(typeof(Union{}), typeof(Union{})) === Bool # could be improved
@test isa_tfunc(typeof(Union{}), Union{}) === Bool # could be improved
@test isa_tfunc(typeof(Union{}), Type{typeof(Union{})}) === Const(true)
@test isa_tfunc(typeof(Union{}), Const(typeof(Union{}))) === Const(true)
let c = Conditional(Core.SlotNumber(0), Const(Union{}), Const(Union{}))
@test isa_tfunc(c, Const(Bool)) === Const(true)
@test isa_tfunc(c, Type{Bool}) === Const(true)
@test isa_tfunc(c, Const(Real)) === Const(true)
@test isa_tfunc(c, Type{Real}) === Const(true)
@test isa_tfunc(c, Const(Signed)) === Const(false)
@test isa_tfunc(c, Type{Complex}) === Const(false)
@test isa_tfunc(c, Type{Complex{T}} where T) === Const(false)
end
end

2 comments on commit 7c31c41

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily benchmark build, I will reply here when finished:

@nanosoldier runbenchmarks(ALL, isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan

Please sign in to comment.