@@ -443,9 +443,28 @@ private module SsaComputeImpl {
443443 )
444444 }
445445
446+ /**
447+ * Holds if `use1` and `use2` form an adjacent use-use-pair of the same
448+ * `SsaSourceVariable`, that is, the value read in `use1` can reach `use2`
449+ * without passing through any other use or any SSA definition of the variable
450+ * except for phi nodes.
451+ */
452+ cached
453+ predicate adjacentUseUse ( ControlFlowNode use1 , ControlFlowNode use2 ) {
454+ adjacentUseUseSameVar ( use1 , use2 )
455+ or
456+ exists ( SsaSourceVariable v , EssaDefinition def , BasicBlock b1 , int i1 , BasicBlock b2 , int i2 |
457+ adjacentVarRefs ( v , b1 , i1 , b2 , i2 ) and
458+ variableUse ( v , use1 , b1 , i1 ) and
459+ definesAt ( def , v , b2 , i2 ) and
460+ firstUse ( def , use2 ) and
461+ def instanceof PhiFunction
462+ )
463+ }
464+
446465 /**
447466 * Holds if the value defined at `def` can reach `use` without passing through
448- * any other uses, but possibly through phi nodes and uncertain implicit updates .
467+ * any other uses, but possibly through phi nodes.
449468 */
450469 cached
451470 predicate firstUse ( EssaDefinition def , ControlFlowNode use ) {
@@ -482,6 +501,19 @@ private module SsaComputeImpl {
482501 b = def .( PhiFunction ) .getBasicBlock ( ) and
483502 i = - 1
484503 }
504+
505+ /**
506+ * Holds if the value defined at `def` can reach `use`, possibly through phi nodes.
507+ */
508+ cached
509+ predicate aUse ( EssaDefinition def , ControlFlowNode use ) {
510+ firstUse ( def , use )
511+ or
512+ exists ( ControlFlowNode firstUse |
513+ firstUse ( def , firstUse ) and
514+ adjacentUseUse ( firstUse , use )
515+ )
516+ }
485517 }
486518}
487519
0 commit comments