On Thu, Sep 18, 2025 at 8:40 PM H.J. Lu <[email protected]> wrote:
>
> 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.

PING.

-- 
H.J.

Reply via email to