phase10: merge 15 + size-first re-ranking — 451 distinct bodies / 460 regions
+1 body (0x800C1424, worker C claim 18, closed with two register-allocation levers: guard-on-the-expression so CSE keeps one load whose destination is the guard's operand, and a counter initialisation as a statement so the counter takes a2). FORECAST FINDING (the important part of this commit): measured the matched corpus against the remaining pool and re-ranked the lever files. matched: 459 regions, median 48 bytes, 454 of 459 at <=200 bytes remaining levered rows: median 456 bytes Size is therefore the strongest predictor left, so .run/p10/lever*.tsv now ranks size band FIRST and lever second: P1 = <=200B and levered (47 rows across partitions) P2 = <=200B, no lever (412) <- the unexploited band that actually matches P3 = levered but >200B (503) P4 = rest (303) Worker C had proposed continuing on fresh P1 rows (old meaning: known-callee), which under the new ranking are mostly P3 -- the 200-800B band where the allocator/optimiser tie-breaks live. Redirected to P2 from the top. Worker C's measured re-flag accepted (last 12 attempts produced 1 match, 8 of 9 sub-8-byte negatives being cc1 scheduling/allocation with no spelling lever) and answered with a band change rather than a stop, since C is at 47% context.
This commit is contained in:
@@ -1272,7 +1272,7 @@
|
||||
1265 0x801007E0 0x80100808 40 fallthrough 3 frame 1 - 1
|
||||
#
|
||||
# listed=1265
|
||||
# excluded_already_registered=459
|
||||
# excluded_already_registered=460
|
||||
# excluded_bad_extent_start=8
|
||||
# excluded_degenerate_body=252
|
||||
# excluded_delay_slot_start=5
|
||||
@@ -1280,5 +1280,5 @@
|
||||
# excluded_low_confidence_grade=90
|
||||
# excluded_named_exclusion=9
|
||||
# excluded_no_extent=0
|
||||
# excluded_recorded_negative=142
|
||||
# excluded_recorded_negative=141
|
||||
# excluded_trapping_arith=54
|
||||
|
||||
|
@@ -359,6 +359,7 @@
|
||||
0x800BFEC0 0x800BFEE0 src/func_800BFEC0.c
|
||||
0x800BFEE0 0x800BFF00 src/func_800BFEE0.c
|
||||
0x800BFF00 0x800BFF20 src/func_800BFF00.c
|
||||
0x800C1424 0x800C14BC src/func_800C1424.c
|
||||
0x800C1EA8 0x800C1F04 src/func_800C1EA8.c
|
||||
0x800C5C84 0x800C5CBC src/func_800C5C84.c
|
||||
0x800F2F6C 0x800F2FB8 src/func_800F2F6C.c maspsx=off
|
||||
|
||||
|
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* func_800C1424 — 152 bytes at 0x800C1424..0x800C14BC
|
||||
*
|
||||
* Byte-identical reconstruction of a framed table search and release: a
|
||||
* pointer field on the object is the base of 30 twelve-byte records, the record
|
||||
* whose first word matches a key is found, and that record is released through
|
||||
* two calls with the found pointer cleared.
|
||||
*
|
||||
* The observed instructions are:
|
||||
* addiu sp,sp,-32
|
||||
* sw ra,24(sp)
|
||||
* sw s1,20(sp)
|
||||
* sw s0,16(sp)
|
||||
* lw a0,468(a0) base = *(int **)(p + 468)
|
||||
* nop (load delay)
|
||||
* beqz a0,0x800C14A4 if (base == 0) return
|
||||
* nop
|
||||
* beqz a1,0x800C14A4 if (key == 0) return
|
||||
* move s0,zero (delay slot) found = 0
|
||||
* move a2,zero i = 0
|
||||
* move s1,a0 base (copied for the calls)
|
||||
* addiu v1,s1,2356 e = (char *)base + 2356
|
||||
* lw v0,0(v1)
|
||||
* nop
|
||||
* bne v0,a1,0x800C1470 if (*e == key) { found = e; break; }
|
||||
* nop
|
||||
* j 0x800C1480
|
||||
* move s0,v1 (delay slot)
|
||||
* addiu a2,a2,1 i++
|
||||
* slti v0,a2,30
|
||||
* bnez v0,0x800C1458
|
||||
* addiu v1,v1,12 (delay slot) e += 12
|
||||
* beqz s0,0x800C14A4 if (found == 0) return
|
||||
* move a0,s1 (delay slot)
|
||||
* move a1,zero
|
||||
* jal 0x800263A8
|
||||
* move a2,s0 (delay slot)
|
||||
* sw zero,0(s0) *found = 0
|
||||
* move a0,s1
|
||||
* jal 0x80026560
|
||||
* move a1,v0 (delay slot)
|
||||
* lw ra,24(sp)
|
||||
* lw s1,20(sp)
|
||||
* lw s0,16(sp)
|
||||
* addiu sp,sp,32
|
||||
* jr ra
|
||||
* nop
|
||||
*
|
||||
* The frame is 32 bytes: the 16-byte o32 outgoing argument area, `s0` at
|
||||
* 16(sp), `s1` at 20(sp) and `ra` at 24(sp). TWO source-shape facts are
|
||||
* load-bearing, and both are about register allocation rather than semantics:
|
||||
*
|
||||
* 1. The guard must be written against the **expression**, not the local:
|
||||
* `if (*(int **)(p + 468) == 0) return;` and only then
|
||||
* `base = *(int **)(p + 468);`. cc1's CSE then keeps ONE load whose
|
||||
* destination is the guard's operand (`a0`) and emits the `move s1,a0` copy
|
||||
* for the longer live range. Writing the guard against the local instead
|
||||
* makes cc1 load straight into `s1` and the copy disappears (148 bytes).
|
||||
* 2. `i = 0;` must be a **statement before** the base assignment, not the
|
||||
* `for`-initialiser: scheduled early, `a0` still holds base, so the loop
|
||||
* counter takes `a2` (the original) rather than `a0` (152 vs 12 differing
|
||||
* bytes with the counter in a0).
|
||||
*
|
||||
* The search is a counted loop with a byte-stride induction pointer (`v1 += 12`)
|
||||
* and a separate counter, and the "found" path sits behind a `j`, so the loop is
|
||||
* written as a `break`. `*found = 0` is a separate statement between the two
|
||||
* calls, which is why the store follows the first `jal`.
|
||||
*
|
||||
* LIMITS: the function name, the callees' arities and parameter types, the
|
||||
* record stride 12, the count 30, the base offset 2356 and the key's meaning
|
||||
* are hypotheses reconstructed from the disassembly. Only the compiled bytes
|
||||
* are evidence.
|
||||
*/
|
||||
|
||||
int func_800263A8(int *, int, int *);
|
||||
void func_80026560(int *, int);
|
||||
|
||||
void func_800C1424(char *p, int key) {
|
||||
int *e;
|
||||
int *found;
|
||||
int i;
|
||||
int *base;
|
||||
int r;
|
||||
|
||||
if (*(int **)(p + 468) == 0)
|
||||
return;
|
||||
if (key == 0)
|
||||
return;
|
||||
|
||||
found = 0;
|
||||
i = 0;
|
||||
base = *(int **)(p + 468);
|
||||
e = (int *)((char *)base + 2356);
|
||||
for (; i < 30; i++) {
|
||||
if (*e == key) {
|
||||
found = e;
|
||||
break;
|
||||
}
|
||||
e = (int *)((char *)e + 12);
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
return;
|
||||
|
||||
r = func_800263A8(base, 0, found);
|
||||
*found = 0;
|
||||
func_80026560(base, r);
|
||||
}
|
||||
Reference in New Issue
Block a user