From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id 9E7DD3858D35 for ; Tue, 21 Nov 2023 07:00:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9E7DD3858D35 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=google.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9E7DD3858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::52d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700550004; cv=none; b=IFI32B1qeNQzS0CxbjzMQaXaSNeIByt0oBuQv4+S3Jzxr5SITEGaE4LtUSsbIn/pmCBqIAEHz5ZPXzIj7W9mB8dIO5UNH/PJ0JIbZbeTm/NTki4eDkkzONtQ4NnTwcpYNHBaLzXuzI4yB+wJD0MnsSj92+BvLGoHfAo6oT8ddVg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700550004; c=relaxed/simple; bh=2ujACXhk3i37B9AUtwEljOvCx0CN5JX7eD5g+UTInjo=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=VGW/pzFj1oEwV0k8TgjtvW32r62PFNXIkwoc5O29bLaWCM1jGz/gWgUxR0kTWZi3f34xpKbjeQBZJ3lmZlnZcNMEi4UpTlw7fC4jjf4a7WBVl5aV4nHVBgOpUL/8sq2ZW15ue4Q4qJfSConR/fY9/6/M94auJr7q1KHK5wxdHtg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-54744e66d27so9023a12.0 for ; Mon, 20 Nov 2023 23:00:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1700550000; x=1701154800; darn=gcc.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=iMOt7ncXazW7SK62ayIFhiq+rcoJn59IbUbgEl4odEg=; b=yBMqI0rDorVRDeOyucLq4FdLWMUkCkjP2YxjVdM2JBGv1Z7MM8SOqNXgGfmOXYg1qk yMLK/01xSc2uJGtxAEcluYLeWWTYIyWqsX82NNEL6ku6YuGBAVGVGGR2t8drWv2+X7MO 3Ekapf6eNDDJGy/sHGyxLPIeee0g/DrAlsSYP+uuKBxlPYYwdL+jh/HU6azKBUjVl2WP IEnC4TLpyVVRr7ELMZAJpwB714NgD2RHq2QFFpUGg+IHzW8IowQtG73t7re3J0PFL8oX ITz5cVc1gAs4MwIOurdl+4kUZjNuExtzUSPDPLDHEOCAGCCoXnPGVwLp79V/pBDe5O+f Hq9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700550000; x=1701154800; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iMOt7ncXazW7SK62ayIFhiq+rcoJn59IbUbgEl4odEg=; b=Yew2y7KlkXHRsJY2rc+JaT1OdwAgNcniZcD70wjSlCvBTUOTxI6G1fXXT2jPH4zFR5 QWRJSG0sQDlsuHnBcZRr6zxIWJUNO+wE1YxBafgVBwF6MA5B2U6cyfbMirX50kkYnGLW 57GhFUsr8kdcvD2bM2SHu0bjzysPXI7JlmAH2kuBbz5xS/kc/ac210PZ8WsAQSN8Imyv OEuizNup/IM5Ge/Qtz4rVni7ee84rzyg9epQQqUBn0pNtdSsTGo4CwH4nj7zGB5AEZaj hE3cgBxDGq37BiGzZgNBW16GNaUahGLzlPKh42yXbFvDgQGYeeXha+yNWpwzIxLaPuHs C2fg== X-Gm-Message-State: AOJu0Yzygqvi9F2mTU9qr9nbdimBNs7eWwuUYew8wt7KtYiIV/KxxSg7 baUtQBv22Yt+3YXOr07cOOY/dO57bL2KJnITy62wFA== X-Google-Smtp-Source: AGHT+IG5ksnWustKGkfOurhTGh/Sdll6T4jfyb4CJzAaAOJoz+9GTm5efqnV3Nk/bCASGIRKilG8PZtJcrN0xqyBCfE= X-Received: by 2002:a05:6402:4414:b0:544:e2b8:ba6a with SMTP id y20-20020a056402441400b00544e2b8ba6amr450097eda.3.1700549999989; Mon, 20 Nov 2023 22:59:59 -0800 (PST) MIME-Version: 1.0 References: <20230817181308.122802-2-ishitatsuyuki@gmail.com> <20231120131726.52280-1-ishitatsuyuki@gmail.com> In-Reply-To: <20231120131726.52280-1-ishitatsuyuki@gmail.com> From: Fangrui Song Date: Mon, 20 Nov 2023 22:59:46 -0800 Message-ID: Subject: Re: [PATCH v3] RISC-V: Implement TLS Descriptors. To: Tatsuyuki Ishi Cc: gcc-patches@gcc.gnu.org, rui314@gmail.com, ruiu@bluewhale.systems, kito.cheng@gmail.com, jeffreyalaw@gmail.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-22.8 required=5.0 tests=BAYES_00,BODY_8BITS,DKIMWL_WL_MED,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,ENV_AND_HDR_SPF_MATCH,GIT_PATCH_0,KAM_SHORT,KAM_STOCKGEN,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Mon, Nov 20, 2023 at 6:20=E2=80=AFAM Tatsuyuki Ishi 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 configure= d > with --with_tls=3D{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 flav= or. > * 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=3Ddesc. > > 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 i= t > ungated. > > In other news, I have made some progress on binutils side, and I'll try t= o > update the GAS / ld patch set with relaxation included, by the end of thi= s > 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=3Dyes > + with_tls=3D${with_tls:-trad} > ;; > riscv*-*-elf* | riscv*-*-rtems*) > tm_file=3D"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=3Dyes > + with_tls=3D${with_tls:-trad} > ;; > > loongarch*-*-linux*) > @@ -4566,7 +4568,7 @@ case "${target}" in > ;; > > riscv*-*-*) > - supported_defaults=3D"abi arch tune riscv_attribute isa_s= pec" > + supported_defaults=3D"abi arch tune riscv_attribute isa_s= pec tls" > > case "${target}" in > riscv-* | riscv32*) xlen=3D32 ;; > @@ -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=3D$wi= th_tls" 1>&2 > + exit 1 > + ;; > + esac > > # Handle --with-multilib-list. > if test "x${with_multilib_list}" !=3D 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 =3D=3D 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-pro= tos.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 =3D 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 =3D gen_rtx_REG (Pmode, GP_RETURN); > - dest =3D gen_reg_rtx (Pmode); > - emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp,= loc); > + if (TARGET_TLSDESC) > + { > + static unsigned seqno; > + tp =3D gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); > + a0 =3D gen_rtx_REG (Pmode, GP_ARG_FIRST); > + dest =3D gen_reg_rtx (Pmode); > + > + emit_insn (gen_tlsdesc (Pmode, loc, GEN_INT (seqno))); > + emit_insn (gen_add3_insn (dest, a0, tp)); > + seqno++; > + } > + else > + { > + tmp =3D gen_rtx_REG (Pmode, GP_RETURN); > + dest =3D gen_reg_rtx (Pmode); > + emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, t= mp, > + 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, con= st 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 optio= n. */ > #define OPTION_DEFAULT_SPECS \ > @@ -68,8 +69,9 @@ extern const char *riscv_multi_lib_check (int argc, con= st char **argv); > {"arch", "%{!march=3D*:" = \ > " %{!mcpu=3D*:-march=3D%(VALUE)}" = \ > " %{mcpu=3D*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" }, = \ > - {"abi", "%{!mabi=3D*:-mabi=3D%(VALUE)}" }, \ > - {"isa_spec", "%{!misa-spec=3D*:-misa-spec=3D%(VALUE)}" }, \ > + {"abi", "%{!mabi=3D*:-mabi=3D%(VALUE)}" }, = \ > + {"isa_spec", "%{!misa-spec=3D*:-misa-spec=3D%(VALUE)}" }, = \ > + {"tls", "%{!mtls-dialect=3D*:-mtls-dialect=3D%(VALUE)}"}, = \ > > #ifdef IN_LIBGCC2 > #undef TARGET_64BIT > @@ -1122,4 +1124,7 @@ extern void riscv_remove_unneeded_save_restore_call= s (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 =3D=3D 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" "")]) > > +(define_insn "@tlsdesc" > + [(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)\;" > + "\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" "")]) > + > (define_insn "auipc" > [(set (match_operand:P 0 "register_operand" "=3Dr") > (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=3Driscv-autovec-lmul=3D > Target RejectNegative Joined Enum(riscv_autovec_lmul) Var(riscv_autovec_= lmul) Init(RVV_M1) > -param=3Driscv-autovec-lmul=3D Set the RVV LMUL of auto-vect= orization 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=3D > +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 t= here 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 T= LS > 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 GN= U 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=3D@var{guard} -mstack-protector-guard-reg=3D@va= r{reg} > -mstack-protector-guard-offset=3D@var{offset} > -mcsr-check -mno-csr-check > --minline-atomics -mno-inline-atomics} > +-minline-atomics -mno-inline-atomics > +-mtls-dialect=3Ddesc -mtls-dialect=3Dtrad} > > @emph{RL78 Options} > @gccoptlist{-msim -mmul=3Dnone -mmul=3Dg13 -mmul=3Dg14 -mallregs > @@ -29403,6 +29404,16 @@ which register to use as base register for readi= ng 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=3Ddesc > +@item -mtls-dialect=3Ddesc > +Use TLS descriptors as the thread-local storage mechanism for dynamic ac= cesses > +of TLS variables. > + > +@opindex mtls-dialect=3Dtrad > +@item -mtls-dialect=3Dtrad > +Use traditional TLS as the thread-local storage mechanism for dynamic ac= cesses > +of TLS variables. This is the default. > @end table > > @node RL78 Options > -- > 2.42.1 > --=20 =E5=AE=8B=E6=96=B9=E7=9D=BF