@@ -1307,11 +1307,14 @@ module Make<LocationSig Location, InputSig<Location> Input> {
13071307 /** An SSA definition into which another SSA definition may flow. */
13081308 private class SsaInputDefinitionExt extends DefinitionExtFinal {
13091309 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+ )
13151318 }
13161319
13171320 /** Holds if `def` may flow into this definition via basic block `input`. */
@@ -1324,30 +1327,45 @@ module Make<LocationSig Location, InputSig<Location> Input> {
13241327
13251328 private module Cached {
13261329 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+ }
13391339
13401340 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 )
13461343 }
13471344 }
13481345
13491346 private import Cached
13501347
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+
13511369 /**
13521370 * A data flow node that we need to reference in the value step relation.
13531371 *
@@ -1627,6 +1645,14 @@ module Make<LocationSig Location, InputSig<Location> Input> {
16271645 */
16281646 signature predicate guardChecksSig ( DfInput:: Guard g , DfInput:: Expr e , boolean branch ) ;
16291647
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+
16301656 /**
16311657 * Provides a set of barrier nodes for a guard that validates an expression.
16321658 *
0 commit comments