mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 19:07:47 -04:00
96 lines
5.6 KiB
Markdown
96 lines
5.6 KiB
Markdown
# CFG metadata repair: validation and scope
|
|
|
|
2026-09-12; PR [#354](https://github.com/RetroPortingToolKit/psxrecomp/pull/354).
|
|
Tracking: `beads-eio.3.148`. Original baseline: `3a275d49397ba2e2f4cc4399d76ffd47465e8d44`.
|
|
|
|
## Confirmed defects and repair
|
|
|
|
The live analyzer omitted reverse edges and called any backward-address edge a
|
|
loop. The real MIPS fixture `80010000 -> 80010020 -> 80010010 -> return` reproduces
|
|
both errors without a game asset. The separate BasicBlockAnalyzer was not the
|
|
affected analyzer. No retail-game failure is claimed to have been caused by this.
|
|
|
|
Rebuild unique in-graph reverse edges, declared-entry reachability and natural
|
|
back edges proven by dominance. Include independent alias entries through a
|
|
synthetic root. Preserve successor ordering, instruction ranges and ownership.
|
|
An iterative traversal avoids recursive stack growth; storage is O(V+E).
|
|
Final codegen fallthrough guards now consume reachability, since unreachable
|
|
blocks may also have predecessors. Block-level CPS/indirect handoffs are unchanged.
|
|
|
|
This graph is incomplete for runtime indirect/CPS entry. Neither one predecessor
|
|
nor a natural-loop label authorizes eliminating cache, slice, IRQ or device checks.
|
|
See [LLVM's loop definition](https://llvm.org/docs/LoopTerminology.html#loop-definition).
|
|
|
|
## Automated checks
|
|
|
|
- All 67 enabled recompiler CTests pass on the combined source tree, repeated
|
|
after rebasing onto the offline build fix. Three pre-existing disabled tests
|
|
(`interpreter_perf_guards`, `runtime_perf_diag_guards`,
|
|
`overlay_pair_dedup_runtime`) are not counted as passes.
|
|
- Real MIPS fixtures, alias roots, duplicate/external edges, true forward-address
|
|
back edges, nested/multiple-latch loops, irreducible/unreachable cycles,
|
|
idempotence and a 12,000-block chain pass.
|
|
- 1000 deterministic random graphs agree with an independent vertex-removal
|
|
dominance oracle, not a second copy of the production algorithm.
|
|
- Generated-tail cases distinguish unreachable incoming edges from reachable
|
|
entry/alias paths. Existing emitter, overlay ownership and BIOS tests pass.
|
|
|
|
Configure the recompiler with `BUILD_TESTING=ON`; build, then run
|
|
`ctest --test-dir <build> --output-on-failure`. Stage the normally generated
|
|
runtime codegen-hash header before tests which compile a runtime overlay fixture.
|
|
|
|
## Fresh title builds and bounded live regression
|
|
|
|
Clang 22.1.8, Windows x64, RelWithDebInfo, OpenGL/headless, debug tools ON,
|
|
netplay/launcher UI OFF, no game mods, normal guest timing defaults. Fresh game
|
|
and SCPH-1001 BIOS generation; retail LLE BIOS boot (not BIOS HLE). The existing
|
|
deterministic HLE thread scheduler remains unchanged; this is not a claim of
|
|
an entirely HLE-free runtime. Each variant has isolated saves/build/cache data.
|
|
The warm run reuses that variant's cold-run overlay cache.
|
|
|
|
Master could not compile this offline configuration because it unconditionally
|
|
required netplay headers and account symbols. PR [#355](https://github.com/RetroPortingToolKit/psxrecomp/pull/355)
|
|
was applied identically to baseline and fixed runtime sources. Thus the A/B
|
|
comparison isolates CFG changes, not different build prerequisites.
|
|
|
|
| Title | Dispatch entries (both) | Native builds | Baseline cold/warm frames | Fixed cold/warm frames |
|
|
| --- | ---: | --- | --- | --- |
|
|
| Tomba! USA SCUS-94236 | 2989 | both pass | 11003 / 11003 | 11000 / 11004 |
|
|
| Mega Man X6 USA v1.1 SLUS-01395 | 2494 | both pass | 11015 / 11000 | 11026 / 11016 |
|
|
| Ape Escape USA SCUS-94423 | 3094 | both pass | 11005 / 11005 | 11004 / 11011 |
|
|
|
|
All twelve runs reached the 11,000-frame threshold, exited 0, reported native
|
|
overlay dispatch, nonzero guest SPU samples and zero kernel-bless mismatches.
|
|
Inspected screenshots show Tomba FMV/title and MMX6/Ape gameplay attract demos.
|
|
Polling captures nearby frames, not identical deterministic snapshots; no
|
|
frame-perfect or guest-state equivalence claim follows from those pictures.
|
|
Headless host audio output is inactive: guest SPU activity is not a listening test.
|
|
|
|
Four additional input smoke runs (`results/retail-input`) reach 14,000 frames
|
|
and exit 0: Tomba baseline/fixed 14004/14011; MMX6 14005/14020. Tomba enters
|
|
its initial scene/dialogue and responds to pause; MMX6 enters the new-game story
|
|
sequence. These are not complete gameplay routes. Inputs are wall-clock polled,
|
|
not lockstep: actual injection frames and dialogue boundaries differ, so this
|
|
does not establish deterministic input/state equivalence.
|
|
|
|
Dispatch tables, declarations and guest code-range manifests are byte-identical
|
|
between variants for each title. Codegen identity changes from `30317be3` to
|
|
`4fe894d2`, so their generated overlay caches are separated. Added final safety-net
|
|
code changes generated tails; one Tomba unknown-function stub moves between
|
|
adjacent shards because of the changed shard line budget, without losing its entry.
|
|
|
|
Evidence remains local under `_validation-fmv-prs/{baseline,fixed}/{tomba,mmx6,ape}`:
|
|
isolated `game.toml`, generated output, native builds and `results/retail-{cold,warm}`
|
|
JSON reports/screenshots. No copyrighted asset, capture, profile or save is committed.
|
|
|
|
## Merge boundary
|
|
|
|
This is a class-level metadata/codegen correctness repair, not an FMV speedup.
|
|
Local suite coverage supports integration but does not prove absence of regressions
|
|
in unvisited levels, other platforms, online play or full playthroughs. No GitHub
|
|
checks were reported. Tomba2 and all game-repository pins are deliberately untouched.
|
|
|
|
Keep [#356](https://github.com/RetroPortingToolKit/psxrecomp/pull/356) (opt-in IPO/PGO validation)
|
|
and [#357](https://github.com/RetroPortingToolKit/psxrecomp/pull/357) (IRQ batching RFC and cache
|
|
counterexample) in draft. No proposed IRQ/slice/I-cache suppression is bundled here.
|