Skip to content

Commit 3766f34

Browse files
committed
some type inference tweaks
adding some sharper typevars in rational and complex
1 parent f84ddeb commit 3766f34

File tree

4 files changed

+45
-32
lines changed

4 files changed

+45
-32
lines changed

j/complex.j

+5-5
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ Complex(x::Real) = Complex(x, zero(x))
107107
real(z::Complex) = z.re
108108
imag(z::Complex) = z.im
109109

110-
convert{T}(::Type{Complex{T}}, x::T) = Complex(x, convert(T,0))
111-
convert{T}(::Type{Complex{T}}, x::Real) = Complex(convert(T,x), convert(T,0))
112-
convert{T}(::Type{Complex{T}}, z::ComplexNum) = Complex(convert(T,real(z)),convert(T,imag(z)))
110+
convert{T<:Real}(::Type{Complex{T}}, x::T) = Complex(x, convert(T,0))
111+
convert{T<:Real}(::Type{Complex{T}}, x::Real) = Complex(convert(T,x), convert(T,0))
112+
convert{T<:Real}(::Type{Complex{T}}, z::ComplexNum) = Complex(convert(T,real(z)),convert(T,imag(z)))
113113

114114
promote_rule{T<:Real}(::Type{Complex{T}}, ::Type{T}) = Complex{T}
115-
promote_rule{T,S<:Real}(::Type{Complex{T}}, ::Type{S}) = Complex{promote_type(T,S)}
116-
promote_rule{T,S}(::Type{Complex{T}}, ::Type{Complex{S}}) = Complex{promote_type(T,S)}
115+
promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{S}) = Complex{promote_type(T,S)}
116+
promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{Complex{S}}) = Complex{promote_type(T,S)}
117117
promote_rule{T<:Real}(::Type{Complex{T}}, ::Type{Complex128}) =
118118
(P = promote_type(Float64,T);
119119
is(P,Float64) ? Complex128 : Complex{P})

j/inference.j

+22-12
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ end
382382
383383
function isconstantfunc(f, vtypes, sv::StaticVarInfo)
384384
if isa(f,Expr) && is(f.head,:top)
385-
abstract_eval(f, vtypes, sv)
385+
abstract_eval(f, vtypes, sv) # to pick up a type annotation
386386
assert(isa(f.args[1],Symbol), "inference.j:333")
387387
return (true, f.args[1])
388388
end
@@ -521,9 +521,9 @@ function abstract_eval_call(e, vtypes, sv::StaticVarInfo)
521521
return ft_tfunc(ft, argtypes)
522522
elseif isType(ft) && isa(ft.parameters[1],StructKind)
523523
st = ft.parameters[1]
524-
#if isgeneric(st)
525-
# return abstract_call_gf(st, fargs, argtypes, e)
526-
#end
524+
if isgeneric(st) && isleaftype(st)
525+
return abstract_call_gf(st, fargs, argtypes, e)
526+
end
527527
# struct constructor
528528
return st
529529
end
@@ -1071,8 +1071,7 @@ end
10711071
# functions with closure environments or varargs are also excluded.
10721072
# static parameters are ok if all the static parameter values are leaf types,
10731073
# meaning they are fully known.
1074-
function inlineable(e::Expr, vars)
1075-
f = eval(e.args[1])
1074+
function inlineable(f, e::Expr, vars)
10761075
argexprs = a2t(e.args[2:])
10771076
atypes = map(exprtype, argexprs)
10781077
meth = getmethods(f, atypes)
@@ -1170,8 +1169,12 @@ function inlining_pass(e::Expr, vars)
11701169
# don't inline first argument of ccall, as this needs to be evaluated
11711170
# by the interpreter and inlining might put in something it can't handle,
11721171
# like another ccall.
1173-
if is(e.head,:call) && isa(e.args[1],Expr) &&
1174-
is(e.args[1].head,:symbol) && is(e.args[1].args[1],:ccall)
1172+
if length(e.args)<1
1173+
return e
1174+
end
1175+
arg1 = e.args[1]
1176+
if is(e.head,:call) && isa(arg1,Expr) &&
1177+
is(arg1.head,:symbol) && is(arg1.args[1],:ccall)
11751178
if length(e.args)>1
11761179
e.args[2] = remove_call1(e.args[2])
11771180
end
@@ -1184,12 +1187,19 @@ function inlining_pass(e::Expr, vars)
11841187
end
11851188
if is(e.head,:call1)
11861189
e.head = :call
1187-
body = inlineable(e, vars)
1190+
ET = exprtype(arg1)
1191+
if isType(ET)
1192+
f = ET.parameters[1]
1193+
else
1194+
f = eval(arg1)
1195+
end
1196+
1197+
body = inlineable(f, e, vars)
11881198
if !is(body,NF)
11891199
#print("inlining ", e, " => ", body, "\n")
11901200
return body
11911201
end
1192-
if is(eval(e.args[1]),apply)
1202+
if is(f,apply)
11931203
if length(e.args) == 3
11941204
aarg = e.args[3]
11951205
if isa(aarg,Expr) && is(aarg.head,:call) &&
@@ -1198,7 +1208,7 @@ function inlining_pass(e::Expr, vars)
11981208
# apply(f,tuple(x,y,...)) => f(x,y,...)
11991209
e.args = append({e.args[2]}, aarg.args[2:])
12001210
# now try to inline the simplified call
1201-
body = inlineable(e, vars)
1211+
body = inlineable(eval(e.args[1]), e, vars)
12021212
if !is(body,NF)
12031213
return body
12041214
end
@@ -1207,7 +1217,7 @@ function inlining_pass(e::Expr, vars)
12071217
end
12081218
end
12091219
elseif is(e.head,:call)
1210-
farg = e.args[1]
1220+
farg = arg1
12111221
# special inlining for some builtin functions that return types
12121222
if isa(farg,Expr) && is(farg.head,:top) &&
12131223
(is(eval(farg),apply_type) || is(eval(farg),fieldtype)) &&

j/rational.j

+8-8
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ function show(x::Rational)
2525
show(den(x))
2626
end
2727

28-
convert{T}(::Type{Rational{T}}, x::T) = Rational(x, convert(T,1))
29-
convert{T}(::Type{Rational{T}}, x::Int) = Rational(convert(T,x), convert(T,1))
30-
convert{T}(::Type{Rational{T}}, x::Rational) = Rational(convert(T,x.num),convert(T,x.den))
28+
convert{T<:Int}(::Type{Rational{T}}, x::T) = Rational(x, convert(T,1))
29+
convert{T<:Int}(::Type{Rational{T}}, x::Int) = Rational(convert(T,x), convert(T,1))
30+
convert{T<:Int}(::Type{Rational{T}}, x::Rational) = Rational(convert(T,x.num),convert(T,x.den))
3131
convert{T<:Float}(::Type{T}, x::Rational) = convert(T,x.num)/convert(T,x.den)
3232
convert{T<:Int}(::Type{T}, x::Rational) = div(convert(T,x.num),convert(T,x.den))
3333

34-
function convert{T}(::Type{Rational{T}}, x::Float, tol::Real)
34+
function convert{T<:Int}(::Type{Rational{T}}, x::Float, tol::Real)
3535
if isnan(x); return zero(T)//zero(T); end
3636
if isinf(x); return sign(x)//zero(T); end
3737
y = x
@@ -47,12 +47,12 @@ function convert{T}(::Type{Rational{T}}, x::Float, tol::Real)
4747
end
4848
end
4949

50-
convert{T}(rt::Type{Rational{T}}, x::Float) = convert(rt,x,eps(x))
50+
convert{T<:Int}(rt::Type{Rational{T}}, x::Float) = convert(rt,x,eps(x))
5151

5252
promote_rule{T<:Int}(::Type{Rational{T}}, ::Type{T}) = Rational{T}
53-
promote_rule{T,S<:Int}(::Type{Rational{T}}, ::Type{S}) = Rational{promote_type(T,S)}
54-
promote_rule{T,S}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)}
55-
promote_rule{T,S<:Float}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S)
53+
promote_rule{T<:Int,S<:Int}(::Type{Rational{T}}, ::Type{S}) = Rational{promote_type(T,S)}
54+
promote_rule{T<:Int,S<:Int}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)}
55+
promote_rule{T<:Int,S<:Float}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S)
5656

5757
num(x::Int) = x
5858
den(x::Int) = one(x)

src/julia-syntax.scm

+10-7
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,16 @@
244244
(call (curly ,name ,@params) ,@field-names))))
245245

246246
(define (new-call Texpr args field-names)
247-
(let ((g (gensy)))
248-
(if (> (length args) (length field-names))
249-
`(call (top error) "new: too many arguments")
250-
`(block (= ,g (new ,Texpr))
251-
,@(map (lambda (fld val) `(= (|.| ,g ,fld) ,val))
252-
(list-head field-names (length args)) args)
253-
,g))))
247+
(cond ((> (length args) (length field-names))
248+
`(call (top error) "new: too many arguments"))
249+
((null? args)
250+
`(new ,Texpr))
251+
(else
252+
(let ((g (gensy)))
253+
`(block (= ,g (new ,Texpr))
254+
,@(map (lambda (fld val) `(= (|.| ,g ,fld) ,val))
255+
(list-head field-names (length args)) args)
256+
,g)))))
254257

255258
(define (rewrite-ctor ctor Tname params field-names)
256259
(define (ctor-body body)

0 commit comments

Comments
 (0)