382
382
383
383
function isconstantfunc(f, vtypes, sv::StaticVarInfo)
384
384
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
386
386
assert(isa(f.args[1],Symbol), "inference.j:333")
387
387
return (true, f.args[1])
388
388
end
@@ -521,9 +521,9 @@ function abstract_eval_call(e, vtypes, sv::StaticVarInfo)
521
521
return ft_tfunc(ft, argtypes)
522
522
elseif isType(ft) && isa(ft.parameters[1],StructKind)
523
523
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
527
527
# struct constructor
528
528
return st
529
529
end
@@ -1071,8 +1071,7 @@ end
1071
1071
# functions with closure environments or varargs are also excluded.
1072
1072
# static parameters are ok if all the static parameter values are leaf types,
1073
1073
# meaning they are fully known.
1074
- function inlineable (e :: Expr , vars )
1075
- f = eval(e.args[1])
1074
+ function inlineable (f , e :: Expr , vars )
1076
1075
argexprs = a2t(e.args[2:])
1077
1076
atypes = map(exprtype, argexprs)
1078
1077
meth = getmethods(f, atypes)
@@ -1170,8 +1169,12 @@ function inlining_pass(e::Expr, vars)
1170
1169
# don't inline first argument of ccall, as this needs to be evaluated
1171
1170
# by the interpreter and inlining might put in something it can't handle,
1172
1171
# 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)
1175
1178
if length(e.args)>1
1176
1179
e.args[2] = remove_call1(e.args[2])
1177
1180
end
@@ -1184,12 +1187,19 @@ function inlining_pass(e::Expr, vars)
1184
1187
end
1185
1188
if is(e.head,:call1)
1186
1189
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)
1188
1198
if !is(body,NF)
1189
1199
#print("inlining ", e, " => ", body, "\n")
1190
1200
return body
1191
1201
end
1192
- if is(eval(e.args[1]) ,apply)
1202
+ if is(f ,apply)
1193
1203
if length(e.args) == 3
1194
1204
aarg = e.args[3]
1195
1205
if isa(aarg,Expr) && is(aarg.head,:call) &&
@@ -1198,7 +1208,7 @@ function inlining_pass(e::Expr, vars)
1198
1208
# apply(f,tuple(x,y,...)) => f(x,y,...)
1199
1209
e.args = append({e .args [2 ]}, aarg .args [2 : ])
1200
1210
# now try to inline the simplified call
1201
- body = inlineable (e, vars)
1211
+ body = inlineable (eval ( e . args [ 1 ]), e, vars)
1202
1212
if ! is (body,NF )
1203
1213
return body
1204
1214
end
@@ -1207,7 +1217,7 @@ function inlining_pass(e::Expr, vars)
1207
1217
end
1208
1218
end
1209
1219
elseif is (e .head ,: call)
1210
- farg = e . args [ 1 ]
1220
+ farg = arg1
1211
1221
# special inlining for some builtin functions that return types
1212
1222
if isa (farg,Expr) && is (farg .head ,: top) &&
1213
1223
(is (eval (farg),apply_type) || is (eval (farg),fieldtype)) &&
0 commit comments