@@ -1307,11 +1307,14 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1307
1307
/** An SSA definition into which another SSA definition may flow. */
1308
1308
private class SsaInputDefinitionExt extends DefinitionExtFinal {
1309
1309
SsaInputDefinitionExt ( ) {
1310
- this instanceof PhiNode
1311
- or
1312
- this instanceof PhiReadNode
1313
- or
1314
- DfInput:: allowFlowIntoUncertainDef ( this )
1310
+ hasCertainRead ( this ) and
1311
+ (
1312
+ this instanceof PhiNode
1313
+ or
1314
+ this instanceof PhiReadNode
1315
+ or
1316
+ DfInput:: allowFlowIntoUncertainDef ( this )
1317
+ )
1315
1318
}
1316
1319
1317
1320
/** Holds if `def` may flow into this definition via basic block `input`. */
@@ -1324,30 +1327,45 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1324
1327
1325
1328
private module Cached {
1326
1329
cached
1327
- newtype TNode =
1328
- TParamNode ( DfInput:: Parameter p ) { DfInput:: ssaDefInitializesParam ( _, p ) } or
1329
- TExprNode ( DfInput:: Expr e , Boolean isPost ) {
1330
- e = DfInput:: getARead ( _)
1331
- or
1332
- DfInput:: ssaDefAssigns ( _, e ) and
1333
- isPost = false
1334
- } or
1335
- TSsaDefinitionNode ( DefinitionExt def ) or
1336
- TSsaInputNode ( SsaInputDefinitionExt def , BasicBlock input ) {
1337
- def .hasInputFromBlock ( _, _, _, _, input )
1338
- }
1330
+ predicate hasCertainRead ( DefinitionExt def ) {
1331
+ exists ( SourceVariable v , BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 |
1332
+ def .definesAt ( v , bb1 , i1 , _) and
1333
+ adjacentDefSkipUncertainReadsExt ( def , v , bb1 , i1 , bb2 , i2 ) and
1334
+ variableRead ( bb2 , i2 , v , true )
1335
+ )
1336
+ or
1337
+ def = getAPhiInputDef ( _, _)
1338
+ }
1339
1339
1340
1340
cached
1341
- Definition getAPhiInputDef ( SsaInputNode n ) {
1342
- exists ( SsaInputDefinitionExt phi , BasicBlock bb |
1343
- phi .hasInputFromBlock ( result , _, _, _, bb ) and
1344
- n .isInputInto ( phi , bb )
1345
- )
1341
+ DefinitionExt getAPhiInputDef ( SsaInputDefinitionExt phi , BasicBlock bb ) {
1342
+ phi .hasInputFromBlock ( result , _, _, _, bb )
1346
1343
}
1347
1344
}
1348
1345
1349
1346
private import Cached
1350
1347
1348
+ private newtype TNode =
1349
+ TParamNode ( DfInput:: Parameter p ) {
1350
+ exists ( WriteDefinition def |
1351
+ DfInput:: ssaDefInitializesParam ( def , p ) and
1352
+ hasCertainRead ( def )
1353
+ )
1354
+ } or
1355
+ TExprNode ( DfInput:: Expr e , Boolean isPost ) {
1356
+ e = DfInput:: getARead ( _)
1357
+ or
1358
+ exists ( DefinitionExt def |
1359
+ DfInput:: ssaDefAssigns ( def , e ) and
1360
+ hasCertainRead ( def ) and
1361
+ isPost = false
1362
+ )
1363
+ } or
1364
+ TSsaDefinitionNode ( DefinitionExt def ) { hasCertainRead ( def ) } or
1365
+ TSsaInputNode ( SsaInputDefinitionExt phi , BasicBlock input ) {
1366
+ exists ( getAPhiInputDef ( phi , input ) )
1367
+ }
1368
+
1351
1369
/**
1352
1370
* A data flow node that we need to reference in the value step relation.
1353
1371
*
@@ -1627,6 +1645,14 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1627
1645
*/
1628
1646
signature predicate guardChecksSig ( DfInput:: Guard g , DfInput:: Expr e , boolean branch ) ;
1629
1647
1648
+ pragma [ nomagic]
1649
+ private Definition getAPhiInputDef ( SsaInputNode n ) {
1650
+ exists ( SsaInputDefinitionExt phi , BasicBlock bb |
1651
+ result = getAPhiInputDef ( phi , bb ) and
1652
+ n .isInputInto ( phi , bb )
1653
+ )
1654
+ }
1655
+
1630
1656
/**
1631
1657
* Provides a set of barrier nodes for a guard that validates an expression.
1632
1658
*
0 commit comments