[PATCH][LTO] Some TBAA fixes

Richard Guenther rguenther@suse.de
Sun Oct 25 20:47:00 GMT 2009


This addresses two things.  First Alexandre reported issues with
-fcompare-debug and fld calling get_alias_set - the patch removes
it (and has to adjust re-setting types_compatible_p, the langhook
is needed if late initializing the FE specific type hashtable
in the get_alias_set langhook.  Ugh).

The 2nd issue is alias-sets of pointers.  While I believe we
should move to a middle-end-only solution for get_alias_set for
4.5 I'll only try to cover up for bugs uncovered with LTO.  This
implements the cheapest way (and possibly enough precision anyway)
for pointer types - the patch mentions all the issues that arise.

Bootstrapped and tested on x86_64-unknown-linux-gnu, SPEC 2006
tested where it fixes the calculix miscompare (which might be
as well a calculix bug, not a LTO bug - but after all, we
should be reasonable and SPEC 2006 seems to be a reasonable
sanity test).

Ok for trunk?

Thanks,
Richard.

2009-10-25  Richard Guenther  <rguenther@suse.de>

	* tree.c (free_lang_data_in_type): Do not call get_alias_set.
	(free_lang_data): Do not reset the types_compatible_p langhook.
	* gimple.c (gimple_get_alias_set): Use the same alias-set for
	all pointer types.

Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 153539)
--- gcc/tree.c	(working copy)
*************** free_lang_data_in_type (tree type)
*** 4176,4186 ****
  {
    gcc_assert (TYPE_P (type));
  
-   /* Fill in the alias-set.  We need to at least track zeroness here
-      for correctness.  */
-   if (lang_hooks.get_alias_set (type) == 0)
-     TYPE_ALIAS_SET (type) = 0;
- 
    /* Give the FE a chance to remove its own data first.  */
    lang_hooks.free_lang_data (type);
  
--- 4176,4181 ----
*************** free_lang_data (void)
*** 4956,4964 ****
    else
      signed_char_type_node = char_type_node;
  
!   /* Reset some langhooks.  */
    lang_hooks.callgraph.analyze_expr = NULL;
-   lang_hooks.types_compatible_p = NULL;
    lang_hooks.dwarf_name = lhd_dwarf_name;
    lang_hooks.decl_printable_name = gimple_decl_printable_name;
    lang_hooks.set_decl_assembler_name = lhd_set_decl_assembler_name;
--- 4951,4959 ----
    else
      signed_char_type_node = char_type_node;
  
!   /* Reset some langhooks.  Do not reset types_compatible_p, it may
!      still be used indirectly via the get_alias_set langhook.  */
    lang_hooks.callgraph.analyze_expr = NULL;
    lang_hooks.dwarf_name = lhd_dwarf_name;
    lang_hooks.decl_printable_name = gimple_decl_printable_name;
    lang_hooks.set_decl_assembler_name = lhd_set_decl_assembler_name;
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 153538)
--- gcc/gimple.c	(working copy)
*************** gimple_signed_type (tree type)
*** 4120,4126 ****
  alias_set_type
  gimple_get_alias_set (tree t)
  {
-   static bool recursing_p;
    tree u;
  
    /* Permit type-punning when accessing a union, provided the access
--- 4120,4125 ----
*************** gimple_get_alias_set (tree t)
*** 4160,4174 ****
      }
    else if (POINTER_TYPE_P (t))
      {
!       tree t1;
  
!       /* ???  We can end up creating cycles with TYPE_MAIN_VARIANT
! 	 and TYPE_CANONICAL.  Avoid recursing endlessly between
! 	 this langhook and get_alias_set.  */
!       if (recursing_p)
! 	return -1;
! 
!       /* Unfortunately, there is no canonical form of a pointer type.
  	 In particular, if we have `typedef int I', then `int *', and
  	 `I *' are different types.  So, we have to pick a canonical
  	 representative.  We do this below.
--- 4159,4167 ----
      }
    else if (POINTER_TYPE_P (t))
      {
!       /* From the common C and C++ langhook implementation:
  
! 	 Unfortunately, there is no canonical form of a pointer type.
  	 In particular, if we have `typedef int I', then `int *', and
  	 `I *' are different types.  So, we have to pick a canonical
  	 representative.  We do this below.
*************** gimple_get_alias_set (tree t)
*** 4190,4204 ****
  	 can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
  	 the pointed-to types.  This issue has been reported to the
  	 C++ committee.  */
!       t1 = build_type_no_quals (t);
!       if (t1 != t)
! 	{
! 	  alias_set_type set;
! 	  recursing_p = true;
! 	  set = get_alias_set (t1);
! 	  recursing_p = false;
! 	  return set;
! 	}
      }
  
    return -1;
--- 4183,4218 ----
  	 can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
  	 the pointed-to types.  This issue has been reported to the
  	 C++ committee.  */
! 
!       /* In addition to the above canonicalization issue with LTO
!          we should also canonicalize `T (*)[]' to `T *' avoiding
! 	 alias issues with pointer-to element types and pointer-to
! 	 array types.
! 
! 	 Likewise we need to deal with the situation of incomplete
! 	 pointed-to types and make `*(struct X **)&a' and
! 	 `*(struct X {} **)&a' alias.  Otherwise we will have to
! 	 guarantee that all pointer-to incomplete type variants
! 	 will be replaced by pointer-to complete type variants if
! 	 they are available.
! 
! 	 With LTO the convenient situation of using `void *' to
! 	 access and store any pointer type will also become
! 	 more appearant (and `void *' is just another pointer-to
! 	 incomplete type).  Assigning alias-set zero to `void *'
! 	 and all pointer-to incomplete types is a not appealing
! 	 solution.  Assigning an effective alias-set zero only
! 	 affecting pointers might be - by recording proper subset
! 	 relationships of all pointer alias-sets.
! 
! 	 Pointer-to function types are another grey area which
! 	 needs caution.  Globbing them all into one alias-set
! 	 or the above effective zero set would work.  */
! 
!       /* For now just assign the same alias-set to all pointers.
!          That's simple and avoids all the above problems.  */
!       if (t != ptr_type_node)
! 	return get_alias_set (ptr_type_node);
      }
  
    return -1;



More information about the Gcc-patches mailing list