MSL_C: build the library optimized (Clanker Warning) - #770
Closed
joeyballentine wants to merge 1 commit into
Closed
Conversation
MSL_C.PPCEABI.H was configured with `-opt level=0, ... -inline off`, but the original library was clearly built optimized. At level 0 CodeWarrior spills user locals to callee-saved registers and emits a stack frame for functions that the target objects implement as leaves. Switching to `-opt level=4, ... -inline auto,deferred` matches 54 additional functions with no source changes, taking the msl category from 31.4% to 49.3% of code matched (138 -> 192 functions). `deferred` inlining makes CodeWarrior emit function bodies in reverse source order, which the project already models as `reverse_fn_order` in tools/project.py. critical_regions.gamecube.c is therefore reordered to keep the emission order it contributes to the DOL correct; it is linked in, so the build sha1 check covers this. signal.c now matches byte-for-byte and is marked Matching.
joeyballentine
marked this pull request as draft
August 3, 2026 04:21
|
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
80.39% | 100.00% | +77 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | exit |
82.83% | 100.00% | +41 |
| ✅ | abort |
76.64% | 100.00% | +36 |
main/MSL_C/MSL_Common/alloc
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
6.84% | 19.87% | +739 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | __pool_free |
10.91% | 100.00% | +78 |
| ✅ | deallocate_from_fixed_pools |
67.67% | 100.00% | +111 |
| ✅ | deallocate_from_var_pools |
16.61% | 100.00% | +550 |
main/MSL_C/MSL_Common/ansi_files
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
32.04% | 35.71% | +28 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | __flush_all |
90.54% | 100.00% | +10 |
| ✅ | __close_all |
89.14% | 100.00% | +18 |
main/MSL_C/MSL_Common_Embedded/ansi_fp
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .data |
59.55% | 100.00% | +145 |
| ✅ | .rodata |
83.26% | 100.00% | +37 |
| 📈 | .text |
17.61% | 99.33% | +11266 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | __dec2num |
18.40% | 97.81% | +3354 |
| ✅ | __num2dec |
36.19% | 100.00% | +268 |
| ✅ | __num2dec_internal |
21.28% | 100.00% | +746 |
| ✅ | __minus_dec |
33.58% | 100.00% | +847 |
| ✅ | __equals_dec |
45.45% | 100.00% | +146 |
| ✅ | __two_exp |
8.20% | 100.00% | +5526 |
| ✅ | __timesdec |
40.13% | 100.00% | +378 |
main/MSL_C/MSL_Common/arith
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
55.00% | 100.00% | +7 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | abs |
55.00% | 100.00% | +7 |
main/MSL_C/MSL_Common/buffer_io
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
19.98% | 30.54% | +85 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | __flush_buffer |
56.22% | 100.00% | +85 |
main/MSL_C/MSL_Common/ctype
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
11.00% | 60.00% | +29 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | tolower |
18.33% | 100.00% | +29 |
main/MSL_C/MSL_Common/direct_io
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
39.63% | 48.61% | +168 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | __fwrite |
84.73% | 100.00% | +119 |
| ✅ | fwrite |
60.16% | 100.00% | +49 |
main/MSL_C/MSL_Common/file_io
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
24.19% | 43.75% | +338 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | fflush |
89.19% | 100.00% | +33 |
| ✅ | fclose |
31.46% | 100.00% | +304 |
main/MSL_C/MSL_Common/FILE_POS
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
63.47% | 100.00% | +309 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | fseek |
64.48% | 100.00% | +38 |
| ✅ | _fseek |
70.44% | 100.00% | +169 |
| ✅ | ftell |
39.10% | 100.00% | +102 |
main/MSL_C/MSL_Common/mbstring
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
49.58% | 64.18% | +117 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | wcstombs |
49.67% | 100.00% | +140 |
| ️ |
mbtowc |
16.46% | 0.00% | --47 |
| ✅ | is_utf8_complete |
89.90% | 100.00% | +23 |
main/MSL_C/MSL_Common/mem
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
29.91% | 100.00% | +257 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | memcmp |
11.05% | 100.00% | +67 |
| ✅ | __memrchr |
0.00% | 100.00% | +44 |
| ✅ | memchr |
0.00% | 100.00% | +44 |
| ✅ | memmove |
49.84% | 100.00% | +102 |
main/MSL_C/MSL_Common/mem_funcs
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
78.71% | 100.00% | +153 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | __copy_longs_rev_unaligned |
82.44% | 100.00% | +30 |
| ✅ | __copy_longs_unaligned |
76.25% | 100.00% | +45 |
| ✅ | __copy_longs_rev_aligned |
79.26% | 100.00% | +34 |
| ✅ | __copy_longs_aligned |
77.32% | 100.00% | +42 |
main/MSL_C/MSL_Common/printf
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .data |
50.00% | 73.74% | +132 |
| ✅ | .rodata |
97.30% | 100.00% | +1 |
| 📈 | .text |
76.30% | 92.38% | +1368 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | sprintf |
52.84% | 100.00% | +105 |
| ✅ | vsprintf |
27.17% | 100.00% | +87 |
| ✅ | vprintf |
66.63% | 100.00% | +50 |
| ✅ | fprintf |
88.95% | 100.00% | +24 |
| ✅ | __StringWrite |
36.15% | 100.00% | +68 |
| ✅ | __FileWrite |
67.41% | 100.00% | +28 |
| ✅ | __pformatter |
85.62% | 100.00% | +274 |
| 📈 | float2str |
72.16% | 89.11% | +300 |
| ✅ | round_decimal |
76.92% | 100.00% | +69 |
| 📈 | double2hex |
73.50% | 97.04% | +193 |
| 📈 | longlong2str |
84.05% | 86.80% | +20 |
| ️ |
long2str |
82.23% | 80.62% | --8 |
| 📈 | parse_format |
82.15% | 94.09% | +153 |
main/MSL_C/MSL_Common/rand
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
85.00% | 100.00% | +4 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | rand |
85.00% | 100.00% | +4 |
main/MSL_C/MSL_Common/scanf
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
73.71% | 92.96% | +802 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | sscanf |
57.43% | 100.00% | +83 |
| ✅ | __StringRead |
62.75% | 100.00% | +53 |
| 📈 | __sformatter |
81.64% | 93.81% | +301 |
| 📈 | parse_format |
62.72% | 89.64% | +363 |
main/MSL_C/MSL_Common/signal
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
70.00% | 100.00% | +57 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | raise |
70.00% | 100.00% | +57 |
main/MSL_C/MSL_Common/string
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
32.46% | 68.73% | +445 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | strstr |
67.50% | 100.00% | +33 |
| ✅ | strchr |
0.00% | 100.00% | +48 |
| ✅ | strncmp |
27.81% | 100.00% | +46 |
| ✅ | strcmp |
59.07% | 100.00% | +121 |
| ✅ | strcat |
35.00% | 100.00% | +28 |
| ✅ | strncpy |
27.06% | 100.00% | +49 |
| ✅ | strcpy |
51.04% | 100.00% | +90 |
| ✅ | strlen |
0.00% | 100.00% | +28 |
main/MSL_C/MSL_Common/strtold
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
30.97% | 83.55% | +2233 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | __strtold |
32.03% | 86.39% | +2233 |
main/MSL_C/MSL_Common/strtoul
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .data |
50.00% | 52.94% | +4 |
| 📈 | .text |
68.24% | 83.29% | +318 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | __strtoull |
73.17% | 92.95% | +204 |
| 📈 | __strtoul |
76.79% | 89.58% | +113 |
main/MSL_C/MSL_Common_Embedded/uart_console_io_gcn
| Section | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | .text |
69.61% | 92.94% | +47 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| 📈 | __write_console |
68.37% | 92.65% | +47 |
main/MSL_C/MSL_Common/wchar_io
| Section | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | .text |
56.88% | 100.00% | +58 |
| Function | From | To | Bytes | |
|---|---|---|---|---|
| ✅ | fwide |
56.88% | 100.00% | +58 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MSL_C.PPCEABI.His configured with-opt level=0, peephole, schedule, nospaceand-inline off, but the original library was built optimized. At level 0 CodeWarrior spills user locals to callee-saved registers and emits a stack frame for functions the target objects implement as leaves, so almost nothing in the library could match.Changing the library flags to
-opt level=4, peephole, schedule, nospaceand-inline auto,deferredmatches 54 additional functions with no source changes:abort_exit,arith,mem,mem_funcs,rand,signal,wchar_io,FILE_POSandmath_ppcgo to fully matching functions;stringgoes from 0/10 to 8/10 andprintffrom 0/14 to 7/14.How the flags were chosen
I swept the plausible variants across every MSL_C unit and picked by total exact-matching functions rather than by any single file:
-opt level=0 -inline off(current)-opt level=4 -inline off-opt level=4 -inline auto/-inline on-opt level=4 -inline auto,deferred-opt level=4,...,space-opt nopeephole-opt noscheduleMeasured end to end with the project's own progress metric,
deferredis worth 41.92% -> 49.29% of msl code on top oflevel=4alone. It is only +3 functions but roughly 8KB more matched code, landing large bodies inprintfandansi_fp— which is why it is included rather than dropped.-sym onand-str poolwere left as they are; neither changed any output in the sweep.Why critical_regions.gamecube.c is reordered
deferredinlining makes CodeWarrior emit function bodies in reverse source order. The project already models this —tools/project.pysetsreverse_fn_orderfrom exactly this flag value.critical_regions.gamecube.cis aMatchingobject, so it is linked into the DOL and its emission order has to stay correct. Its three stub functions are reordered so the object still emits__end_critical_region,__begin_critical_region,__kill_critical_regions, matching the target. Verified withreadelfagainstbuild/GQPE78/obj/. No other linked object changed order.signal.cnow matches byte-for-byte and is markedMatching.Verification
ninjais clean and the DOL sha1 check passes, so everyMatchingobject still produces identical linked output.I checked the other libraries for the same class of misconfiguration while I was here;
cflags_bfbbandcflags_dolphinare already correct and no variant improved them.