public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Fangrui Song <maskray@google.com>
To: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Cc: gcc-patches@gcc.gnu.org, rui314@gmail.com,
	ruiu@bluewhale.systems,  kito.cheng@gmail.com,
	jeffreyalaw@gmail.com
Subject: Re: [PATCH v3] RISC-V: Implement TLS Descriptors.
Date: Mon, 20 Nov 2023 22:59:46 -0800	[thread overview]
Message-ID: <CAFP8O3KY-vaQUSZkH+QW8yYC7GBDZzrx4oWhyKG-43f7X78rCg@mail.gmail.com> (raw)
In-Reply-To: <20231120131726.52280-1-ishitatsuyuki@gmail.com>

On Mon, Nov 20, 2023 at 6:20 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>
> This implements TLS Descriptors (TLSDESC) as specified in [1].
>
> The 4-instruction sequence is implemented as a single RTX insn for
> simplicity, but this can be revisited later if instruction scheduling or
> more flexible RA is desired.
>
> The default remains to be the traditional TLS model, but can be configured
> with --with_tls={trad,desc}. The choice can be revisited once toolchain
> and libc support ships.
>
> [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373.
>
> gcc/Changelog:
>         * config/riscv/riscv.opt: Add -mtls-dialect to configure TLS flavor.
>         * config.gcc: Add --with_tls configuration option to change the
>         default TLS flavor.
>         * config/riscv/riscv.h: Add TARGET_TLSDESC determined from
>         -mtls-dialect and with_tls defaults.
>         * config/riscv/riscv-opts.h: Define enum riscv_tls_type for the
>         two TLS flavors.
>         * config/riscv/riscv-protos.h: Define SYMBOL_TLSDESC symbol type.
>         * config/riscv/riscv.md: Add instruction sequence for TLSDESC.
>         * config/riscv/riscv.cc (riscv_symbol_insns): Add instruction
>         sequence length data for TLSDESC.
>         (riscv_legitimize_tls_address): Add lowering of TLSDESC.
>         * doc/install.texi: Document --with-tls for RISC-V.
>         * doc/invoke.texi: Document --mtls-dialect for RISC-V.

Nit: One dash for --mtls-dialect.

> ---
> No regression in gcc tests for rv64gc, tested alongside the binutils and
> glibc implementation. Tested with --with_tls=desc.
>
> v2: Add with_tls configuration option, and a few readability improvements.
>     Added Changelog.
> v3: Add documentation per Kito's suggestion.
>     Fix minor issues pointed out by Kito and Jeff.
>     Thanks Kito Cheng and Jeff Law for review.
>
> I've considered gating this behind a GAS feature test, but it seems
> nontrivial especially for restricting the variants available at runtime.
> Since TLS descriptors is not selected by default, I've decided to leave it
> ungated.
>
> In other news, I have made some progress on binutils side, and I'll try to
> update the GAS / ld patch set with relaxation included, by the end of this
> month.

Thanks for the update.  I understand the complexity adding a runtime
test when the feature also requires binutils and rtld support.
I hope that we add a test checking assembly under
gcc/testsuite/gcc.target/riscv/tls , otherwise as a non-default test,
when this breaks, it may be difficult to figure it out.
(glibc/elf/tst-* will need a runtime test, but GCC needs to have its own.)

>  gcc/config.gcc                  | 15 ++++++++++++++-
>  gcc/config/riscv/riscv-opts.h   |  6 ++++++
>  gcc/config/riscv/riscv-protos.h |  5 +++--
>  gcc/config/riscv/riscv.cc       | 24 ++++++++++++++++++++----
>  gcc/config/riscv/riscv.h        |  9 +++++++--
>  gcc/config/riscv/riscv.md       | 21 ++++++++++++++++++++-
>  gcc/config/riscv/riscv.opt      | 14 ++++++++++++++
>  gcc/doc/install.texi            |  3 +++
>  gcc/doc/invoke.texi             | 13 ++++++++++++-
>  9 files changed, 99 insertions(+), 11 deletions(-)
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 415e0e1ebc5..2c1a7179b02 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -2434,6 +2434,7 @@ riscv*-*-linux*)
>         # Force .init_array support.  The configure script cannot always
>         # automatically detect that GAS supports it, yet we require it.
>         gcc_cv_initfini_array=yes
> +       with_tls=${with_tls:-trad}
>         ;;
>  riscv*-*-elf* | riscv*-*-rtems*)
>         tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
> @@ -2476,6 +2477,7 @@ riscv*-*-freebsd*)
>         # Force .init_array support.  The configure script cannot always
>         # automatically detect that GAS supports it, yet we require it.
>         gcc_cv_initfini_array=yes
> +       with_tls=${with_tls:-trad}
>         ;;
>
>  loongarch*-*-linux*)
> @@ -4566,7 +4568,7 @@ case "${target}" in
>                 ;;
>
>         riscv*-*-*)
> -               supported_defaults="abi arch tune riscv_attribute isa_spec"
> +               supported_defaults="abi arch tune riscv_attribute isa_spec tls"
>
>                 case "${target}" in
>                 riscv-* | riscv32*) xlen=32 ;;
> @@ -4694,6 +4696,17 @@ case "${target}" in
>                                 ;;
>                         esac
>                 fi
> +               # Handle --with-tls.
> +               case "$with_tls" in
> +               "" \
> +               | trad | desc)
> +                       # OK
> +                       ;;
> +               *)
> +                       echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
> +                       exit 1
> +                       ;;
> +               esac
>
>                 # Handle --with-multilib-list.
>                 if test "x${with_multilib_list}" != xdefault; then
> diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> index 378a17699cd..db03f35430a 100644
> --- a/gcc/config/riscv/riscv-opts.h
> +++ b/gcc/config/riscv/riscv-opts.h
> @@ -319,4 +319,10 @@ enum riscv_entity
>  #define TARGET_VECTOR_VLS                                                      \
>    (TARGET_VECTOR && riscv_autovec_preference == RVV_SCALABLE)
>
> +/* TLS types.  */
> +enum riscv_tls_type {
> +  TLS_TRADITIONAL,
> +  TLS_DESCRIPTORS
> +};
> +

I wonder whether `enum class` can be used instead and we can get rid
of the `TLS_` prefix.
gcc/config/ already has some uses.

>  #endif /* ! GCC_RISCV_OPTS_H */
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index 472c00dc439..9b7471f7591 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -33,9 +33,10 @@ enum riscv_symbol_type {
>    SYMBOL_TLS,
>    SYMBOL_TLS_LE,
>    SYMBOL_TLS_IE,
> -  SYMBOL_TLS_GD
> +  SYMBOL_TLS_GD,
> +  SYMBOL_TLSDESC,
>  };
> -#define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1)
> +#define NUM_SYMBOL_TYPES (SYMBOL_TLSDESC + 1)
>
>  /* Classifies an address.
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 49062bef9fc..c158e224aaa 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -799,6 +799,7 @@ static int riscv_symbol_insns (enum riscv_symbol_type type)
>      case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference.  */
>      case SYMBOL_PCREL: return 2; /* AUIPC + the reference.  */
>      case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference.  */
> +    case SYMBOL_TLSDESC: return 6; /* 4-instruction call + ADD TP + the reference.  */
>      case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference.  */
>      default: gcc_unreachable ();
>      }
> @@ -1734,7 +1735,7 @@ riscv_call_tls_get_addr (rtx sym, rtx result)
>  static rtx
>  riscv_legitimize_tls_address (rtx loc)
>  {
> -  rtx dest, tp, tmp;
> +  rtx dest, tp, tmp, a0;
>    enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
>
>  #if 0
> @@ -1750,9 +1751,24 @@ riscv_legitimize_tls_address (rtx loc)
>        /* Rely on section anchors for the optimization that LDM TLS
>          provides.  The anchor's address is loaded with GD TLS. */
>      case TLS_MODEL_GLOBAL_DYNAMIC:
> -      tmp = gen_rtx_REG (Pmode, GP_RETURN);
> -      dest = gen_reg_rtx (Pmode);
> -      emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
> +      if (TARGET_TLSDESC)
> +       {
> +         static unsigned seqno;
> +         tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
> +         a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
> +         dest = gen_reg_rtx (Pmode);
> +
> +         emit_insn (gen_tlsdesc (Pmode, loc, GEN_INT (seqno)));
> +         emit_insn (gen_add3_insn (dest, a0, tp));
> +         seqno++;
> +       }
> +      else
> +       {
> +         tmp = gen_rtx_REG (Pmode, GP_RETURN);
> +         dest = gen_reg_rtx (Pmode);
> +         emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp,
> +                             loc);
> +       }
>        break;
>
>      case TLS_MODEL_INITIAL_EXEC:
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index e18a0081297..faea78f5f4c 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -59,6 +59,7 @@ extern const char *riscv_multi_lib_check (int argc, const char **argv);
>     --with-abi is ignored if -mabi is specified.
>     --with-tune is ignored if -mtune or -mcpu is specified.
>     --with-isa-spec is ignored if -misa-spec is specified.
> +   --with-tls is ignored if -mtls-dialect is specified.
>
>     But using default -march/-mtune value if -mcpu don't have valid option.  */
>  #define OPTION_DEFAULT_SPECS \
> @@ -68,8 +69,9 @@ extern const char *riscv_multi_lib_check (int argc, const char **argv);
>    {"arch", "%{!march=*:"                                               \
>            "  %{!mcpu=*:-march=%(VALUE)}"                               \
>            "  %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" },  \
> -  {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
> -  {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" }, \
> +  {"abi", "%{!mabi=*:-mabi=%(VALUE)}" },                               \
> +  {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" },                        \
> +  {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},                \
>
>  #ifdef IN_LIBGCC2
>  #undef TARGET_64BIT
> @@ -1122,4 +1124,7 @@ extern void riscv_remove_unneeded_save_restore_calls (void);
>  #define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR)
>  #define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, riscv_vector::FRM_NONE}
>
> +/* Check TLS Descriptors mechanism is selected.  */
> +#define TARGET_TLSDESC (riscv_tls_dialect == TLS_DESCRIPTORS)
> +
>  #endif /* ! GCC_RISCV_H */
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index b456fa6abb3..7c66c64b893 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -47,7 +47,7 @@
>    UNSPEC_TLS_LE
>    UNSPEC_TLS_IE
>    UNSPEC_TLS_GD
> -
> +  UNSPEC_TLSDESC
>    ;; High part of PC-relative address.
>    UNSPEC_AUIPC
>
> @@ -121,6 +121,7 @@
>     (T1_REGNUM                  6)
>     (S0_REGNUM                  8)
>     (S1_REGNUM                  9)
> +   (A0_REGNUM                  10)
>     (S2_REGNUM                  18)
>     (S3_REGNUM                  19)
>     (S4_REGNUM                  20)
> @@ -1869,6 +1870,24 @@
>    [(set_attr "got" "load")
>     (set_attr "mode" "<MODE>")])
>
> +(define_insn "@tlsdesc<mode>"
> +  [(set (reg:P A0_REGNUM)
> +           (unspec:P
> +                       [(match_operand:P 0 "symbolic_operand" "")
> +                        (match_operand:P 1 "const_int_operand")]
> +                       UNSPEC_TLSDESC))
> +   (clobber (reg:P T0_REGNUM))]
> +  "TARGET_TLSDESC"
> +  {
> +    return ".LT%1: auipc\ta0, %%tlsdesc_hi(%0)\;"
> +           "<load>\tt0,%%tlsdesc_load_lo(.LT%1)(a0)\;"
> +           "addi\ta0,a0,%%tlsdesc_add_lo(.LT%1)\;"
> +           "jalr\tt0,t0,%%tlsdesc_call(.LT%1)";
> +  }
> +  [(set_attr "type" "multi")
> +   (set_attr "length" "16")
> +   (set_attr "mode" "<MODE>")])
> +
>  (define_insn "auipc<mode>"
>    [(set (match_operand:P           0 "register_operand" "=r")
>         (unspec:P
> diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> index 6304efebfd5..9ba690f8497 100644
> --- a/gcc/config/riscv/riscv.opt
> +++ b/gcc/config/riscv/riscv.opt
> @@ -311,3 +311,17 @@ Enum(riscv_autovec_lmul) String(m8) Value(RVV_M8)
>  -param=riscv-autovec-lmul=
>  Target RejectNegative Joined Enum(riscv_autovec_lmul) Var(riscv_autovec_lmul) Init(RVV_M1)
>  -param=riscv-autovec-lmul=<string>     Set the RVV LMUL of auto-vectorization in the RISC-V port.
> +
> +Enum
> +Name(tls_type) Type(enum riscv_tls_type)
> +The possible TLS dialects:
> +
> +EnumValue
> +Enum(tls_type) String(trad) Value(TLS_TRADITIONAL)
> +
> +EnumValue
> +Enum(tls_type) String(desc) Value(TLS_DESCRIPTORS)
> +
> +mtls-dialect=
> +Target RejectNegative Joined Enum(tls_type) Var(riscv_tls_dialect) Init(TLS_TRADITIONAL) Save
> +Specify TLS dialect.
> diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
> index e099cd0b568..6ee533c0a40 100644
> --- a/gcc/doc/install.texi
> +++ b/gcc/doc/install.texi
> @@ -1174,6 +1174,9 @@ Specify the default TLS dialect, for systems were there is a choice.
>  For ARM targets, possible values for @var{dialect} are @code{gnu} or
>  @code{gnu2}, which select between the original GNU dialect and the GNU TLS
>  descriptor-based dialect.
> +For RISC-V targets, possible values for @var{dialect} are @code{trad} or
> +@code{desc}, which select between the traditional GNU dialect and the GNU TLS
> +descriptor-based dialect.
>
>  @item --enable-multiarch
>  Specify whether to enable or disable multiarch support.  The default is
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index f2c1067ab7d..77b82c46311 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1234,7 +1234,8 @@ See RS/6000 and PowerPC Options.
>  -mstack-protector-guard=@var{guard}  -mstack-protector-guard-reg=@var{reg}
>  -mstack-protector-guard-offset=@var{offset}
>  -mcsr-check -mno-csr-check
> --minline-atomics  -mno-inline-atomics}
> +-minline-atomics  -mno-inline-atomics
> +-mtls-dialect=desc  -mtls-dialect=trad}
>
>  @emph{RL78 Options}
>  @gccoptlist{-msim  -mmul=none  -mmul=g13  -mmul=g14  -mallregs
> @@ -29403,6 +29404,16 @@ which register to use as base register for reading the canary,
>  and from what offset from that base register. There is no default
>  register or offset as this is entirely for use within the Linux
>  kernel.
> +
> +@opindex mtls-dialect=desc
> +@item -mtls-dialect=desc
> +Use TLS descriptors as the thread-local storage mechanism for dynamic accesses
> +of TLS variables.
> +
> +@opindex mtls-dialect=trad
> +@item -mtls-dialect=trad
> +Use traditional TLS as the thread-local storage mechanism for dynamic accesses
> +of TLS variables.  This is the default.
>  @end table
>
>  @node RL78 Options
> --
> 2.42.1
>


-- 
宋方睿

  reply	other threads:[~2023-11-21  7:00 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-17 18:12 [PATCH] " Tatsuyuki Ishi
2023-08-29 13:40 ` Kito Cheng
2023-09-08 10:49 ` [PATCH v2] " Tatsuyuki Ishi
2023-10-02 14:10   ` Kito Cheng
2023-11-16  1:17     ` Fangrui Song
2023-11-16  1:39       ` Tatsuyuki Ishi
2023-11-16  5:21         ` Jeff Law
2023-11-16  5:18       ` Jeff Law
2023-11-16  1:07   ` Jeff Law
2023-11-16  1:51     ` Tatsuyuki Ishi
2023-11-16  5:23       ` Jeff Law
2023-11-16  5:33         ` Fangrui Song
2023-11-16  5:36           ` Jeff Law
2023-11-16  5:37           ` Tatsuyuki Ishi
2023-11-20 13:17 ` [PATCH v3] " Tatsuyuki Ishi
2023-11-21  6:59   ` Fangrui Song [this message]
2023-11-21  7:07     ` Tatsuyuki Ishi
2023-12-05 16:49     ` Tatsuyuki Ishi
2023-11-23 10:57   ` Florian Weimer
2023-11-23 11:34     ` Tatsuyuki Ishi
2023-11-23 11:40       ` Florian Weimer
2023-12-05  7:01 ` [PATCH v4] " Tatsuyuki Ishi
2024-01-27  3:24   ` Fangrui Song
2024-03-29  5:52 ` [PATCH v5] " Tatsuyuki Ishi
2024-03-29  6:32   ` Kito Cheng
2024-04-08 14:31     ` Kito Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFP8O3KY-vaQUSZkH+QW8yYC7GBDZzrx4oWhyKG-43f7X78rCg@mail.gmail.com \
    --to=maskray@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=ishitatsuyuki@gmail.com \
    --cc=jeffreyalaw@gmail.com \
    --cc=kito.cheng@gmail.com \
    --cc=rui314@gmail.com \
    --cc=ruiu@bluewhale.systems \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).