[PATCH][mem-ref2] Fix some corner-cases wrt TBAA

Richard Guenther rguenther@suse.de
Mon Jun 21 00:21:00 GMT 2010


This fixes some latent problems.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2010-06-20  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.c (ao_ref_base_alias_set): Properly differentiate
	base object for offset and TBAA.
	(indirect_ref_may_alias_decl_p): Add tbaa_p parameter and test it.
	(indirect_refs_may_alias_p): Likewise.
	(refs_may_alias_p_1): Use ao_ref_base_alias_set for the
	pointer-vs-decl case.
	* alias.c (ao_ref_from_mem): Do not set base_alias_set here.
	(get_alias_set): Split MEM_REF and INDIRECT_REF case again
	and fix MEM_REF case.
	* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Init
	base_alias_set.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 161049)
--- gcc/tree-ssa-alias.c	(working copy)
*************** ao_ref_base (ao_ref *ref)
*** 474,485 ****
  
  /* Returns the base object alias set of the memory reference *REF.  */
  
! static alias_set_type ATTRIBUTE_UNUSED
  ao_ref_base_alias_set (ao_ref *ref)
  {
    if (ref->base_alias_set != -1)
      return ref->base_alias_set;
!   ref->base_alias_set = get_alias_set (ao_ref_base (ref));
    return ref->base_alias_set;
  }
  
--- 474,491 ----
  
  /* Returns the base object alias set of the memory reference *REF.  */
  
! static alias_set_type
  ao_ref_base_alias_set (ao_ref *ref)
  {
+   tree base_ref;
    if (ref->base_alias_set != -1)
      return ref->base_alias_set;
!   if (!ref->ref)
!     return 0;
!   base_ref = ref->ref;
!   while (handled_component_p (base_ref))
!     base_ref = TREE_OPERAND (base_ref, 0);
!   ref->base_alias_set = get_alias_set (base_ref);
    return ref->base_alias_set;
  }
  
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 678,684 ****
  			       tree ref2 ATTRIBUTE_UNUSED, tree base2,
  			       HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
  			       alias_set_type ref2_alias_set,
! 			       alias_set_type base2_alias_set)
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptrtype1;
--- 684,690 ----
  			       tree ref2 ATTRIBUTE_UNUSED, tree base2,
  			       HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
  			       alias_set_type ref2_alias_set,
! 			       alias_set_type base2_alias_set, bool tbaa_p)
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptrtype1;
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 698,704 ****
      return false;
  
    /* Disambiguations that rely on strict aliasing rules follow.  */
!   if (!flag_strict_aliasing)
      return true;
  
    if (TREE_CODE (base1) == MEM_REF)
--- 704,710 ----
      return false;
  
    /* Disambiguations that rely on strict aliasing rules follow.  */
!   if (!flag_strict_aliasing || !tbaa_p)
      return true;
  
    if (TREE_CODE (base1) == MEM_REF)
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 763,769 ****
  			   tree ref2 ATTRIBUTE_UNUSED, tree base2,
  			   HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
  			   alias_set_type ref2_alias_set,
! 			   alias_set_type base2_alias_set)
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptr2 = TREE_OPERAND (base2, 0);
--- 769,775 ----
  			   tree ref2 ATTRIBUTE_UNUSED, tree base2,
  			   HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
  			   alias_set_type ref2_alias_set,
! 			   alias_set_type base2_alias_set, bool tbaa_p)
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptr2 = TREE_OPERAND (base2, 0);
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 784,790 ****
      return false;
  
    /* Disambiguations that rely on strict aliasing rules follow.  */
!   if (!flag_strict_aliasing)
      return true;
  
    if (TREE_CODE (base1) == MEM_REF)
--- 790,796 ----
      return false;
  
    /* Disambiguations that rely on strict aliasing rules follow.  */
!   if (!flag_strict_aliasing || !tbaa_p)
      return true;
  
    if (TREE_CODE (base1) == MEM_REF)
*************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref
*** 849,855 ****
    HOST_WIDE_INT offset1 = 0, offset2 = 0;
    HOST_WIDE_INT max_size1 = -1, max_size2 = -1;
    bool var1_p, var2_p, ind1_p, ind2_p;
-   alias_set_type set;
  
    gcc_assert ((!ref1->ref
  	       || SSA_VAR_P (ref1->ref)
--- 855,860 ----
*************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref
*** 935,955 ****
      return true;
  
    /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
-   set = tbaa_p ? -1 : 0;
    if (var1_p && ind2_p)
      return indirect_ref_may_alias_decl_p (ref2->ref, base2,
  					  offset2, max_size2,
! 					  ao_ref_alias_set (ref2), set,
  					  ref1->ref, base1,
  					  offset1, max_size1,
! 					  ao_ref_alias_set (ref1), set);
    else if (ind1_p && ind2_p)
      return indirect_refs_may_alias_p (ref1->ref, base1,
  				      offset1, max_size1,
! 				      ao_ref_alias_set (ref1), set,
  				      ref2->ref, base2,
  				      offset2, max_size2,
! 				      ao_ref_alias_set (ref2), set);
  
    gcc_unreachable ();
  }
--- 940,962 ----
      return true;
  
    /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
    if (var1_p && ind2_p)
      return indirect_ref_may_alias_decl_p (ref2->ref, base2,
  					  offset2, max_size2,
! 					  ao_ref_alias_set (ref2), -1,
  					  ref1->ref, base1,
  					  offset1, max_size1,
! 					  ao_ref_alias_set (ref1),
! 					  ao_ref_base_alias_set (ref1),
! 					  tbaa_p);
    else if (ind1_p && ind2_p)
      return indirect_refs_may_alias_p (ref1->ref, base1,
  				      offset1, max_size1,
! 				      ao_ref_alias_set (ref1), -1,
  				      ref2->ref, base2,
  				      offset2, max_size2,
! 				      ao_ref_alias_set (ref2), -1,
! 				      tbaa_p);
  
    gcc_unreachable ();
  }
Index: gcc/alias.c
===================================================================
*** gcc/alias.c	(revision 161049)
--- gcc/alias.c	(working copy)
*************** ao_ref_from_mem (ao_ref *ref, const_rtx
*** 294,303 ****
        void *namep;
        namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
        if (namep)
! 	{
! 	  ref->base_alias_set = get_alias_set (base);
! 	  ref->base = build_simple_mem_ref (*(tree *)namep);
! 	}
      }
  
    ref->ref_alias_set = MEM_ALIAS_SET (mem);
--- 294,300 ----
        void *namep;
        namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
        if (namep)
! 	ref->base = build_simple_mem_ref (*(tree *)namep);
      }
  
    ref->ref_alias_set = MEM_ALIAS_SET (mem);
*************** get_alias_set (tree t)
*** 674,686 ****
  
        /* Handle pointer dereferences here, they can override the
  	 alias-set.  */
!       if (INDIRECT_REF_P (inner)
! 	  || TREE_CODE (inner) == MEM_REF)
  	{
  	  set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
  	  if (set != -1)
  	    return set;
  	}
  
        /* If the innermost reference is a MEM_REF that has a
  	 conversion embedded treat it like a VIEW_CONVERT_EXPR above,
--- 671,688 ----
  
        /* Handle pointer dereferences here, they can override the
  	 alias-set.  */
!       if (INDIRECT_REF_P (inner))
  	{
  	  set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
  	  if (set != -1)
  	    return set;
  	}
+       else if (TREE_CODE (inner) == MEM_REF)
+ 	{
+ 	  set = get_deref_alias_set_1 (TREE_OPERAND (inner, 1));
+ 	  if (set != -1)
+ 	    return set;
+ 	}
  
        /* If the innermost reference is a MEM_REF that has a
  	 conversion embedded treat it like a VIEW_CONVERT_EXPR above,
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 161049)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -889,7 +889,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
   ref->size = size;
   ref->max_size = max_size;
   ref->ref_alias_set = set;
-  ref->base_alias_set = -1;
+  ref->base_alias_set = get_alias_set (base);
 
   return true;
 }



More information about the Gcc-patches mailing list