re: recover ISL conditions by CFG dataflow instead of a linear walk
The linear walk's 10% unknown was a floor imposed by the method: a block entered only
by a branch has a well-defined state, just not one a straight-line pass can see.
tools/re-capture/isl_cfg.py replaces it with a worklist fixpoint that joins each
block's state over its ACTUAL predecessors -- a value survives only if every
predecessor agrees.
Over all 28 stages:
instructions reached by the CFG 85.0%
condition sites, unknown LHS 756 (10.00%) -> 402 (5.32%)
of those, never reached at all 389
joined away (predecessors disagree) 13
both resolve but DISAGREE 161 <- linear walk was wrong here
Those 161 are on top of the 889 the previous jmp fix caught.
Two zero-results on the way, both my own bug, both caught because the number looked
wrong rather than because a test failed:
* The first CFG run reached only 36% of instructions and made things WORSE (35%
unknown). Cause: the phase bases reach almost nothing. Most routines are
COROUTINES the engine starts from its trigger queue, with no static predecessor,
so every start_coroutine target has to be seeded as an entry.
* That seeding then found ZERO entries in a file with 216 start_coroutine calls,
because the target is staged in TWO steps -- special[0] = imm, then
local[0] = special[0] -- and I matched only the direct-immediate form.
Reachability went 36% -> 64% -> 85% as each was fixed.
The 389 still unreached are an honest limit rather than a gap: nothing in the bytecode
starts them; they are entered from the trigger queue at phase+272, by data rather than
code, so no purely static analysis reaches them.
isl_report.py conditions now uses isl_cfg; calls and phase-ends regenerate
byte-identical. Stage 02 unknowns drop from 71 to 25.
This commit is contained in:
@@ -1442,9 +1442,18 @@ premise was wrong.**
|
||||
on `builtin80`, which returns only 1 or 0. A/B over 28 stages: **889 of 7563
|
||||
sites (11.75 %) change**, and unresolved goes **34 (0.45 %) → 756 (10.00 %)**.
|
||||
The earlier "0.0 % unresolved" was a MISSING CHECK, not a strong result.
|
||||
🟡 Recovering the 756 needs a real dataflow **join over each block's actual
|
||||
predecessors** (a CFG fixpoint) — the branch targets are all known, the analysis
|
||||
is not written. ▶️ **Still open:** the 35 unnamed built-ins (`builtin16` 132
|
||||
~~🟡 Recovering the 756 needs a real dataflow join over each block's actual
|
||||
predecessors (a CFG fixpoint) — the analysis is not written.~~
|
||||
✅ **(2026-08-27) WRITTEN — `tools/re-capture/isl_cfg.py`.** Worklist fixpoint,
|
||||
join over actual predecessors. **85.0 %** of instructions reached; unknown LHS
|
||||
**756 (10.00 %) → 402 (5.32 %)**, of which **389 are never reached** and only
|
||||
**13** are genuine join-aways. It also found **161 more sites where the linear
|
||||
walk gave a confident WRONG answer**. ⚠️ Two of my own zero-results on the way:
|
||||
the phase bases reach only 36 % (most routines are coroutines with no static
|
||||
predecessor, so every `start_coroutine` target must be seeded), and that seeding
|
||||
first found **0 entries in a file with 216** because the target is staged in TWO
|
||||
steps (`special[0]=imm` then `local[0]=special[0]`). 🟡 The 389 are a real limit:
|
||||
they are started from the **trigger queue at `phase+272`** — by data, not code. ▶️ **Still open:** the 35 unnamed built-ins (`builtin16` 132
|
||||
sites, `builtin105` 117, `builtin103` 115 — each now a vtable-slot lookup);
|
||||
✅ **(2026-08-27) partial — [structures/isl-unit-args](structures/isl-unit-args.md):**
|
||||
reading the implementations shows **55** built-ins take a unit at `local[4]`,
|
||||
|
||||
@@ -6,37 +6,41 @@ The deque ops are an expression stack: `push.i` saves the comparand,
|
||||
the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
`pop.i` restores the comparand into `special[1]`, then `cmp.i` compares.
|
||||
|
||||
Operands come from a CFG dataflow fixpoint (`isl_cfg.py`), joining each
|
||||
block over its ACTUAL predecessors — not from a linear walk.
|
||||
|
||||
965 condition sites; phase bases 0xe4 0x14aa8 0x24b4c
|
||||
|
||||
## most-tested predicates
|
||||
unit_state 255
|
||||
hp_pct_test 167
|
||||
unit_state 248
|
||||
hp_pct_test 165
|
||||
dist_lt 92
|
||||
unit_alive 71
|
||||
unit_alive 62
|
||||
unit_relation 52
|
||||
builtin103 39
|
||||
builtin105 38
|
||||
read_freg 10
|
||||
builtin103 35
|
||||
random 26
|
||||
unit_hp_pct 9
|
||||
read_freg 9
|
||||
builtin7 9
|
||||
builtin99 1
|
||||
|
||||
## phase 1 — 435 sites
|
||||
0x002E48 if builtin103() != 1 -> 0x322C
|
||||
0x0032F4 if unit_alive(TCN105) != 1 -> 0x3388
|
||||
0x0044A4 if unit_alive(TCN105) != 1 -> 0x4538
|
||||
0x002E48 if <unknown: no static entry> != <unknown> -> 0x322C
|
||||
0x0032F4 if <unknown: no static entry> != <unknown> -> 0x3388
|
||||
0x0044A4 if <unknown: no static entry> != <unknown> -> 0x4538
|
||||
0x004D70 if unit_hp_pct(TCN001, Character_Player_Test) != 0 -> 0x51FC
|
||||
0x005110 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x4E68
|
||||
0x005124 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x4F10
|
||||
0x005138 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x4FB8
|
||||
0x00514C if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x5060
|
||||
0x005110 if random(3) == 0 -> 0x4E68
|
||||
0x005124 if random(3) == 1 -> 0x4F10
|
||||
0x005138 if random(3) == 2 -> 0x4FB8
|
||||
0x00514C if random(3) == 3 -> 0x5060
|
||||
0x00523C if hp_pct_test(TCN004, 0) != 1 -> 0x5840
|
||||
0x00572C if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x5334
|
||||
0x005740 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x53DC
|
||||
0x005754 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x5484
|
||||
0x005768 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x552C
|
||||
0x00577C if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x55D4
|
||||
0x005790 if <unknown: block entered by a branch, not by fall-through> == 5 -> 0x567C
|
||||
0x00572C if random(5) == 0 -> 0x5334
|
||||
0x005740 if random(5) == 1 -> 0x53DC
|
||||
0x005754 if random(5) == 2 -> 0x5484
|
||||
0x005768 if random(5) == 3 -> 0x552C
|
||||
0x00577C if random(5) == 4 -> 0x55D4
|
||||
0x005790 if random(5) == 5 -> 0x567C
|
||||
0x005888 if read_freg(0) <= 210 -> 0x6028
|
||||
0x0058DC if hp_pct_test(ADT102, 0) != 1 -> 0x6028
|
||||
0x005930 if hp_pct_test(ADT107, 0) != 1 -> 0x6028
|
||||
@@ -270,21 +274,21 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x0103D0 if unit_state(ADT113) == 1 -> 0x10438
|
||||
0x010484 if unit_state(ADN114) == 1 -> 0x104EC
|
||||
0x010538 if unit_state(ADN115) == 1 -> 0x105A0
|
||||
0x0105C4 if <unknown: block entered by a branch, not by fall-through> == 28 -> 0xFB1C
|
||||
0x0105D8 if <unknown: block entered by a branch, not by fall-through> == 29 -> 0xFBD0
|
||||
0x0105EC if <unknown: block entered by a branch, not by fall-through> == 30 -> 0xFC84
|
||||
0x010600 if <unknown: block entered by a branch, not by fall-through> == 31 -> 0xFD38
|
||||
0x010614 if <unknown: block entered by a branch, not by fall-through> == 32 -> 0xFDEC
|
||||
0x010628 if <unknown: block entered by a branch, not by fall-through> == 33 -> 0xFEA0
|
||||
0x01063C if <unknown: block entered by a branch, not by fall-through> == 34 -> 0xFF54
|
||||
0x010650 if <unknown: block entered by a branch, not by fall-through> == 35 -> 0x10008
|
||||
0x010664 if <unknown: block entered by a branch, not by fall-through> == 36 -> 0x100BC
|
||||
0x010678 if <unknown: block entered by a branch, not by fall-through> == 37 -> 0x10170
|
||||
0x01068C if <unknown: block entered by a branch, not by fall-through> == 38 -> 0x10224
|
||||
0x0106A0 if <unknown: block entered by a branch, not by fall-through> == 39 -> 0x102D8
|
||||
0x0106B4 if <unknown: block entered by a branch, not by fall-through> == 40 -> 0x1038C
|
||||
0x0106C8 if <unknown: block entered by a branch, not by fall-through> == 41 -> 0x10440
|
||||
0x0106DC if <unknown: block entered by a branch, not by fall-through> == 42 -> 0x104F4
|
||||
0x0105C4 if global[20] == 28 -> 0xFB1C
|
||||
0x0105D8 if global[20] == 29 -> 0xFBD0
|
||||
0x0105EC if global[20] == 30 -> 0xFC84
|
||||
0x010600 if global[20] == 31 -> 0xFD38
|
||||
0x010614 if global[20] == 32 -> 0xFDEC
|
||||
0x010628 if global[20] == 33 -> 0xFEA0
|
||||
0x01063C if global[20] == 34 -> 0xFF54
|
||||
0x010650 if global[20] == 35 -> 0x10008
|
||||
0x010664 if global[20] == 36 -> 0x100BC
|
||||
0x010678 if global[20] == 37 -> 0x10170
|
||||
0x01068C if global[20] == 38 -> 0x10224
|
||||
0x0106A0 if global[20] == 39 -> 0x102D8
|
||||
0x0106B4 if global[20] == 40 -> 0x1038C
|
||||
0x0106C8 if global[20] == 41 -> 0x10440
|
||||
0x0106DC if global[20] == 42 -> 0x104F4
|
||||
0x010728 if builtin103() != 0 -> 0x10748
|
||||
0x010788 if hp_pct_test(TCN004, 30) != 1 -> 0x108D4
|
||||
0x010814 if dist_lt(TCN004, TCN001, 10000) == 1 -> 0x108D4
|
||||
@@ -404,31 +408,31 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x012F1C if unit_state(ADN131) != 2 -> 0x12FAC
|
||||
0x012F30 if global[36] != 0 -> 0x12FAC
|
||||
0x012F68 if builtin105(ADN131) != 1 -> 0x12FAC
|
||||
0x012FF0 if unit_state(ADN132, global[12], 1) != 2 -> 0x13080
|
||||
0x012FF0 if unit_state(ADN132) != 2 -> 0x13080
|
||||
0x013004 if global[40] != 0 -> 0x13080
|
||||
0x01303C if builtin105(ADN132) != 1 -> 0x13080
|
||||
0x0130C4 if unit_state(ADN133, global[12], 1) != 2 -> 0x13154
|
||||
0x0130C4 if unit_state(ADN133) != 2 -> 0x13154
|
||||
0x0130D8 if global[44] != 0 -> 0x13154
|
||||
0x013110 if builtin105(ADN133) != 1 -> 0x13154
|
||||
0x013198 if unit_state(ADN134, global[12], 1) != 2 -> 0x13228
|
||||
0x013198 if unit_state(ADN134) != 2 -> 0x13228
|
||||
0x0131AC if global[48] != 0 -> 0x13228
|
||||
0x0131E4 if builtin105(ADN134) != 1 -> 0x13228
|
||||
0x01326C if unit_state(ADN135, global[12], 1) != 2 -> 0x132FC
|
||||
0x01326C if unit_state(ADN135) != 2 -> 0x132FC
|
||||
0x013280 if global[52] != 0 -> 0x132FC
|
||||
0x0132B8 if builtin105(ADN135) != 1 -> 0x132FC
|
||||
0x013340 if unit_state(ADN136, global[12], 1) != 2 -> 0x133D0
|
||||
0x013340 if unit_state(ADN136) != 2 -> 0x133D0
|
||||
0x013354 if global[56] != 0 -> 0x133D0
|
||||
0x01338C if builtin105(ADN136) != 1 -> 0x133D0
|
||||
0x013414 if unit_state(ADN137, global[12], 1) != 2 -> 0x134A4
|
||||
0x013414 if unit_state(ADN137) != 2 -> 0x134A4
|
||||
0x013428 if global[60] != 0 -> 0x134A4
|
||||
0x013460 if builtin105(ADN137) != 1 -> 0x134A4
|
||||
0x0134E8 if unit_state(ADN138, global[12], 1) != 2 -> 0x13578
|
||||
0x0134E8 if unit_state(ADN138) != 2 -> 0x13578
|
||||
0x0134FC if global[64] != 0 -> 0x13578
|
||||
0x013534 if builtin105(ADN138) != 1 -> 0x13578
|
||||
0x0135BC if unit_state(ADN139, global[12], 1) != 2 -> 0x1364C
|
||||
0x0135BC if unit_state(ADN139) != 2 -> 0x1364C
|
||||
0x0135D0 if global[68] != 0 -> 0x1364C
|
||||
0x013608 if builtin105(ADN139) != 1 -> 0x1364C
|
||||
0x013690 if unit_state(ADN140, global[12], 1) != 2 -> 0x13720
|
||||
0x013690 if unit_state(ADN140) != 2 -> 0x13720
|
||||
0x0136A4 if global[72] != 0 -> 0x13720
|
||||
0x0136DC if builtin105(ADN140) != 1 -> 0x13720
|
||||
0x013724 if global[12] < 6 -> 0x14264
|
||||
@@ -452,28 +456,28 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x014340 if global[16] >= 4 -> 0x143F4
|
||||
0x0143F4 if global[12] < 3 -> 0x144BC
|
||||
0x014408 if global[16] >= 3 -> 0x144BC
|
||||
0x014504 if builtin103(global[12]) != 0 -> 0x14524
|
||||
0x014504 if builtin103() != 0 -> 0x14524
|
||||
0x014524 if global[28] != 1 -> 0x145E4
|
||||
0x014628 if unit_state(ADS151) != 1 -> 0x14694
|
||||
0x014680 if unit_state(TCS151) == 1 -> 0x146A0
|
||||
0x014744 if dist_lt(TCN001, ADS151, 8000) == 1 -> 0x1481C
|
||||
|
||||
## phase 2 — 302 sites
|
||||
0x018580 if builtin103() != 1 -> 0x186E8
|
||||
0x018C30 if unit_alive(TCN208) != 1 -> 0x18C98
|
||||
0x018CBC if unit_alive(TCN207) != 1 -> 0x18D24
|
||||
0x018DB8 if hp_pct_test(ADN204, 0) != 1 -> 0x18E4C
|
||||
0x018FFC if hp_pct_test(ADN208, 0) != 1 -> 0x19090
|
||||
0x019124 if builtin103() != 1 -> 0x1915C
|
||||
0x018580 if <unknown: no static entry> != <unknown> -> 0x186E8
|
||||
0x018C30 if <unknown: no static entry> != <unknown> -> 0x18C98
|
||||
0x018CBC if <unknown: no static entry> != <unknown> -> 0x18D24
|
||||
0x018DB8 if <unknown: no static entry> != <unknown> -> 0x18E4C
|
||||
0x018FFC if <unknown: no static entry> != <unknown> -> 0x19090
|
||||
0x019124 if <unknown: no static entry> != <unknown> -> 0x1915C
|
||||
0x0191CC if unit_hp_pct(TCN001, Character_Player_Test) != 0 -> 0x19658
|
||||
0x01956C if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x192C4
|
||||
0x019580 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1936C
|
||||
0x019594 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x19414
|
||||
0x0195A8 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x194BC
|
||||
0x01956C if random(3) == 0 -> 0x192C4
|
||||
0x019580 if random(3) == 1 -> 0x1936C
|
||||
0x019594 if random(3) == 2 -> 0x19414
|
||||
0x0195A8 if random(3) == 3 -> 0x194BC
|
||||
0x019698 if hp_pct_test(TCT206, 0) != 1 -> 0x1994C
|
||||
0x0199C8 if builtin7(TCT206, 1, Route_TCT206_p2S, 4294967295, 500) == 1 -> 0x19A38
|
||||
0x019A24 if read_freg(0) <= 600 -> 0x19A44
|
||||
0x019A8C if read_freg(0, 1) <= 240 -> 0x1A1E4
|
||||
0x019A8C if <unknown: no static entry> <= 240 -> 0x1A1E4
|
||||
0x019AE0 if hp_pct_test(ADN201, 0) != 1 -> 0x1A1E4
|
||||
0x019B34 if hp_pct_test(ADN202, 0) != 1 -> 0x1A1E4
|
||||
0x019B88 if hp_pct_test(ADN203, 0) != 1 -> 0x1A1E4
|
||||
@@ -499,18 +503,18 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01A1E4 if global[4] == 0 -> 0x1AC5C
|
||||
0x01A2B0 if global[4] != 1 -> 0x1A864
|
||||
0x01A2F4 if unit_alive(ADN201, 0) != 1 -> 0x1A32C
|
||||
0x01A350 if unit_alive(ADN202, global[104]) != 1 -> 0x1A388
|
||||
0x01A3AC if unit_alive(ADN207, global[104]) != 1 -> 0x1A3E4
|
||||
0x01A408 if unit_alive(ADN223, global[104]) != 1 -> 0x1A440
|
||||
0x01A464 if unit_alive(ADN224, global[104]) != 1 -> 0x1A49C
|
||||
0x01A4C0 if unit_alive(ADN225, global[104]) != 1 -> 0x1A4F8
|
||||
0x01A51C if unit_alive(ADN226, global[104]) != 1 -> 0x1A554
|
||||
0x01A578 if unit_alive(ADN227, global[104]) != 1 -> 0x1A5B0
|
||||
0x01A5D4 if unit_alive(ADN228, global[104]) != 1 -> 0x1A60C
|
||||
0x01A630 if unit_alive(ADN229, global[104]) != 1 -> 0x1A668
|
||||
0x01A68C if unit_alive(ADN230, global[104]) != 1 -> 0x1A6C4
|
||||
0x01A6E8 if unit_alive(ADN231, global[104]) != 1 -> 0x1A720
|
||||
0x01A744 if unit_alive(ADN232, global[104]) != 1 -> 0x1A77C
|
||||
0x01A350 if unit_alive(ADN202) != 1 -> 0x1A388
|
||||
0x01A3AC if unit_alive(ADN207) != 1 -> 0x1A3E4
|
||||
0x01A408 if unit_alive(ADN223) != 1 -> 0x1A440
|
||||
0x01A464 if unit_alive(ADN224) != 1 -> 0x1A49C
|
||||
0x01A4C0 if unit_alive(ADN225) != 1 -> 0x1A4F8
|
||||
0x01A51C if unit_alive(ADN226) != 1 -> 0x1A554
|
||||
0x01A578 if unit_alive(ADN227) != 1 -> 0x1A5B0
|
||||
0x01A5D4 if unit_alive(ADN228) != 1 -> 0x1A60C
|
||||
0x01A630 if unit_alive(ADN229) != 1 -> 0x1A668
|
||||
0x01A68C if unit_alive(ADN230) != 1 -> 0x1A6C4
|
||||
0x01A6E8 if unit_alive(ADN231) != 1 -> 0x1A720
|
||||
0x01A744 if unit_alive(ADN232) != 1 -> 0x1A77C
|
||||
0x01A77C if global[104] <= 1 -> 0x1A844
|
||||
0x01A924 if hp_pct_test(TCT206, 89.9) != 0 -> 0x1AA38
|
||||
0x01AA38 if global[104] != 0 -> 0x1AAEC
|
||||
@@ -536,12 +540,12 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01B554 if dist_lt(TCT206, ADN231, 20000) == 1 -> 0x1B598
|
||||
0x01B5E0 if hp_pct_test(ADN232, 0) == 1 -> 0x1B680
|
||||
0x01B66C if dist_lt(TCT206, ADN232, 20000) == 1 -> 0x1B6B0
|
||||
0x01B6C0 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x1AC74
|
||||
0x01B6D4 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1B140
|
||||
0x01B6E8 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x1B258
|
||||
0x01B6FC if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x1B370
|
||||
0x01B710 if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x1B488
|
||||
0x01B724 if <unknown: block entered by a branch, not by fall-through> == 5 -> 0x1B5A0
|
||||
0x01B6C0 if global[76] == 0 -> 0x1AC74
|
||||
0x01B6D4 if global[76] == 1 -> 0x1B140
|
||||
0x01B6E8 if global[76] == 2 -> 0x1B258
|
||||
0x01B6FC if global[76] == 3 -> 0x1B370
|
||||
0x01B710 if global[76] == 4 -> 0x1B488
|
||||
0x01B724 if global[76] == 5 -> 0x1B5A0
|
||||
0x01B77C if hp_pct_test(TCN207, 0) != 1 -> 0x1B79C
|
||||
0x01B7D4 if unit_alive(ADN201) != 1 -> 0x1B8A4
|
||||
0x01B840 if dist_lt(TCN207, ADN201, 15000) != 1 -> 0x1B8A4
|
||||
@@ -563,12 +567,12 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01C090 if dist_lt(TCN207, ADN231, 20000) == 1 -> 0x1C0D4
|
||||
0x01C11C if hp_pct_test(ADN232, 0) == 1 -> 0x1C1BC
|
||||
0x01C1A8 if dist_lt(TCN207, ADN232, 20000) == 1 -> 0x1C1EC
|
||||
0x01C1FC if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x1B7B0
|
||||
0x01C210 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1BC7C
|
||||
0x01C224 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x1BD94
|
||||
0x01C238 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x1BEAC
|
||||
0x01C24C if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x1BFC4
|
||||
0x01C260 if <unknown: block entered by a branch, not by fall-through> == 5 -> 0x1C0DC
|
||||
0x01C1FC if global[80] == 0 -> 0x1B7B0
|
||||
0x01C210 if global[80] == 1 -> 0x1BC7C
|
||||
0x01C224 if global[80] == 2 -> 0x1BD94
|
||||
0x01C238 if global[80] == 3 -> 0x1BEAC
|
||||
0x01C24C if global[80] == 4 -> 0x1BFC4
|
||||
0x01C260 if global[80] == 5 -> 0x1C0DC
|
||||
0x01C2B8 if hp_pct_test(TCN208, 0) != 1 -> 0x1C2D8
|
||||
0x01C310 if unit_alive(ADN201) != 1 -> 0x1C3E0
|
||||
0x01C37C if dist_lt(TCN208, ADN201, 15000) != 1 -> 0x1C3E0
|
||||
@@ -590,12 +594,12 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01CBCC if dist_lt(TCN208, ADN231, 20000) == 1 -> 0x1CC10
|
||||
0x01CC58 if hp_pct_test(ADN232, 0) == 1 -> 0x1CCF8
|
||||
0x01CCE4 if dist_lt(TCN208, ADN232, 20000) == 1 -> 0x1CD28
|
||||
0x01CD38 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x1C2EC
|
||||
0x01CD4C if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1C7B8
|
||||
0x01CD60 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x1C8D0
|
||||
0x01CD74 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x1C9E8
|
||||
0x01CD88 if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x1CB00
|
||||
0x01CD9C if <unknown: block entered by a branch, not by fall-through> == 5 -> 0x1CC18
|
||||
0x01CD38 if global[84] == 0 -> 0x1C2EC
|
||||
0x01CD4C if global[84] == 1 -> 0x1C7B8
|
||||
0x01CD60 if global[84] == 2 -> 0x1C8D0
|
||||
0x01CD74 if global[84] == 3 -> 0x1C9E8
|
||||
0x01CD88 if global[84] == 4 -> 0x1CB00
|
||||
0x01CD9C if global[84] == 5 -> 0x1CC18
|
||||
0x01D200 if hp_pct_test(ADN201, 0) != 1 -> 0x1D244
|
||||
0x01D27C if unit_alive(TCN207) != 1 -> 0x1D34C
|
||||
0x01D2E8 if dist_lt(ADN201, TCN207, 15000) != 1 -> 0x1D34C
|
||||
@@ -611,11 +615,11 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01D9EC if dist_lt(ADN201, TCN208, 20000) == 1 -> 0x1DA30
|
||||
0x01DAA8 if builtin7(ADN201, 1, Route_ADN201_p2S, 4294967295, 500) != 1 -> 0x1DB48
|
||||
0x01DBC0 if dist_lt(ADN201, TCT206, 20000) == 1 -> 0x1DC04
|
||||
0x01DC1C if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x1D258
|
||||
0x01DC30 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1D5E8
|
||||
0x01DC44 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x1D810
|
||||
0x01DC58 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x1DA38
|
||||
0x01DC6C if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x1DC0C
|
||||
0x01DC1C if global[88] == 0 -> 0x1D258
|
||||
0x01DC30 if global[88] == 1 -> 0x1D5E8
|
||||
0x01DC44 if global[88] == 2 -> 0x1D810
|
||||
0x01DC58 if global[88] == 3 -> 0x1DA38
|
||||
0x01DC6C if global[88] == 4 -> 0x1DC0C
|
||||
0x01DCC4 if hp_pct_test(ADN202, 0) != 1 -> 0x1DD08
|
||||
0x01DD4C if hp_pct_test(ADN207, 0) != 1 -> 0x1DD6C
|
||||
0x01DDA4 if unit_alive(TCN207) != 1 -> 0x1DE74
|
||||
@@ -636,11 +640,11 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x01E7D4 if builtin7(ADN207, 1, Route_ADN207_p2S, 3, 55) != 1 -> 0x1E914
|
||||
0x01E80C if unit_alive(TCN208) != 1 -> 0x1E8AC
|
||||
0x01E98C if dist_lt(ADN207, TCT206, 20000) == 1 -> 0x1E9D0
|
||||
0x01E9E8 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x1DD80
|
||||
0x01E9FC if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x1E1D4
|
||||
0x01EA10 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x1E49C
|
||||
0x01EA24 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x1E764
|
||||
0x01EA38 if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x1E9D8
|
||||
0x01E9E8 if global[96] == 0 -> 0x1DD80
|
||||
0x01E9FC if global[96] == 1 -> 0x1E1D4
|
||||
0x01EA10 if global[96] == 2 -> 0x1E49C
|
||||
0x01EA24 if global[96] == 3 -> 0x1E764
|
||||
0x01EA38 if global[96] == 4 -> 0x1E9D8
|
||||
0x01F78C if unit_state(ADN201) != 1 -> 0x1F7F8
|
||||
0x01F7E4 if unit_state(TCT206) == 1 -> 0x1F804
|
||||
0x01F85C if dist_lt(ADN201, TCT206, 10000) != 1 -> 0x1FA7C
|
||||
@@ -763,24 +767,24 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x02492C if dist_lt(TCT206, ADN202, 10000) != 1 -> 0x249EC
|
||||
|
||||
## phase 3 — 228 sites
|
||||
0x028B98 if builtin103() != 1 -> 0x28E20
|
||||
0x029C78 if unit_alive(TCN002) != 1 -> 0x29D04
|
||||
0x02A4D8 if unit_alive(TCN002) != 1 -> 0x2A60C
|
||||
0x02A630 if unit_alive(TCN003) != 1 -> 0x2A764
|
||||
0x02B0D8 if unit_alive(TCN002) != 1 -> 0x2B20C
|
||||
0x02B230 if unit_alive(TCN003) != 1 -> 0x2B310
|
||||
0x028B98 if <unknown: no static entry> != <unknown> -> 0x28E20
|
||||
0x029C78 if <unknown: no static entry> != <unknown> -> 0x29D04
|
||||
0x02A4D8 if <unknown: no static entry> != <unknown> -> 0x2A60C
|
||||
0x02A630 if <unknown: no static entry> != <unknown> -> 0x2A764
|
||||
0x02B0D8 if <unknown: no static entry> != <unknown> -> 0x2B20C
|
||||
0x02B230 if <unknown: no static entry> != <unknown> -> 0x2B310
|
||||
0x02B4F8 if unit_hp_pct(TCN001, Character_Player_Test) != 0 -> 0x2B984
|
||||
0x02B898 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x2B5F0
|
||||
0x02B8AC if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x2B698
|
||||
0x02B8C0 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x2B740
|
||||
0x02B8D4 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x2B7E8
|
||||
0x02B898 if random(3) == 0 -> 0x2B5F0
|
||||
0x02B8AC if random(3) == 1 -> 0x2B698
|
||||
0x02B8C0 if random(3) == 2 -> 0x2B740
|
||||
0x02B8D4 if random(3) == 3 -> 0x2B7E8
|
||||
0x02B9C4 if hp_pct_test(TCN004, 0) != 1 -> 0x2BFC8
|
||||
0x02BEB4 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x2BABC
|
||||
0x02BEC8 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x2BB64
|
||||
0x02BEDC if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x2BC0C
|
||||
0x02BEF0 if <unknown: block entered by a branch, not by fall-through> == 3 -> 0x2BCB4
|
||||
0x02BF04 if <unknown: block entered by a branch, not by fall-through> == 4 -> 0x2BD5C
|
||||
0x02BF18 if <unknown: block entered by a branch, not by fall-through> == 5 -> 0x2BE04
|
||||
0x02BEB4 if random(5) == 0 -> 0x2BABC
|
||||
0x02BEC8 if random(5) == 1 -> 0x2BB64
|
||||
0x02BEDC if random(5) == 2 -> 0x2BC0C
|
||||
0x02BEF0 if random(5) == 3 -> 0x2BCB4
|
||||
0x02BF04 if random(5) == 4 -> 0x2BD5C
|
||||
0x02BF18 if random(5) == 5 -> 0x2BE04
|
||||
0x02BFC8 if global[112] < 4 -> 0x2C1F8
|
||||
0x02C240 if read_freg(0) <= 300 -> 0x2CF8C
|
||||
0x02C294 if hp_pct_test(ADT301, 0) != 1 -> 0x2CF8C
|
||||
@@ -839,12 +843,12 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x02F5BC if global[124] != 0 -> 0x2F664
|
||||
0x02F5F4 if unit_alive(ADT306) != 1 -> 0x2F664
|
||||
0x02F644 if unit_relation(TCN003, ADT306) != 1 -> 0x2F664
|
||||
0x02F6A4 if hp_pct_test(ADT306, 0, 1) != 1 -> 0x2F82C
|
||||
0x02F6A4 if hp_pct_test(ADT306, 0) != 1 -> 0x2F82C
|
||||
0x02F6B8 if global[120] != 0 -> 0x2F780
|
||||
0x02F6CC if global[124] != 1 -> 0x2F780
|
||||
0x02F830 if global[108] != 1 -> 0x2F9FC
|
||||
0x02F9C8 if <unknown: block entered by a branch, not by fall-through> == 0 -> 0x2F870
|
||||
0x02F9DC if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x2F918
|
||||
0x02F9C8 if random(1) == 0 -> 0x2F870
|
||||
0x02F9DC if random(1) == 1 -> 0x2F918
|
||||
0x02FA44 if 8 < 1 -> 0x2FBC8
|
||||
0x02FC10 if 8 < 3 -> 0x2FCF4
|
||||
0x02FD3C if 8 < 4 -> 0x2FE20
|
||||
@@ -964,7 +968,7 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x034110 if global[16] >= 2 -> 0x341C4
|
||||
0x0341C4 if global[12] < 1 -> 0x3428C
|
||||
0x0341D8 if global[16] >= 1 -> 0x3428C
|
||||
0x0342EC if unit_state(ADT301, global[12]) == 1 -> 0x34358
|
||||
0x0342EC if unit_state(ADT301) == 1 -> 0x34358
|
||||
0x034344 if unit_state(ADT302) != 1 -> 0x345FC
|
||||
0x03439C if unit_state(TCN000) == 1 -> 0x343BC
|
||||
0x034400 if unit_state(ADT301) == 1 -> 0x34478
|
||||
@@ -974,20 +978,20 @@ the right-hand side is evaluated (its result lands in `special[0]`),
|
||||
0x03460C if global[20] == 8 -> 0x34634
|
||||
0x034620 if global[20] != 9 -> 0x34640
|
||||
0x034640 if global[20] != 0 -> 0x346B8
|
||||
0x034698 if unit_state(ADT301) == 1 -> 0x346B8
|
||||
0x034698 if unit_state(ADT301, 1) == 1 -> 0x346B8
|
||||
0x0346B8 if global[20] != 1 -> 0x34730
|
||||
0x034710 if unit_state(ADT302) == 1 -> 0x34730
|
||||
0x034710 if <unknown: no static entry> == 1 -> 0x34730
|
||||
0x034730 if global[20] != 2 -> 0x347A8
|
||||
0x034788 if unit_state(ADT303) == 1 -> 0x347A8
|
||||
0x034788 if <unknown: no static entry> == 1 -> 0x347A8
|
||||
0x0347A8 if global[20] != 3 -> 0x34820
|
||||
0x034800 if unit_state(ADT304) == 1 -> 0x34820
|
||||
0x034800 if <unknown: no static entry> == 1 -> 0x34820
|
||||
0x034820 if global[20] != 4 -> 0x34898
|
||||
0x034878 if unit_state(ADT305) == 1 -> 0x34898
|
||||
0x034878 if <unknown: no static entry> == 1 -> 0x34898
|
||||
0x034898 if global[20] != 5 -> 0x34910
|
||||
0x0348F0 if unit_state(ADT306) == 1 -> 0x34910
|
||||
0x0348F0 if <unknown: no static entry> == 1 -> 0x34910
|
||||
0x034910 if global[20] != 6 -> 0x34988
|
||||
0x034968 if unit_state(ADT307) == 1 -> 0x34988
|
||||
0x034968 if <unknown: no static entry> == 1 -> 0x34988
|
||||
0x034988 if global[20] != 7 -> 0x34A00
|
||||
0x0349E0 if unit_state(ADT308) == 1 -> 0x34A00
|
||||
0x034A90 if <unknown: block entered by a branch, not by fall-through> == 1 -> 0x34A30
|
||||
0x034AA4 if <unknown: block entered by a branch, not by fall-through> == 2 -> 0x34A5C
|
||||
0x0349E0 if <unknown: no static entry> == 1 -> 0x34A00
|
||||
0x034A90 if <unknown: no static entry> == <unknown> -> 0x34A30
|
||||
0x034AA4 if <unknown: no static entry> == <unknown> -> 0x34A5C
|
||||
|
||||
@@ -47,7 +47,7 @@ the stack, then reports each compare with its branch:
|
||||
| | all 28 stages |
|
||||
|---|---|
|
||||
| condition sites | **7 563** |
|
||||
| **LHS honestly unresolved** | **756 — 10.0 %** |
|
||||
| **LHS honestly unresolved** | **402 — 5.3 %** (CFG dataflow; the linear walk left 756) |
|
||||
| RHS is a plain number | 7 544 — 99.7 % |
|
||||
|
||||
🔴 **The first version of this table claimed 0.0 % unresolved. That was wrong** —
|
||||
@@ -182,4 +182,47 @@ word@+4`), so the CFG is available; the analysis is not written.
|
||||
|
||||
**Method note worth keeping:** when the same defect appears twice, fix the class.
|
||||
Patching `end_coroutine` alone left 22× more bad sites in place than it removed,
|
||||
and only another impossible-looking output exposed them.
|
||||
and only another impossible-looking output exposed them.
|
||||
|
||||
## ✅ Replaced by a CFG dataflow fixpoint — `isl_cfg.py`
|
||||
|
||||
The linear walk's honest 10 % unknown was a floor imposed by the method, not by
|
||||
the data: a block entered only by a branch has *a* well-defined state, just not
|
||||
one a straight-line pass can see. So the walk is gone, replaced by a worklist
|
||||
fixpoint that joins each block's state over its **actual predecessors** — a value
|
||||
survives only if every predecessor agrees.
|
||||
|
||||
| over all 28 stages | linear walk | CFG dataflow |
|
||||
|---|---|---|
|
||||
| instructions reached | (all, but with stale state) | **85.0 %** |
|
||||
| condition sites with an unknown LHS | 756 — 10.00 % | **402 — 5.32 %** |
|
||||
| of those, never reached at all | — | 389 |
|
||||
| joined away (predecessors genuinely disagree) | — | **13** |
|
||||
| **sites where both resolve but DISAGREE** | — | **161** |
|
||||
|
||||
Those 161 are 161 more places the linear walk reported a confident wrong answer,
|
||||
on top of the 889 the `jmp` fix caught.
|
||||
|
||||
### ⚠️ Two zero-results that were both my bug
|
||||
|
||||
The first CFG run reached only **36 %** of instructions and made things *worse*
|
||||
— 35 % unknown against the walk's 10 %. Two causes, and each surfaced as a
|
||||
suspiciously round zero:
|
||||
|
||||
1. **The phase bases reach almost nothing.** Most routines are **coroutines** the
|
||||
engine starts from its trigger queue, so they have no static predecessor at
|
||||
all. They must be seeded from every `start_coroutine` target.
|
||||
2. **The seeding found ZERO entries in a file with 216 `start_coroutine` calls.**
|
||||
The target is staged in *two* steps — `special[0] = imm`, then
|
||||
`local[0] = special[0]` — and I matched only the direct-immediate form.
|
||||
|
||||
Reachability went 36 % → 64 % → **85 %** as each was fixed. The lesson is the one
|
||||
this corpus keeps re-teaching: *a count that does not move when it should is the
|
||||
bug reporting itself.* Both times I checked because the number looked wrong, not
|
||||
because a test failed.
|
||||
|
||||
### 🟡 The 389 that remain are a real limit, not a gap
|
||||
|
||||
Nothing in the bytecode starts them. They are entered from the **trigger queue at
|
||||
`phase+272`** — by data, not by code — so no purely static analysis reaches them.
|
||||
Resolving those needs the trigger table's contents, which is a separate question.
|
||||
|
||||
Reference in New Issue
Block a user