CT_00_046 - Improve Long branch/jump support (GCC)
About
Once a function exceeds 1M in total size the possibility exists that jump may not be able to reach its intended target. This can happen for a variety of reasons:
LTO and aggressive inlining can generally improve code performance, but will tend to make larger functions.
Some uarchs desire code alignments for loop boundaries and such. Honoring those alignment needs will also tend to make larger funtions.
Aggressive hot/code partitioning will move expected cold code after the main part of the function, thus increasing the chance that we'll have a long branch to anther point in the function.
$ra is used as a scratch register for these cases and as a result is not available to the register allocator. Making it available, even in limited cases could improve register allocation. For example, in a non-leaf function where the size of the function is known to be small (<1M) or there are no conditional branches we could use $ra as an additional scratch register. A review of IRA/LRA doesn't show a particularly good way to add $ra to the usable set of registers, but that can probably be handled by adding another target hook.
GCC currently does a poor job at computing instruction lengths, particularly WRT compressed instructions. As a result it will sometimes use less efficient mechanisms than it could for some call/jump sequences. This could be improved.
In particular, the use of $ra as a scratch in a long jump sequence can clobber the return-address-stack predictors available in higher performance hardware. While this is not expected to happen often in practice, when it does happen, the performance hit will be significant – once the stack gets out of sync we can get a cascade of mispredicts. We would like to see this addressed using a register scavenging scheme – essentially looking prior to the branch or at the target/fallthrough of a branch to see if there is a scratch register already available. If so, that scratch register should be preferred over $ra. We can still fall back to $ra if no such register can be found.
The Embecosm team is reported to have worked a bit on hot/code partitioning in the presence of limited branching range which may be of value here as well.
Stakeholders/Partners
RISE:
Ventana: Jeff Law
SiFive: Andrew Waterman
External:
Dependencies
Status
Development | NOT YET STARTED |
|
|---|---|---|
Development Timeline | NA |
|
Upstreaming | NOT YET STARTED |
|
Upstream Version |
|
|
Contacts | Jeff Law (Ventana) |
|
Dependencies | None |
|
Updates
Feb 3, 2025
Added as project for 1H2025.