[v1,0/5] LoongArch tls le model linker relaxation support.

Message ID 20231201090730.20521-1-changjiachen@stu.xupt.edu.cn
Headers
Series LoongArch tls le model linker relaxation support. |

Message

changjiachen Dec. 1, 2023, 9:07 a.m. UTC
  This is the v1 version of patches to support loongarch linker tls le model relax.

This support does three main things:

1. Modify LoongArch tls le model assembly instruction sequence.

This change is mainly implemented in gcc. Due to the characteristics 
of st.w instruction in Loongarch and the unique addressing mode of 
tls le model, in order to implement tls le model linker relax, it is 
decided to change the tls le model instruction sequence.

The specific changes are as follows:

example: __thread int a = 1;

old insn sequence:

lu12i.w $r12,%le_hi20_r(a)
ori     $r12,$r12,%le_lo12_r(a)
add.d   $r12,$r12,$r2,%le_add_r(a)
li.w	$r13,$r0,1
stptr.w $r13,$r12,0

new insn sequence:

lu12i.w $r12,%le_hi20_r(a)
add.d   $r12,$r12,$r2,%le_add_r(a)
li.w    $r13,$r0,1
st.w    $r13,$r12,%le_lo12_r(a)

2. Added LoongArch three relocations related to tls le model relax.

In order to ensure forward compatibility of binutils versions and 
implement tls le model relax, it was decided to add three relocation items.

The relocation items are as follows:

R_LARCH_TLS_LE_HI20_R
R_LARCH_TLS_LE_LO12_R
R_LARCH_TLS_LE_ADD_R

3. Implement Loongarch tls le model relax in ld.

This change will add a loongarch_relax_tls_le function to relax tls le model.

The instructions before and after relax change as follows:

example: __thread int a = 1;

before relax insn:

lu12i.w	 $t0, 0
add.d	 $t0, $t0, $tp
li.w	 $t1, 1
st.w	 $t1, $t0, 0

after relax insn:

li.w     $t1, 1
st.w     $t1, $tp, 0

changjiachen (5):
  LoongArch: bfd: Add support for tls le relax.
  LoongArch: include: Add support for tls le relax.
  LoongArch: opcodes: Add support for tls le relax.
  LoongArch: gas: Add support for tls le relax.
  LoongArch: ld: Add support for tls le relax.

 bfd/bfd-in2.h                                 |   4 +
 bfd/elfnn-loongarch.c                         |  74 +++++++++
 bfd/elfxx-loongarch.c                         |  50 ++++++
 bfd/libbfd.h                                  |   3 +
 bfd/reloc.c                                   |   6 +
 gas/config/tc-loongarch.c                     |  12 +-
 gas/testsuite/gas/loongarch/reloc.d           |  18 +++
 gas/testsuite/gas/loongarch/reloc.s           |  11 ++
 include/elf/loongarch.h                       |  13 ++
 ld/testsuite/ld-loongarch-elf/old-tls-le.s    |  19 +++
 .../relax-bound-check-tls-le.s                |  48 ++++++
 .../ld-loongarch-elf/relax-check-tls-le.s     |  43 ++++++
 ld/testsuite/ld-loongarch-elf/relax-tls-le.s  |  17 ++
 ld/testsuite/ld-loongarch-elf/relax.exp       | 146 +++++++++++++++++-
 .../tls-relax-compatible-check-old.s          |  39 +++++
 opcodes/loongarch-opc.c                       |   1 +
 16 files changed, 501 insertions(+), 3 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/old-tls-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-tls-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
  

Comments

Xi Ruoyao Dec. 1, 2023, 9:56 a.m. UTC | #1
On Fri, 2023-12-01 at 17:07 +0800, changjiachen wrote:
> R_LARCH_TLS_LE_HI20_R
> R_LARCH_TLS_LE_LO12_R
> R_LARCH_TLS_LE_ADD_R

Why do we need them?  Why not just use a combination of R_LARCH_RELAX
and R_LARCH_TLS_LE_HI20/LO12?
  
Jinyang He Dec. 2, 2023, 1:55 a.m. UTC | #2
On 2023-12-01 17:07, changjiachen wrote:

> This is the v1 version of patches to support loongarch linker tls le model relax.
>
> This support does three main things:
>
> 1. Modify LoongArch tls le model assembly instruction sequence.
>
> This change is mainly implemented in gcc. Due to the characteristics
> of st.w instruction in Loongarch and the unique addressing mode of
> tls le model, in order to implement tls le model linker relax, it is
> decided to change the tls le model instruction sequence.
>
> The specific changes are as follows:
>
> example: __thread int a = 1;
>
> old insn sequence:
>
> lu12i.w $r12,%le_hi20_r(a)
> ori     $r12,$r12,%le_lo12_r(a)
> add.d   $r12,$r12,$r2,%le_add_r(a)
> li.w	$r13,$r0,1
> stptr.w $r13,$r12,0

Hi,


It's more complex than I thought as you said it is mainly implemented
in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
like follows,

lu12i.w $r12,%le_hi20(a)
ori     $r12,$r12,%le_lo12(a)
addi.w  $r13,$r0,1
stx.w   $r13,$r12,$r2

It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc implementation
change this sequence?


>
> new insn sequence:
>
> lu12i.w $r12,%le_hi20_r(a)
> add.d   $r12,$r12,$r2,%le_add_r(a)
> li.w    $r13,$r0,1
> st.w    $r13,$r12,%le_lo12_r(a)

In old sequence, $r12 is the real address of "a". In new sequence, $r12 is
not the real address of "a". How about we use $r12 after this sequence?


> 2. Added LoongArch three relocations related to tls le model relax.
>
> In order to ensure forward compatibility of binutils versions and
> implement tls le model relax, it was decided to add three relocation items.
>
> The relocation items are as follows:
>
> R_LARCH_TLS_LE_HI20_R
> R_LARCH_TLS_LE_LO12_R
> R_LARCH_TLS_LE_ADD_R
>
> 3. Implement Loongarch tls le model relax in ld.
>
> This change will add a loongarch_relax_tls_le function to relax tls le model.
>
> The instructions before and after relax change as follows:
>
> example: __thread int a = 1;
>
> before relax insn:
>
> lu12i.w	 $t0, 0
> add.d	 $t0, $t0, $tp
> li.w	 $t1, 1
> st.w	 $t1, $t0, 0
>
> after relax insn:
>
> li.w     $t1, 1
> st.w     $t1, $tp, 0
>
> changjiachen (5):
>    LoongArch: bfd: Add support for tls le relax.
>    LoongArch: include: Add support for tls le relax.
>    LoongArch: opcodes: Add support for tls le relax.
>    LoongArch: gas: Add support for tls le relax.
>    LoongArch: ld: Add support for tls le relax.
>
>   bfd/bfd-in2.h                                 |   4 +
>   bfd/elfnn-loongarch.c                         |  74 +++++++++
>   bfd/elfxx-loongarch.c                         |  50 ++++++
>   bfd/libbfd.h                                  |   3 +
>   bfd/reloc.c                                   |   6 +
>   gas/config/tc-loongarch.c                     |  12 +-
>   gas/testsuite/gas/loongarch/reloc.d           |  18 +++
>   gas/testsuite/gas/loongarch/reloc.s           |  11 ++
>   include/elf/loongarch.h                       |  13 ++
>   ld/testsuite/ld-loongarch-elf/old-tls-le.s    |  19 +++
>   .../relax-bound-check-tls-le.s                |  48 ++++++
>   .../ld-loongarch-elf/relax-check-tls-le.s     |  43 ++++++
>   ld/testsuite/ld-loongarch-elf/relax-tls-le.s  |  17 ++
>   ld/testsuite/ld-loongarch-elf/relax.exp       | 146 +++++++++++++++++-
>   .../tls-relax-compatible-check-old.s          |  39 +++++
>   opcodes/loongarch-opc.c                       |   1 +
>   16 files changed, 501 insertions(+), 3 deletions(-)
>   create mode 100644 ld/testsuite/ld-loongarch-elf/old-tls-le.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/relax-tls-le.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
>
  
chenglulu Dec. 2, 2023, 2:49 a.m. UTC | #3
在 2023/12/2 上午9:55, Jinyang He 写道:
> On 2023-12-01 17:07, changjiachen wrote:
>
>> This is the v1 version of patches to support loongarch linker tls le 
>> model relax.
>>
>> This support does three main things:
>>
>> 1. Modify LoongArch tls le model assembly instruction sequence.
>>
>> This change is mainly implemented in gcc. Due to the characteristics
>> of st.w instruction in Loongarch and the unique addressing mode of
>> tls le model, in order to implement tls le model linker relax, it is
>> decided to change the tls le model instruction sequence.
>>
>> The specific changes are as follows:
>>
>> example: __thread int a = 1;
>>
>> old insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> ori     $r12,$r12,%le_lo12_r(a)
>> add.d   $r12,$r12,$r2,%le_add_r(a)
>> li.w    $r13,$r0,1
>> stptr.w $r13,$r12,0
>
> Hi,
>
>
> It's more complex than I thought as you said it is mainly implemented
> in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
> like follows,
>
> lu12i.w $r12,%le_hi20(a)
> ori     $r12,$r12,%le_lo12(a)
> addi.w  $r13,$r0,1
> stx.w   $r13,$r12,$r2
>
> It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc 
> implementation
> change this sequence?
>
First, the compilation generated in this scenario should be as follows 
(at the O0 optimization level):

     lu12i.w    $r12,%le_hi20(a)
     ori    $r12,$r12,%le_lo12(a)
     add.d    $r12,$r12,$r2
     addi.w    $r13,$r0,1            # 0x1
     stptr.w    $r13,$r12,0

After adding optimizations, this sequence may be optimized,

e.g. O2 will generate the following:

     lu12i.w    $r12,%le_hi20(.LANCHOR0)
     addi.w    $r13,$r0,1            # 0x1
     ori    $r12,$r12,%le_lo12(.LANCHOR0)
     stx.w    $r13,$r12,$r2
At the same time, the instruction sequence may also change.

Lulu

>
>>
>> new insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> add.d   $r12,$r12,$r2,%le_add_r(a)
>> li.w    $r13,$r0,1
>> st.w    $r13,$r12,%le_lo12_r(a)
>
> In old sequence, $r12 is the real address of "a". In new sequence, 
> $r12 is
> not the real address of "a". How about we use $r12 after this sequence?
>
>
>> 2. Added LoongArch three relocations related to tls le model relax.
>>
>> In order to ensure forward compatibility of binutils versions and
>> implement tls le model relax, it was decided to add three relocation 
>> items.
>>
>> The relocation items are as follows:
>>
>> R_LARCH_TLS_LE_HI20_R
>> R_LARCH_TLS_LE_LO12_R
>> R_LARCH_TLS_LE_ADD_R
>>
>> 3. Implement Loongarch tls le model relax in ld.
>>
>> This change will add a loongarch_relax_tls_le function to relax tls 
>> le model.
>>
>> The instructions before and after relax change as follows:
>>
>> example: __thread int a = 1;
>>
>> before relax insn:
>>
>> lu12i.w     $t0, 0
>> add.d     $t0, $t0, $tp
>> li.w     $t1, 1
>> st.w     $t1, $t0, 0
>>
>> after relax insn:
>>
>> li.w     $t1, 1
>> st.w     $t1, $tp, 0
>>
>> changjiachen (5):
>>    LoongArch: bfd: Add support for tls le relax.
>>    LoongArch: include: Add support for tls le relax.
>>    LoongArch: opcodes: Add support for tls le relax.
>>    LoongArch: gas: Add support for tls le relax.
>>    LoongArch: ld: Add support for tls le relax.
>>
>>   bfd/bfd-in2.h                                 |   4 +
>>   bfd/elfnn-loongarch.c                         |  74 +++++++++
>>   bfd/elfxx-loongarch.c                         |  50 ++++++
>>   bfd/libbfd.h                                  |   3 +
>>   bfd/reloc.c                                   |   6 +
>>   gas/config/tc-loongarch.c                     |  12 +-
>>   gas/testsuite/gas/loongarch/reloc.d           |  18 +++
>>   gas/testsuite/gas/loongarch/reloc.s           |  11 ++
>>   include/elf/loongarch.h                       |  13 ++
>>   ld/testsuite/ld-loongarch-elf/old-tls-le.s    |  19 +++
>>   .../relax-bound-check-tls-le.s                |  48 ++++++
>>   .../ld-loongarch-elf/relax-check-tls-le.s     |  43 ++++++
>>   ld/testsuite/ld-loongarch-elf/relax-tls-le.s  |  17 ++
>>   ld/testsuite/ld-loongarch-elf/relax.exp       | 146 +++++++++++++++++-
>>   .../tls-relax-compatible-check-old.s          |  39 +++++
>>   opcodes/loongarch-opc.c                       |   1 +
>>   16 files changed, 501 insertions(+), 3 deletions(-)
>>   create mode 100644 ld/testsuite/ld-loongarch-elf/old-tls-le.s
>>   create mode 100644 
>> ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
>>   create mode 100644 ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s
>>   create mode 100644 ld/testsuite/ld-loongarch-elf/relax-tls-le.s
>>   create mode 100644 
>> ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
>>
  
changjiachen Dec. 4, 2023, 4:37 a.m. UTC | #4
From: Jinyang He <hejinyang@loongson.cn>
Date: 2023-12-02 09:55:14
To:  changjiachen <changjiachen@stu.xupt.edu.cn>,binutils@sourceware.org
Cc:  xuchenghua@loongson.cn,chenglulu@loongson.cn,liuzhensong@loongson.cn,xry111@xry111.site,i.swmail@xen0n.name,maskray@google.com,cailulu@loongson.cn,luweining@loongson.cn,wanglei@loongson.cn,Lazy_Linux@126.com
Subject: Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.>On 2023-12-01 17:07, changjiachen wrote:
>
>> This is the v1 version of patches to support loongarch linker tls le model relax.
>>
>> This support does three main things:
>>
>> 1. Modify LoongArch tls le model assembly instruction sequence.
>>
>> This change is mainly implemented in gcc. Due to the characteristics
>> of st.w instruction in Loongarch and the unique addressing mode of
>> tls le model, in order to implement tls le model linker relax, it is
>> decided to change the tls le model instruction sequence.
>>
>> The specific changes are as follows:
>>
>> example: __thread int a = 1;
>>
>> old insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> ori     $r12,$r12,%le_lo12_r(a)
>> add.d   $r12,$r12,$r2,%le_add_r(a)
>> li.w	$r13,$r0,1
>> stptr.w $r13,$r12,0
>
>Hi,
>
>
>It's more complex than I thought as you said it is mainly implemented
>in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
>like follows,
>
>lu12i.w $r12,%le_hi20(a)
>ori     $r12,$r12,%le_lo12(a)
>addi.w  $r13,$r0,1
>stx.w   $r13,$r12,$r2
>
>It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc implementation
>change this sequence?
>


>>
>> new insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> add.d   $r12,$r12,$r2,%le_add_r(a)
>> li.w    $r13,$r0,1
>> st.w    $r13,$r12,%le_lo12_r(a)
>
>In old sequence, $r12 is the real address of "a". In new sequence, $r12 is
>not the real address of "a". How about we use $r12 after this sequence?
>
>To solve this problem, I will give you the following explanation


> In the new and old sequences, the final r12 value is different, 
> and there are some small changes in the address calculation of the tls variable.
> 
> The address calculation of the tls variable is of the form tp+offset.
>
> In the old sequence:
> In the old sequence, the hi20 and lo12 parts of the offset of the tls variable 
> were computed first, then the entire offet and tp were added together, and 
> the result was stored in r12.
>
> In the new sequence:
> In the new sequence, the hi20 part of the offset of the tls variable is computed, 
> the hi20 part and tp are added together, and the result is stored in r12. The immediate 
> portion of the st.w instruction stores the lo12 portion of the tls variable, and finally the st.w 
> instruction stores the value in the address r12+offset(lo12).
>
> To sum up, in the old sequence, r12 stores the real address of tls variable (tp+offset(hi20)+offset(lo12)),
> while in the new sequence r12 does not store the real address of tls variable (tp+offset(hi20)),
> but takes advantage of the instruction characteristics of st.w. So the new sequence and the old 
> sequence actually point to the same address.
>
> Note: st.w rd, rj, s12
> The memory address of this instruction is the sum of the value in the universal register rj 
> and the 12-bit immediate number si12 after the symbol extension.
> >> 2. Added LoongArch three relocations related to tls le model relax. >> >> In order to ensure forward compatibility of binutils versions and >> implement tls le model relax, it was decided to add three relocation items. >> >> The relocation items are as follows: >> >> R_LARCH_TLS_LE_HI20_R >> R_LARCH_TLS_LE_LO12_R >> R_LARCH_TLS_LE_ADD_R >> >> 3. Implement Loongarch tls le model relax in ld. >> >> This change will add a loongarch_relax_tls_le function to relax tls le model. >> >> The instructions before and after relax change as follows: >> >> example: __thread int a = 1; >> >> before relax insn: >> >> lu12i.w $t0, 0 >> add.d $t0, $t0, $tp >> li.w $t1, 1 >> st.w $t1, $t0, 0 >> >> after relax insn: >> >> li.w $t1, 1 >> st.w $t1, $tp, 0 >> >> changjiachen (5): >> LoongArch: bfd: Add support for tls le relax. >> LoongArch: include: Add support for tls le relax. >> LoongArch: opcodes: Add support for tls le relax. >> LoongArch: gas: Add support for tls le relax. >> LoongArch: ld: Add support for tls le relax. >> >> bfd/bfd-in2.h | 4 + >> bfd/elfnn-loongarch.c | 74 +++++++++ >> bfd/elfxx-loongarch.c | 50 ++++++ >> bfd/libbfd.h | 3 + >> bfd/reloc.c | 6 + >> gas/config/tc-loongarch.c | 12 +- >> gas/testsuite/gas/loongarch/reloc.d | 18 +++ >> gas/testsuite/gas/loongarch/reloc.s | 11 ++ >> include/elf/loongarch.h | 13 ++ >> ld/testsuite/ld-loongarch-elf/old-tls-le.s | 19 +++ >> .../relax-bound-check-tls-le.s | 48 ++++++ >> .../ld-loongarch-elf/relax-check-tls-le.s | 43 ++++++ >> ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++ >> ld/testsuite/ld-loongarch-elf/relax.exp | 146 +++++++++++++++++- >> .../tls-relax-compatible-check-old.s | 39 +++++ >> opcodes/loongarch-opc.c | 1 + >> 16 files changed, 501 insertions(+), 3 deletions(-) >> create mode 100644 ld/testsuite/ld-loongarch-elf/old-tls-le.s >> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s >> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s >> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-tls-le.s >> create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s >> >