@@ -49,7 +49,23 @@ private module SsaInput implements SsaImplCommon::InputSig {
49
49
}
50
50
}
51
51
52
- import SsaImplCommon:: Make< SsaInput >
52
+ private import SsaImplCommon:: Make< SsaInput > as Impl
53
+
54
+ class Definition = Impl:: Definition ;
55
+
56
+ class WriteDefinition = Impl:: WriteDefinition ;
57
+
58
+ class UncertainWriteDefinition = Impl:: UncertainWriteDefinition ;
59
+
60
+ class PhiNode = Impl:: PhiNode ;
61
+
62
+ module Consistency = Impl:: Consistency;
63
+
64
+ module ExposedForTestingOnly {
65
+ predicate ssaDefReachesReadExt = Impl:: ssaDefReachesReadExt / 4 ;
66
+
67
+ predicate phiHasInputFromBlockExt = Impl:: phiHasInputFromBlockExt / 3 ;
68
+ }
53
69
54
70
/**
55
71
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
@@ -1072,7 +1088,7 @@ private predicate adjacentDefRead(
1072
1088
Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2 ,
1073
1089
SsaInput:: SourceVariable v
1074
1090
) {
1075
- adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
1091
+ Impl :: adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
1076
1092
v = def .getSourceVariable ( )
1077
1093
}
1078
1094
@@ -1088,7 +1104,7 @@ private predicate adjacentDefReachesRead(
1088
1104
exists ( SsaInput:: BasicBlock bb3 , int i3 |
1089
1105
adjacentDefReachesRead ( def , bb1 , i1 , bb3 , i3 ) and
1090
1106
SsaInput:: variableRead ( bb3 , i3 , _, false ) and
1091
- adjacentDefRead ( def , bb3 , i3 , bb2 , i2 )
1107
+ Impl :: adjacentDefRead ( def , bb3 , i3 , bb2 , i2 )
1092
1108
)
1093
1109
}
1094
1110
@@ -1111,11 +1127,11 @@ private predicate adjacentDefReachesUncertainRead(
1111
1127
/** Same as `lastRefRedef`, but skips uncertain reads. */
1112
1128
pragma [ nomagic]
1113
1129
private predicate lastRefSkipUncertainReads ( Definition def , SsaInput:: BasicBlock bb , int i ) {
1114
- lastRef ( def , bb , i ) and
1130
+ Impl :: lastRef ( def , bb , i ) and
1115
1131
not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
1116
1132
or
1117
1133
exists ( SsaInput:: BasicBlock bb0 , int i0 |
1118
- lastRef ( def , bb0 , i0 ) and
1134
+ Impl :: lastRef ( def , bb0 , i0 ) and
1119
1135
adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
1120
1136
)
1121
1137
}
@@ -1237,7 +1253,7 @@ private module Cached {
1237
1253
v = def .getSourceVariable ( ) and
1238
1254
capturedReadIn ( _, _, v , edef .getSourceVariable ( ) , c , additionalCalls ) and
1239
1255
def = def0 .getAnUltimateDefinition ( ) and
1240
- ssaDefReachesRead ( _, def0 , bb , i ) and
1256
+ Impl :: ssaDefReachesRead ( _, def0 , bb , i ) and
1241
1257
capturedReadIn ( bb , i , v , _, _, _) and
1242
1258
c = bb .getNode ( i )
1243
1259
)
@@ -1264,18 +1280,18 @@ private module Cached {
1264
1280
1265
1281
cached
1266
1282
predicate isLiveAtEndOfBlock ( Definition def , ControlFlow:: BasicBlock bb ) {
1267
- ssaDefReachesEndOfBlock ( bb , def , _)
1283
+ Impl :: ssaDefReachesEndOfBlock ( bb , def , _)
1268
1284
}
1269
1285
1270
1286
cached
1271
- Definition phiHasInputFromBlock ( PhiNode phi , ControlFlow:: BasicBlock bb ) {
1272
- phiHasInputFromBlock ( phi , result , bb )
1287
+ Definition phiHasInputFromBlock ( Ssa :: PhiNode phi , ControlFlow:: BasicBlock bb ) {
1288
+ Impl :: phiHasInputFromBlock ( phi , result , bb )
1273
1289
}
1274
1290
1275
1291
cached
1276
1292
AssignableRead getAReadAtNode ( Definition def , ControlFlow:: Node cfn ) {
1277
1293
exists ( Ssa:: SourceVariable v , ControlFlow:: BasicBlock bb , int i |
1278
- ssaDefReachesRead ( v , def , bb , i ) and
1294
+ Impl :: ssaDefReachesRead ( v , def , bb , i ) and
1279
1295
variableReadActual ( bb , i , v ) and
1280
1296
cfn = bb .getNode ( i ) and
1281
1297
result .getAControlFlowNode ( ) = cfn
@@ -1313,11 +1329,11 @@ private module Cached {
1313
1329
/** Same as `lastRefRedef`, but skips uncertain reads. */
1314
1330
cached
1315
1331
predicate lastRefBeforeRedef ( Definition def , ControlFlow:: BasicBlock bb , int i , Definition next ) {
1316
- lastRefRedef ( def , bb , i , next ) and
1332
+ Impl :: lastRefRedef ( def , bb , i , next ) and
1317
1333
not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
1318
1334
or
1319
1335
exists ( SsaInput:: BasicBlock bb0 , int i0 |
1320
- lastRefRedef ( def , bb0 , i0 , next ) and
1336
+ Impl :: lastRefRedef ( def , bb0 , i0 , next ) and
1321
1337
adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
1322
1338
)
1323
1339
}
@@ -1333,7 +1349,7 @@ private module Cached {
1333
1349
1334
1350
cached
1335
1351
Definition uncertainWriteDefinitionInput ( UncertainWriteDefinition def ) {
1336
- uncertainWriteDefinitionInput ( def , result )
1352
+ Impl :: uncertainWriteDefinitionInput ( def , result )
1337
1353
}
1338
1354
1339
1355
cached
@@ -1343,10 +1359,57 @@ private module Cached {
1343
1359
v = def .getSourceVariable ( ) and
1344
1360
p = v .getAssignable ( ) and
1345
1361
def = def0 .getAnUltimateDefinition ( ) and
1346
- ssaDefReachesRead ( _, def0 , bb , i ) and
1362
+ Impl :: ssaDefReachesRead ( _, def0 , bb , i ) and
1347
1363
outRefExitRead ( bb , i , v )
1348
1364
)
1349
1365
}
1350
1366
}
1351
1367
1352
1368
import Cached
1369
+
1370
+ private string getSplitString ( DefinitionExt def ) {
1371
+ exists ( ControlFlow:: BasicBlock bb , int i , ControlFlow:: Node cfn |
1372
+ def .definesAt ( _, bb , i , _) and
1373
+ result = cfn .( ControlFlow:: Nodes:: ElementNode ) .getSplitsString ( )
1374
+ |
1375
+ cfn = bb .getNode ( i )
1376
+ or
1377
+ not exists ( bb .getNode ( i ) ) and
1378
+ cfn = bb .getFirstNode ( )
1379
+ )
1380
+ }
1381
+
1382
+ string getToStringPrefix ( DefinitionExt def ) {
1383
+ result = "[" + getSplitString ( def ) + "] "
1384
+ or
1385
+ not exists ( getSplitString ( def ) ) and
1386
+ result = ""
1387
+ }
1388
+
1389
+ /**
1390
+ * An extended static single assignment (SSA) definition.
1391
+ *
1392
+ * This is either a normal SSA definition (`Definition`) or a
1393
+ * phi-read node (`PhiReadNode`).
1394
+ *
1395
+ * Only intended for internal use.
1396
+ */
1397
+ class DefinitionExt extends Impl:: DefinitionExt {
1398
+ override string toString ( ) { result = this .( Ssa:: Definition ) .toString ( ) }
1399
+
1400
+ /** Gets the location of this definition. */
1401
+ Location getLocation ( ) { result = this .( Ssa:: Definition ) .getLocation ( ) }
1402
+ }
1403
+
1404
+ /**
1405
+ * A phi-read node.
1406
+ *
1407
+ * Only intended for internal use.
1408
+ */
1409
+ class PhiReadNode extends DefinitionExt , Impl:: PhiReadNode {
1410
+ override string toString ( ) {
1411
+ result = getToStringPrefix ( this ) + "SSA phi read(" + this .getSourceVariable ( ) + ")"
1412
+ }
1413
+
1414
+ override Location getLocation ( ) { result = this .getBasicBlock ( ) .getLocation ( ) }
1415
+ }
0 commit comments