Fix issue PR99619, which asks to optimize TLS access based on visibility. The fix is implemented as an IPA optimization, which allows to take optimized visibility status into account (as well as avoid modifying all language frontends).
2022-04-17 Artem Klimov <jakmob...@gmail.com> gcc/ChangeLog: PR middle-end/99619 * ipa-visibility.cc (function_and_variable_visibility): Add an explicit TLS model update after visibility optimisation loops. gcc/testsuite/ChangeLog: PR middle-end/99619 * gcc.dg/tls/vis-attr-gd.c: New test. * gcc.dg/tls/vis-attr-hidden-gd.c: New test. * gcc.dg/tls/vis-attr-hidden.c: New test. * gcc.dg/tls/vis-flag-hidden-gd.c: New test. * gcc.dg/tls/vis-flag-hidden.c: New test. * gcc.dg/tls/vis-pragma-hidden-gd.c: New test. * gcc.dg/tls/vis-pragma-hidden.c: New test. Co-Authored-By: Alexander Monakov <amona...@gcc.gnu.org> Signed-off-by: Artem Klimov <jakmob...@gmail.com> --- gcc/ipa-visibility.cc | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/tls/vis-attr-gd.c | 10 ++++++++++ gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c | 11 +++++++++++ gcc/testsuite/gcc.dg/tls/vis-attr-hidden.c | 10 ++++++++++ gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c | 11 +++++++++++ gcc/testsuite/gcc.dg/tls/vis-flag-hidden.c | 10 ++++++++++ gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/tls/vis-pragma-hidden.c | 14 ++++++++++++++ 8 files changed, 97 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tls/vis-attr-gd.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-attr-hidden.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-flag-hidden.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c create mode 100644 gcc/testsuite/gcc.dg/tls/vis-pragma-hidden.c diff --git a/gcc/ipa-visibility.cc b/gcc/ipa-visibility.cc index e95a0dd252f..ca5b9a95f5e 100644 --- a/gcc/ipa-visibility.cc +++ b/gcc/ipa-visibility.cc @@ -872,6 +872,22 @@ function_and_variable_visibility (bool whole_program) } } } + FOR_EACH_VARIABLE (vnode) + { + tree decl = vnode->decl; + + /* Optimize TLS model based on visibility (taking into account + optimizations done in the preceding loop), unless it was + specified explicitly. */ + + if (DECL_THREAD_LOCAL_P (decl) + && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl))) + { + enum tls_model new_model = decl_default_tls_model (decl); + gcc_checking_assert (new_model >= decl_tls_model (decl)); + set_decl_tls_model (decl, new_model); + } + } if (dump_file) { diff --git a/gcc/testsuite/gcc.dg/tls/vis-attr-gd.c b/gcc/testsuite/gcc.dg/tls/vis-attr-gd.c new file mode 100644 index 00000000000..473c7846f74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-attr-gd.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility" } */ + +// tls_model should be global-dynamic due to explicitly specified attribute +__attribute__((tls_model("global-dynamic"))) +__thread int x; + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-global-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c new file mode 100644 index 00000000000..8f592052361 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden-gd.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility" } */ + +// tls_model should be global-dynamic due to explicitly specified attribute +__attribute__((visibility("hidden"))) +__attribute__((tls_model("global-dynamic"))) +__thread int x; + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-global-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-attr-hidden.c b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden.c new file mode 100644 index 00000000000..2da1bc3fa42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-attr-hidden.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility" } */ + +//tls_model should be local-dynamic due to visibility("hidden") +__attribute__((visibility("hidden"))) +__thread int x; + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c new file mode 100644 index 00000000000..de01ef31776 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden-gd.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility -fvisibility=hidden" } */ + + +// tls_model should be global-dynamic due to explicitly specified attribute +__attribute__((tls_model("global-dynamic"))) +__thread int x; + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-global-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-flag-hidden.c b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden.c new file mode 100644 index 00000000000..3701eaafd62 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-flag-hidden.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility -fvisibility=hidden" } */ + + +// tls_model should be local-dynamic due to -fvisibility=hidden +__thread int x; + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c new file mode 100644 index 00000000000..39cc4bed17d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden-gd.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility" } */ + + +#pragma GCC visibility push(hidden) + +// tls_model should be global-dynamic due to explicitly specified attribute +__attribute__((tls_model("global-dynamic"))) +__thread int x; + +#pragma GCC visibility pop + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-global-dynamic" "visibility" } } */ diff --git a/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden.c b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden.c new file mode 100644 index 00000000000..1d6b9b144b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/vis-pragma-hidden.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-O2 -fPIC -fdump-ipa-visibility" } */ + + +#pragma GCC visibility push(hidden) + +// tls_model should be local-dynamic due to a pragma +__thread int x; + +#pragma GCC visibility pop + +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-dynamic" "visibility" } } */ -- 2.25.1