@@ -318,16 +318,12 @@ abstract class BarrierGuardNode extends DataFlow::Node {
318318 *
319319 * INTERNAL: this predicate should only be used from within `blocks(boolean, Expr)`.
320320 */
321- pragma [ noinline, nomagic]
322321 predicate internalBlocks ( DataFlow:: Node nd , string label ) {
323322 // 1) `nd` is a use of a refinement node that blocks its input variable
324323 exists ( SsaRefinementNode ref , boolean outcome |
325324 nd = DataFlow:: ssaDefinitionNode ( ref ) and
326- forex ( SsaVariable input | input = ref .getAnInput ( ) |
327- getEnclosingExpr ( ) = ref .getGuard ( ) .getTest ( ) and
328- outcome = ref .getGuard ( ) .( ConditionGuardNode ) .getOutcome ( ) and
329- barrierGuardBlocksExpr ( this , outcome , input .getAUse ( ) , label )
330- )
325+ outcome = ref .getGuard ( ) .( ConditionGuardNode ) .getOutcome ( ) and
326+ ssaRefinementBlocks ( outcome , ref , label )
331327 )
332328 or
333329 // 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p`
@@ -337,8 +333,21 @@ abstract class BarrierGuardNode extends DataFlow::Node {
337333 outcome = cond .getOutcome ( ) and
338334 barrierGuardBlocksAccessPath ( this , outcome , p , label ) and
339335 cond .dominates ( bb )
336+ )
337+ }
338+
339+ /**
340+ * Holds if there exists an input variable of `ref` that blocks the label `label`.
341+ *
342+ * This predicate is outlined to give the optimizer a hint about the join ordering.
343+ */
344+ private predicate ssaRefinementBlocks ( boolean outcome , SsaRefinementNode ref , string label ) {
345+ getEnclosingExpr ( ) = ref .getGuard ( ) .getTest ( ) and
346+ forex ( SsaVariable input | input = ref .getAnInput ( ) |
347+ barrierGuardBlocksExpr ( this , outcome , input .getAUse ( ) , label )
340348 )
341349 }
350+
342351
343352 /**
344353 * Holds if this node blocks expression `e` provided it evaluates to `outcome`.
0 commit comments