@@ -174,34 +174,15 @@ private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) {
174174}
175175
176176cached
177- private module Cached {
178- cached
179- newtype TDefinition =
180- TWriteDef ( SourceVariable v , BasicBlock bb , int i ) {
181- variableWrite ( bb , i , v , _) and
182- liveAfterWrite ( bb , i , v )
183- } or
184- TPhiNode ( SourceVariable v , BasicBlock bb ) {
185- inDefDominanceFrontier ( bb , v ) and
186- liveAtEntry ( bb , v )
187- }
188-
189- cached
190- predicate uncertainWriteDefinitionInput ( UncertainWriteDefinition def , Definition inp ) {
191- lastRefRedef ( inp , _, _, def )
192- }
193-
194- cached
195- predicate phiHasInputFromBlock ( PhiNode phi , Definition inp , BasicBlock bb ) {
196- exists ( SourceVariable v , BasicBlock bbDef |
197- phi .definesAt ( v , bbDef , _) and
198- getABasicBlockPredecessor ( bbDef ) = bb and
199- ssaDefReachesEndOfBlock ( bb , inp , v )
200- )
177+ newtype TDefinition =
178+ TWriteDef ( SourceVariable v , BasicBlock bb , int i ) {
179+ variableWrite ( bb , i , v , _) and
180+ liveAfterWrite ( bb , i , v )
181+ } or
182+ TPhiNode ( SourceVariable v , BasicBlock bb ) {
183+ inDefDominanceFrontier ( bb , v ) and
184+ liveAtEntry ( bb , v )
201185 }
202- }
203-
204- import Cached
205186
206187private module SsaDefReaches {
207188 newtype TSsaRefKind =
@@ -406,6 +387,20 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable
406387 not ssaRef ( bb , _, v , SsaDef ( ) )
407388}
408389
390+ /**
391+ * NB: If this predicate is exposed, it should be cached.
392+ *
393+ * Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`.
394+ */
395+ pragma [ nomagic]
396+ predicate phiHasInputFromBlock ( PhiNode phi , Definition inp , BasicBlock bb ) {
397+ exists ( SourceVariable v , BasicBlock bbDef |
398+ phi .definesAt ( v , bbDef , _) and
399+ getABasicBlockPredecessor ( bbDef ) = bb and
400+ ssaDefReachesEndOfBlock ( bb , inp , v )
401+ )
402+ }
403+
409404/**
410405 * NB: If this predicate is exposed, it should be cached.
411406 *
@@ -446,7 +441,11 @@ private predicate adjacentDefReachesRead(
446441 Definition def , BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2
447442) {
448443 adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
449- not variableRead ( bb1 , i1 , def .getSourceVariable ( ) , false )
444+ exists ( SourceVariable v | v = def .getSourceVariable ( ) |
445+ ssaRef ( bb1 , i1 , v , SsaDef ( ) )
446+ or
447+ variableRead ( bb1 , i1 , v , true )
448+ )
450449 or
451450 exists ( BasicBlock bb3 , int i3 |
452451 adjacentDefReachesRead ( def , bb1 , i1 , bb3 , i3 ) and
@@ -490,6 +489,18 @@ predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
490489 )
491490}
492491
492+ /**
493+ * NB: If this predicate is exposed, it should be cached.
494+ *
495+ * Holds if `inp` is an immediately preceding definition of uncertain definition
496+ * `def`. Since `def` is uncertain, the value from the preceding definition might
497+ * still be valid.
498+ */
499+ pragma [ nomagic]
500+ predicate uncertainWriteDefinitionInput ( UncertainWriteDefinition def , Definition inp ) {
501+ lastRefRedef ( inp , _, _, def )
502+ }
503+
493504private predicate adjacentDefReachesUncertainRead (
494505 Definition def , BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2
495506) {
@@ -574,24 +585,6 @@ class Definition extends TDefinition {
574585 /** Gets the basic block to which this SSA definition belongs. */
575586 final BasicBlock getBasicBlock ( ) { this .definesAt ( _, result , _) }
576587
577- /**
578- * Gets an SSA definition whose value can flow to this one in one step. This
579- * includes inputs to phi nodes and the prior definitions of uncertain writes.
580- */
581- private Definition getAPseudoInputOrPriorDefinition ( ) {
582- result = this .( PhiNode ) .getAnInput ( ) or
583- result = this .( UncertainWriteDefinition ) .getPriorDefinition ( )
584- }
585-
586- /**
587- * Gets a definition that ultimately defines this SSA definition and is
588- * not itself a phi node.
589- */
590- Definition getAnUltimateDefinition ( ) {
591- result = this .getAPseudoInputOrPriorDefinition * ( ) and
592- not result instanceof PhiNode
593- }
594-
595588 /** Gets a textual representation of this SSA definition. */
596589 string toString ( ) { none ( ) }
597590}
@@ -609,12 +602,6 @@ class WriteDefinition extends Definition, TWriteDef {
609602
610603/** A phi node. */
611604class PhiNode extends Definition , TPhiNode {
612- /** Gets an input of this phi node. */
613- Definition getAnInput ( ) { this .hasInputFromBlock ( result , _) }
614-
615- /** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
616- predicate hasInputFromBlock ( Definition inp , BasicBlock bb ) { phiHasInputFromBlock ( this , inp , bb ) }
617-
618605 override string toString ( ) { result = "Phi" }
619606}
620607
@@ -629,10 +616,4 @@ class UncertainWriteDefinition extends WriteDefinition {
629616 variableWrite ( bb , i , v , false )
630617 )
631618 }
632-
633- /**
634- * Gets the immediately preceding definition. Since this update is uncertain,
635- * the value from the preceding definition might still be valid.
636- */
637- Definition getPriorDefinition ( ) { uncertainWriteDefinitionInput ( this , result ) }
638619}
0 commit comments