Skip to content

TU promotion is quietly spending CONVERTED credit — 15 of 29 exception rows, and rising #2029

Description

@andrewboudreau

TU promotion is now the single largest consumer of converted-backslide-exceptions.jsonl, and nothing tracks the running total. This issue is to make the cost visible and to name the concrete work that buys it back.

The number

config/converted-backslide-exceptions.jsonl on origin/main (e9de9103a) holds 29 rows. Classified by the reason text:

cause rows
TU promotion consolidating a banked path into a mixed TU 15
everything else 14

Two open PRs add eight more: #2023 adds 4 (ov004/dScMgBase_c) and #2024 adds 4 (ov002/daObjPushblock_c). That takes TU promotion to 23 of 37, and #1993 still has slices 2-5 to come.

Why this is a cost and not a defect

The rows are honest. The mechanism is documented and the reason text on each is specific and true — I checked #2023's and #2024's against tiers.score_file rather than reading them. A promoted TU is scored file-wide, so when a reconstructed TU absorbs both banked and never-converted functions from the same linker run, the file cannot pass no_mangled_refs (a reconstructed TU must spell vague-linkage symbols like _ZN7fBase_cnwEj directly or its range will not link) and often cannot pass no_raw_offset or no_unk_field either, because the un-migrated siblings still use them.

The trade also goes the right way under this project's stated ordering — byte-match first, readability last. src_tu/ is not in the build, so a reconstruction sitting there is gated by nothing; promoting it puts the range under the ROM link. That is a real verification gain.

But it is bought with readability credit, once per promotion, permanently, and no single PR ever has to look at the total. That is exactly the shape of thing that is obvious in hindsight and invisible in review.

What buys it back

The credit returns for free the moment a TU's un-migrated members are migrated: the file-wide score then passes and the exception rows can be deleted. So each row names a concrete piece of decomp work.

ov004/dScMgBase_c (#2023) — 8 functions, 4 banked, 4 not. The four standing between this class and its four CONVERTED rows:

  • _ZN11dScMgBase_c19BeforeInitResourcesEv
  • _ZN11dScMgBase_c14BeforeBehaviorEv
  • _ZN11dScMgBase_c12BeforeRenderEv
  • _ZN11dScMgBase_c21AfterCleanupResourcesEj

The absorbing src/actors/dScMgBase_c.cpp measures 384 lines, 32 mangled _Z declarations, 15 raw pointer casts, 4 unk_<off> fields. Migrating those four should clear no_raw_offset and no_unk_field for the file; no_mangled_refs is the structural one and may not clear at all while the TU has to hand-spell its allocator.

Asks

  1. Report the total. Have tiers_ratchet.py --check print the exception-row count and how many are TU-promotion-caused, the way it already prints (N moved into a promoted TU). A number in the gate output is what makes a slow drift arguable.
  2. Prefer the free promotions. Where a TU's members are all either banked or all un-banked, promotion costs nothing. ov004/dScMgBase_c is mixed and costs 4; the six Mg* TUs in the same PR are unmixed and cost 0. Ordering slices to take the unmixed ones first is free and defers the cost to when it can be avoided entirely.
  3. Decide whether the file-wide criteria are still the right instrument for a promoted TU. Add fail-closed compiler-owned C++ TU promotion #2001 is already moving tiers_ratchet toward per-member identities. If a promoted TU were scored per member, a mixed TU would keep credit for the members that earned it and lose it only for the ones that did not — and most of these 23 rows would not need to exist. That is a design question, not a bug, and it should be settled before slices 2-5 add more rows under the current rule.

Not a blocker on anything

#2023 and #2024 should both land with their rows as written. This is about the trend, not those PRs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions