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.
