[PATCH] Remove special-casing of PTR_IS_REF_ALL pointers from alias analysis

Richard Guenther rguenther@suse.de
Tue Apr 29 17:48:00 GMT 2008


On Mon, 28 Apr 2008, Richard Guenther wrote:

> On Mon, 28 Apr 2008, Eric Botcazou wrote:
> 
> > Maybe PTR_IS_REF_ALL is overkill now though, testing TYPE_REF_CAN_ALIAS_ALL 
> > directly would be more straightforward.
> 
> I'll update the patch to remove the indirection.

This is what I applied after re-boostrapping and testing.

Richard.

2008-04-28  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.c (finalize_ref_all_pointers): Remove.
	(compute_may_aliases): Do not call finalize_ref_all_pointers.
	(compute_flow_insensitive_aliasing): Do not treat
	PTR_IS_REF_ALL pointers special.
	(get_smt_for): Likewise.
	(may_alias_p): Re-structure.
	(is_escape_site): A ref-all pointer conversion is not an escape site.
	* tree-ssa-structalias.c (find_what_p_points_to): Do not treat
	PTR_IS_REF_ALL pointers special.
	* tree-ssa-structalias.h (struct alias_info): Remove
	ref_all_symbol_mem_tag field.
	(PTR_IS_REF_ALL): Remove.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2008-04-29 14:05:43.000000000 +0200
--- gcc/tree-ssa-alias.c	2008-04-29 16:30:59.000000000 +0200
*************** static bitmap_obstack alias_bitmap_obsta
*** 196,202 ****
  
  /* Local functions.  */
  static void compute_flow_insensitive_aliasing (struct alias_info *);
- static void finalize_ref_all_pointers (struct alias_info *);
  static void dump_alias_stats (FILE *);
  static bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
  static tree create_memory_tag (tree type, bool is_type_tag);
--- 196,201 ----
*************** compute_may_aliases (void)
*** 1800,1811 ****
       avoid invalid transformations on them.  */
    maybe_create_global_var ();
  
-   /* If the program contains ref-all pointers, finalize may-alias information
-      for them.  This pass needs to be run after call-clobbering information
-      has been computed.  */
-   if (ai->ref_all_symbol_mem_tag)
-     finalize_ref_all_pointers (ai);
- 
    /* Compute memory partitions for every memory variable.  */
    compute_memory_partitions ();
  
--- 1799,1804 ----
*************** compute_flow_insensitive_aliasing (struc
*** 2408,2417 ****
        tree tag = symbol_mem_tag (p_map->var);
        tree var;
  
-       /* Call-clobbering information is not finalized yet at this point.  */
-       if (PTR_IS_REF_ALL (p_map->var))
- 	continue;
- 
        for (j = 0; j < ai->num_addressable_vars; j++)
  	{
  	  struct alias_map_d *v_map;
--- 2401,2406 ----
*************** compute_flow_insensitive_aliasing (struc
*** 2473,2481 ****
        tree tag1 = symbol_mem_tag (p_map1->var);
        bitmap may_aliases1 = MTAG_ALIASES (tag1);
  
-       if (PTR_IS_REF_ALL (p_map1->var))
- 	continue;
- 
        for (j = 0; j < ai->num_pointers; j++)
  	{
  	  struct alias_map_d *p_map2 = ai->pointers[j];
--- 2462,2467 ----
*************** compute_flow_insensitive_aliasing (struc
*** 2486,2494 ****
  	  if (tag1 == tag2)
  	    continue;
  
- 	  if (PTR_IS_REF_ALL (p_map2->var))
- 	    continue;
- 
  	  /* If the pointers may not point to each other, do nothing.  */
  	  if (!may_alias_p (p_map1->var, p_map1->set, tag2, p_map2->set, true))
  	    continue;
--- 2472,2477 ----
*************** compute_flow_insensitive_aliasing (struc
*** 2505,2553 ****
  }
  
  
- /* Finalize may-alias information for ref-all pointers.  Traverse all
-    the addressable variables found in setup_pointers_and_addressables.
- 
-    If flow-sensitive alias analysis has attached a name memory tag to
-    a ref-all pointer, we will use it for the dereferences because that
-    will have more precise aliasing information.  But if there is no
-    name tag, we will use a special symbol tag that aliases all the
-    call-clobbered addressable variables.  */
- 
- static void
- finalize_ref_all_pointers (struct alias_info *ai)
- {
-   size_t i;
- 
-   /* First add the real call-clobbered variables.  */
-   for (i = 0; i < ai->num_addressable_vars; i++)
-     {
-       tree var = ai->addressable_vars[i]->var;
-       if (is_call_clobbered (var))
- 	add_may_alias (ai->ref_all_symbol_mem_tag, var);
-     }
- 
-   /* Then add the call-clobbered pointer memory tags.  See
-      compute_flow_insensitive_aliasing for the rationale.  */
-   for (i = 0; i < ai->num_pointers; i++)
-     {
-       tree ptr = ai->pointers[i]->var, tag;
-       /* Avoid adding to self and clean up.  */
-       if (PTR_IS_REF_ALL (ptr))
- 	{
- 	  struct ptr_info_def *pi = get_ptr_info (ptr);
- 	  if (pi->is_dereferenced)
- 	    pi->pt_anything = 0;
- 	  continue;
- 	}
-       tag = symbol_mem_tag (ptr);
-       if (is_call_clobbered (tag))
- 	add_may_alias (ai->ref_all_symbol_mem_tag, tag);
-     }
- 
- }
- 
- 
  /* Create a new alias set entry for VAR in AI->ADDRESSABLE_VARS.  */
  
  static void
--- 2488,2493 ----
*************** may_alias_p (tree ptr, alias_set_type me
*** 2842,2926 ****
        return false;
      }
  
!   gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG);
! 
!   if (!DECL_NO_TBAA_P (ptr))
      {
!       alias_stats.tbaa_queries++;
  
!       /* If the pointed to memory has alias set zero or the pointer
! 	 is ref-all, the MEM can alias VAR.  */
!       if (mem_alias_set == 0
! 	  || PTR_IS_REF_ALL (ptr))
! 	{
! 	  alias_stats.alias_mayalias++;
! 	  alias_stats.tbaa_resolved++;
! 	  return true;
! 	}
  
!       /* If the alias sets don't conflict then MEM cannot alias VAR.  */
!       if (mem_alias_set != var_alias_set
! 	  && !alias_set_subset_of (mem_alias_set, var_alias_set))
! 	{
! 	  alias_stats.alias_noalias++;
! 	  alias_stats.tbaa_resolved++;
! 	  return false;
! 	}
  
!       /* If VAR is a record or union type, PTR cannot point into VAR
! 	 unless there is some explicit address operation in the
! 	 program that can reference a field of the type pointed-to by
! 	 PTR.  This also assumes that the types of both VAR and PTR
! 	 are contained within the compilation unit, and that there is
! 	 no fancy addressing arithmetic associated with any of the
! 	 types involved.  */
!       if (mem_alias_set != 0 && var_alias_set != 0)
! 	{
! 	  tree ptr_type = TREE_TYPE (ptr);
! 	  tree var_type = TREE_TYPE (var);
        
! 	  /* The star count is -1 if the type at the end of the
! 	     pointer_to chain is not a record or union type. */ 
! 	  if ((!alias_set_only) && 
! 	      ipa_type_escape_star_count_of_interesting_type (var_type) >= 0)
! 	    {
! 	      int ptr_star_count = 0;
  	  
! 	      /* ipa_type_escape_star_count_of_interesting_type is a
! 		 little too restrictive for the pointer type, need to
! 		 allow pointers to primitive types as long as those
! 		 types cannot be pointers to everything.  */
! 	      while (POINTER_TYPE_P (ptr_type))
! 		{
! 		  /* Strip the *s off.  */ 
! 		  ptr_type = TREE_TYPE (ptr_type);
! 		  ptr_star_count++;
! 		}
  	  
! 	      /* There does not appear to be a better test to see if
! 		 the pointer type was one of the pointer to everything
! 		 types.  */
! 	      if (ptr_star_count > 0)
! 		{
! 		  alias_stats.structnoaddress_queries++;
! 		  if (ipa_type_escape_field_does_not_clobber_p (var_type, 
! 								TREE_TYPE (ptr)))
! 		    {
! 		      alias_stats.structnoaddress_resolved++;
! 		      alias_stats.alias_noalias++;
! 		      return false;
! 		    }
! 		}
! 	      else if (ptr_star_count == 0)
  		{
- 		  /* If PTR_TYPE was not really a pointer to type, it cannot 
- 		     alias.  */ 
- 		  alias_stats.structnoaddress_queries++;
  		  alias_stats.structnoaddress_resolved++;
  		  alias_stats.alias_noalias++;
  		  return false;
  		}
  	    }
  	}
      }
  
--- 2782,2866 ----
        return false;
      }
  
!   /* If the pointed to memory has alias set zero, or the pointer
!      is ref-all, or the pointer decl is marked that no TBAA is to
!      be applied, the MEM can alias VAR.  */
!   if (mem_alias_set == 0
!       || DECL_POINTER_ALIAS_SET (ptr) == 0
!       || TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr))
!       || DECL_NO_TBAA_P (ptr))
      {
!       alias_stats.alias_mayalias++;
!       alias_stats.simple_resolved++;
!       return true;
!     }
  
!   gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG);
  
!   alias_stats.tbaa_queries++;
  
!   /* If the alias sets don't conflict then MEM cannot alias VAR.  */
!   if (mem_alias_set != var_alias_set
!       && !alias_set_subset_of (mem_alias_set, var_alias_set))
!     {
!       alias_stats.alias_noalias++;
!       alias_stats.tbaa_resolved++;
!       return false;
!     }
! 
!   /* If VAR is a record or union type, PTR cannot point into VAR
!      unless there is some explicit address operation in the
!      program that can reference a field of the type pointed-to by
!      PTR.  This also assumes that the types of both VAR and PTR
!      are contained within the compilation unit, and that there is
!      no fancy addressing arithmetic associated with any of the
!      types involved.  */
!   if (mem_alias_set != 0 && var_alias_set != 0)
!     {
!       tree ptr_type = TREE_TYPE (ptr);
!       tree var_type = TREE_TYPE (var);
        
!       /* The star count is -1 if the type at the end of the
! 	 pointer_to chain is not a record or union type. */ 
!       if (!alias_set_only
! 	  && ipa_type_escape_star_count_of_interesting_type (var_type) >= 0)
! 	{
! 	  int ptr_star_count = 0;
  	  
! 	  /* ipa_type_escape_star_count_of_interesting_type is a
! 	     little too restrictive for the pointer type, need to
! 	     allow pointers to primitive types as long as those
! 	     types cannot be pointers to everything.  */
! 	  while (POINTER_TYPE_P (ptr_type))
! 	    {
! 	      /* Strip the *s off.  */ 
! 	      ptr_type = TREE_TYPE (ptr_type);
! 	      ptr_star_count++;
! 	    }
  	  
! 	  /* There does not appear to be a better test to see if
! 	     the pointer type was one of the pointer to everything
! 	     types.  */
! 	  if (ptr_star_count > 0)
! 	    {
! 	      alias_stats.structnoaddress_queries++;
! 	      if (ipa_type_escape_field_does_not_clobber_p (var_type, 
! 							    TREE_TYPE (ptr)))
  		{
  		  alias_stats.structnoaddress_resolved++;
  		  alias_stats.alias_noalias++;
  		  return false;
  		}
  	    }
+ 	  else if (ptr_star_count == 0)
+ 	    {
+ 	      /* If PTR_TYPE was not really a pointer to type, it cannot 
+ 		 alias.  */ 
+ 	      alias_stats.structnoaddress_queries++;
+ 	      alias_stats.structnoaddress_resolved++;
+ 	      alias_stats.alias_noalias++;
+ 	      return false;
+ 	    }
  	}
      }
  
*************** is_escape_site (tree stmt)
*** 3026,3037 ****
  	     pointer escapes since we can't track the integer.  */
  	  if (POINTER_TYPE_P (from) && !POINTER_TYPE_P (to))
  	    return ESCAPE_BAD_CAST;
- 
- 	  /* Same if the RHS is a conversion between a regular pointer and a
- 	     ref-all pointer since we can't track the SMT of the former.  */
- 	  if (POINTER_TYPE_P (from) && !TYPE_REF_CAN_ALIAS_ALL (from)
- 	      && POINTER_TYPE_P (to) && TYPE_REF_CAN_ALIAS_ALL (to))
- 	    return ESCAPE_BAD_CAST;
  	}
  
        /* If the LHS is an SSA name, it can't possibly represent a non-local
--- 2966,2971 ----
*************** get_smt_for (tree ptr, struct alias_info
*** 3137,3150 ****
    tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
    alias_set_type tag_set = get_alias_set (tag_type);
  
-   /* We use a unique memory tag for all the ref-all pointers.  */
-   if (PTR_IS_REF_ALL (ptr))
-     {
-       if (!ai->ref_all_symbol_mem_tag)
- 	ai->ref_all_symbol_mem_tag = create_memory_tag (void_type_node, true);
-       return ai->ref_all_symbol_mem_tag;
-     }
- 
    /* To avoid creating unnecessary memory tags, only create one memory tag
       per alias set class.  Note that it may be tempting to group
       memory tags based on conflicting alias sets instead of
--- 3071,3076 ----
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2008-04-29 14:05:43.000000000 +0200
--- gcc/tree-ssa-structalias.c	2008-04-29 16:27:01.000000000 +0200
*************** find_what_p_points_to (tree p)
*** 4969,4985 ****
  
  	  /* Instead of using pt_anything, we merge in the SMT aliases
  	     for the underlying SMT.  In addition, if they could have
! 	     pointed to anything, they could point to global memory.
! 	     But we cannot do that for ref-all pointers because these
! 	     aliases have not been computed yet.  */
  	  if (was_pt_anything)
  	    {
- 	      if (PTR_IS_REF_ALL (p))
- 		{
- 		  pi->pt_anything = 1;
- 		  return false;
- 		}
- 
  	      merge_smts_into (p, finished_solution);
  	      pi->pt_global_mem = 1;
  	    }
--- 4969,4977 ----
  
  	  /* Instead of using pt_anything, we merge in the SMT aliases
  	     for the underlying SMT.  In addition, if they could have
! 	     pointed to anything, they could point to global memory.  */
  	  if (was_pt_anything)
  	    {
  	      merge_smts_into (p, finished_solution);
  	      pi->pt_global_mem = 1;
  	    }
Index: gcc/tree-ssa-structalias.h
===================================================================
*** gcc/tree-ssa-structalias.h.orig	2008-04-29 14:05:43.000000000 +0200
--- gcc/tree-ssa-structalias.h	2008-04-29 16:27:47.000000000 +0200
***************
*** 21,29 ****
  #ifndef TREE_SSA_STRUCTALIAS_H
  #define TREE_SSA_STRUCTALIAS_H
  
- /* True if the data pointed to by PTR can alias anything.  */
- #define PTR_IS_REF_ALL(PTR) TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (PTR))
- 
  struct constraint;
  typedef struct constraint *constraint_t;
  
--- 21,26 ----
*************** struct alias_info
*** 57,65 ****
  
    /* Pointers that have been used in an indirect load operation.  */
    struct pointer_set_t *dereferenced_ptrs_load;
- 
-   /* Memory tag for all the PTR_IS_REF_ALL pointers.  */
-   tree ref_all_symbol_mem_tag;
  };
  
  /* In tree-ssa-alias.c.  */
--- 54,59 ----



More information about the Gcc-patches mailing list