test(cfg): R5 contrast — dense ceiling fires, SSA solver converges (#2201 U6)

This commit is contained in:
Gergo Magyar 2026-06-15 14:38:36 +00:00
parent 99625c20b6
commit 0a8dbd43d5

View file

@ -8,6 +8,8 @@ import {
} from '../../../src/core/ingestion/cfg/visitors/typescript.js';
import {
computeReachingDefs,
computeReachingDefsDense,
computeReachingDefsSparse,
type DefUseFact,
} from '../../../src/core/ingestion/cfg/reaching-defs.js';
import type {
@ -371,6 +373,33 @@ describe('computeReachingDefs — determinism and convergence', () => {
expect(capped.facts).toEqual([]);
expect(capped.defCount).toBe(full.defCount);
});
it('#2201 R5: the ceiling fires on the dense oracle but not on the SSA solver', () => {
// Contrast the two solvers on a looping CFG under a budget below the dense
// worklist's convergence: the dense oracle truncates to a sound-empty result
// (the ceiling fires), while the SSA solver — which has no fixpoint
// iteration — always converges (the ceiling that fired on the dense worklist
// effectively never fires). The facts the SSA solver computes are identical
// to the dense oracle's unbounded result. This is the #2201 acceptance: the
// blocks×64 ceiling stops firing on deep loops.
const blocks: BlockSpec[] = [{}, {}, { stmts: [stmt(3, [0], [0])] }];
const edges: [number, number][] = [
[0, 2],
[2, 2], // self-loop → the dense fixpoint must re-visit block 2
[2, 1],
];
const denseFull = computeReachingDefsDense(mkCfg(blocks, edges, ['x']));
const denseCeiling = computeReachingDefsDense(mkCfg(blocks, edges, ['x']), {
maxBlockVisits: 1,
});
const sparse = computeReachingDefsSparse(mkCfg(blocks, edges, ['x']), { maxBlockVisits: 1 });
expect(denseFull.status).toBe('computed');
expect(denseFull.facts.length).toBeGreaterThan(0);
expect(denseCeiling.status).toBe('truncated'); // ceiling fires on the dense worklist
expect(sparse.status).toBe('computed'); // SSA ignores the ceiling — it never fires
expect(render(sparse.facts)).toEqual(render(denseFull.facts)); // and the facts match
});
});
describe('computeReachingDefs — parser-direct acceptance (with U1/U2)', () => {