public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Optimize constinit thread_local vars [PR101786]
@ 2021-08-06  8:16 Jakub Jelinek
  2021-08-11 19:21 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2021-08-06  8:16 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

The paper that introduced constinit mentioned in rationale that constinit
can be used on externs as well and that it can be used to avoid the
thread_local initialization wrappers, because the standard requires that
if constinit is present on any declaration, it is also present on the
initialization declaration, even if it is in some other TU etc.

There is a small problem though, we use the tls wrappers not just if
the thread_local variable needs dynamic initialization, but also when
it has static initialization, but non-trivial destructor, as the
"dynamic initialization" in that case needs to register the destructor.

So, the following patch optimizes constinit thread_local vars only
if we can prove they will not have non-trivial destructors.  That includes
the case where we have incomplete type where we don't know and need to
conservatively assume the type will have non-trivial destructor at the
initializing declaration side.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-08-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/101786
	* decl2.c (var_defined_without_dynamic_init): Return true for
	DECL_DECLARED_CONSTINIT_P with complete type and trivial destructor.

	* g++.dg/cpp2a/constinit16.C: New test.

--- gcc/cp/decl2.c.jj	2021-07-02 21:59:12.359171627 +0200
+++ gcc/cp/decl2.c	2021-08-05 16:09:39.833599188 +0200
@@ -3447,6 +3447,12 @@ set_guard (tree guard)
 static bool
 var_defined_without_dynamic_init (tree var)
 {
+  /* constinit vars are guaranteed to not have dynamic initializer,
+     but still registering the destructor counts as dynamic initialization.  */
+  if (DECL_DECLARED_CONSTINIT_P (var)
+      && COMPLETE_TYPE_P (TREE_TYPE (var))
+      && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
+    return true;
   /* If it's defined in another TU, we can't tell.  */
   if (DECL_EXTERNAL (var))
     return false;
--- gcc/testsuite/g++.dg/cpp2a/constinit16.C.jj	2021-08-05 15:50:49.702463664 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constinit16.C	2021-08-05 16:14:52.893202685 +0200
@@ -0,0 +1,21 @@
+// PR c++/101786
+// { dg-do compile { target c++20 } }
+// { dg-add-options tls }
+// { dg-require-alias "" }
+// { dg-require-effective-target tls_runtime }
+// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar1" } }
+// { dg-final { scan-assembler "_ZTH17mythreadlocalvar2" } }
+// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar3" } }
+// { dg-final { scan-assembler "_ZTH17mythreadlocalvar4" } }
+
+extern thread_local constinit int mythreadlocalvar1;
+struct S;
+extern thread_local constinit S mythreadlocalvar2;
+struct T { int t; };
+extern thread_local constinit T mythreadlocalvar3;
+struct U { int u; ~U (); };
+extern thread_local constinit U mythreadlocalvar4;
+int foo () { return mythreadlocalvar1; }
+S *bar () { return &mythreadlocalvar2; }
+T *baz () { return &mythreadlocalvar3; }
+U *qux () { return &mythreadlocalvar4; }

	Jakub


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] c++: Optimize constinit thread_local vars [PR101786]
  2021-08-06  8:16 [PATCH] c++: Optimize constinit thread_local vars [PR101786] Jakub Jelinek
@ 2021-08-11 19:21 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2021-08-11 19:21 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On 8/6/21 4:16 AM, Jakub Jelinek wrote:
> Hi!
> 
> The paper that introduced constinit mentioned in rationale that constinit
> can be used on externs as well and that it can be used to avoid the
> thread_local initialization wrappers, because the standard requires that
> if constinit is present on any declaration, it is also present on the
> initialization declaration, even if it is in some other TU etc.
> 
> There is a small problem though, we use the tls wrappers not just if
> the thread_local variable needs dynamic initialization, but also when
> it has static initialization, but non-trivial destructor, as the
> "dynamic initialization" in that case needs to register the destructor.
> 
> So, the following patch optimizes constinit thread_local vars only
> if we can prove they will not have non-trivial destructors.  That includes
> the case where we have incomplete type where we don't know and need to
> conservatively assume the type will have non-trivial destructor at the
> initializing declaration side.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2021-08-06  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/101786
> 	* decl2.c (var_defined_without_dynamic_init): Return true for
> 	DECL_DECLARED_CONSTINIT_P with complete type and trivial destructor.
> 
> 	* g++.dg/cpp2a/constinit16.C: New test.
> 
> --- gcc/cp/decl2.c.jj	2021-07-02 21:59:12.359171627 +0200
> +++ gcc/cp/decl2.c	2021-08-05 16:09:39.833599188 +0200
> @@ -3447,6 +3447,12 @@ set_guard (tree guard)
>   static bool
>   var_defined_without_dynamic_init (tree var)
>   {
> +  /* constinit vars are guaranteed to not have dynamic initializer,
> +     but still registering the destructor counts as dynamic initialization.  */
> +  if (DECL_DECLARED_CONSTINIT_P (var)
> +      && COMPLETE_TYPE_P (TREE_TYPE (var))
> +      && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
> +    return true;
>     /* If it's defined in another TU, we can't tell.  */
>     if (DECL_EXTERNAL (var))
>       return false;
> --- gcc/testsuite/g++.dg/cpp2a/constinit16.C.jj	2021-08-05 15:50:49.702463664 +0200
> +++ gcc/testsuite/g++.dg/cpp2a/constinit16.C	2021-08-05 16:14:52.893202685 +0200
> @@ -0,0 +1,21 @@
> +// PR c++/101786
> +// { dg-do compile { target c++20 } }
> +// { dg-add-options tls }
> +// { dg-require-alias "" }
> +// { dg-require-effective-target tls_runtime }
> +// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar1" } }
> +// { dg-final { scan-assembler "_ZTH17mythreadlocalvar2" } }
> +// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar3" } }
> +// { dg-final { scan-assembler "_ZTH17mythreadlocalvar4" } }
> +
> +extern thread_local constinit int mythreadlocalvar1;
> +struct S;
> +extern thread_local constinit S mythreadlocalvar2;
> +struct T { int t; };
> +extern thread_local constinit T mythreadlocalvar3;
> +struct U { int u; ~U (); };
> +extern thread_local constinit U mythreadlocalvar4;
> +int foo () { return mythreadlocalvar1; }
> +S *bar () { return &mythreadlocalvar2; }
> +T *baz () { return &mythreadlocalvar3; }
> +U *qux () { return &mythreadlocalvar4; }
> 
> 	Jakub
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-08-11 19:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-06  8:16 [PATCH] c++: Optimize constinit thread_local vars [PR101786] Jakub Jelinek
2021-08-11 19:21 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).