Avoid a heap allocation in TerminatorEdges::AssignOnReturn [-0.13%] - #64
Draft
xmakro wants to merge 1 commit into
Draft
Avoid a heap allocation in TerminatorEdges::AssignOnReturn [-0.13%]#64xmakro wants to merge 1 commit into
xmakro wants to merge 1 commit into
Conversation
Call terminators have at most one return target and Yield at most two, yet building their edges heap-allocated a boxed slice on every visit, repeated by every dataflow analysis. Use inline SmallVec storage; InlineAsm with many targets still spills to the heap. The inline capacity of 2 is load-bearing: SmallVec<[BasicBlock; 4]> is the same 24 bytes (the union already reserves 16 for the heap variant), but measured at +0.01% versus -0.13% for capacity 2, so the larger inline array is not free despite the identical size.
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.
Call terminators have at most one return target and Yield at most two, yet building their edges heap-allocated a boxed slice on every visit, repeated by every dataflow analysis. Use inline SmallVec storage; InlineAsm with many targets still spills.
The inline capacity of 2 is load-bearing and counter-intuitive.
SmallVec<[BasicBlock; 4]>is exactly the same 24 bytes (the union already reserves 16 bytes for the heap variant), so on size grounds capacity 4 looks strictly better. It is not: measured alone, capacity 4 gives +0.01% while capacity 2 gives -0.13%. Same struct size, different codegen — the inline array is 8 vs 16 bytes to initialize and move. Do not "simplify" this constant upward without re-measuring.Result: -0.13% geomean, cargo check -0.32%, ripgrep check -0.25%, 0 regressed cells. This is the only change of five in this batch whose isolated measurement clears 0.25% on any cell.
Measured in isolation against a clean base (ThinLTO stage2, glibc, instructions:u, full scenario, 5 crates x 3 profiles = 15 cells). This change was measured alone, not as part of a batch.
Reviewed adversarially before submission; findings that survived are reflected in the code and described above.