Skip to content

Commit adeebbd

Browse files
committed
Python: cache exposed shared SSA adjacency relations
The shared SSA module requires language adapters to cache predicates that they expose. The Python adapter exposed firstUse, adjacentUseUse, and useOfDef without restoring that cache boundary, unlike the legacy AdjacentUses implementation. On exact historical Salt, the missing boundary caused the same 6,313,793-row liveAtExit fixed point to be evaluated twice. The equivalent plans received distinct RA hashes (c6bc8xgji0uv6seurbhesjqd315 versus fabf1xs3jb6t67a2buq2iv8iof4 for unsafe deserialization, and c6bc8xgji0uv6seurbhesjqd315 versus 8270excv27ldlfrtk19ou81d206 for modification-of-default-value) because one inherited an unrelated cached-empty sentinel while the other used a literal empty base. Cache the three Python adapter relations rather than generic liveness. This restores the documented shared-SSA contract at the narrow language boundary and avoids imposing a 6.31M-row generic cache on every language instantiation. On current head 1a8e317 with exact saltstack/salt@d036b117, three matched prewarmed -j1 repeats reduced median evaluator time from 51.294s to 45.103s for unsafe deserialization and from 42.377s to 34.238s for modification-of-default-value. Median paired reductions were 6.428s and 8.247s. Joined tuples fell by 58,255,670 and 85,664,313; recursive pipeline runs fell by 1,999 and 3,015. Both queries retained the identical empty endpoint hash 2a514e093aae140a14f6bf77beebe1ad in every repeat. Historical exact controls also retained 483,922 definitions, 169,921 phi inputs, 390,548 first uses, 475,226 adjacent uses, and 123,231 semantic call edges with zero left-only or right-only rows. Historical Salt evaluator recovery was 16.5% and 19.9%. Cold prewarm evaluator time was neutral (106.609s to 106.620s), so this is a warm-query optimization rather than a claimed cold-cache speedup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 21ab8585-861f-42c9-a834-451604646c6b
1 parent 9630cbb commit adeebbd

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

  • python/ql/lib/semmle/python/dataflow/new/internal

python/ql/lib/semmle/python/dataflow/new/internal/SsaImpl.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,10 @@ class EssaVariable extends Ssa::SsaDefinition {
564564
* library. Provides the same interface as legacy
565565
* `semmle.python.essa.SsaCompute::AdjacentUses`.
566566
*/
567+
cached
567568
module AdjacentUses {
568569
/** Holds if `nodeFrom` and `nodeTo` are adjacent uses of the same SSA variable. */
570+
cached
569571
predicate adjacentUseUse(Cfg::NameNode nodeFrom, Cfg::NameNode nodeTo) {
570572
exists(CfgImpl::BasicBlock bb1, int i1, CfgImpl::BasicBlock bb2, int i2 |
571573
Impl::adjacentUseUse(bb1, i1, bb2, i2, _, _) and
@@ -575,6 +577,7 @@ module AdjacentUses {
575577
}
576578

577579
/** Holds if `use` is a first use of definition `def`. */
580+
cached
578581
predicate firstUse(Ssa::SsaDefinition def, Cfg::NameNode use) {
579582
exists(CfgImpl::BasicBlock bb, int i |
580583
Impl::firstUse(def, bb, i, _) and
@@ -586,6 +589,7 @@ module AdjacentUses {
586589
* Holds if `use` is any reachable use of definition `def`. Combines
587590
* `firstUse` with transitive use-use adjacency.
588591
*/
592+
cached
589593
predicate useOfDef(Ssa::SsaDefinition def, Cfg::NameNode use) {
590594
firstUse(def, use)
591595
or

0 commit comments

Comments
 (0)