@@ -15,6 +15,7 @@ type StaticVarInfo
15
15
vars:: Array{Any,1} # names of args and locals
16
16
gensym_types:: Array{Any,1} # types of the GenSym's in this function
17
17
label_counter:: Int # index of the current highest label for this function
18
+ fedbackvars:: ObjectIdDict
18
19
end
19
20
20
21
type EmptyCallStack
@@ -342,7 +343,7 @@ const getfield_tfunc = function (A, s0, name)
342
343
return abstract_eval_constant (eval (A1,fld))
343
344
end
344
345
if s === Module
345
- return Top
346
+ return Any
346
347
end
347
348
if isType (s0)
348
349
sp = s0. parameters[1 ]
939
940
940
941
function abstract_eval_arg (a:: ANY , vtypes:: ANY , sv:: StaticVarInfo )
941
942
t = abstract_eval (a, vtypes, sv)
942
- if isa (a,Symbol) || isa (a,SymbolNode) || isa (a,GenSym)
943
- t = typeintersect (t,Any) # remove Undef
944
- end
945
943
if isa (t,TypeVar) && t. lb == Bottom && isleaftype (t. ub)
946
944
t = t. ub
947
945
end
@@ -1018,19 +1016,18 @@ function abstract_eval(e::ANY, vtypes, sv::StaticVarInfo)
1018
1016
abstract_eval (e. args[1 ], vtypes, sv)
1019
1017
t = Any
1020
1018
elseif is (e. head,:static_typeof )
1021
- t0 = abstract_eval (e. args[1 ], vtypes, sv)
1022
- # intersect with Any to remove Undef
1023
- t = typeintersect (t0, Any)
1019
+ var = e. args[1 ]
1020
+ t = t0 = abstract_eval (var, vtypes, sv)
1024
1021
if isa (t,DataType) && typeseq (t,t. name. primary)
1025
1022
# remove unnecessary typevars
1026
1023
t = t. name. primary
1027
1024
end
1028
- if is (t,Bottom) && Undef <: t0
1029
- # the first time we see this statement the variable will probably
1030
- # be Undef; return Bottom so this doesn't contribute to the type
1031
- # we eventually pick.
1032
- elseif is (t, Bottom)
1033
- t = Type{Bottom}
1025
+ if is (t,Bottom)
1026
+ # if we haven't gotten fed-back type info yet, return Bottom. otherwise
1027
+ # Bottom is the actual type of the variable, so return Type{Bottom}.
1028
+ if haskey (sv . fedbackvars, var)
1029
+ t = Type{ Bottom}
1030
+ end
1034
1031
elseif isleaftype (t)
1035
1032
t = Type{t}
1036
1033
elseif isleaftype (inference_stack. types)
@@ -1059,7 +1056,7 @@ function abstract_eval(e::ANY, vtypes, sv::StaticVarInfo)
1059
1056
else
1060
1057
t = Any
1061
1058
end
1062
- if isa (t,TypeVar) && t . lb === Bottom
1059
+ if isa (t,TypeVar)
1063
1060
# no need to use a typevar as the type of an expression
1064
1061
t = t. ub
1065
1062
end
@@ -1082,30 +1079,20 @@ function abstract_eval_constant(x::ANY)
1082
1079
return typeof (x)
1083
1080
end
1084
1081
1085
- # Undef is the static type of a value location (e.g. variable) that is
1086
- # undefined. The corresponding run-time type is Bottom, since accessing an
1087
- # undefined location is an error. A non-lvalue expression cannot have
1088
- # type Undef, only Bottom.
1089
- # typealias Top Union(Any,Undef)
1090
-
1091
1082
abstract_eval_global (s:: Symbol ) =
1092
1083
abstract_eval_global ((inference_stack:: CallStack ). mod, s)
1093
1084
1094
1085
function abstract_eval_global (M, s:: Symbol )
1095
1086
if isconst (M,s)
1096
1087
return abstract_eval_constant (eval (M,s))
1097
1088
end
1098
- if ! isdefined (M,s)
1099
- return Top
1100
- end
1101
- # TODO : change to Undef if there's a way to clear variables
1102
1089
return Any
1103
1090
end
1104
1091
1105
1092
function abstract_eval_gensym (s:: GenSym , sv:: StaticVarInfo )
1106
1093
typ = sv. gensym_types[s. id+ 1 ]
1107
1094
if typ === NF
1108
- return Undef
1095
+ return Bottom
1109
1096
end
1110
1097
return typ
1111
1098
end
@@ -1137,7 +1124,7 @@ function abstract_eval_symbol(s::Symbol, vtypes::ObjectIdDict, sv::StaticVarInfo
1137
1124
end
1138
1125
if s in sv. vars
1139
1126
# local variable use not reached
1140
- return Top
1127
+ return Bottom
1141
1128
end
1142
1129
# global
1143
1130
return abstract_eval_global (s)
@@ -1208,18 +1195,10 @@ function type_too_complex(t::ANY, d)
1208
1195
end
1209
1196
1210
1197
function tmerge (typea:: ANY , typeb:: ANY )
1211
- if is (typea,NF)
1212
- return typeb
1213
- end
1214
- if is (typeb,NF)
1215
- return typea
1216
- end
1217
- if typea <: typeb
1218
- return typeb
1219
- end
1220
- if typeb <: typea
1221
- return typea
1222
- end
1198
+ is (typea, NF ) && return typeb
1199
+ is (typeb, NF) && return typea
1200
+ typea <: typeb && return typeb
1201
+ typeb <: typea && return typea
1223
1202
if isa (typea, Tuple) && isa (typeb, Tuple)
1224
1203
if length (typea) == length (typeb) && ! isvatuple (typea) && ! isvatuple (typeb)
1225
1204
return typejoin (typea, typeb)
@@ -1230,7 +1209,7 @@ function tmerge(typea::ANY, typeb::ANY)
1230
1209
if length (u. types) > MAX_TYPEUNION_LEN || type_too_complex (u, 0 )
1231
1210
# don't let type unions get too big
1232
1211
# TODO : something smarter, like a common supertype
1233
- return Undef <: u ? Top : Any
1212
+ return Any
1234
1213
end
1235
1214
return u
1236
1215
end
@@ -1252,13 +1231,19 @@ function stupdate(state::ObjectIdDict, changes::Union(StateUpdate,VarTable), var
1252
1231
state
1253
1232
end
1254
1233
1255
- function stchanged (new:: Union(StateUpdate,VarTable) , old, vars )
1234
+ function stchanged (new:: Union(StateUpdate,VarTable) , old, vinflist )
1256
1235
if is (old,())
1257
1236
return true
1258
1237
end
1259
- for i = 1 : length (vars)
1260
- v = vars[i]
1261
- if tchanged (new[v], get (old,v,NF))
1238
+ for vi in vinflist
1239
+ v = vi[1 ]
1240
+ newtype = new[v]
1241
+ oldtype = get (old,v,NF)
1242
+ if (newtype === Bottom && oldtype != = NF && oldtype != = Bottom) ||
1243
+ (oldtype === Bottom && newtype != = NF && newtype != = Bottom)
1244
+ vi[3 ] |= 32
1245
+ end
1246
+ if tchanged (newtype, oldtype)
1262
1247
return true
1263
1248
end
1264
1249
end
@@ -1457,7 +1442,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1457
1442
# initial types
1458
1443
s[1 ] = ObjectIdDict ()
1459
1444
for v in vars
1460
- s[1 ][v] = Undef
1445
+ s[1 ][v] = Bottom
1461
1446
end
1462
1447
if la > 0
1463
1448
lastarg = ast. args[1 ][la]
@@ -1507,7 +1492,8 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1507
1492
cenv[vname] = vtype
1508
1493
s[1 ][vname] = vtype
1509
1494
end
1510
- for vi = ((ast. args[2 ][2 ]):: Array{Any,1} )
1495
+ vinflist = ast. args[2 ][2 ]:: Array{Any,1}
1496
+ for vi in vinflist
1511
1497
vi:: Array{Any,1}
1512
1498
if (vi[3 ]& 4 )!= 0
1513
1499
# variables assigned by inner functions are treated like
@@ -1523,7 +1509,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1523
1509
gensym_init = Any[ NF for i = 1 : length (gensym_uses) ]
1524
1510
gensym_types = copy (gensym_init)
1525
1511
1526
- sv = StaticVarInfo (sparams, cenv, vars, gensym_types, length (labels))
1512
+ sv = StaticVarInfo (sparams, cenv, vars, gensym_types, length (labels), ObjectIdDict () )
1527
1513
frame. sv = sv
1528
1514
1529
1515
recpts = IntSet () # statements that depend recursively on our value
@@ -1565,7 +1551,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1565
1551
if ! is (cur_hand,())
1566
1552
# propagate type info to exception handler
1567
1553
l = cur_hand[1 ]:: Int
1568
- if stchanged (changes, s[l], vars )
1554
+ if stchanged (changes, s[l], vinflist )
1569
1555
push! (W, l)
1570
1556
s[l] = stupdate (s[l], changes, vars)
1571
1557
end
@@ -1598,7 +1584,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1598
1584
else
1599
1585
# general case
1600
1586
handler_at[l] = cur_hand
1601
- if stchanged (changes, s[l], vars )
1587
+ if stchanged (changes, s[l], vinflist )
1602
1588
push! (W, l)
1603
1589
s[l] = stupdate (s[l], changes, vars)
1604
1590
end
@@ -1619,6 +1605,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1619
1605
gensym_init[id] = vt
1620
1606
typegotoredo = true
1621
1607
end
1608
+ sv. fedbackvars[var] = true
1622
1609
end
1623
1610
elseif is (hd,:return )
1624
1611
pc´ = n+ 1
@@ -1663,7 +1650,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
1663
1650
end
1664
1651
end
1665
1652
if pc´<= n && (handler_at[pc´] = cur_hand; true ) &&
1666
- stchanged (changes, s[pc´], vars )
1653
+ stchanged (changes, s[pc´], vinflist )
1667
1654
s[pc´] = stupdate (s[pc´], changes, vars)
1668
1655
pc = pc´
1669
1656
elseif pc´ in W
@@ -1752,7 +1739,7 @@ function record_var_type(e::Symbol, t::ANY, decls)
1752
1739
end
1753
1740
end
1754
1741
1755
- function eval_annotate (e:: ANY , vtypes:: ANY , sv:: StaticVarInfo , decls, clo)
1742
+ function eval_annotate (e:: ANY , vtypes:: ANY , sv:: StaticVarInfo , decls, clo, undefs )
1756
1743
if isa (e, Symbol)
1757
1744
e = e:: Symbol
1758
1745
@@ -1761,13 +1748,19 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::StaticVarInfo, decls, clo)
1761
1748
return e
1762
1749
end
1763
1750
t = abstract_eval (e, vtypes, sv)
1751
+ if t === Bottom
1752
+ undefs[e] = true
1753
+ end
1764
1754
record_var_type (e, t, decls)
1765
1755
return (is (t,Any) || is (t,IntrinsicFunction)) ? e : SymbolNode (e, t)
1766
1756
end
1767
1757
1768
1758
if isa (e, SymbolNode)
1769
1759
e = e:: SymbolNode
1770
1760
curtype = e. typ
1761
+ if curtype === Bottom
1762
+ undefs[e. name] = true
1763
+ end
1771
1764
t = abstract_eval (e. name, vtypes, sv)
1772
1765
if ! (curtype <: t ) || typeseq (curtype, t)
1773
1766
record_var_type (e. name, t, decls)
@@ -1800,7 +1793,7 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::StaticVarInfo, decls, clo)
1800
1793
# we don't use types on assignment LHS
1801
1794
s = s. name
1802
1795
end
1803
- e. args[2 ] = eval_annotate (e. args[2 ], vtypes, sv, decls, clo)
1796
+ e. args[2 ] = eval_annotate (e. args[2 ], vtypes, sv, decls, clo, undefs )
1804
1797
if isa (s,Symbol)
1805
1798
# TODO : if this def does not reach any uses, maybe don't do this
1806
1799
rhstype = exprtype (e. args[2 ], sv)
@@ -1814,7 +1807,7 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::StaticVarInfo, decls, clo)
1814
1807
for i= i0: length (e. args)
1815
1808
subex = e. args[i]
1816
1809
if ! (isa (subex,Number) || isa (subex,AbstractString))
1817
- e. args[i] = eval_annotate (subex, vtypes, sv, decls, clo)
1810
+ e. args[i] = eval_annotate (subex, vtypes, sv, decls, clo, undefs )
1818
1811
end
1819
1812
end
1820
1813
if (head === :call || head === :call1 ) && isa (e. args[1 ],LambdaStaticData)
@@ -1832,6 +1825,7 @@ end
1832
1825
function type_annotate (ast:: Expr , states:: Array{Any,1} , sv:: ANY , rettype:: ANY ,
1833
1826
args)
1834
1827
decls = ObjectIdDict ()
1828
+ undefs = ObjectIdDict ()
1835
1829
# initialize decls with argument types
1836
1830
for arg in args
1837
1831
decls[arg] = states[1 ][arg]
@@ -1842,7 +1836,7 @@ function type_annotate(ast::Expr, states::Array{Any,1}, sv::ANY, rettype::ANY,
1842
1836
st_i = states[i]
1843
1837
if st_i != = ()
1844
1838
# st_i === () => unreached statement (see issue #7836)
1845
- body[i] = eval_annotate (body[i], st_i, sv, decls, closures)
1839
+ body[i] = eval_annotate (body[i], st_i, sv, decls, closures, undefs )
1846
1840
end
1847
1841
end
1848
1842
ast. args[3 ]. typ = rettype
@@ -1852,11 +1846,17 @@ function type_annotate(ast::Expr, states::Array{Any,1}, sv::ANY, rettype::ANY,
1852
1846
if (vi[3 ]& 4 )== 0
1853
1847
vi[2 ] = get (decls, vi[1 ], vi[2 ])
1854
1848
end
1849
+ if haskey (undefs, vi[1 ])
1850
+ vi[3 ] |= 32
1851
+ end
1855
1852
end
1856
1853
for vi in ast. args[2 ][3 ]:: Array{Any,1}
1857
1854
if (vi[3 ]& 4 )== 0
1858
1855
vi[2 ] = get (decls, vi[1 ], vi[2 ])
1859
1856
end
1857
+ if haskey (undefs, vi[1 ])
1858
+ vi[3 ] |= 32
1859
+ end
1860
1860
end
1861
1861
ast. args[2 ][4 ] = sv. gensym_types
1862
1862
@@ -2350,7 +2350,6 @@ function inlineable(f::ANY, e::Expr, atypes::Tuple, sv::StaticVarInfo, enclosing
2350
2350
for i = 1 : numarg
2351
2351
name = newnames[i]
2352
2352
argtype = exprtype (argexprs[i],sv)
2353
- argtype = typeintersect (argtype,Any) # remove Undef
2354
2353
push! (locals, Any[name,argtype,0 ])
2355
2354
push! (newcall. args, argtype=== Any ? name : SymbolNode (name, argtype))
2356
2355
end
@@ -3044,7 +3043,7 @@ function remove_redundant_temp_vars(ast, sa)
3044
3043
# this transformation is not valid for vars used before def.
3045
3044
# we need to preserve the point of assignment to know where to
3046
3045
# throw errors (issue #4645).
3047
- if ! occurs_undef (v, ast. args[3 ])
3046
+ if ! occurs_undef (v, ast. args[3 ], varinfo )
3048
3047
3049
3048
# the transformation is not ideal if the assignment
3050
3049
# is present for the auto-unbox functionality
@@ -3063,18 +3062,22 @@ end
3063
3062
3064
3063
function local_typeof (v, varinfo)
3065
3064
for (v2, typ, info) in varinfo
3066
- if v === v2
3067
- return typ
3068
- end
3065
+ v === v2 && return typ
3066
+ end
3067
+ @assert false " v not in varinfo"
3068
+ end
3069
+ function var_infobits (v, varinfo)
3070
+ for (v2, typ, info) in varinfo
3071
+ v === v2 && return info
3069
3072
end
3070
3073
@assert false " v not in varinfo"
3071
3074
end
3072
3075
3073
- occurs_undef (var:: GenSym , expr) = false
3076
+ occurs_undef (var:: GenSym , expr, varinfo ) = false
3074
3077
3075
- occurs_undef (var, expr) =
3076
- occurs_more (expr,
3077
- e -> ( isa (e,SymbolNode) && symequal (var,e) && issubtype (Undef,e . typ )), 0 )> 0
3078
+ occurs_undef (var, expr, varinfo ) =
3079
+ occurs_more (expr, e -> ( isa (e,SymbolNode) && symequal (var,e) &&
3080
+ (( var_infobits (e . name,varinfo) & 32 ) != 0 )), 0 )> 0
3078
3081
3079
3082
# compute set of vars assigned once
3080
3083
function find_sa_vars (ast)
0 commit comments