On AArch64, it is safe to let the linker relax unconditional branches if
x16 is available across the branch. If x16 is not available across the
branch but some other register is, we can relax the branch by either
spilling x16 or using the free register for an indirect branch.
Programs that use machine function splitting care most about the
performance of hot code at the expense of the performance of cold code.
When there is a branch from the cold section to the hot section,
prioritize leaving hot code intact. For H -> C branches, avoid spilling
since that requires code for restoring the spilled register in the hot
section. If no registers are free and we must spill, place the restore
block at the end of the hot function instead of the middle and make the
restore block jump to the destination.
Hot -> Cold [x16 is free across the branch] Do nothing; let the linker relax the branch. Cold -> Hot [x16 is free across the branch] Do nothing; let the linker relax the branch. Hot -> Cold [x16 not free, but others are] Spill x16; let the linker relax the branch. Cold -> Hot [x16 not free, but others are] Manually insert an indirect branch. Hot -> Cold [No free regs] Spill x16; let the linker relax the branch. Cold -> Hot [No free regs] Spill x16 and put the restore block at the end of the hot function; let the linker relax the branch. Ex: [Hot section] func.hot: ... hot code... func.restore: ... restore x16 ... B func.hot [Cold section] func.cold: ... spill x16 ... B func.restore