Skip to content

Commit

Permalink
make singleton objects more inferable and remove invalid @generated f…
Browse files Browse the repository at this point in the history
…unctions from irrationals
  • Loading branch information
vtjnash committed Oct 3, 2016
1 parent d5baf6a commit 8e39436
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
35 changes: 26 additions & 9 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ typealias VarTable Array{Any,1}
type VarState
typ
undef::Bool
VarState(typ::ANY, undef::Bool) = new(typ, undef)
end

immutable Const
val
Const(v::ANY) = new(v)
end

type InferenceState
Expand Down Expand Up @@ -107,11 +109,11 @@ type InferenceState
if linfo.def.isva
if atypes === Tuple
if la > 1
atypes = Tuple{Any[Any for i=1:la-1]..., Tuple.parameters[1]}
atypes = Tuple{Any[Any for i = 1:(la - 1)]..., Tuple.parameters[1]}
end
s[1][la] = VarState(Tuple,false)
s[1][la] = VarState(Tuple, false)
else
s[1][la] = VarState(tuple_tfunc(limit_tuple_depth(tupletype_tail(atypes,la))),false)
s[1][la] = VarState(tuple_tfunc(limit_tuple_depth(tupletype_tail(atypes, la))), false)
end
la -= 1
end
Expand All @@ -127,17 +129,25 @@ type InferenceState
if isa(lastatype, TypeVar)
lastatype = lastatype.ub
end
if isa(lastatype, DataType) && isdefined(lastatype, :instance)
# replace singleton types with their equivalent Const object
lastatype = Const(lastatype.instance)
end
if laty > la
laty = la
end
for i=1:laty
for i = 1:laty
atyp = atypes.parameters[i]
if isa(atyp, TypeVar)
atyp = atyp.ub
end
if isa(atyp, DataType) && isdefined(atyp, :instance)
# replace singleton types with their equivalent Const object
atyp = Const(atyp.instance)
end
s[1][i] = VarState(atyp, false)
end
for i=laty+1:la
for i = (laty + 1):la
s[1][i] = VarState(lastatype, false)
end
else
Expand Down Expand Up @@ -668,12 +678,15 @@ function invoke_tfunc(f::ANY, types::ANY, argtype::ANY, sv::InferenceState)
end

function tuple_tfunc(argtype::ANY)
if isa(argtype,DataType) && argtype.name === Tuple.name
p = map(x->(isType(x) && !isa(x.parameters[1],TypeVar) ? typeof(x.parameters[1]) : x),
if isa(argtype, DataType) && argtype.name === Tuple.name
p = map(x->(isType(x) && !isa(x.parameters[1], TypeVar) ? typeof(x.parameters[1]) : x),
argtype.parameters)
return Tuple{p...}
t = Tuple{p...}
# replace a singleton type with its equivalent Const object
isdefined(t, :instance) && return Const(t.instance)
return t
end
argtype
return argtype
end

function builtin_tfunction(f::ANY, argtypes::Array{Any,1}, sv::InferenceState)
Expand Down Expand Up @@ -1220,6 +1233,10 @@ function abstract_eval(e::ANY, vtypes::VarTable, sv::InferenceState)
# no need to use a typevar as the type of an expression
t = t.ub
end
if isa(t, DataType) && isdefined(t, :instance)
# replace singleton types with their equivalent Const object
t = Const(t.instance)
end
e.typ = t
return t
end
Expand Down
45 changes: 31 additions & 14 deletions base/irrationals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,44 @@ end
x < big(y)
end

<=(x::Irrational,y::AbstractFloat) = x < y
<=(x::AbstractFloat,y::Irrational) = x < y
<=(x::Irrational, y::AbstractFloat) = x < y
<=(x::AbstractFloat, y::Irrational) = x < y

# Irrational vs Rational
@generated function <{T}(x::Irrational, y::Rational{T})
bx = big(x())
bx < 0 && T <: Unsigned && return true
rx = rationalize(T,bx,tol=0)
rx < bx ? :($rx < y) : :($rx <= y)
@pure function rationalize{T<:Integer}(::Type{T}, x::Irrational; tol::Real=0)
return rationalize(T, big(x), tol=tol)
end
@generated function <{T}(x::Rational{T}, y::Irrational)
by = big(y())
by < 0 && T <: Unsigned && return false
ry = rationalize(T,by,tol=0)
ry < by ? :(x <= $ry) : :(x < $ry)
@pure function rationalize{T<:Integer}(::Type{T}, x::Irrational)
return rationalize(T, big(x), tol=0)
end
@pure function lessrational{T<:Integer}(rx::Rational{T}, x::Irrational)
# an @pure version of `<` for determining if the rationalization of
# an irrational number required rounding up or down
return rx < big(x)
end
function <{T}(x::Irrational, y::Rational{T})
T <: Unsigned && x < 0.0 && return true
rx = rationalize(T, x)
if lessrational(rx, x)
return rx < y
else
return rx <= y
end
end
function <{T}(x::Rational{T}, y::Irrational)
T <: Unsigned && y < 0.0 && return false
ry = rationalize(T, y)
if lessrational(ry, y)
return x <= ry
else
return x < ry
end
end
<(x::Irrational, y::Rational{BigInt}) = big(x) < y
<(x::Rational{BigInt}, y::Irrational) = x < big(y)

<=(x::Irrational,y::Rational) = x < y
<=(x::Rational,y::Irrational) = x < y
<=(x::Irrational, y::Rational) = x < y
<=(x::Rational, y::Irrational) = x < y

isfinite(::Irrational) = true

Expand Down

0 comments on commit 8e39436

Please sign in to comment.