@@ -1067,6 +1067,59 @@ private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::Sou
1067
1067
capturedReadIn ( bb , i , v , _, _, _)
1068
1068
}
1069
1069
1070
+ pragma [ noinline]
1071
+ private predicate adjacentDefRead (
1072
+ Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2 ,
1073
+ SsaInput:: SourceVariable v
1074
+ ) {
1075
+ adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
1076
+ v = def .getSourceVariable ( )
1077
+ }
1078
+
1079
+ private predicate adjacentDefReachesRead (
1080
+ Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2
1081
+ ) {
1082
+ exists ( SsaInput:: SourceVariable v | adjacentDefRead ( def , bb1 , i1 , bb2 , i2 , v ) |
1083
+ def .definesAt ( v , bb1 , i1 )
1084
+ or
1085
+ SsaInput:: variableRead ( bb1 , i1 , v , true )
1086
+ )
1087
+ or
1088
+ exists ( SsaInput:: BasicBlock bb3 , int i3 |
1089
+ adjacentDefReachesRead ( def , bb1 , i1 , bb3 , i3 ) and
1090
+ SsaInput:: variableRead ( bb3 , i3 , _, false ) and
1091
+ adjacentDefRead ( def , bb3 , i3 , bb2 , i2 )
1092
+ )
1093
+ }
1094
+
1095
+ /** Same as `adjacentDefRead`, but skips uncertain reads. */
1096
+ pragma [ nomagic]
1097
+ private predicate adjacentDefSkipUncertainReads (
1098
+ Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2
1099
+ ) {
1100
+ adjacentDefReachesRead ( def , bb1 , i1 , bb2 , i2 ) and
1101
+ SsaInput:: variableRead ( bb2 , i2 , _, true )
1102
+ }
1103
+
1104
+ private predicate adjacentDefReachesUncertainRead (
1105
+ Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2
1106
+ ) {
1107
+ adjacentDefReachesRead ( def , bb1 , i1 , bb2 , i2 ) and
1108
+ SsaInput:: variableRead ( bb2 , i2 , _, false )
1109
+ }
1110
+
1111
+ /** Same as `lastRefRedef`, but skips uncertain reads. */
1112
+ pragma [ nomagic]
1113
+ private predicate lastRefSkipUncertainReads ( Definition def , SsaInput:: BasicBlock bb , int i ) {
1114
+ lastRef ( def , bb , i ) and
1115
+ not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
1116
+ or
1117
+ exists ( SsaInput:: BasicBlock bb0 , int i0 |
1118
+ lastRef ( def , bb0 , i0 ) and
1119
+ adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
1120
+ )
1121
+ }
1122
+
1070
1123
cached
1071
1124
private module Cached {
1072
1125
cached
@@ -1237,7 +1290,7 @@ private module Cached {
1237
1290
predicate firstReadSameVar ( Definition def , ControlFlow:: Node cfn ) {
1238
1291
exists ( ControlFlow:: BasicBlock bb1 , int i1 , ControlFlow:: BasicBlock bb2 , int i2 |
1239
1292
def .definesAt ( _, bb1 , i1 ) and
1240
- adjacentDefNoUncertainReads ( def , bb1 , i1 , bb2 , i2 ) and
1293
+ adjacentDefSkipUncertainReads ( def , bb1 , i1 , bb2 , i2 ) and
1241
1294
cfn = bb2 .getNode ( i2 )
1242
1295
)
1243
1296
}
@@ -1252,20 +1305,27 @@ private module Cached {
1252
1305
exists ( ControlFlow:: BasicBlock bb1 , int i1 , ControlFlow:: BasicBlock bb2 , int i2 |
1253
1306
cfn1 = bb1 .getNode ( i1 ) and
1254
1307
variableReadActual ( bb1 , i1 , _) and
1255
- adjacentDefNoUncertainReads ( def , bb1 , i1 , bb2 , i2 ) and
1308
+ adjacentDefSkipUncertainReads ( def , bb1 , i1 , bb2 , i2 ) and
1256
1309
cfn2 = bb2 .getNode ( i2 )
1257
1310
)
1258
1311
}
1259
1312
1313
+ /** Same as `lastRefRedef`, but skips uncertain reads. */
1260
1314
cached
1261
1315
predicate lastRefBeforeRedef ( Definition def , ControlFlow:: BasicBlock bb , int i , Definition next ) {
1262
- lastRefRedefNoUncertainReads ( def , bb , i , next )
1316
+ lastRefRedef ( def , bb , i , next ) and
1317
+ not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
1318
+ or
1319
+ exists ( SsaInput:: BasicBlock bb0 , int i0 |
1320
+ lastRefRedef ( def , bb0 , i0 , next ) and
1321
+ adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
1322
+ )
1263
1323
}
1264
1324
1265
1325
cached
1266
1326
predicate lastReadSameVar ( Definition def , ControlFlow:: Node cfn ) {
1267
1327
exists ( ControlFlow:: BasicBlock bb , int i |
1268
- lastRefNoUncertainReads ( def , bb , i ) and
1328
+ lastRefSkipUncertainReads ( def , bb , i ) and
1269
1329
variableReadActual ( bb , i , _) and
1270
1330
cfn = bb .getNode ( i )
1271
1331
)
0 commit comments