SSA: Improve performance of finding relevant phi input nodes.

This commit is contained in:
Anders Schack-Mulligen
2026-01-08 15:02:34 +01:00
parent 22b88aea06
commit af5adbac30

View File

@@ -2081,6 +2081,54 @@ module Make<
)
}
pragma[nomagic]
private predicate phiInputHasRead(SsaPhiExt phi, BasicBlock input) {
exists(DfInput::getARead(getAPhiInputDef(phi, input)))
}
/** Holds if `bb` is the target end of a branch edge of a guard and the guard controls `bb`. */
pragma[nomagic]
private predicate guardControlledBranchTarget(BasicBlock bb) {
exists(BasicBlock guard |
any(DfInput::Guard g).hasValueBranchEdge(guard, bb, _) and
dominatingEdge(guard, bb)
)
}
/**
* Holds if `prev` is the block containing the unique predecessor of `phi`
* that reaches `phi` through the input block `input`, and that `mid` is a
* block in the dominator tree between `prev` and `input` that is
* guard-equivalent with `input` in the sense that the set of guards
* controlling `mid` is the same as the set of guards controlling `input`.
*
* This is restricted to phi inputs that are actually read.
*/
private predicate phiInputGuardEquivalenceReaches(
BasicBlock prev, BasicBlock mid, SsaPhiExt phi, BasicBlock input
) {
phiInputHasRead(phi, input) and
AdjacentSsaRefs::adjacentRefPhi(prev, _, input, phi.getBasicBlock(), phi.getSourceVariable()) and
mid = input
or
exists(BasicBlock mid0 |
phiInputGuardEquivalenceReaches(prev, mid0, phi, input) and
not guardControlledBranchTarget(mid0) and
mid0 != prev and
mid = mid0.getImmediateDominator()
)
}
/**
* Holds if the immediately preceding reference to the input to `phi` from
* the block `input` is guard-equivalent with `input`.
*
* This is restricted to phi inputs that are actually read.
*/
private predicate phiInputIsGuardEquivalentWithPreviousRef(SsaPhiExt phi, BasicBlock input) {
exists(BasicBlock prev | phiInputGuardEquivalenceReaches(prev, prev, phi, input))
}
/**
* Holds if the input to `phi` from the block `input` might be relevant for
* barrier guards as a separately synthesized `TSsaInputNode`.
@@ -2095,7 +2143,7 @@ module Make<
or
DfInput::supportBarrierGuardsOnPhiEdges() and
// If the input isn't explicitly read then a guard cannot check it.
exists(DfInput::getARead(getAPhiInputDef(phi, input))) and
phiInputHasRead(phi, input) and
(
// The input node is relevant either if it sits directly on a branch
// edge for a guard,
@@ -2114,15 +2162,19 @@ module Make<
// }
// // phi-read node for `x`
// ```
exists(BasicBlock prev |
AdjacentSsaRefs::adjacentRefPhi(prev, _, input, phi.getBasicBlock(),
phi.getSourceVariable()) and
prev != input and
exists(DfInput::Guard g, DfInput::GuardValue val |
DfInput::guardDirectlyControlsBlock(g, input, val) and
not DfInput::guardDirectlyControlsBlock(g, prev, val)
)
)
not phiInputIsGuardEquivalentWithPreviousRef(phi, input)
// An equivalent, but less performant, way to express this is as follows:
// ```
// exists(BasicBlock prev |
// AdjacentSsaRefs::adjacentRefPhi(prev, _, input, phi.getBasicBlock(),
// phi.getSourceVariable()) and
// prev != input and
// exists(DfInput::Guard g, DfInput::GuardValue val |
// DfInput::guardDirectlyControlsBlock(g, input, val) and
// not DfInput::guardDirectlyControlsBlock(g, prev, val)
// )
// )
// ```
)
}