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

Reply via email to