290
290
291
291
let # typeassert
292
292
result = code_escapes ((Any,)) do x
293
- y = x:: String
293
+ y = x:: Base.RefValue{Any}
294
294
return y
295
295
end
296
296
r = only (findall (isreturn, result. ir. stmts. stmt))
305
305
r = only (findall (isreturn, result. ir. stmts. stmt))
306
306
@test has_return_escape (result. state[Argument (2 )], r)
307
307
@test ! has_all_escape (result. state[Argument (2 )])
308
-
309
- result = code_escapes ((Module,)) do m
310
- isdefined (m, 10 ) # throws
311
- end
312
- @test has_thrown_escape (result. state[Argument (2 )])
313
308
end
314
309
end
315
310
685
680
@test has_all_escape (result. state[Argument (2 )])
686
681
end
687
682
let result = @eval EATModule () begin
688
- const Rx = SafeRef {String} ( " Rx " )
689
- $ code_escapes ((String,)) do s
683
+ const Rx = SafeRef {Any} ( nothing )
684
+ $ code_escapes ((Base . RefValue{ String} ,)) do s
690
685
setfield! (Rx, :x , s)
691
686
Core. sizeof (Rx[])
692
687
end
712
707
# ------------
713
708
714
709
# field escape should propagate to :new arguments
715
- let result = code_escapes ((String,)) do a
710
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
716
711
o = SafeRef (a)
717
712
Core. donotdelete (o)
718
713
return o[]
722
717
@test has_return_escape (result. state[Argument (2 )], r)
723
718
@test is_load_forwardable (result. state[SSAValue (i)])
724
719
end
725
- let result = code_escapes ((String,)) do a
720
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
726
721
t = SafeRef ((a,))
727
722
f = t[][1 ]
728
723
return f
731
726
r = only (findall (isreturn, result. ir. stmts. stmt))
732
727
@test has_return_escape (result. state[Argument (2 )], r)
733
728
@test is_load_forwardable (result. state[SSAValue (i)])
734
- result. state[SSAValue (i)]. AliasInfo
735
729
end
736
- let result = code_escapes ((String, String)) do a, b
730
+ let result = code_escapes ((Base . RefValue{ String}, Base . RefValue{ String} )) do a, b
737
731
obj = SafeRefs (a, b)
738
732
Core. donotdelete (obj)
739
733
fld1 = obj[1 ]
@@ -748,31 +742,31 @@ end
748
742
end
749
743
750
744
# field escape should propagate to `setfield!` argument
751
- let result = code_escapes ((String,)) do a
752
- o = SafeRef (" foo" )
745
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
746
+ o = SafeRef (Ref ( " foo" ) )
753
747
Core. donotdelete (o)
754
748
o[] = a
755
749
return o[]
756
750
end
757
- i = only (findall (isnew, result. ir. stmts. stmt))
751
+ i = last (findall (isnew, result. ir. stmts. stmt))
758
752
r = only (findall (isreturn, result. ir. stmts. stmt))
759
753
@test has_return_escape (result. state[Argument (2 )], r)
760
754
@test is_load_forwardable (result. state[SSAValue (i)])
761
755
end
762
756
# propagate escape information imposed on return value of `setfield!` call
763
- let result = code_escapes ((String,)) do a
764
- obj = SafeRef (" foo" )
757
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
758
+ obj = SafeRef (Ref ( " foo" ) )
765
759
Core. donotdelete (obj)
766
760
return (obj[] = a)
767
761
end
768
- i = only (findall (isnew, result. ir. stmts. stmt))
762
+ i = last (findall (isnew, result. ir. stmts. stmt))
769
763
r = only (findall (isreturn, result. ir. stmts. stmt))
770
764
@test has_return_escape (result. state[Argument (2 )], r)
771
765
@test is_load_forwardable (result. state[SSAValue (i)])
772
766
end
773
767
774
768
# nested allocations
775
- let result = code_escapes ((String,)) do a
769
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
776
770
o1 = SafeRef (a)
777
771
o2 = SafeRef (o1)
778
772
return o2[]
787
781
end
788
782
end
789
783
end
790
- let result = code_escapes ((String,)) do a
784
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
791
785
o1 = (a,)
792
786
o2 = (o1,)
793
787
return o2[1 ]
802
796
end
803
797
end
804
798
end
805
- let result = code_escapes ((String,)) do a
799
+ let result = code_escapes ((Base . RefValue{ String} ,)) do a
806
800
o1 = SafeRef (a)
807
801
o2 = SafeRef (o1)
808
802
o1′ = o2[]
844
838
@test has_return_escape (result. state[SSAValue (i)], r)
845
839
end
846
840
end
847
- let result = code_escapes ((String,)) do x
841
+ let result = code_escapes ((Base . RefValue{ String} ,)) do x
848
842
o = Ref (x)
849
843
Core. donotdelete (o)
850
844
broadcast (identity, o)
892
886
end
893
887
end
894
888
# when ϕ-node merges values with different types
895
- let result = code_escapes ((Bool,String, String, String)) do cond, x, y, z
889
+ let result = code_escapes ((Bool,Base . RefValue{ String},Base . RefValue{ String},Base . RefValue{ String} )) do cond, x, y, z
896
890
local out
897
891
if cond
898
892
ϕ = SafeRef (x)
904
898
end
905
899
r = only (findall (isreturn, result. ir. stmts. stmt))
906
900
t = only (findall (iscall ((result. ir, throw)), result. ir. stmts. stmt))
907
- ϕ = only (findall (== (Union{SafeRef{String},SafeRefs{String, String}}), result. ir. stmts. type))
901
+ ϕ = only (findall (== (Union{SafeRef{Base . RefValue{ String}} ,SafeRefs{Base . RefValue{ String},Base . RefValue{ String} }}), result. ir. stmts. type))
908
902
@test has_return_escape (result. state[Argument (3 )], r) # x
909
903
@test ! has_return_escape (result. state[Argument (4 )], r) # y
910
904
@test has_return_escape (result. state[Argument (5 )], r) # z
@@ -1038,7 +1032,7 @@ end
1038
1032
end
1039
1033
# alias via typeassert
1040
1034
let result = code_escapes ((Any,)) do a
1041
- r = a:: String
1035
+ r = a:: Base.RefValue{ String}
1042
1036
return r
1043
1037
end
1044
1038
r = only (findall (isreturn, result. ir. stmts. stmt))
@@ -1077,11 +1071,11 @@ end
1077
1071
@test has_all_escape (result. state[Argument (3 )]) # a
1078
1072
end
1079
1073
# alias via ϕ-node
1080
- let result = code_escapes ((Bool,String)) do cond, x
1074
+ let result = code_escapes ((Bool,Base . RefValue{ String} )) do cond, x
1081
1075
if cond
1082
- ϕ2 = ϕ1 = SafeRef (" foo" )
1076
+ ϕ2 = ϕ1 = SafeRef (Ref ( " foo" ) )
1083
1077
else
1084
- ϕ2 = ϕ1 = SafeRef (" bar" )
1078
+ ϕ2 = ϕ1 = SafeRef (Ref ( " bar" ) )
1085
1079
end
1086
1080
ϕ2[] = x
1087
1081
return ϕ1[]
@@ -1094,14 +1088,16 @@ end
1094
1088
@test is_load_forwardable (result. state[SSAValue (i)])
1095
1089
end
1096
1090
for i in findall (isnew, result. ir. stmts. stmt)
1097
- @test is_load_forwardable (result. state[SSAValue (i)])
1091
+ if result. ir[SSAValue (i)][:type ] <: SafeRef
1092
+ @test is_load_forwardable (result. state[SSAValue (i)])
1093
+ end
1098
1094
end
1099
1095
end
1100
- let result = code_escapes ((Bool,Bool,String)) do cond1, cond2, x
1096
+ let result = code_escapes ((Bool,Bool,Base . RefValue{ String} )) do cond1, cond2, x
1101
1097
if cond1
1102
- ϕ2 = ϕ1 = SafeRef (" foo" )
1098
+ ϕ2 = ϕ1 = SafeRef (Ref ( " foo" ) )
1103
1099
else
1104
- ϕ2 = ϕ1 = SafeRef (" bar" )
1100
+ ϕ2 = ϕ1 = SafeRef (Ref ( " bar" ) )
1105
1101
end
1106
1102
cond2 && (ϕ2[] = x)
1107
1103
return ϕ1[]
@@ -1114,12 +1110,14 @@ end
1114
1110
@test is_load_forwardable (result. state[SSAValue (i)])
1115
1111
end
1116
1112
for i in findall (isnew, result. ir. stmts. stmt)
1117
- @test is_load_forwardable (result. state[SSAValue (i)])
1113
+ if result. ir[SSAValue (i)][:type ] <: SafeRef
1114
+ @test is_load_forwardable (result. state[SSAValue (i)])
1115
+ end
1118
1116
end
1119
1117
end
1120
1118
# alias via π-node
1121
1119
let result = code_escapes ((Any,)) do x
1122
- if isa (x, String)
1120
+ if isa (x, Base . RefValue{ String} )
1123
1121
return x
1124
1122
end
1125
1123
throw (" error!" )
@@ -1213,7 +1211,7 @@ end
1213
1211
1214
1212
# conservatively handle unknown field:
1215
1213
# all fields should be escaped, but the allocation itself doesn't need to be escaped
1216
- let result = code_escapes ((String, Symbol)) do a, fld
1214
+ let result = code_escapes ((Base . RefValue{ String} , Symbol)) do a, fld
1217
1215
obj = SafeRef (a)
1218
1216
return getfield (obj, fld)
1219
1217
end
@@ -1222,7 +1220,7 @@ end
1222
1220
@test has_return_escape (result. state[Argument (2 )], r) # a
1223
1221
@test ! is_load_forwardable (result. state[SSAValue (i)]) # obj
1224
1222
end
1225
- let result = code_escapes ((String, String, Symbol)) do a, b, fld
1223
+ let result = code_escapes ((Base . RefValue{ String}, Base . RefValue{ String} , Symbol)) do a, b, fld
1226
1224
obj = SafeRefs (a, b)
1227
1225
return getfield (obj, fld) # should escape both `a` and `b`
1228
1226
end
@@ -1232,7 +1230,7 @@ end
1232
1230
@test has_return_escape (result. state[Argument (3 )], r) # b
1233
1231
@test ! is_load_forwardable (result. state[SSAValue (i)]) # obj
1234
1232
end
1235
- let result = code_escapes ((String, String, Int)) do a, b, idx
1233
+ let result = code_escapes ((Base . RefValue{ String}, Base . RefValue{ String} , Int)) do a, b, idx
1236
1234
obj = SafeRefs (a, b)
1237
1235
return obj[idx] # should escape both `a` and `b`
1238
1236
end
@@ -1242,33 +1240,33 @@ end
1242
1240
@test has_return_escape (result. state[Argument (3 )], r) # b
1243
1241
@test ! is_load_forwardable (result. state[SSAValue (i)]) # obj
1244
1242
end
1245
- let result = code_escapes ((String, String, Symbol)) do a, b, fld
1246
- obj = SafeRefs (" a" , " b" )
1243
+ let result = code_escapes ((Base . RefValue{ String}, Base . RefValue{ String} , Symbol)) do a, b, fld
1244
+ obj = SafeRefs (Ref ( " a" ), Ref ( " b" ) )
1247
1245
setfield! (obj, fld, a)
1248
1246
return obj[2 ] # should escape `a`
1249
1247
end
1250
- i = only (findall (isnew, result. ir. stmts. stmt))
1248
+ i = last (findall (isnew, result. ir. stmts. stmt))
1251
1249
r = only (findall (isreturn, result. ir. stmts. stmt))
1252
1250
@test has_return_escape (result. state[Argument (2 )], r) # a
1253
1251
@test ! has_return_escape (result. state[Argument (3 )], r) # b
1254
1252
@test ! is_load_forwardable (result. state[SSAValue (i)]) # obj
1255
1253
end
1256
- let result = code_escapes ((String, Symbol)) do a, fld
1257
- obj = SafeRefs (" a" , " b" )
1254
+ let result = code_escapes ((Base . RefValue{ String} , Symbol)) do a, fld
1255
+ obj = SafeRefs (Ref ( " a" ), Ref ( " b" ) )
1258
1256
setfield! (obj, fld, a)
1259
1257
return obj[1 ] # this should escape `a`
1260
1258
end
1261
- i = only (findall (isnew, result. ir. stmts. stmt))
1259
+ i = last (findall (isnew, result. ir. stmts. stmt))
1262
1260
r = only (findall (isreturn, result. ir. stmts. stmt))
1263
1261
@test has_return_escape (result. state[Argument (2 )], r) # a
1264
1262
@test ! is_load_forwardable (result. state[SSAValue (i)]) # obj
1265
1263
end
1266
- let result = code_escapes ((String, String, Int)) do a, b, idx
1267
- obj = SafeRefs (" a" , " b" )
1264
+ let result = code_escapes ((Base . RefValue{ String}, Base . RefValue{ String} , Int)) do a, b, idx
1265
+ obj = SafeRefs (Ref ( " a" ), Ref ( " b" ) )
1268
1266
obj[idx] = a
1269
1267
return obj[2 ] # should escape `a`
1270
1268
end
1271
- i = only (findall (isnew, result. ir. stmts. stmt))
1269
+ i = last (findall (isnew, result. ir. stmts. stmt))
1272
1270
r = only (findall (isreturn, result. ir. stmts. stmt))
1273
1271
@test has_return_escape (result. state[Argument (2 )], r) # a
1274
1272
@test ! has_return_escape (result. state[Argument (3 )], r) # b
@@ -1280,7 +1278,7 @@ end
1280
1278
1281
1279
let result = @eval EATModule () begin
1282
1280
@noinline getx (obj) = obj[]
1283
- $ code_escapes ((String,)) do a
1281
+ $ code_escapes ((Base . RefValue{ String} ,)) do a
1284
1282
obj = SafeRef (a)
1285
1283
fld = getx (obj)
1286
1284
return fld
@@ -1294,8 +1292,8 @@ end
1294
1292
end
1295
1293
1296
1294
# TODO interprocedural alias analysis
1297
- let result = code_escapes ((SafeRef{String},)) do s
1298
- s[] = " bar"
1295
+ let result = code_escapes ((SafeRef{Base . RefValue{ String} },)) do s
1296
+ s[] = Ref ( " bar" )
1299
1297
global GV = s[]
1300
1298
nothing
1301
1299
end
@@ -1335,7 +1333,7 @@ end
1335
1333
let result = @eval EATModule () begin
1336
1334
@noinline mysetindex! (x, a) = x[1 ] = a
1337
1335
const Ax = Vector {Any} (undef, 1 )
1338
- $ code_escapes ((String,)) do s
1336
+ $ code_escapes ((Base . RefValue{ String} ,)) do s
1339
1337
mysetindex! (Ax, s)
1340
1338
end
1341
1339
end
@@ -1391,11 +1389,11 @@ end
1391
1389
end
1392
1390
1393
1391
# handle conflicting field information correctly
1394
- let result = code_escapes ((Bool,String, String,)) do cnd, baz, qux
1392
+ let result = code_escapes ((Bool,Base . RefValue{ String},Base . RefValue{ String} ,)) do cnd, baz, qux
1395
1393
if cnd
1396
- o = SafeRef (" foo" )
1394
+ o = SafeRef (Ref ( " foo" ) )
1397
1395
else
1398
- o = SafeRefs (" bar" , baz)
1396
+ o = SafeRefs (Ref ( " bar" ) , baz)
1399
1397
r = getfield (o, 2 )
1400
1398
end
1401
1399
if cnd
@@ -1409,12 +1407,14 @@ end
1409
1407
@test has_return_escape (result. state[Argument (3 )], r) # baz
1410
1408
@test has_return_escape (result. state[Argument (4 )], r) # qux
1411
1409
for new in findall (isnew, result. ir. stmts. stmt)
1412
- @test is_load_forwardable (result. state[SSAValue (new)])
1410
+ if ! (result. ir[SSAValue (new)][:type ] <: Base.RefValue )
1411
+ @test is_load_forwardable (result. state[SSAValue (new)])
1412
+ end
1413
1413
end
1414
1414
end
1415
- let result = code_escapes ((Bool,String, String,)) do cnd, baz, qux
1415
+ let result = code_escapes ((Bool,Base . RefValue{ String},Base . RefValue{ String} ,)) do cnd, baz, qux
1416
1416
if cnd
1417
- o = SafeRefs (" foo" , " bar" )
1417
+ o = SafeRefs (Ref ( " foo" ), Ref ( " bar" ) )
1418
1418
r = setfield! (o, 2 , baz)
1419
1419
else
1420
1420
o = SafeRef (qux)
@@ -2141,9 +2141,9 @@ end
2141
2141
# propagate escapes imposed on call arguments
2142
2142
@noinline broadcast_noescape2 (b) = broadcast (identity, b)
2143
2143
let result = code_escapes () do
2144
- broadcast_noescape2 (Ref (" Hi" ))
2144
+ broadcast_noescape2 (Ref (Ref ( " Hi" ) ))
2145
2145
end
2146
- i = only (findall (isnew, result. ir. stmts. stmt))
2146
+ i = last (findall (isnew, result. ir. stmts. stmt))
2147
2147
@test_broken ! has_return_escape (result. state[SSAValue (i)]) # TODO interprocedural alias analysis
2148
2148
@test ! has_thrown_escape (result. state[SSAValue (i)])
2149
2149
end
0 commit comments