RISC-V: Use long jumps when crossing section boundaries.
GCC now uses long jumps for RISC-V when jumping between code sections that may be far apart, preventing linker errors with -freorder-blocks-and-partition.
This patch addresses an issue in the RISC-V backend of GCC where jumps between different code sections (e.g., hot code in .text and cold code in .text.unlikely) could exceed the range of the JAL instruction when using -freorder-blocks-and-partition. To fix this, GCC now checks for cross-section jumps and uses the longer AUIPC+JALR instruction sequence (8 bytes) instead of the shorter JAL instruction (4 bytes) when necessary, ensuring that jumps can reach targets beyond the JAL instruction’s ±1MB range.
In Details
The RISC-V backend in GCC uses the JAL instruction for jumps, which has a limited range of ±1MB. When using -freorder-blocks-and-partition, code can be placed in separate sections (e.g., .text and .text.unlikely) that might be placed far apart by the linker. The patch modifies the length attribute calculation in riscv.md to check for CROSSING_JUMP_P and use the longer AUIPC+JALR sequence when a jump crosses section boundaries.
For Context
When compiling code, GCC divides it into different sections, such as .text for executable code and .data for data. The -freorder-blocks-and-partition optimization can further split code into hot and cold sections and place them in different locations in memory. RISC-V's JAL instruction has a limited jump range. This patch ensures that when hot and cold sections are far apart, GCC uses a longer jump sequence to reach the destination, avoiding linker errors caused by jumps that are out of range.