On Wed, Sep 10, 2025 at 11:11 AM H.J. Lu <[email protected]> wrote:
>
> Since C, C++, and Fortran front-ends now set the TLS access model after
> a variable has been fully processed, not in the middle of processing it,
> add an option, -fipa-tls-access, for TLS access optimization as the part
> of IPA whole-program visibility optimization.  Enabled by default, it
> doesn't check tls_model attribute when optimizing TLS access since
>
> 1. -ftls-model=initial-exec can specify the weakest TLS access model
> without tls_model attribute.
> 2. Linker can optimize TLS access at link-time.
> 3. LTO should perform the similar optimization.
>
> The recomputed model of an undefined TLS variable with LOCAL_EXEC
> attribute is INITIAL_EXEC.  Linker will issue an error if the TLS
> model isn't supported in shared library.  But compiler doesn't know
> where the TLS variable is defined nor if the generated code will be
> linked into executable or shared library.
>
> gcc/
>
>         PR middle-end/121352
>         * common.opt: Add -fipa-tls-access.
>         * common.opt.urls: Regenerated.
>         * ipa-visibility.cc (function_and_variable_visibility): Don't
>         check tls_model attribute.  Update TLS access comments.
>         * doc/extend.texi: Update the tls_model attribute.
>         * doc/invoke.texi: Document -fipa-tls-access.
>
> gcc/testsuite/
>
>         PR middle-end/121352
>         * c-c++-common/tls-attr-hidden-gd.c: New test.
>         * c-c++-common/tls-attr-le-undef.c: Likewise.
>         * c-c++-common/tls-flag-hidden-gd.c: Likewise.
>         * c-c++-common/tls-pragma-hidden-gd.c: Likewise.
>         * gcc.dg/tls/vis-attr-hidden-gd.c: Pass -fno-ipa-tls-access.
>         * gcc.dg/tls/vis-flag-hidden-gd.c: Likewise.
>         * gcc.dg/tls/vis-pragma-hidden-gd.c: Likewise.
>
> Signed-off-by: H.J. Lu <[email protected]>
> ---
>  gcc/common.opt                                  |  4 ++++
>  gcc/common.opt.urls                             |  3 +++
>  gcc/doc/extend.texi                             | 14 +++++++++-----
>  gcc/doc/invoke.texi                             |  6 ++++++
>  gcc/ipa-visibility.cc                           | 14 ++++++++++----
>  gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c | 13 +++++++++++++
>  gcc/testsuite/c-c++-common/tls-attr-le-undef.c  | 15 +++++++++++++++
>  gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c | 13 +++++++++++++
>  .../c-c++-common/tls-pragma-hidden-gd.c         | 17 +++++++++++++++++
>  gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c   |  2 +-
>  gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c   |  2 +-
>  gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c |  2 +-
>  12 files changed, 93 insertions(+), 12 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c
>  create mode 100644 gcc/testsuite/c-c++-common/tls-attr-le-undef.c
>  create mode 100644 gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c
>  create mode 100644 gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index f6d93dc05fb..42c424b45d0 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2190,6 +2190,10 @@ fipa-icf-variables
>  Common Var(flag_ipa_icf_variables) Optimization
>  Perform Identical Code Folding for variables.
>
> +fipa-tls-access
> +Common Var(flag_ipa_tls_access) Init(1) Optimization
> +Perform TLS access optimization.
> +
>  fipa-reference
>  Common Var(flag_ipa_reference) Init(0) Optimization
>  Discover read-only and non addressable static variables.
> diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
> index ddc5eaf9c6b..b1af1b500f5 100644
> --- a/gcc/common.opt.urls
> +++ b/gcc/common.opt.urls
> @@ -917,6 +917,9 @@ UrlSuffix(gcc/Optimize-Options.html#index-fipa-pure-const)
>  fipa-icf
>  UrlSuffix(gcc/Optimize-Options.html#index-fipa-icf)
>
> +fipa-tls-access
> +UrlSuffix(gcc/Optimize-Options.html#index-fipa-tls-access)
> +
>  fipa-reference
>  UrlSuffix(gcc/Optimize-Options.html#index-fipa-reference)
>
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 2922d9e9839..9d55fbb61af 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -7559,11 +7559,15 @@ information.
>  @cindex @code{tls_model} variable attribute
>  @item tls_model ("@var{tls_model}")
>  The @code{tls_model} attribute sets thread-local storage model
> -(@pxref{Thread-Local}) of a particular @code{__thread} variable,
> -overriding @option{-ftls-model=} command-line switch on a per-variable
> -basis.
> -The @var{tls_model} argument should be one of @code{global-dynamic},
> -@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
> +(@pxref{Thread-Local}) of a particular @code{__thread} variable on a
> +per-variable basis.  The @var{tls_model} argument should be one of
> +@code{global-dynamic}, @code{local-dynamic}, @code{initial-exec} or
> +@code{local-exec}.  The @code{tls_model} attribute specifies the
> +weakest @acronym{TLS} model.  It overrides @option{-ftls-model=}
> +command-line switch if it is stronger than the @acronym{TLS} model
> +specified by the command-line switch.  GCC may optimize @acronym{TLS}
> +access to a stronger @acronym{TLS} model by C/C++ front end as well
> +as IPA optimization (see @option{-fno-ipa-tls-access}).
>
>  Not all targets support this attribute.
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index d0c13d4a24e..b6019cf2746 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -14216,6 +14216,12 @@ option is not enabled by default otherwise.
>  Reduce stack alignment on call sites if possible.
>  Enabled by default.
>
> +@opindex fno-ipa-tls-access
> +@opindex fipa-tls-access
> +@item -fno-ipa-tls-access
> +Don't upgrade TLS model as the part of IPA whole-program visibility
> +optimization.
> +
>  @opindex fipa-pta
>  @item -fipa-pta
>  Perform interprocedural pointer analysis and interprocedural modification
> diff --git a/gcc/ipa-visibility.cc b/gcc/ipa-visibility.cc
> index 8097a03e240..56bc39816bf 100644
> --- a/gcc/ipa-visibility.cc
> +++ b/gcc/ipa-visibility.cc
> @@ -883,18 +883,24 @@ function_and_variable_visibility (bool whole_program)
>           tree decl = vnode->decl;
>
>           /* Upgrade TLS access model based on optimized visibility status,
> -            unless it was specified explicitly or no references remain.  */
> +            unless TLS access optimization is disabled or no references
> +            remain.  */
>           if (DECL_THREAD_LOCAL_P (decl)
> -             && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl))
> +             && flag_ipa_tls_access
>               && vnode->ref_list.referring.length ())
>             {
>               enum tls_model new_model = decl_default_tls_model (decl);
>               STATIC_ASSERT (TLS_MODEL_GLOBAL_DYNAMIC < 
> TLS_MODEL_LOCAL_DYNAMIC);
>               STATIC_ASSERT (TLS_MODEL_INITIAL_EXEC < TLS_MODEL_LOCAL_EXEC);
> -             /* We'd prefer to assert that recomputed model is not weaker 
> than
> -                what the front-end assigned, but cannot: see PR 107353.  */
> +             /* decl_default_tls_model does not scan the attribute list
> +                and may return a weaker model than the attribute.  If
> +                there was no attribute, we can expect that recomputed
> +                model is never weaker.   */
>               if (new_model >= decl_tls_model (decl))
>                 set_decl_tls_model (decl, new_model);
> +             else
> +               gcc_checking_assert (lookup_attribute ("tls_model",
> +                                                      DECL_ATTRIBUTES 
> (decl)));
>             }
>         }
>      }
> diff --git a/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c 
> b/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c
> new file mode 100644
> index 00000000000..4512bff04ad
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-attr-hidden-gd.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */
> +
> +__attribute__((visibility("hidden")))
> +__attribute__((tls_model("global-dynamic")))
> +__thread int x;
> +
> +void reference() { x++; }
> +
> +// tls_model should be local-dynamic due to hidden visibility.
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/c-c++-common/tls-attr-le-undef.c 
> b/gcc/testsuite/c-c++-common/tls-attr-le-undef.c
> new file mode 100644
> index 00000000000..b11c5c9dabc
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-attr-le-undef.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fdump-ipa-whole-program" } */
> +
> +__attribute__ ((tls_model ("local-exec")))
> +extern __thread int i;
> +
> +int *
> +foo (void)
> +{
> +  return &i;
> +}
> +
> +/* tls_model should be local-exec due to tls_model attribute.  */
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-exec" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c 
> b/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c
> new file mode 100644
> index 00000000000..fba79cfd75a
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-flag-hidden-gd.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program -fvisibility=hidden" } */
> +
> +
> +__attribute__((tls_model("global-dynamic")))
> +__thread int x;
> +
> +void reference() { x++; }
> +
> +// tls_model should be local-dynamic due to hidden visibility.
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c 
> b/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c
> new file mode 100644
> index 00000000000..3649b6f7272
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-pragma-hidden-gd.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */
> +
> +
> +#pragma GCC visibility push(hidden)
> +
> +__attribute__((tls_model("global-dynamic")))
> +__thread int x;
> +
> +#pragma GCC visibility pop
> +
> +void reference() { x++; }
> +
> +// tls_model should be local-dynamic due to hidden visibility.
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c 
> b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c
> index e32565588c8..05b04cc774b 100644
> --- a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c
> +++ b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile } */
>  /* { dg-require-effective-target fpic } */
>  /* { dg-require-effective-target tls } */
> -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */
> +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program" } */
>
>  // tls_model should be global-dynamic due to explicitly specified attribute
>  __attribute__((visibility("hidden")))
> diff --git a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c 
> b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c
> index cad41e0c8e6..85ee07fb563 100644
> --- a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c
> +++ b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile } */
>  /* { dg-require-effective-target fpic } */
>  /* { dg-require-effective-target tls } */
> -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program -fvisibility=hidden" } */
> +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program 
> -fvisibility=hidden" } */
>
>
>  // tls_model should be global-dynamic due to explicitly specified attribute
> diff --git a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c 
> b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c
> index 3b3598134fe..7b0a01b8629 100644
> --- a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c
> +++ b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c
> @@ -1,7 +1,7 @@
>  /* { dg-do compile } */
>  /* { dg-require-effective-target fpic } */
>  /* { dg-require-effective-target tls } */
> -/* { dg-options "-O2 -fPIC -fdump-ipa-whole-program" } */
> +/* { dg-options "-O2 -fPIC -fno-ipa-tls-access -fdump-ipa-whole-program" } */
>
>
>  #pragma GCC visibility push(hidden)
> --
> 2.51.0
>

PING.

-- 
H.J.

Reply via email to