mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
feat(pdg): stamp the reaching-defs solver identity for incremental re-analysis (#2201 review R3)
The SSA-sparse rewrite computes full REACHING_DEF facts for deep-loop functions the old dense worklist truncated to empty at the blocks×64 ceiling. But an existing `--pdg` index carries those stale-truncated rows, and nothing forced a re-analysis: RepoMeta.pdg had no solver-identity key, so an upgraded run over an unchanged file kept the incremental fast path and never recomputed. Add a constant `reachingDefSolver: 'ssa-sparse-v1'` to the resolved pdg stamp (and to the RepoMeta['pdg'] type). It rides the existing key-union pdgModeMismatch comparator: a pre-#2201 stamp lacks the key, so 'ssa-sparse-v1' !== undefined trips one full writeback that recomputes the fuller coverage — no `--force` needed — exactly like the M2 REACHING_DEF cap and M5 CDG cap upgrade paths. A matching post-#2201 stamp compares equal, so there is no spurious re-analysis churn on steady-state re-runs. Tests: new pre-#2201→SSA upgrade block in pdg-mode-flip.test.ts (stamp present, absent-key mismatch, identical-stamp no-churn) + the persisted-stamp shape assertions and resolvePdgConfig DEFAULTS updated for the new key. tsc clean; pdg-mode-flip + run-analyze suites green (55/55). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
20b44b0d65
commit
4dfafee20c
4 changed files with 64 additions and 0 deletions
|
|
@ -415,6 +415,14 @@ export const resolvePdgConfig = (options: PdgOptions): RepoMeta['pdg'] =>
|
|||
// outlive the model that produced them — ANY model-content change
|
||||
// ships as a new digest and repopulates the taint edges.
|
||||
taintModelVersion,
|
||||
// #2201 review R3: reaching-defs solver identity. The SSA-sparse rewrite
|
||||
// computes full facts for deep-loop functions the dense worklist used to
|
||||
// truncate to empty, so an existing `--pdg` index carries stale-truncated
|
||||
// REACHING_DEF rows. Absent on any pre-#2201 stamp → the key-union
|
||||
// pdgModeMismatch trips on the first upgraded run and forces the full
|
||||
// writeback that recomputes the fuller coverage (no `--force` needed).
|
||||
// Bump this tag on any future change to which facts the solver emits.
|
||||
reachingDefSolver: 'ssa-sparse-v1',
|
||||
}
|
||||
: undefined;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,19 @@ export interface RepoMeta {
|
|||
* without `--force`. Optional: absent on pre-M3 stamps.
|
||||
*/
|
||||
taintModelVersion?: string;
|
||||
/**
|
||||
* Identity of the reaching-definitions solver the persisted REACHING_DEF
|
||||
* rows were produced under (#2201 review R3). The SSA-sparse rewrite computes
|
||||
* FULL facts for deep-loop functions the old dense worklist truncated to
|
||||
* empty (the blocks×64 ceiling no longer fires) — but an existing `--pdg`
|
||||
* index built under the old solver carries those truncated rows. ABSENT on
|
||||
* any pre-#2201 stamp, so that absence trips `pdgModeMismatch` on the first
|
||||
* upgraded run and forces the full writeback that recomputes the now-fuller
|
||||
* REACHING_DEF coverage without `--force`. Bump the tag on any future change
|
||||
* that alters which facts the solver emits. Optional for that upgrade reason;
|
||||
* resolved (always present) on every post-#2201 write.
|
||||
*/
|
||||
reachingDefSolver?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,42 @@ describe('pdgModeMismatch — pre-M5→M5 CDG-cap stamp upgrade (#2085 M5, pure)
|
|||
});
|
||||
});
|
||||
|
||||
describe('pdgModeMismatch — pre-#2201→SSA reaching-defs solver upgrade (#2201 review R3, pure)', () => {
|
||||
it('resolvePdgConfig stamps the reaching-defs solver identity', async () => {
|
||||
const { resolvePdgConfig } = await import('../../src/core/run-analyze.js');
|
||||
const stamp = resolvePdgConfig({ pdg: true });
|
||||
expect(stamp?.reachingDefSolver).toBe('ssa-sparse-v1');
|
||||
});
|
||||
|
||||
it('a pre-#2201 stamp (no solver key) mismatches the SSA request — upgrade recomputes truncated deep-loop facts', async () => {
|
||||
const { pdgModeMismatch } = await import('../../src/core/run-analyze.js');
|
||||
// What a pre-#2201 (M5-era) run wrote: every cap + model digest, but NO
|
||||
// reachingDefSolver. The key-union comparator sees 'ssa-sparse-v1' !==
|
||||
// undefined and trips the full writeback that recomputes the now-fuller
|
||||
// REACHING_DEF coverage — the deep-loop functions the dense worklist
|
||||
// truncated to empty at the blocks×64 ceiling now compute full facts.
|
||||
const m5Stamp = {
|
||||
maxFunctionLines: 2000,
|
||||
maxEdgesPerFunction: 5000,
|
||||
maxReachingDefEdgesPerFunction: 4000,
|
||||
maxCdgEdgesPerFunction: 5000,
|
||||
maxTaintFindingsPerFunction: 200,
|
||||
maxTaintHops: 32,
|
||||
maxInterprocFindings: 2000,
|
||||
maxInterprocHops: 32,
|
||||
maxInterprocEdges: 1000,
|
||||
taintModelVersion,
|
||||
};
|
||||
expect(pdgModeMismatch(m5Stamp, { pdg: true })).toBe(true);
|
||||
});
|
||||
|
||||
it('an identical post-#2201 stamp compares equal (no spurious re-analysis churn)', async () => {
|
||||
const { pdgModeMismatch, resolvePdgConfig } = await import('../../src/core/run-analyze.js');
|
||||
const stamp = resolvePdgConfig({ pdg: true });
|
||||
expect(pdgModeMismatch(stamp, { pdg: true })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('detect_changes BasicBlock exclusion (#2082 U7)', () => {
|
||||
it('the symbol-overlap id-prefix filter excludes exactly the BasicBlock rows', async () => {
|
||||
const repo = await setupMiniRepo();
|
||||
|
|
@ -258,6 +294,7 @@ describe('runFullAnalysis — pdg-mode flip (#2099 F1)', () => {
|
|||
maxInterprocHops: 32,
|
||||
maxInterprocEdges: 1000,
|
||||
taintModelVersion,
|
||||
reachingDefSolver: 'ssa-sparse-v1',
|
||||
});
|
||||
expect(stamped!.incrementalInProgress).toBeUndefined(); // cleared on success
|
||||
|
||||
|
|
@ -314,6 +351,7 @@ describe('runFullAnalysis — pdg-mode flip (#2099 F1)', () => {
|
|||
maxInterprocHops: 32,
|
||||
maxInterprocEdges: 1000,
|
||||
taintModelVersion,
|
||||
reachingDefSolver: 'ssa-sparse-v1',
|
||||
});
|
||||
// The CFG layer survives a rebuild under a tighter edge cap (blocks are
|
||||
// never capped, only edges).
|
||||
|
|
|
|||
|
|
@ -349,6 +349,10 @@ describe('pdgModeMismatch / resolvePdgConfig (#2099 F1)', () => {
|
|||
// Content digest, not a tunable cap — pinned via the exported constant
|
||||
// (its VALUE changes whenever the built-in model changes, by design).
|
||||
taintModelVersion,
|
||||
// Solver identity, not a tunable cap — always stamped on a pdg-on run
|
||||
// (#2201 review R3). Bumps when the reaching-defs solver's emitted facts
|
||||
// change; absence on a pre-#2201 stamp forces a re-analysis.
|
||||
reachingDefSolver: 'ssa-sparse-v1',
|
||||
};
|
||||
|
||||
it('resolvePdgConfig: pdg-off run resolves to undefined (the meta field is omitted)', async () => {
|
||||
|
|
@ -384,6 +388,7 @@ describe('pdgModeMismatch / resolvePdgConfig (#2099 F1)', () => {
|
|||
maxInterprocHops: 0,
|
||||
maxInterprocEdges: 0,
|
||||
taintModelVersion, // not a cap — always stamped on a pdg-on run
|
||||
reachingDefSolver: 'ssa-sparse-v1', // solver identity — always stamped (#2201 R3)
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue