Skip to content

Commit ea08c60

Browse files
committed
SSA: Copy 3 predicates from the outer scope verbatim into the new Reaches module.
1 parent 613323e commit ea08c60

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

shared/ssa/codeql/ssa/Ssa.qll

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,37 @@ module Make<LocationSig Location, InputSig<Location> Input> {
436436
rnk = ssaRefRank(bb, _, v, SsaActualRead())
437437
}
438438

439+
pragma[nomagic]
440+
predicate liveThroughExt(BasicBlock bb, SourceVariable v) {
441+
liveAtExit(bb, v) and
442+
not ssaRef(bb, _, v, ssaDefExt())
443+
}
444+
445+
/**
446+
* NB: If this predicate is exposed, it should be cached.
447+
*
448+
* Holds if the SSA definition of `v` at `def` reaches the end of basic
449+
* block `bb`, at which point it is still live, without crossing another
450+
* SSA definition of `v`.
451+
*/
452+
pragma[nomagic]
453+
predicate ssaDefReachesEndOfBlockExt(BasicBlock bb, DefinitionExt def, SourceVariable v) {
454+
exists(int last |
455+
last = maxSsaRefRank(pragma[only_bind_into](bb), pragma[only_bind_into](v)) and
456+
ssaDefReachesRank(bb, def, last, v) and
457+
liveAtExit(bb, v)
458+
)
459+
or
460+
// The construction of SSA form ensures that each read of a variable is
461+
// dominated by its definition. An SSA definition therefore reaches a
462+
// control flow node if it is the _closest_ SSA definition that dominates
463+
// the node. If two definitions dominate a node then one must dominate the
464+
// other, so therefore the definition of _closest_ is given by the dominator
465+
// tree. Thus, reaching definitions can be calculated in terms of dominance.
466+
ssaDefReachesEndOfBlockExt(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
467+
liveThroughExt(bb, pragma[only_bind_into](v))
468+
}
469+
439470
/**
440471
* Holds if the SSA definition of `v` at `def` reaches index `i` in the same
441472
* basic block `bb`, without crossing another SSA definition of `v`.
@@ -446,6 +477,21 @@ module Make<LocationSig Location, InputSig<Location> Input> {
446477
rnk = ssaRefRank(bb, i, v, SsaActualRead())
447478
)
448479
}
480+
481+
/**
482+
* NB: If this predicate is exposed, it should be cached.
483+
*
484+
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
485+
* basic block `bb`, without crossing another SSA definition of `v`.
486+
*/
487+
pragma[nomagic]
488+
predicate ssaDefReachesReadExt(SourceVariable v, DefinitionExt def, BasicBlock bb, int i) {
489+
ssaDefReachesReadWithinBlock(v, def, bb, i)
490+
or
491+
ssaRef(bb, i, v, SsaActualRead()) and
492+
ssaDefReachesEndOfBlockExt(getABasicBlockPredecessor(bb), def, v) and
493+
not ssaDefReachesReadWithinBlock(v, _, bb, i)
494+
}
449495
}
450496

451497
private module SsaDefReaches {

0 commit comments

Comments
 (0)