re: the per-phase clear conditions, by dominance over the ISL CFG
Closes the backlog's "which condition guards each END_PHASE". With the CFG from the previous commit this is a graph query, not new machinery. The obvious query is WRONG for this language, and I implemented it first: "one successor reaches END_PHASE and the other does not" finds 1/62/1 guards across Stage 02's three phases, and the 1s are both the same read_freg(0) < 1200 timeout -- every objective test missed. The cause is the dominant idiom: a POLL LOOP's loop-back branch also reaches the exit, one iteration later, so neither successor discriminates. The asymmetric 1/62/1 is what exposed it; a uniform number would have read as plausible. Dominance has no such blind spot: a condition dominates an exit when every path from an entry passes through it, so it is NECESSARY for the phase to end that way, and a poll loop's test dominates its own exit by construction. Iterative dominators converge in 3 passes over 15670/18739 instructions (83.6%). Result for Stage 02 -- every exit in all three phases is dominated by unit_hp_pct(TCN001, Character_Player_Test) != 0, the player's ship being alive, which falls out rather than being assumed. Beyond that, phase 1's objective exit requires hp_pct_test on ADT102, ADT107 and ADT113; phase 3's requires ADT301 and ADT302; read_freg(0) gates at 210 / 300 and times out at 1200; random(3) and random(5) dominate only the exits that pick one of several closing lines. Two of the 15 exits are reachable from NO static entry, both FORCE_END_PHASE. That agrees with the independently measured 389 unreachable routines: they are started from the trigger queue at phase+272, by data rather than code. Practical note recorded: the first dominator run was OOM-killed -- 6743 nodes each holding a Python set of up to 6743 elements. Integer bitmasks run in seconds. Not settled, and said so: dominance gives necessary, not sufficient, conditions; only Stage 02's artefact is committed; one listed condition is still an unresolved <unknown>; read_freg's units are inferred from the gate values, not read. calls, phase-ends and conditions all regenerate byte-identical.
This commit is contained in:
102
docs/re/data/isl-stage02-phase-guards.txt
Normal file
102
docs/re/data/isl-stage02-phase-guards.txt
Normal file
@@ -0,0 +1,102 @@
|
||||
# Stage02.ssb — what each phase exit requires
|
||||
|
||||
Generated by `tools/re-capture/isl_report.py phase-guards`.
|
||||
|
||||
A condition is listed when it DOMINATES the exit: every path from an
|
||||
entry to that `END_PHASE` passes through it, so it is NECESSARY for the
|
||||
phase to end that way. Reachability alone is the wrong query here —
|
||||
in a poll loop both successors reach the exit.
|
||||
|
||||
CFG reached 15670 of 18739 instructions (83.6%).
|
||||
|
||||
## phase 1 — END_PHASE at 0x0051E4: 2 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x005110 random(3) == 0
|
||||
|
||||
## phase 1 — END_PHASE at 0x005828: 3 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x00572C random(5) == 0
|
||||
|
||||
## phase 1 — END_PHASE at 0x006010: 7 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x005888 read_freg(0) <= 210
|
||||
0x0058DC hp_pct_test(ADT102, 0) != 1
|
||||
0x005930 hp_pct_test(ADT107, 0) != 1
|
||||
0x005984 hp_pct_test(ADT113, 0) != 1
|
||||
0x005B3C hp_pct_test(ADN101, 0) != 1
|
||||
|
||||
## phase 1 — END_PHASE at 0x006260: 4 necessary condition(s)
|
||||
0x004D70 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x00523C hp_pct_test(TCN004, 0) != 1
|
||||
0x005888 read_freg(0) <= 210
|
||||
0x006070 read_freg(0) < 1200
|
||||
|
||||
## phase 1 — FORCE_END_PHASE at 0x01482C: UNREACHABLE from any static entry
|
||||
(started from the trigger queue at `phase+272`, by data not code)
|
||||
|
||||
## phase 2 — END_PHASE at 0x019640: 2 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x01956C random(3) == 0
|
||||
|
||||
## phase 2 — END_PHASE at 0x019934: 2 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
|
||||
## phase 2 — END_PHASE at 0x01AC44: 9 necessary condition(s)
|
||||
0x0191CC unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x019698 hp_pct_test(TCT206, 0) != 1
|
||||
0x0199C8 builtin7(TCT206, 1, Route_TCT206_p2S, 4294967295, 500) == 1
|
||||
0x019A8C <unknown> <= 240
|
||||
0x01A1E4 global[4] == 0
|
||||
0x01A2B0 global[4] != 1
|
||||
0x01A924 hp_pct_test(TCT206, 89.9) != 0
|
||||
0x01AA38 global[104] != 0
|
||||
0x01AAF8 global[4] == 0
|
||||
|
||||
## phase 2 — FORCE_END_PHASE at 0x0249F0: 2 necessary condition(s)
|
||||
0x0247E4 hp_pct_test(ADN202, 0) != 1
|
||||
0x024848 unit_state(TCT206) != 1
|
||||
|
||||
## phase 3 — END_PHASE at 0x02B96C: 2 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B898 random(3) == 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02BFB0: 3 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BEB4 random(5) == 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02C1E0: 3 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
|
||||
## phase 3 — END_PHASE at 0x02CF74: 16 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
0x02C240 read_freg(0) <= 300
|
||||
0x02C294 hp_pct_test(ADT301, 0) != 1
|
||||
0x02C2E8 hp_pct_test(ADT302, 0) != 1
|
||||
0x02C33C hp_pct_test(ADT303, 0) != 1
|
||||
0x02C390 hp_pct_test(ADT304, 0) != 1
|
||||
0x02C3E4 hp_pct_test(ADT305, 0) != 1
|
||||
0x02C438 hp_pct_test(ADT306, 0) != 1
|
||||
0x02C48C hp_pct_test(ADT307, 0) != 1
|
||||
0x02C4E0 hp_pct_test(ADT308, 0) != 1
|
||||
0x02C5C4 global[112] != 0
|
||||
0x02CC0C global[112] != 0
|
||||
0x02CDC8 global[4] == 0
|
||||
0x02CE9C global[112] != 0
|
||||
|
||||
## phase 3 — END_PHASE at 0x02D1DC: 5 necessary condition(s)
|
||||
0x02B4F8 unit_hp_pct(TCN001, Character_Player_Test) != 0
|
||||
0x02B9C4 hp_pct_test(TCN004, 0) != 1
|
||||
0x02BFC8 global[112] < 4
|
||||
0x02C240 read_freg(0) <= 300
|
||||
0x02CFD4 read_freg(0) < 1200
|
||||
|
||||
## phase 3 — FORCE_END_PHASE at 0x034A10: UNREACHABLE from any static entry
|
||||
(started from the trigger queue at `phase+272`, by data not code)
|
||||
Reference in New Issue
Block a user