@@ -1483,6 +1483,15 @@ module Make<
14831483 */
14841484 default predicate includeWriteDefsInFlowStep ( ) { any ( ) }
14851485
1486+ /**
1487+ * Holds if phi definitions should always have a data flow node, even when
1488+ * they have a unique next reference. This is useful for language-specific
1489+ * APIs that expose a node for each SSA definition.
1490+ *
1491+ * Phi reads may still be skipped.
1492+ */
1493+ default predicate includePhiDefsInFlowStep ( ) { none ( ) }
1494+
14861495 /**
14871496 * Holds if barrier guards should be supported on input edges to phi
14881497 * nodes. Disable this only if barrier guards are not going to be used.
@@ -1540,9 +1549,20 @@ module Make<
15401549 )
15411550 }
15421551
1552+ private Definition getAValuePreservingInputDef ( Definition def ) {
1553+ result = def
1554+ or
1555+ exists ( Definition inp |
1556+ DfInput:: allowFlowIntoUncertainDef ( def ) and
1557+ not DfInput:: ssaDefHasSource ( def ) and
1558+ uncertainWriteDefinitionInput ( def , inp ) and
1559+ result = getAValuePreservingInputDef ( inp )
1560+ )
1561+ }
1562+
15431563 pragma [ nomagic]
15441564 private predicate phiInputHasRead ( SsaPhiExt phi , BasicBlock input ) {
1545- exists ( DfInput:: getARead ( getAPhiInputDef ( phi , input ) ) )
1565+ exists ( DfInput:: getARead ( getAValuePreservingInputDef ( getAPhiInputDef ( phi , input ) ) ) )
15461566 }
15471567
15481568 /** Holds if `bb` is the target end of a branch edge of a guard and the guard controls `bb`. */
@@ -1667,6 +1687,7 @@ module Make<
16671687 * flow edges.
16681688 */
16691689 private predicate phiHasUniqNextNode ( SsaPhiExt phi ) {
1690+ not ( phi instanceof PhiNode and DfInput:: includePhiDefsInFlowStep ( ) ) and
16701691 not relevantBackEdge ( phi , _) and
16711692 exists ( int nextPhiInput , int nextPhi , int nextRef |
16721693 1 = nextPhiInput + nextPhi + nextRef and
@@ -2119,7 +2140,7 @@ module Make<
21192140 private predicate guardChecksSsaDef (
21202141 DfInput:: Guard g , Definition def , DfInput:: GuardValue val , State state
21212142 ) {
2122- guardChecks ( g , DfInput:: getARead ( def ) , val , state )
2143+ guardChecks ( g , DfInput:: getARead ( getAValuePreservingInputDef ( def ) ) , val , state )
21232144 }
21242145
21252146 private module Barrier = BarrierGuardDefWithState< State , guardChecksSsaDef / 4 > ;
0 commit comments