@@ -431,16 +431,40 @@ private module SsaComputeImpl {
431431 defSourceUseRank(v, b2, 1, i2)
432432 }
433433
434+ /**
435+ * Holds if `use1` is a use of the variable `v`, and there exists an adjacent reference to `v`
436+ * in basic block `b1` at index `i1`.
437+ *
438+ * A helper predicate for `adjacentUseUseSameVar`, to prevent the first join from being between
439+ * the two instances of `variableSourceUse` in
440+ * ```ql
441+ * exists(SsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
442+ * adjacentVarRefs(v, b1, i1, b2, i2) and
443+ * variableSourceUse(v, use1, b1, i1) and
444+ * variableSourceUse(v, use2, b2, i2)
445+ * )
446+ * ```
447+ */
448+ pragma[nomagic]
449+ cached
450+ private predicate adjacentRefUse(
451+ SsaSourceVariable v, BasicBlock b2, int i2, ControlFlowNode use1
452+ ) {
453+ exists(BasicBlock b1, int i1 |
454+ adjacentVarRefs(v, b1, i1, b2, i2) and
455+ variableSourceUse(v, use1, b1, i1)
456+ )
457+ }
458+
434459 /**
435460 * Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
436461 * variable, that is, the value read in `use1` can reach `use2` without passing
437462 * through any other use or any SSA definition of the variable.
438463 */
439464 cached
440465 predicate adjacentUseUseSameVar(ControlFlowNode use1, ControlFlowNode use2) {
441- exists(SsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
442- adjacentVarRefs(v, b1, i1, b2, i2) and
443- variableSourceUse(v, use1, b1, i1) and
466+ exists(SsaSourceVariable v, BasicBlock b2, int i2 |
467+ adjacentRefUse(v, b2, i2, use1) and
444468 variableSourceUse(v, use2, b2, i2)
445469 )
446470 }
0 commit comments