@@ -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
@@ -1282,136 +1308,163 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
1282
1308
end
1283
1309
min_valid = UInt[typemin (UInt)]
1284
1310
max_valid = UInt[typemax (UInt)]
1285
- applicable = _methods_by_ftype (argtype, sv. params. MAX_METHODS, sv. params. world, min_valid, max_valid)
1286
- rettype = Bottom
1287
- if applicable === false
1288
- # this means too many methods matched
1289
- return Any
1311
+ splitunions = 1 < countunionsplit (argtypes) <= sv. params. MAX_UNION_SPLITTING
1312
+ if splitunions
1313
+ splitsigs = switchtupleunion (argtype)
1314
+ applicable = Any[]
1315
+ for sig_n in splitsigs
1316
+ xapplicable = _methods_by_ftype (sig_n, sv. params. MAX_METHODS, sv. params. world, min_valid, max_valid)
1317
+ xapplicable === false && return Any
1318
+ append! (applicable, xapplicable)
1319
+ end
1320
+ else
1321
+ applicable = _methods_by_ftype (argtype, sv. params. MAX_METHODS, sv. params. world, min_valid, max_valid)
1322
+ if applicable === false
1323
+ # this means too many methods matched
1324
+ return Any
1325
+ end
1290
1326
end
1291
1327
applicable = applicable:: Array{Any,1}
1328
+ napplicable = length (applicable)
1292
1329
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
1330
+ rettype = Bottom
1331
+ for i in 1 : napplicable
1332
+ match = applicable[i]:: SimpleVector
1333
+ method = match[3 ]:: Method
1299
1334
if ! fullmatch && (argtype <: method.sig )
1300
1335
fullmatch = true
1301
1336
end
1337
+ sig = match[1 ]
1338
+ sigtuple = unwrap_unionall (sig):: DataType
1339
+ splitunions = 1 < countunionsplit (sigtuple. parameters) * napplicable <= sv. params. MAX_UNION_SPLITTING
1340
+ if splitunions
1341
+ splitsigs = switchtupleunion (sig)
1342
+ for sig_n in splitsigs
1343
+ rt = abstract_call_method (method, f, sig_n, svec (), sv)
1344
+ rettype = tmerge (rettype, rt)
1345
+ rettype === Any && break
1346
+ end
1347
+ rettype === Any && break
1348
+ else
1349
+ rt = abstract_call_method (method, f, sig, match[2 ]:: SimpleVector , sv)
1350
+ rettype = tmerge (rettype, rt)
1351
+ rettype === Any && break
1352
+ end
1353
+ end
1354
+ if ! (fullmatch || rettype === Any)
1355
+ # also need an edge to the method table in case something gets
1356
+ # added that did not intersect with any existing method
1357
+ add_mt_backedge (ftname. mt, argtype, sv)
1358
+ update_valid_age! (min_valid[1 ], max_valid[1 ], sv)
1359
+ end
1360
+ # print("=> ", rettype, "\n")
1361
+ return rettype
1362
+ end
1302
1363
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
1364
+ function abstract_call_method (method:: Method , f:: ANY , sig:: ANY , sparams:: SimpleVector , sv:: InferenceState )
1365
+ sigtuple = unwrap_unionall (sig):: DataType
1366
+ recomputesvec = false
1367
+
1368
+ # limit argument type tuple growth
1369
+ msig = unwrap_unionall (method. sig)
1370
+ lsig = length (msig. parameters)
1371
+ ls = length (sigtuple. parameters)
1372
+ td = type_depth (sig)
1373
+ mightlimitlength = ls > lsig + 1
1374
+ mightlimitdepth = td > 2
1375
+ limitlength = false
1376
+ if mightlimitlength || mightlimitdepth
1377
+ # TODO : FIXME : this heuristic depends on non-local state making type-inference unpredictable
1378
+ cyclei = 0
1379
+ infstate = sv
1380
+ while infstate != = nothing
1381
+ infstate = infstate:: InferenceState
1382
+ if isdefined (infstate. linfo, :def ) && method === infstate. linfo. def
1383
+ if mightlimitlength && ls > length (unwrap_unionall (infstate. linfo. specTypes). parameters)
1384
+ limitlength = true
1385
+ end
1386
+ if mightlimitdepth && td > type_depth (infstate. linfo. specTypes)
1387
+ # impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
1388
+ if td > MAX_TYPE_DEPTH
1389
+ sig = limit_type_depth (sig, 0 )
1390
+ sigtuple = unwrap_unionall (sig)
1391
+ recomputesvec = true
1392
+ break
1393
+ else
1394
+ p1, p2 = sigtuple. parameters, unwrap_unionall (infstate. linfo. specTypes). parameters
1395
+ if length (p2) == ls
1396
+ limitdepth = false
1397
+ newsig = Vector {Any} (ls)
1398
+ for i = 1 : ls
1399
+ if p1[i] <: Function && type_depth (p1[i]) > type_depth (p2[i]) &&
1400
+ isa (p1[i],DataType)
1401
+ # if a Function argument is growing (e.g. nested closures)
1402
+ # then widen to the outermost function type. without this
1403
+ # inference fails to terminate on do_quadgk.
1404
+ newsig[i] = p1[i]. name. wrapper
1405
+ limitdepth = true
1406
+ else
1407
+ newsig[i] = limit_type_depth (p1[i], 1 )
1350
1408
end
1351
1409
end
1410
+ if limitdepth
1411
+ sigtuple = Tuple{newsig... }
1412
+ sig = rewrap_unionall (sigtuple, sig)
1413
+ recomputesvec = true
1414
+ break
1415
+ end
1352
1416
end
1353
1417
end
1354
1418
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
1419
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
1420
+ # iterate through the cycle before walking to the parent
1421
+ if cyclei < length (infstate. callers_in_cycle)
1422
+ cyclei += 1
1423
+ infstate = infstate. callers_in_cycle[cyclei]
1424
+ else
1425
+ cyclei = 0
1426
+ infstate = infstate. parent
1427
+ end
1428
+ end
1429
+ end
1430
+
1431
+ # limit length based on size of definition signature.
1432
+ # for example, given function f(T, Any...), limit to 3 arguments
1433
+ # instead of the default (MAX_TUPLETYPE_LEN)
1434
+ if limitlength
1435
+ tm = _topmod (sv)
1436
+ if ! istopfunction (tm, f, :promote_typeof )
1437
+ fst = sigtuple. parameters[lsig + 1 ]
1438
+ allsame = true
1439
+ # allow specializing on longer arglists if all the trailing
1440
+ # arguments are the same, since there is no exponential
1441
+ # blowup in this case.
1442
+ for i = (lsig + 2 ): ls
1443
+ if sigtuple. parameters[i] != fst
1444
+ allsame = false
1445
+ break
1386
1446
end
1387
1447
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
1448
+ if ! allsame
1449
+ sigtuple = limit_tuple_type_n (sigtuple, lsig + 1 )
1450
+ sig = rewrap_unionall (sigtuple, sig)
1451
+ recomputesvec = true
1397
1452
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
1405
1453
end
1406
1454
end
1407
- if ! (fullmatch || rettype === Any)
1408
- # also need an edge to the method table in case something gets
1409
- # added that did not intersect with any existing method
1410
- add_mt_backedge (ftname. mt, argtype, sv)
1411
- update_valid_age! (min_valid[1 ], max_valid[1 ], sv)
1455
+
1456
+ # if sig changed, may need to recompute the sparams environment
1457
+ if isa (method. sig, UnionAll) && (recomputesvec || isempty (sparams))
1458
+ recomputed = ccall (:jl_env_from_type_intersection , Ref{SimpleVector}, (Any, Any), sig, method. sig)
1459
+ sig = recomputed[1 ]
1460
+ if ! isa (unwrap_unionall (sig), DataType) # probably Union{}
1461
+ return Any
1462
+ end
1463
+ sparams = recomputed[2 ]:: SimpleVector
1412
1464
end
1413
- # print("=> ", rettype, "\n")
1414
- return rettype
1465
+ rt, edge = typeinf_edge (method, sig, sparams, sv)
1466
+ edge != = nothing && add_backedge! (edge:: MethodInstance , sv)
1467
+ return rt
1415
1468
end
1416
1469
1417
1470
# determine whether `ex` abstractly evals to constant `c`
@@ -1562,6 +1615,9 @@ function abstract_apply(aft::ANY, fargs::Vector{Any}, aargtypes::Vector{Any}, vt
1562
1615
return res
1563
1616
end
1564
1617
1618
+ # TODO : this function is a very buggy and poor model of the return_type function
1619
+ # since abstract_call_gf_by_type is a very inaccurate model of _method and of typeinf_type,
1620
+ # while this assumes that it is a precisely accurate and exact model of both
1565
1621
function return_type_tfunc (argtypes:: ANY , vtypes:: VarTable , sv:: InferenceState )
1566
1622
if length (argtypes) == 3
1567
1623
tt = argtypes[3 ]
@@ -2112,8 +2168,10 @@ function issubconditional(a::Conditional, b::Conditional)
2112
2168
end
2113
2169
2114
2170
function ⊑ (a:: ANY , b:: ANY )
2115
- a === NF && return true
2116
- b === NF && return false
2171
+ (a === NF || b === Any) && return true
2172
+ (a === Any || b === NF) && return false
2173
+ a === Union{} && return true
2174
+ b === Union{} && return false
2117
2175
if isa (a, Conditional)
2118
2176
if isa (b, Conditional)
2119
2177
return issubconditional (a, b)
@@ -3483,7 +3541,7 @@ function is_self_quoting(x::ANY)
3483
3541
return isa (x,Number) || isa (x,AbstractString) || isa (x,Tuple) || isa (x,Type)
3484
3542
end
3485
3543
3486
- function countunionsplit (atypes:: Vector{Any} )
3544
+ function countunionsplit (atypes)
3487
3545
nu = 1
3488
3546
for ti in atypes
3489
3547
if isa (ti, Union)
0 commit comments