[v1,0/6] LoongArch linker relaxation support.

Message ID 20221205080453.1352069-1-mengqinggang@loongson.cn
Headers
Series LoongArch linker relaxation support. |

Message

mengqinggang Dec. 5, 2022, 8:04 a.m. UTC
  There are two instrunction sequence can be relaxed in LoongArch. The first one  
is "pcala12i + addi.d" which can be relaxed to pcaddi. Another one is           
"pcalau12i + ld.d" which can be relaxed to "pcalau12i + addi.d". And it can be  
relaxed to pcaddi one more time. Pcaddi instrunction can address a signed 22       
bits 4-byte alinged offset relative to pc. 

Now, only the instrunctions expand from macro (la.local, la.got, etc.) at          
assembly time can be relaxed, because gcc instruction scheduling causes relax   
unable to handle some special cases. Gcc can add -mno-explicit-relocs option       
to generate macro instrunction.

mengqinggang (6):
  LoongArch: include: Add support for linker relaxation.
  LoongArch: bfd: Add support for linker relaxation.
  LoongArch: opcodes: Add support for linker relaxation.
  LoongArch: binutils: Add support for linker relaxation.
  LoongArch: gas: Add support for linker relaxation.
  LoongArch: ld: Add support for linker relaxation.

 bfd/bfd-in2.h                                 |   8 +
 bfd/elfnn-loongarch.c                         | 582 +++++++++++++--
 bfd/elfxx-loongarch.c                         | 676 +++++++++++++-----
 bfd/elfxx-loongarch.h                         |  10 +-
 bfd/libbfd.h                                  |   8 +
 bfd/reloc.c                                   |  22 +
 binutils/readelf.c                            |  84 ++-
 binutils/testsuite/binutils-all/readelf.exp   |  13 +-
 gas/config/tc-loongarch.c                     | 412 +++++++++--
 gas/config/tc-loongarch.h                     |  45 +-
 gas/testsuite/gas/all/align.d                 |   5 +-
 gas/testsuite/gas/all/gas.exp                 |  10 +-
 gas/testsuite/gas/all/relax.d                 |   4 +
 gas/testsuite/gas/elf/dwarf-5-irp.d           |   3 +-
 gas/testsuite/gas/elf/dwarf-5-loc0.d          |   3 +-
 gas/testsuite/gas/elf/dwarf2-11.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-15.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-16.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-17.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-18.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-19.d             |   3 +-
 gas/testsuite/gas/elf/dwarf2-5.d              |   3 +-
 gas/testsuite/gas/elf/ehopt0.d                |   3 +
 gas/testsuite/gas/elf/elf.exp                 |   3 +
 gas/testsuite/gas/elf/section11.d             |   4 +-
 gas/testsuite/gas/lns/lns.exp                 |   1 +
 gas/testsuite/gas/loongarch/jmp_op.d          |  65 +-
 gas/testsuite/gas/loongarch/li.d              |   9 +-
 gas/testsuite/gas/loongarch/macro_op.d        |  69 +-
 .../gas/loongarch/macro_op_large_abs.d        | 103 +--
 .../gas/loongarch/macro_op_large_pc.d         | 103 +--
 gas/testsuite/gas/loongarch/relax_align.d     |  25 +
 gas/testsuite/gas/loongarch/relax_align.s     |   5 +
 gas/testsuite/gas/loongarch/uleb128.d         |  35 +
 gas/testsuite/gas/loongarch/uleb128.s         |  20 +
 include/elf/loongarch.h                       |  20 +
 include/opcode/loongarch.h                    |   3 +
 ld/emultempl/loongarchelf.em                  |   3 +
 ld/testsuite/ld-elf/compressed1d.d            |   3 +
 ld/testsuite/ld-elf/pr26936.d                 |   4 +-
 ld/testsuite/ld-loongarch-elf/disas-jirl.d    |   4 +-
 ld/testsuite/ld-loongarch-elf/jmp_op.d        |  65 +-
 ld/testsuite/ld-loongarch-elf/macro_op.d      | 138 ++--
 ld/testsuite/ld-loongarch-elf/relax-align.dd  |   7 +
 ld/testsuite/ld-loongarch-elf/relax-align.s   |   9 +
 ld/testsuite/ld-loongarch-elf/relax.dd        |   5 +
 ld/testsuite/ld-loongarch-elf/relax.exp       |  65 ++
 ld/testsuite/ld-loongarch-elf/relax.s         |  50 ++
 ld/testsuite/ld-loongarch-elf/uleb128.dd      |  10 +
 ld/testsuite/ld-loongarch-elf/uleb128.s       |  21 +
 opcodes/loongarch-opc.c                       |   5 +-
 51 files changed, 2223 insertions(+), 540 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/relax_align.d
 create mode 100644 gas/testsuite/gas/loongarch/relax_align.s
 create mode 100644 gas/testsuite/gas/loongarch/uleb128.d
 create mode 100644 gas/testsuite/gas/loongarch/uleb128.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.dd
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax.dd
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax.exp
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.dd
 create mode 100644 ld/testsuite/ld-loongarch-elf/uleb128.s
  

Comments

Xi Ruoyao Dec. 5, 2022, 8:43 a.m. UTC | #1
On Mon, 2022-12-05 at 16:04 +0800, mengqinggang wrote:
> Now, only the instrunctions expand from macro (la.local, la.got, etc.) at          
> assembly time can be relaxed, because gcc instruction scheduling causes relax   
> unable to handle some special cases. Gcc can add -mno-explicit-relocs option       
> to generate macro instrunction.

Frankly, I don't like this.  Can the compiler explicitly emit some
relocations to mark a instruction chain suitable for relaxation?  Some
random thought:

.reloc R_LARCH_RELOC_X 1
pcalau12i $a0, %got_pc_hi20(sym_a)
.reloc R_LARCH_RELOC_X 2
pcalau12i $a1, %got_pc_hi20(sym_b)
.reloc R_LARCH_RELOC_X 1
ld.d $a0, $a0, %got_pc_lo12(sym_a)
.reloc R_LARCH_RELOC_X 2
ld.d $a1, $a1, %got_pc_lo12(sym_b)
.reloc R_LARCH_RELOC_X 1
ld.d $a0, $a0, 0
.reloc R_LARCH_RELOC_X 2
ld.d $a1, $a1, 0

Here "R_LARCH_RELOC_X" is an imaginary relocation type.  We may be able
to use the different values of the 32-bit addend to distinguish two load
sequences interleaved after scheduling (I don't think there will be more
than 2147483647 load sequences in an object file).

This is just some random thoughts, I don't understand the linking
process very well anyway.
  
mengqinggang Dec. 6, 2022, 1:58 a.m. UTC | #2
We tried this method. We use R_LARCH_RELAX addend to distinguish two load
sequences. But there is a problem that has not been solved.
If there are two load sequences after a branch instruction like this:

   branch ------------
     | |
   pcalau12i pcalau12i
   ld.d ld.d

After scheduling, two pcalau12i may be reduced to one and put before
branch instruction like this:

pcalau12i
   branch -----------
     | |
    ld.d ld.d

For this case, if one branch make a relax, another branch will get a 
mistake.

But we will try to solve this question in relax v2 version.


在 2022/12/5 下午4:43, Xi Ruoyao 写道:
> On Mon, 2022-12-05 at 16:04 +0800, mengqinggang wrote:
>> Now, only the instrunctions expand from macro (la.local, la.got, etc.) at
>> assembly time can be relaxed, because gcc instruction scheduling causes relax
>> unable to handle some special cases. Gcc can add -mno-explicit-relocs option
>> to generate macro instrunction.
> Frankly, I don't like this.  Can the compiler explicitly emit some
> relocations to mark a instruction chain suitable for relaxation?  Some
> random thought:
>
> .reloc R_LARCH_RELOC_X 1
> pcalau12i $a0, %got_pc_hi20(sym_a)
> .reloc R_LARCH_RELOC_X 2
> pcalau12i $a1, %got_pc_hi20(sym_b)
> .reloc R_LARCH_RELOC_X 1
> ld.d $a0, $a0, %got_pc_lo12(sym_a)
> .reloc R_LARCH_RELOC_X 2
> ld.d $a1, $a1, %got_pc_lo12(sym_b)
> .reloc R_LARCH_RELOC_X 1
> ld.d $a0, $a0, 0
> .reloc R_LARCH_RELOC_X 2
> ld.d $a1, $a1, 0
>
> Here "R_LARCH_RELOC_X" is an imaginary relocation type.  We may be able
> to use the different values of the 32-bit addend to distinguish two load
> sequences interleaved after scheduling (I don't think there will be more
> than 2147483647 load sequences in an object file).
>
> This is just some random thoughts, I don't understand the linking
> process very well anyway.
>