Skip to content

Commit e8f16c0

Browse files
gyntclaude
andcommitted
cheat sheet: record four rejected explanations for the LTCG ecx spill
Each was tested on processSyncPacket / translateMultiplayerIDsIntoPlayerIDs and left the match unchanged at 26.2%, so the list saves repeating them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 306b4b0 commit e8f16c0

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

‎IMPLEMENTATION_CHEAT_SHEET.md‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,22 @@ A volatile register (usually ECX or EDX) that stays live across a call in the or
490490
that call was compiled with LTCG. This is fixable, not a permanent blocker: add the `.cpp` to `cmake/compiler-flags-gl.txt`
491491
so it is built with `/GL`. SHC_3BB0A8C1_0x00504EE0 went from 38.5% to 100% and SHC_3BB0A8C1_0x0045B7F0 to 100% that way.
492492

493-
`/GL` on both sides does not always recover it, and the reason is not yet known. `processSyncPacket` and its callee
493+
`/GL` on both sides does not always recover it, and the reason is still unknown. `processSyncPacket` and its callee
494494
`translateMultiplayerIDsIntoPlayerIDs` are both listed in `compiler-flags-gl.txt` and both produce IL objects
495495
(`0000 ffff`), yet the caller still emits `mov esi, ecx` and spills `this`, where the original keeps it in `ecx`
496-
across the call. The entire remaining 26% diff on `processSyncPacket` is that one register rename. If you hit this,
497-
do not assume the `/GL` entry is missing - check the object first.
496+
across the call. The entire remaining 26% diff on `processSyncPacket` is that one register rename.
497+
498+
Four explanations were tested on that pair and all are wrong, so do not spend time on them again:
499+
500+
- *The callee is exported from the DLL.* `OpenSHC.dll` exports exactly one symbol, `luaopen_OpenSHC`.
501+
- *Its address is taken by `MACRO_FUNCTION_RESOLVER`.* True, but it is equally true of the known-good cases above.
502+
- *Every caller has to be in the LTCG set.* Adding the six other callers of
503+
`translateMultiplayerIDsIntoPlayerIDs` to `compiler-flags-gl.txt` left the match at exactly 26.2%.
504+
- *Caller and callee have to share a translation unit.* `#include`-ing the callee's `.cpp` into the caller and
505+
dropping it from the source list still emits `mov esi, ecx`, and still emits a real `call` rather than inlining.
506+
507+
What is left untested is whether the original callee had internal linkage, which a member function declared in the
508+
class header and reached through a resolver cannot have.
498509

499510
### Parameters
500511

0 commit comments

Comments
 (0)