diff options
author | Lifang Xia <lifang_xia@linux.alibaba.com> | 2022-10-27 11:19:15 +0800 |
---|---|---|
committer | Nelson Chu <nelson@rivosinc.com> | 2023-04-21 15:47:47 +0800 |
commit | 0699f2d795cdb4bc4db2bcf438291ec09d21f0da (patch) | |
tree | 597c645a7be8beeac977ec7ec64f75134b8cf0e1 /ld | |
parent | 3a117c5887312afb3f1567f1cae3316872d575f4 (diff) | |
download | binutils-0699f2d795cdb4bc4db2bcf438291ec09d21f0da.zip binutils-0699f2d795cdb4bc4db2bcf438291ec09d21f0da.tar.gz binutils-0699f2d795cdb4bc4db2bcf438291ec09d21f0da.tar.bz2 |
RISC-V: Optimize relaxation of gp with max_alignment.
This should be the first related issue, which posted in riscv-gnu-toolchain,
https://github.com/riscv-collab/riscv-gnu-toolchain/issues/497
If the output sections are not between gp and the symbol, then their alignments
shouldn't affect the gp relaxation. However, this patch improves this idea
even more, it limits the range to the gp+-2k, which means only the output
section which are in the [gp-2K, gp+2K) range need to be considered.
Even if the output section candidates may be different for each relax passes,
the symbol that can be relaxed ar this round will not be truncated at next
round. That is because this round you can do relaxation which means that the
section where the symbol is located is within the [gp-2K, gp+2K) range, so all
the output section alignments between them should be considered. In other
words, if the alignments between them may cause truncated, then we should
already preserve the size and won't do the gp relaxation this time.
This patch can resolve the github issue which mentioned above, and also passed
all gcc/binutils regressions of riscv-gnu-toolchain, so should be worth and
safe enough to commit.
Originally, this patch also do the same optimization for the call relaxations,
https://sourceware.org/pipermail/binutils/2022-October/123918.html
But just in case there is something that has not been considered, we only
deal with the gp relaxation at this time.
bfd/
* elfnn-riscv.c (riscv_elf_link_hash_table): Added new bfd_vma,
max_alignment_for_gp. It is used to record the maximum alignment of
the output sections, which are in the [gp-2K, gp+2k) range.
(riscv_elf_link_hash_table_create): Init max_alignment_for_gp to -1.
(_bfd_riscv_get_max_alignment): Added new parameter, gp. If gp is
zero, then all the output section alignments are possible candidates;
Otherwise, only the output sections which are in the [gp-2K, gp+2K)
range need to be considered.
(_bfd_riscv_relax_lui): Called _bfd_riscv_get_max_alignment with the
non-zero gp if the max_alignment_for_gp is -1.
(_bfd_riscv_relax_pc): Likewise.
(_bfd_riscv_relax_section): Record the first input section, so that
we can reset the max_alignment_for_gp for each repeated relax passes.
ld/
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
* testsuite/ld-riscv-elf/relax-max-align-gp.*: New testcase. It fails
without this patch.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relax-max-align-gp.d | 46 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relax-max-align-gp.s | 28 |
3 files changed, 75 insertions, 0 deletions
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 43572c5..9e103b2 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -171,6 +171,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "attr-merge-priv-spec-failed-05" run_dump_test "attr-merge-priv-spec-failed-06" run_dump_test "attr-phdr" + run_dump_test "relax-max-align-gp" run_ld_link_tests [list \ [list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \ "-march=rv32i -mabi=ilp32" {weakref32.s} \ diff --git a/ld/testsuite/ld-riscv-elf/relax-max-align-gp.d b/ld/testsuite/ld-riscv-elf/relax-max-align-gp.d new file mode 100644 index 0000000..637de42 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relax-max-align-gp.d @@ -0,0 +1,46 @@ +#source: relax-max-align-gp.s +#ld: +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+add[ ]+.*<gdata> +.*:[ ]+[0-9a-f]+[ ]+jal[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+j[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop + +0+[0-9a-f]+ <func>: +.*:[ ]+[0-9a-f]+[ ]+ret +[ ]+... diff --git a/ld/testsuite/ld-riscv-elf/relax-max-align-gp.s b/ld/testsuite/ld-riscv-elf/relax-max-align-gp.s new file mode 100644 index 0000000..ce3da21 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relax-max-align-gp.s @@ -0,0 +1,28 @@ + +.global _start +_start: + lui a0, %hi(gdata) + addi a0, a0, %lo(gdata) + call func + j . + .size _start, . - _start + +.global func +.align 7 +func: + ret + .size func, . - func + +.data +padding: + .long 0 + .long 0 + .long 0 + .long 0 + .size padding, . - padding + +.global gdata +.type gdata, object +gdata: + .zero 4 + .size gdata, . - gdata |