[RFC PATCH 0/5] RISC-V: Add Zcmt table-jump relaxation support
Jiawei <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
This RFC series adds RISC-V Zcmt table-jump relaxation support to GNU ld. The optimization is default-off and must be requested with `--relax-zcmt`. The implementation follows a post-relaxation profitability model. It records the residual `R_RISCV_CALL`, `R_RISCV_CALL_PLT`, and `R_RISCV_JAL` opportunities that still have paired `R_RISCV_RELAX` relocations after ordinary RISC-V relaxation. It then ranks JT and JALT candidates separately, uses a deterministic prefix selection, accounts for the JVT payload cost, and emits no `.riscv.jvt` section if no positive-benefit table is selected. Runtime policy: - when a non-empty `.riscv.jvt` is emitted, the linker defines local `__jvt_base$` at the table base; - programs that execute `cm.jt`/`cm.jalt` remain responsible for initializing CSR `jvt` to `__jvt_base$` first; - when no profitable JVT is emitted, `__jvt_base$` is not defined; - generic startup code that unconditionally references `__jvt_base$` is not supported unless it arranges an optional reference or is linked only when a JVT is emitted. ISA/profile policy: - Zcmt relaxation is enabled only when output attributes explicitly support `zcmt`, `zca`, and `zicsr`; - output attributes containing `zcd` disable Zcmt relaxation because the encodings conflict. Scope: - non-position-independent executable links only; - PIC, PIE, and shared-object links are conservatively not relaxed; - no Linux ABI claim for automatic `jvt` initialization; Open questions: - Is the `__jvt_base$` emission policy acceptable for v1? - Is `R_RISCV_TABLE_JUMP` acceptable as an internal linker relocation? - Are `.riscv.jvt` section naming, flags, and 64-byte alignment suitable? - Should objdump present JVT entries as `jvt.jt[]`/`jvt.jalt[]`, or use a more conservative `.word`/`.dword` presentation? (Patch 4 is separable; if maintainers prefer, the linker relaxation support can be reviewed independently from the objdump JVT annotation.) - Is default-off `--relax-zcmt` the desired upstream user interface? Contributors: This RFC builds on earlier Zcmt table-jump relaxation work carried out with contributions and discussions from Embecosm, SiFive and ISCAS. Thanks to Jeremy Bennet, Kito Cheng, Mary Bennett, Nandni Jamnadas, Simon Cook, Charlie Keaney, Hau Hsu, Jerry Zhang Jian, Sinan Lin, Shihua Liao and Yulong Shi for the earlier work and feedback that helped shape this series. Since this upstream version has been substantially reworked, the commit authorship is limited to the current patch submission, while the earlier collaborative work is acknowledged here rather than carrying over historical authorship trailers. RISC-V: Add Zcmt table-jump relocation definitions RISC-V: Add Zcmt table-jump relaxation ld: Add RISC-V --relax-zcmt option RISC-V: Decode Zcmt JVT entries in objdump RISC-V: Add Zcmt table-jump linker tests bfd/elfnn-riscv.c | 1134 ++++++++++++++++- bfd/elfxx-riscv.c | 4 + bfd/elfxx-riscv.h | 21 + include/elf/riscv.h | 5 + include/opcode/riscv.h | 9 + ld/NEWS | 3 + ld/emultempl/riscvelf.em | 17 +- ld/gen-doc.texi | 2 +- ld/ld.texi | 35 + ld/ldlex.h | 2 + ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 50 + ld/testsuite/ld-riscv-elf/table-jump-addend.d | 18 + ld/testsuite/ld-riscv-elf/table-jump-addend.s | 21 + .../ld-riscv-elf/table-jump-base-collision.d | 4 + .../ld-riscv-elf/table-jump-base-collision.s | 18 + .../table-jump-base-local-collision.d | 4 + .../table-jump-base-local-collision.s | 17 + .../ld-riscv-elf/table-jump-be32-bytes.d | 10 + .../ld-riscv-elf/table-jump-be32-text.d | 13 + .../ld-riscv-elf/table-jump-be64-bytes.d | 10 + .../ld-riscv-elf/table-jump-be64-text.d | 13 + .../ld-riscv-elf/table-jump-benefit.d | 17 + .../ld-riscv-elf/table-jump-benefit.s | 51 + .../table-jump-default-jvt-relocs.d | 9 + .../table-jump-default-jvt-symbol.d | 10 + .../ld-riscv-elf/table-jump-default-jvt.d | 12 + .../ld-riscv-elf/table-jump-default-no-jvt.d | 15 + .../ld-riscv-elf/table-jump-dump-unknown.d | 25 + .../ld-riscv-elf/table-jump-emit-relocs.d | 9 + .../ld-riscv-elf/table-jump-equal-benefit.d | 18 + .../ld-riscv-elf/table-jump-equal-benefit.s | 19 + .../table-jump-gc-comdat-symbol.d | 9 + .../ld-riscv-elf/table-jump-gc-comdat.d | 11 + .../ld-riscv-elf/table-jump-gc-comdat.s | 18 + .../ld-riscv-elf/table-jump-gc-dead-symbol.d | 9 + .../ld-riscv-elf/table-jump-gc-dead.d | 11 + .../ld-riscv-elf/table-jump-gc-dead.s | 18 + ld/testsuite/ld-riscv-elf/table-jump-jalt.d | 18 + ld/testsuite/ld-riscv-elf/table-jump-jt.d | 23 + .../table-jump-multiple-local-sym-2.s | 12 + .../table-jump-multiple-local-sym.d | 16 + .../table-jump-multiple-local-sym.s | 18 + .../table-jump-no-benefit-jvt-ref.d | 4 + .../table-jump-no-benefit-jvt-ref.s | 16 + .../table-jump-no-benefit-section.d | 9 + .../table-jump-no-benefit-symbol.d | 9 + .../ld-riscv-elf/table-jump-no-benefit.s | 12 + .../ld-riscv-elf/table-jump-no-relax-zcmt.d | 17 + .../ld-riscv-elf/table-jump-no-relo-1.s | 7 + .../ld-riscv-elf/table-jump-no-relo-2.s | 12 + .../ld-riscv-elf/table-jump-no-relo.d | 16 + .../ld-riscv-elf/table-jump-no-zcmt.d | 16 + .../ld-riscv-elf/table-jump-no-zcmt.s | 16 + .../ld-riscv-elf/table-jump-norelax.d | 15 + .../ld-riscv-elf/table-jump-norelax.s | 17 + .../ld-riscv-elf/table-jump-overflow.d | 11 + .../ld-riscv-elf/table-jump-overflow.s | 49 + .../ld-riscv-elf/table-jump-pie-relocs.d | 9 + .../ld-riscv-elf/table-jump-pie-text.d | 9 + ld/testsuite/ld-riscv-elf/table-jump-pie.d | 9 + ld/testsuite/ld-riscv-elf/table-jump-pie.s | 13 + .../ld-riscv-elf/table-jump-relax-zcmt.d | 23 + ld/testsuite/ld-riscv-elf/table-jump-rv32.d | 15 + ld/testsuite/ld-riscv-elf/table-jump-rv32.s | 25 + .../ld-riscv-elf/table-jump-shared-relocs.d | 9 + .../ld-riscv-elf/table-jump-shared-symbol.d | 9 + .../ld-riscv-elf/table-jump-shared-text.d | 9 + ld/testsuite/ld-riscv-elf/table-jump-shared.d | 12 + ld/testsuite/ld-riscv-elf/table-jump-shared.s | 15 + .../ld-riscv-elf/table-jump-strip-symbol.d | 9 + .../ld-riscv-elf/table-jump-symbol-policy.d | 8 + .../ld-riscv-elf/table-jump-vma-lma.d | 16 + .../ld-riscv-elf/table-jump-vma-lma.ld | 10 + .../ld-riscv-elf/table-jump-vma-zero.d | 15 + .../ld-riscv-elf/table-jump-vma-zero.ld | 13 + .../ld-riscv-elf/table-jump-vma-zero.s | 14 + .../ld-riscv-elf/table-jump-zcd-conflict.d | 9 + .../ld-riscv-elf/table-jump-zcmt-no-zca.d | 9 + .../ld-riscv-elf/table-jump-zcmt-no-zca.s | 24 + .../ld-riscv-elf/table-jump-zcmt-no-zicsr.d | 9 + .../ld-riscv-elf/table-jump-zcmt-no-zicsr.s | 24 + ld/testsuite/ld-riscv-elf/table-jump.ld | 16 + ld/testsuite/ld-riscv-elf/table-jump.s | 46 + opcodes/riscv-dis.c | 164 ++- 84 files changed, 2478 insertions(+), 54 deletions(-) create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-addend.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-addend.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-collision.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-collision.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-local-collision.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-local-collision.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be32-bytes.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be32-text.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be64-bytes.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be64-text.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-benefit.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-benefit.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt-relocs.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-no-jvt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-dump-unknown.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-emit-relocs.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-equal-benefit.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-equal-benefit.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-jalt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-jt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym-2.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-jvt-ref.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-jvt-ref.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-section.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relax-zcmt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo-1.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo-2.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-norelax.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-norelax.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-overflow.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-overflow.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie-relocs.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie-text.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-relax-zcmt.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-rv32.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-rv32.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-relocs.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-text.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-strip-symbol.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-symbol-policy.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-lma.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-lma.ld create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.ld create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcd-conflict.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zca.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zca.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zicsr.d create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zicsr.s create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.ld create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.s -- 2.43.0