@@ -1253,8 +1253,34 @@ end
1253
1253
1254
1254
# ### recursing into expression ####
1255
1255
1256
+ # take a Tuple where one or more parameters are Unions
1257
+ # and return an array such that those Unions are removed
1258
+ # and `Union{return...} == ty`
1259
+ function switchtupleunion (ty:: ANY )
1260
+ tparams = (unwrap_unionall (ty):: DataType ). parameters
1261
+ return _switchtupleunion (Any[tparams... ], length (tparams), [], ty)
1262
+ end
1263
+
1264
+ function _switchtupleunion (t:: Vector{Any} , i:: Int , tunion:: Vector{Any} , origt:: ANY )
1265
+ if i == 0
1266
+ tpl = rewrap_unionall (Tuple{t... }, origt)
1267
+ push! (tunion, tpl)
1268
+ else
1269
+ ti = t[i]
1270
+ if isa (ti, Union)
1271
+ for ty in uniontypes (ti:: Union )
1272
+ t[i] = ty
1273
+ _switchtupleunion (t, i - 1 , tunion, origt)
1274
+ end
1275
+ t[i] = ti
1276
+ else
1277
+ _switchtupleunion (t, i - 1 , tunion, origt)
1278
+ end
1279
+ end
1280
+ return tunion
1281
+ end
1282
+
1256
1283
function abstract_call_gf_by_type (f:: ANY , atype:: ANY , sv:: InferenceState )
1257
- tm = _topmod (sv)
1258
1284
# don't consider more than N methods. this trades off between
1259
1285
# compiler performance and generated code performance.
1260
1286
# typically, considering many methods means spending lots of time
@@ -1289,119 +1315,29 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
1289
1315
return Any
1290
1316
end
1291
1317
applicable = applicable:: Array{Any,1}
1318
+ napplicable = length (applicable)
1292
1319
fullmatch = false
1293
- for (m:: SimpleVector ) in applicable
1294
- sig = m[1 ]
1295
- sigtuple = unwrap_unionall (sig):: DataType
1296
- method = m[3 ]:: Method
1297
- sparams = m[2 ]:: SimpleVector
1298
- recomputesvec = false
1320
+ for i in 1 : napplicable
1321
+ match = applicable[i]:: SimpleVector
1322
+ method = match[3 ]:: Method
1299
1323
if ! fullmatch && (argtype <: method.sig )
1300
1324
fullmatch = true
1301
1325
end
1302
-
1303
- # limit argument type tuple growth
1304
- msig = unwrap_unionall (method. sig)
1305
- lsig = length (msig. parameters)
1306
- ls = length (sigtuple. parameters)
1307
- td = type_depth (sig)
1308
- mightlimitlength = ls > lsig + 1
1309
- mightlimitdepth = td > 2
1310
- limitlength = false
1311
- if mightlimitlength || mightlimitdepth
1312
- # TODO : FIXME : this heuristic depends on non-local state making type-inference unpredictable
1313
- cyclei = 0
1314
- infstate = sv
1315
- while infstate != = nothing
1316
- infstate = infstate:: InferenceState
1317
- if isdefined (infstate. linfo, :def ) && method === infstate. linfo. def
1318
- if mightlimitlength && ls > length (unwrap_unionall (infstate. linfo. specTypes). parameters)
1319
- limitlength = true
1320
- end
1321
- if mightlimitdepth && td > type_depth (infstate. linfo. specTypes)
1322
- # impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
1323
- if td > MAX_TYPE_DEPTH
1324
- sig = limit_type_depth (sig, 0 )
1325
- sigtuple = unwrap_unionall (sig)
1326
- recomputesvec = true
1327
- break
1328
- else
1329
- p1, p2 = sigtuple. parameters, unwrap_unionall (infstate. linfo. specTypes). parameters
1330
- if length (p2) == ls
1331
- limitdepth = false
1332
- newsig = Vector {Any} (ls)
1333
- for i = 1 : ls
1334
- if p1[i] <: Function && type_depth (p1[i]) > type_depth (p2[i]) &&
1335
- isa (p1[i],DataType)
1336
- # if a Function argument is growing (e.g. nested closures)
1337
- # then widen to the outermost function type. without this
1338
- # inference fails to terminate on do_quadgk.
1339
- newsig[i] = p1[i]. name. wrapper
1340
- limitdepth = true
1341
- else
1342
- newsig[i] = limit_type_depth (p1[i], 1 )
1343
- end
1344
- end
1345
- if limitdepth
1346
- sigtuple = Tuple{newsig... }
1347
- sig = rewrap_unionall (sigtuple, sig)
1348
- recomputesvec = true
1349
- break
1350
- end
1351
- end
1352
- end
1353
- end
1354
- end
1355
- # iterate through the cycle before walking to the parent
1356
- if cyclei < length (infstate. callers_in_cycle)
1357
- cyclei += 1
1358
- infstate = infstate. callers_in_cycle[cyclei]
1359
- else
1360
- cyclei = 0
1361
- infstate = infstate. parent
1362
- end
1363
- end
1364
- end
1365
-
1366
- # limit length based on size of definition signature.
1367
- # for example, given function f(T, Any...), limit to 3 arguments
1368
- # instead of the default (MAX_TUPLETYPE_LEN)
1369
- if limitlength
1370
- if ! istopfunction (tm, f, :promote_typeof )
1371
- fst = sigtuple. parameters[lsig + 1 ]
1372
- allsame = true
1373
- # allow specializing on longer arglists if all the trailing
1374
- # arguments are the same, since there is no exponential
1375
- # blowup in this case.
1376
- for i = (lsig + 2 ): ls
1377
- if sigtuple. parameters[i] != fst
1378
- allsame = false
1379
- break
1380
- end
1381
- end
1382
- if ! allsame
1383
- sigtuple = limit_tuple_type_n (sigtuple, lsig + 1 )
1384
- sig = rewrap_unionall (sigtuple, sig)
1385
- recomputesvec = true
1386
- end
1387
- end
1388
- end
1389
-
1390
- # if sig changed, may need to recompute the sparams environment
1391
- if recomputesvec && ! isempty (sparams)
1392
- recomputed = ccall (:jl_env_from_type_intersection , Ref{SimpleVector}, (Any, Any), sig, method. sig)
1393
- sig = recomputed[1 ]
1394
- if ! isa (unwrap_unionall (sig), DataType) # probably Union{}
1395
- rettype = Any
1396
- break
1397
- end
1398
- sparams = recomputed[2 ]:: SimpleVector
1399
- end
1400
- rt, edge = typeinf_edge (method, sig, sparams, sv)
1401
- edge != = nothing && add_backedge! (edge:: MethodInstance , sv)
1402
- rettype = tmerge (rettype, rt)
1403
- if rettype === Any
1404
- break
1326
+ sig = match[1 ]
1327
+ sigtuple = unwrap_unionall (sig):: DataType
1328
+ splitunions = 1 < countunionsplit (sigtuple. parameters) * napplicable <= sv. params. MAX_UNION_SPLITTING * 2
1329
+ if splitunions
1330
+ splitsigs = switchtupleunion (sig)
1331
+ for sig_n in splitsigs
1332
+ rt = abstract_call_method (method, f, sig_n, svec (), sv)
1333
+ rettype = tmerge (rettype, rt)
1334
+ rettype === Any && break
1335
+ end
1336
+ rettype === Any && break
1337
+ else
1338
+ rt = abstract_call_method (method, f, sig, match[2 ]:: SimpleVector , sv)
1339
+ rettype = tmerge (rettype, rt)
1340
+ rettype === Any && break
1405
1341
end
1406
1342
end
1407
1343
if ! (fullmatch || rettype === Any)
@@ -1418,6 +1354,112 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
1418
1354
return rettype
1419
1355
end
1420
1356
1357
+ function abstract_call_method (method:: Method , f:: ANY , sig:: ANY , sparams:: SimpleVector , sv:: InferenceState )
1358
+ sigtuple = unwrap_unionall (sig):: DataType
1359
+ recomputesvec = false
1360
+
1361
+ # limit argument type tuple growth
1362
+ msig = unwrap_unionall (method. sig)
1363
+ lsig = length (msig. parameters)
1364
+ ls = length (sigtuple. parameters)
1365
+ td = type_depth (sig)
1366
+ mightlimitlength = ls > lsig + 1
1367
+ mightlimitdepth = td > 2
1368
+ limitlength = false
1369
+ if mightlimitlength || mightlimitdepth
1370
+ # TODO : FIXME : this heuristic depends on non-local state making type-inference unpredictable
1371
+ cyclei = 0
1372
+ infstate = sv
1373
+ while infstate != = nothing
1374
+ infstate = infstate:: InferenceState
1375
+ if isdefined (infstate. linfo, :def ) && method === infstate. linfo. def
1376
+ if mightlimitlength && ls > length (unwrap_unionall (infstate. linfo. specTypes). parameters)
1377
+ limitlength = true
1378
+ end
1379
+ if mightlimitdepth && td > type_depth (infstate. linfo. specTypes)
1380
+ # impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
1381
+ if td > MAX_TYPE_DEPTH
1382
+ sig = limit_type_depth (sig, 0 )
1383
+ sigtuple = unwrap_unionall (sig)
1384
+ recomputesvec = true
1385
+ break
1386
+ else
1387
+ p1, p2 = sigtuple. parameters, unwrap_unionall (infstate. linfo. specTypes). parameters
1388
+ if length (p2) == ls
1389
+ limitdepth = false
1390
+ newsig = Vector {Any} (ls)
1391
+ for i = 1 : ls
1392
+ if p1[i] <: Function && type_depth (p1[i]) > type_depth (p2[i]) &&
1393
+ isa (p1[i],DataType)
1394
+ # if a Function argument is growing (e.g. nested closures)
1395
+ # then widen to the outermost function type. without this
1396
+ # inference fails to terminate on do_quadgk.
1397
+ newsig[i] = p1[i]. name. wrapper
1398
+ limitdepth = true
1399
+ else
1400
+ newsig[i] = limit_type_depth (p1[i], 1 )
1401
+ end
1402
+ end
1403
+ if limitdepth
1404
+ sigtuple = Tuple{newsig... }
1405
+ sig = rewrap_unionall (sigtuple, sig)
1406
+ recomputesvec = true
1407
+ break
1408
+ end
1409
+ end
1410
+ end
1411
+ end
1412
+ end
1413
+ # iterate through the cycle before walking to the parent
1414
+ if cyclei < length (infstate. callers_in_cycle)
1415
+ cyclei += 1
1416
+ infstate = infstate. callers_in_cycle[cyclei]
1417
+ else
1418
+ cyclei = 0
1419
+ infstate = infstate. parent
1420
+ end
1421
+ end
1422
+ end
1423
+
1424
+ # limit length based on size of definition signature.
1425
+ # for example, given function f(T, Any...), limit to 3 arguments
1426
+ # instead of the default (MAX_TUPLETYPE_LEN)
1427
+ if limitlength
1428
+ tm = _topmod (sv)
1429
+ if ! istopfunction (tm, f, :promote_typeof )
1430
+ fst = sigtuple. parameters[lsig + 1 ]
1431
+ allsame = true
1432
+ # allow specializing on longer arglists if all the trailing
1433
+ # arguments are the same, since there is no exponential
1434
+ # blowup in this case.
1435
+ for i = (lsig + 2 ): ls
1436
+ if sigtuple. parameters[i] != fst
1437
+ allsame = false
1438
+ break
1439
+ end
1440
+ end
1441
+ if ! allsame
1442
+ sigtuple = limit_tuple_type_n (sigtuple, lsig + 1 )
1443
+ sig = rewrap_unionall (sigtuple, sig)
1444
+ recomputesvec = true
1445
+ end
1446
+ end
1447
+ end
1448
+
1449
+ # if sig changed, may need to recompute the sparams environment
1450
+ if isa (method. sig, UnionAll) && (recomputesvec || isempty (sparams))
1451
+ recomputed = ccall (:jl_env_from_type_intersection , Ref{SimpleVector}, (Any, Any), sig, method. sig)
1452
+ sig = recomputed[1 ]
1453
+ if ! isa (unwrap_unionall (sig), DataType) # probably Union{}
1454
+ return Any
1455
+ end
1456
+ sparams = recomputed[2 ]:: SimpleVector
1457
+ end
1458
+ rt, edge = typeinf_edge (method, sig, sparams, sv)
1459
+ edge != = nothing && add_backedge! (edge:: MethodInstance , sv)
1460
+ return rt
1461
+ end
1462
+
1421
1463
# determine whether `ex` abstractly evals to constant `c`
1422
1464
function abstract_evals_to_constant (ex:: ANY , c:: ANY , vtypes:: VarTable , sv:: InferenceState )
1423
1465
av = abstract_eval (ex, vtypes, sv)
@@ -1566,6 +1608,9 @@ function abstract_apply(aft::ANY, fargs::Vector{Any}, aargtypes::Vector{Any}, vt
1566
1608
return res
1567
1609
end
1568
1610
1611
+ # TODO : this function is a very buggy and poor model of the return_type function
1612
+ # since abstract_call_gf_by_type is a very inaccurate model of _method and of typeinf_type,
1613
+ # while this assumes that it is an exact of both
1569
1614
function return_type_tfunc (argtypes:: ANY , vtypes:: VarTable , sv:: InferenceState )
1570
1615
if length (argtypes) == 3
1571
1616
tt = argtypes[3 ]
@@ -2122,8 +2167,10 @@ function issubconditional(a::Conditional, b::Conditional)
2122
2167
end
2123
2168
2124
2169
function ⊑ (a:: ANY , b:: ANY )
2125
- a === NF && return true
2126
- b === NF && return false
2170
+ (a === NF || b === Any) && return true
2171
+ (a === Any || b === NF) && return false
2172
+ a === Union{} && return true
2173
+ b === Union{} && return false
2127
2174
if isa (a, Conditional)
2128
2175
if isa (b, Conditional)
2129
2176
return issubconditional (a, b)
@@ -3474,7 +3521,7 @@ function is_self_quoting(x::ANY)
3474
3521
return isa (x,Number) || isa (x,AbstractString) || isa (x,Tuple) || isa (x,Type)
3475
3522
end
3476
3523
3477
- function countunionsplit (atypes:: Vector{Any} )
3524
+ function countunionsplit (atypes)
3478
3525
nu = 1
3479
3526
for ti in atypes
3480
3527
if isa (ti, Union)
0 commit comments