This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Improve TBAA for types in anonymous namespaces


On Thu, 18 Jul 2019, Jan Hubicka wrote:

> Hi,
> this patch adjusts LTO tree merging to treat anonymous namespace types
> as local to a given TU, so just like !TREE_PUBLIC decls they are not
> merged (this is unify_scc change). This makes them to get different
> canonical types and act as independent types for TBAA.
> 
> I also modified canonical type calculation to never consider anonymous
> namespace types as interoperable with structurally equivalent types
> declared in non-C++ translation units.
> 
> Both these changes are tested by the testcase (first change makes set1
> and set2 independent and second chnage makes set1&set2 independent of
> set3).
> 
> lto-bootstrapped/regtested x86_64-linux

OK.  I wonder if we can/should carve off some bits to note
type_with_linkage_p and type_in_anonymous_namespace_p in the tree
itself?  At least in type_common there's plenty of bits left.
Not sure how expensive / reliable (non-C++?) those tests otherwise are.

Thanks,
Richard.

> Honza
> 
> 	* lto-common.c (gimple_register_canonical_type_1): Do not look for
> 	non-ODR conflicts of types in anonymous namespaces.
> 	(unify_scc): Do not merge anonymous namespace types.
> 	* g++.dg/lto/alias-5_0.C: New testcase.
> 	* g++.dg/lto/alias-5_1.C: New.
> 	* g++.dg/lto/alias-5_2.c: New.
> Index: lto/lto-common.c
> ===================================================================
> --- lto/lto-common.c	(revision 273551)
> +++ lto/lto-common.c	(working copy)
> @@ -418,13 +418,19 @@ gimple_register_canonical_type_1 (tree t
>    if (RECORD_OR_UNION_TYPE_P (t)
>        && odr_type_p (t) && !odr_type_violation_reported_p (t))
>      {
> -      /* Here we rely on fact that all non-ODR types was inserted into
> -	 canonical type hash and thus we can safely detect conflicts between
> -	 ODR types and interoperable non-ODR types.  */
> -      gcc_checking_assert (type_streaming_finished
> -			   && TYPE_MAIN_VARIANT (t) == t);
> -      slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
> -				       NO_INSERT);
> +      /* Anonymous namespace types never conflict with non-C++ types.  */
> +      if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
> +	slot = NULL;
> +      else
> +	{
> +	  /* Here we rely on fact that all non-ODR types was inserted into
> +	     canonical type hash and thus we can safely detect conflicts between
> +	     ODR types and interoperable non-ODR types.  */
> +	  gcc_checking_assert (type_streaming_finished
> +			       && TYPE_MAIN_VARIANT (t) == t);
> +	  slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
> +					   NO_INSERT);
> +	}
>        if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
>  	{
>  	  tree nonodr = *(tree *)slot;
> @@ -1640,11 +1646,14 @@ unify_scc (class data_in *data_in, unsig
>        tree t = streamer_tree_cache_get_tree (cache, from + i);
>        scc->entries[i] = t;
>        /* Do not merge SCCs with local entities inside them.  Also do
> -	 not merge TRANSLATION_UNIT_DECLs.  */
> +	 not merge TRANSLATION_UNIT_DECLs and anonymous namespace types.  */
>        if (TREE_CODE (t) == TRANSLATION_UNIT_DECL
>  	  || (VAR_OR_FUNCTION_DECL_P (t)
>  	      && !(TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
> -	  || TREE_CODE (t) == LABEL_DECL)
> +	  || TREE_CODE (t) == LABEL_DECL
> +	  || (TYPE_P (t)
> +	      && type_with_linkage_p (TYPE_MAIN_VARIANT (t))
> +	      && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t))))
>  	{
>  	  /* Avoid doing any work for these cases and do not worry to
>  	     record the SCCs for further merging.  */
> Index: testsuite/g++.dg/lto/alias-5_0.C
> ===================================================================
> --- testsuite/g++.dg/lto/alias-5_0.C	(nonexistent)
> +++ testsuite/g++.dg/lto/alias-5_0.C	(working copy)
> @@ -0,0 +1,35 @@
> +/* { dg-lto-do run } */
> +/* { dg-lto-options { { -O3 -flto } } } */
> +/* This testcase tests that anonymous namespaces in different TUs are treated
> +   as different types by LTO TBAA and that they never alias with structurally
> +   same C types.  */
> +namespace {
> +  __attribute__((used))
> +  struct a {int a;} *p,**ptr=&p;
> +};
> +void
> +set1()
> +{
> +  *ptr=0;
> +}
> +void
> +get1()
> +{
> +  if (!__builtin_constant_p (*ptr==0))
> +    __builtin_abort ();
> +}
> +extern void set2();
> +extern "C" void set3();
> +int n = 1;
> +int
> +main()
> +{
> +  for (int i = 0; i < n; i++)
> +    {
> +      set1();
> +      set2();
> +      set3();
> +      get1();
> +    }
> +  return 0;
> +}
> Index: testsuite/g++.dg/lto/alias-5_1.C
> ===================================================================
> --- testsuite/g++.dg/lto/alias-5_1.C	(nonexistent)
> +++ testsuite/g++.dg/lto/alias-5_1.C	(working copy)
> @@ -0,0 +1,9 @@
> +namespace {
> +  __attribute__((used))
> +  struct a {int a;} *p,**ptr=&p,q;
> +};
> +void
> +set2()
> +{
> +  *ptr=&q;
> +}
> Index: testsuite/g++.dg/lto/alias-5_2.c
> ===================================================================
> --- testsuite/g++.dg/lto/alias-5_2.c	(nonexistent)
> +++ testsuite/g++.dg/lto/alias-5_2.c	(working copy)
> @@ -0,0 +1,7 @@
> +  __attribute__((used))
> +  struct a {int a;} *p,**ptr=&p,q;
> +void
> +set3()
> +{
> +  *ptr=&q;
> +}
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]