Repository navigation
Conversation
…are read A VF write to some lanes of its variable joined the variable's earlier value whenever another lane had been written before, to keep those lanes in the same register. Lane flags accumulate along a path, so on a loop's second trip a write was joined to the last trip's value even when every lane it kept was written again before any read. Values rewritten lane by lane on each trip then stayed live for the whole program, and Tyra's stapip_cull_td_vu1, which SCE vcl compiles, ran out of VF registers for outputColor3. Work out which lanes are read after each partial write before they are written again, with a block's outputs read at its exit, and join only when one of the kept lanes is. completeLiveRanges already joins a read that needs lanes from several writes to all of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Follow-up to #9.
Problem
A VF write to some lanes of a variable (
add.xyz fC, ...) was joined to the variable's earlier value whenever any other lane had been written before, so that the kept lanes stay in the same register.BranchStateaccumulates the lane flags along a path, so on a loop's second trip the write was joined to the previous trip's value even when every lane it kept was written again before being read (add.xyz fCthenadd.w fC, thensq fC). Values rewritten lane by lane on every trip then stayed live for the whole program and pinned a register each.Tyra's
stapip_cull_td_vu1builds its three output colours this way; SCE vcl compiles it, openvcl failed with "ran out of VF registers (31 available) for outputColor3" (its exact live ranges need 29).Fix
Before the branch-state walk,
collectLanesLiveAfterWritesworks out, for each partial write, which of the lanes it keeps are read before they are written again (a block'sout_vfoutputs count as read at its exit).BranchState::writeFloatjoins the write to the earlier value only when one of those lanes is live. A read that needs lanes from several writes is still joined to all of them bycompleteLiveRangesfrom #9.Tests
test_loop_liveness.cppgains "a partial write starts a new value when the lanes it keeps are dead": a loop that writesfCxyz then w before storing it, with four VF registers; current master runs out of registers, this passes.Effect on generated code
Checked against the ps2gl fixtures, Tyra's 15 programs and quake2-ps2's, each assembled with dvp-as and checked with vu-checker, master (17cbadb) against this branch:
stapip_cull_td_vu1now compiles.scei,billboard_renderer, 10 Tyra programs, quake2textured_triangles), 21 are byte-identical.general_tri,general_pv_diff_tri,general_quadandgeneral_pv_diff_quad("instruction 171 (move.xyzw) reads VF30, which holds any of intensity66, normal depending on the path") is gone, and nothing new is reported.