[PATCH][alias-improvements] Use PTA information in the oracle

Richard Guenther rguenther@suse.de
Thu Jan 1 18:17:00 GMT 2009


This patch starts to use (a bit of) PTA information from the alias oracle
to disambiguate memory references.  It also seperates the points-to
solution and its computation so I can later use this to compute and store
the solutions for the escaped and callused sets properly.  On the way
it cleans up the dump files from the alias analysis.

Bootstrapped and tested on x86-64_unknown-linux-gnu, we now

XPASS: gcc.dg/tree-ssa/sra-3.c scan-tree-dump-times optimized "link_error" 0

as the only change.

Committed to the branch.

Richard.

2009-01-01  Richard Guenther  <rguenther@suse.de>

	* tree-dfa.c (dump_referenced_vars): Tidy.
	(get_ref_base_and_extent): Allow bare decls.
	(refs_may_alias_p): Unconditionally initialize size/max_size.
	Handle register/constant bases.  Handle mixed the pointer/decl
	case with both offset and PTA disambiguation.
	* tree-flow.h (struct ptr_info_def): Remove pt_global_mem, factor
	the points-to solution part into a pt_solution sub-structure.
	Add nonlocal, escaped and vars_contains_global flags.
	(dump_points_to_info): Remove.
	(debug_points_to_info): Likewise.
	(find_what_p_points_to): Likewise.
	* tree-into-ssa.c (dump_decl_set): Do not print a newline.
	(debug_decl_set): Do it here.
	(dump_update_ssa): And here.
	* tree-ssa-alias.c (compute_flow_sensitive_aliasing): Remove.
	(set_pt_anything): Likewise.
	(compute_may_aliases): Do not call compute_flow_sensitive_aliasing,
	dump_points_to_info.
	(reset_alias_info): Cleanup, initialize a correct points-to solution.
	(may_point_to_global_var): Adjust.
	(may_point_to_decl): New function.
	(dump_alias_info): Clean.
	(get_ptr_info): Initialize a correct points-to solution.
	(dump_points_to_info_for): Adjust.
	(dump_points_to_info): Remove.
	(debug_points_to_info): Likewise.
	* tree-ssanames.c (duplicate_ssa_name_ptr_info): No need to copy
	the shared bitmaps.
	* tree-ssa-alias.h (may_point_to_decl): Declare.
	* tree-ssa-structalias.c (set_uids_in_ptset): Take a points-to
	solution struct.
	(find_what_var_points_to): Split out generic parts from ...
	(find_what_p_points_to): ... here.
	(compute_points_to_sets): Do what compute_flow_sensitive_aliasing
	did as well.

Index: alias-improvements/gcc/tree-dfa.c
===================================================================
*** alias-improvements.orig/gcc/tree-dfa.c	2008-12-31 15:08:57.000000000 +0100
--- alias-improvements/gcc/tree-dfa.c	2009-01-01 16:55:35.000000000 +0100
*************** dump_referenced_vars (FILE *file)
*** 254,261 ****
      {
        fprintf (file, "Variable: ");
        dump_variable (file, var);
-       fprintf (file, "\n");
      }
  }
  
  
--- 254,262 ----
      {
        fprintf (file, "Variable: ");
        dump_variable (file, var);
      }
+ 
+   fprintf (file, "\n");
  }
  
  
*************** get_ref_base_and_extent (tree exp, HOST_
*** 763,770 ****
    HOST_WIDE_INT bit_offset = 0;
    bool seen_variable_array_ref = false;
  
-   gcc_assert (!SSA_VAR_P (exp));
- 
    /* First get the final access size from just the outermost expression.  */
    if (TREE_CODE (exp) == COMPONENT_REF)
      size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
--- 764,769 ----
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 957,968 ****
      return false;
  
    /* Decompose the references into their base objects and the access.  */
!   base1 = ref1;
!   if (handled_component_p (ref1))
!     base1 = get_ref_base_and_extent (ref1, &offset1, &size1, &max_size1);
!   base2 = ref2;
!   if (handled_component_p (ref2))
!     base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &max_size2);
  
    /* If both references are based on different variables, they cannot alias.
       If both references are based on the same variable, they cannot alias if
--- 956,972 ----
      return false;
  
    /* Decompose the references into their base objects and the access.  */
!   base1 = get_ref_base_and_extent (ref1, &offset1, &size1, &max_size1);
!   base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &max_size2);
! 
!   /* We can end up with registers or constants as bases for example from
!      *D.1663_44 = VIEW_CONVERT_EXPR<struct DB_LSN>(__tmp$B0F64_59);
!      which is seen as a struct copy.  */
!   if (TREE_CODE (base1) == SSA_NAME
!       || CONSTANT_CLASS_P (base1)
!       || TREE_CODE (base2) == SSA_NAME
!       || CONSTANT_CLASS_P (base2))
!     return false;
  
    /* If both references are based on different variables, they cannot alias.
       If both references are based on the same variable, they cannot alias if
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 975,991 ****
        return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
      }
  
!   /* If one reference is based on a pointer and one is based on a local
!      variable that does not have its address taken, they cannot alias.  */
!   if ((SSA_VAR_P (base1)
!        && !TREE_ADDRESSABLE (base1)
!        && !is_global_var (base1)
!        && INDIRECT_REF_P (base2))
!       || (SSA_VAR_P (base2)
! 	  && !TREE_ADDRESSABLE (base2)
! 	  && !is_global_var (base2)
! 	  && INDIRECT_REF_P (base1)))
!     return false;
  
    /* If one base is a ref-all pointer or a TARGET_MEM_REF weird things
       are allowed.  */
--- 979,1007 ----
        return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
      }
  
!   /* If only one reference is based on a variable, they cannot alias if
!      the pointer access is beyond the extent of the variable access.
!      (the pointer base cannot validly point to an offset less than zero
!      of the variable).
!      They also cannot alias if the pointer may not point to the decl.  */
!   if (SSA_VAR_P (base1)
!       && INDIRECT_REF_P (base2))
!     {
!       if (max_size1 != -1
! 	  && !ranges_overlap_p (0, offset1 + max_size1, offset2, max_size2))
! 	return false;
!       if (!may_point_to_decl (TREE_OPERAND (base2, 0), base1))
! 	return false;
!     }
!   else if (SSA_VAR_P (base2)
! 	   && INDIRECT_REF_P (base1))
!     {
!       if (max_size2 != -1
! 	  && !ranges_overlap_p (offset1, max_size1, 0, offset2 + max_size2))
! 	return false;
!       if (!may_point_to_decl (TREE_OPERAND (base1, 0), base2))
! 	return false;
!     }
  
    /* If one base is a ref-all pointer or a TARGET_MEM_REF weird things
       are allowed.  */
Index: alias-improvements/gcc/tree-flow.h
===================================================================
*** alias-improvements.orig/gcc/tree-flow.h	2008-12-31 15:08:57.000000000 +0100
--- alias-improvements/gcc/tree-flow.h	2008-12-31 15:43:15.000000000 +0100
*************** struct ptr_info_def GTY(())
*** 156,179 ****
    /* Mask of reasons this pointer's value escapes the function.  */
    ENUM_BITFIELD (escape_type) escape_mask : 9;
  
-   /* Nonzero if points-to analysis couldn't determine where this pointer
-      is pointing to.  */
-   unsigned int pt_anything : 1;
- 
    /* Nonzero if the value of this pointer escapes the current function.  */
    unsigned int value_escapes_p : 1;
  
    /* Nonzero if this pointer is really dereferenced.  */
    unsigned int is_dereferenced : 1;
  
!   /* Nonzero if this pointer points to a global variable.  */
!   unsigned int pt_global_mem : 1;
  
!   /* Nonzero if this pointer points to NULL.  */
!   unsigned int pt_null : 1;
  
!   /* Set of variables that this pointer may point to.  */
!   bitmap pt_vars;
  };
  
  
--- 156,195 ----
    /* Mask of reasons this pointer's value escapes the function.  */
    ENUM_BITFIELD (escape_type) escape_mask : 9;
  
    /* Nonzero if the value of this pointer escapes the current function.  */
    unsigned int value_escapes_p : 1;
  
    /* Nonzero if this pointer is really dereferenced.  */
    unsigned int is_dereferenced : 1;
  
!   /* The points-to solution.
! 
!      The points-to solution is a union of pt_vars and the abstract
!      sets specified by the flags.  */
!   struct pt_solution
!   {
!     /* Nonzero if points-to analysis couldn't determine where this pointer
!        is pointing to.  */
!     unsigned int anything : 1;
! 
!     /* Nonzero if the points-to set includes any global memory.  Note that
!        even if this is zero pt_vars can still include global variables.  */
!     unsigned int nonlocal : 1;
! 
!     /* Nonzero if the points-to set includes any escaped local variable.  */
!     unsigned int escaped : 1;
! 
!     /* Nonzero if the points-to set includes 'nothing', the points-to set
!        includes memory at address NULL.  */
!     unsigned int null : 1;
! 
  
!     /* Nonzero if the pt_vars bitmap includes a global variable.  */
!     unsigned int vars_contains_global : 1;
  
!     /* Set of variables that this pointer may point to.  */
!     bitmap vars;
!   } pt;
  };
  
  
*************** extern void dump_may_aliases_for (FILE *
*** 699,706 ****
  extern void debug_may_aliases_for (tree);
  extern void dump_alias_info (FILE *);
  extern void debug_alias_info (void);
- extern void dump_points_to_info (FILE *);
- extern void debug_points_to_info (void);
  extern void dump_points_to_info_for (FILE *, tree);
  extern void debug_points_to_info_for (tree);
  extern bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
--- 715,720 ----
*************** tree force_gimple_operand_gsi (gimple_st
*** 1024,1030 ****
  tree gimple_fold_indirect_ref (tree);
  
  /* In tree-ssa-structalias.c */
- bool find_what_p_points_to (tree);
  bool clobber_what_escaped (void);
  void compute_call_used_vars (void);
  
--- 1038,1043 ----
Index: alias-improvements/gcc/tree-into-ssa.c
===================================================================
*** alias-improvements.orig/gcc/tree-into-ssa.c	2008-12-31 15:08:57.000000000 +0100
--- alias-improvements/gcc/tree-into-ssa.c	2008-12-31 15:43:15.000000000 +0100
*************** dump_decl_set (FILE *file, bitmap set)
*** 1466,1475 ****
  	  fprintf (file, " ");
  	}
  
!       fprintf (file, "}\n");
      }
    else
!     fprintf (file, "NIL\n");
  }
  
  
--- 1466,1475 ----
  	  fprintf (file, " ");
  	}
  
!       fprintf (file, "}");
      }
    else
!     fprintf (file, "NIL");
  }
  
  
*************** void
*** 1479,1484 ****
--- 1479,1485 ----
  debug_decl_set (bitmap set)
  {
    dump_decl_set (stderr, set);
+   fprintf (stderr, "\n");
  }
  
  
*************** dump_update_ssa (FILE *file)
*** 2620,2625 ****
--- 2621,2627 ----
      {
        fprintf (file, "\n\nSymbols to be put in SSA form\n\n");
        dump_decl_set (file, syms_to_rename);
+       fprintf (file, "\n");
      }
    if (cfun->gimple_df->vop_needs_renaming)
      {
Index: alias-improvements/gcc/tree-ssa-alias.c
===================================================================
*** alias-improvements.orig/gcc/tree-ssa-alias.c	2008-12-31 15:43:14.000000000 +0100
--- alias-improvements/gcc/tree-ssa-alias.c	2009-01-01 16:55:34.000000000 +0100
*************** static struct alias_stats_d alias_stats;
*** 188,195 ****
  
  /* Local functions.  */
  static void dump_alias_stats (FILE *);
- static void compute_flow_sensitive_aliasing (void);
- static void set_pt_anything (tree);
  static void reset_alias_info (void);
  
  
--- 188,193 ----
*************** compute_may_aliases (void)
*** 376,385 ****
       (i.e., whether &V is stored in a global variable or if its passed as a
       function call argument).  */
    compute_points_to_sets ();
- 
-   /* Compute flow-sensitive, points-to based aliasing for all the name
-      memory tags.  */
-   compute_flow_sensitive_aliasing ();
    
    /* Compute call clobbering information.  */
    compute_call_clobbered ();
--- 374,379 ----
*************** compute_may_aliases (void)
*** 388,394 ****
    if (dump_file)
      {
        dump_alias_info (dump_file);
-       dump_points_to_info (dump_file);
  
        if (dump_flags & TDF_STATS)
  	dump_alias_stats (dump_file);
--- 382,387 ----
*************** reset_alias_info (void)
*** 537,587 ****
  	{
  	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
  
! 	  /* Clear all the flags but keep the name tag to
! 	     avoid creating new temporaries unnecessarily.  If
! 	     this pointer is found to point to a subset or
! 	     superset of its former points-to set, then a new
! 	     tag will need to be created in create_name_tags.  */
! 	  pi->pt_anything = 0;
! 	  pi->pt_null = 0;
  	  pi->value_escapes_p = 0;
  	  pi->is_dereferenced = 0;
! 	  if (pi->pt_vars)
! 	    bitmap_clear (pi->pt_vars);
  	}
      }
  }
  
  
- 
- /* For every pointer P_i in AI->PROCESSED_PTRS, create may-alias sets for
-    the name memory tag (NMT) associated with P_i.  If P_i escapes, then its
-    name tag and the variables it points-to are call-clobbered.  Finally, if
-    P_i escapes and we could not determine where it points to, then all the
-    variables in the same alias set as *P_i are marked call-clobbered.  This
-    is necessary because we must assume that P_i may take the address of any
-    variable in the same alias set.  */
- 
- static void
- compute_flow_sensitive_aliasing (void)
- {
-   unsigned i;
- 
-   timevar_push (TV_FLOW_SENSITIVE);
- 
-   for (i = 0; i < num_ssa_names; ++i)
-     {
-       tree ptr = ssa_name (i);
-       if (ptr
- 	  && POINTER_TYPE_P (TREE_TYPE (ptr)))
- 	if (!find_what_p_points_to (ptr))
- 	  set_pt_anything (ptr);
-     }
- 
-   timevar_pop (TV_FLOW_SENSITIVE);
- }
- 
- 
  /* Return TRUE if pointer PTR may point to variable VAR.
     
     MEM_ALIAS_SET is the alias set for the memory location pointed-to by PTR
--- 530,553 ----
  	{
  	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
  
! 	  /* Clear all the flags and reset the points-to solution.  */
  	  pi->value_escapes_p = 0;
  	  pi->is_dereferenced = 0;
! 	  pi->pt.anything = 1;
! 	  pi->pt.nonlocal = 0;
! 	  pi->pt.escaped = 0;
! 	  pi->pt.null = 0;
! 	  pi->pt.vars_contains_global = 0;
! 	  if (pi->pt.vars)
! 	    {
! 	      bitmap_clear (pi->pt.vars);
! 	      pi->pt.vars = NULL;
! 	    }
  	}
      }
  }
  
  
  /* Return TRUE if pointer PTR may point to variable VAR.
     
     MEM_ALIAS_SET is the alias set for the memory location pointed-to by PTR
*************** may_point_to_global_var (tree ptr)
*** 721,741 ****
    if (!pi)
      return true;
  
!   return pi->pt_global_mem;
  }
  
  
! /* Mark pointer PTR as pointing to an arbitrary memory location.  */
! 
! static void
! set_pt_anything (tree ptr)
  {
!   struct ptr_info_def *pi = get_ptr_info (ptr);
  
!   pi->pt_anything = 1;
!   /* Anything includes global memory.  */
!   pi->pt_global_mem = 1;
!   pi->pt_vars = NULL;
  }
  
  
--- 687,737 ----
    if (!pi)
      return true;
  
!   return pi->pt.anything || pi->pt.nonlocal || pi->pt.vars_contains_global;
  }
  
+ /* Return true if PTR may point to DECL.  */
  
! bool
! may_point_to_decl (tree ptr, tree decl)
  {
!   struct ptr_info_def *pi;
! 
!   /* ???  During SCCVN/PRE we can end up with *&x during valueizing
!      operands.  Likewise we can end up with dereferencing constant
!      pointers.  Just bail out in these cases for now.  */
!   if (TREE_CODE (ptr) == ADDR_EXPR
!       || TREE_CODE (ptr) == INTEGER_CST)
!     return true;
! 
!   gcc_assert (TREE_CODE (ptr) == SSA_NAME
! 	      && (TREE_CODE (decl) == VAR_DECL
! 		  || TREE_CODE (decl) == PARM_DECL
! 		  || TREE_CODE (decl) == RESULT_DECL));
! 
!   /* Local variables that do not have their address taken
!      can not be pointed to.  */
!   if (!TREE_ADDRESSABLE (decl)
!       && !is_global_var (decl))
!     return false;
  
!   /* If we do not have useful points-to information for this pointer
!      we cannot disambiguate anything else.  */
!   pi = SSA_NAME_PTR_INFO (ptr);
!   if (!pi
!       || pi->pt.anything)
!     return true;
! 
!   /* If the points-to set includes the variable we are done.  */
!   if (bitmap_bit_p (pi->pt.vars, DECL_UID (decl)))
!     return true;
! 
!   /* pt_nonlocal includes any global variable.  */
!   if (is_global_var (decl)
!       && pi->pt.nonlocal)
!     return true;
! 
!   return false;
  }
  
  
*************** dump_alias_info (FILE *file)
*** 877,883 ****
    referenced_var_iterator rvi;
    tree var;
  
!   fprintf (file, "\nAlias information for %s\n\n", funcname);
  
    fprintf (file, "Aliased symbols\n\n");
    
--- 873,879 ----
    referenced_var_iterator rvi;
    tree var;
  
!   fprintf (file, "\n\nAlias information for %s\n\n", funcname);
  
    fprintf (file, "Aliased symbols\n\n");
    
*************** dump_alias_info (FILE *file)
*** 887,897 ****
  	dump_variable (file, var);
      }
  
!   fprintf (file, "\nDereferenced pointers\n\n");
  
-   fprintf (file, "\n\nFlow-sensitive alias information for %s\n\n", funcname);
- 
-   fprintf (file, "SSA_NAME pointers\n\n");
    for (i = 1; i < num_ssa_names; i++)
      {
        tree ptr = ssa_name (i);
--- 883,890 ----
  	dump_variable (file, var);
      }
  
!   fprintf (file, "\n\nFlow-insensitive points-to information for %s\n\n", funcname);
  
    for (i = 1; i < num_ssa_names; i++)
      {
        tree ptr = ssa_name (i);
*************** get_ptr_info (tree t)
*** 933,938 ****
--- 926,932 ----
    if (pi == NULL)
      {
        pi = GGC_CNEW (struct ptr_info_def);
+       pi->pt.anything = 1;
        SSA_NAME_PTR_INFO (t) = pi;
      }
  
*************** dump_points_to_info_for (FILE *file, tre
*** 956,971 ****
        if (pi->value_escapes_p)
  	fprintf (file, ", its value escapes");
  
!       if (pi->pt_anything)
  	fprintf (file, ", points-to anything");
  
!       if (pi->pt_null)
  	fprintf (file, ", points-to NULL");
  
!       if (pi->pt_vars)
  	{
  	  fprintf (file, ", points-to vars: ");
! 	  dump_decl_set (file, pi->pt_vars);
  	}
      }
  
--- 950,973 ----
        if (pi->value_escapes_p)
  	fprintf (file, ", its value escapes");
  
!       if (pi->pt.anything)
  	fprintf (file, ", points-to anything");
  
!       if (pi->pt.nonlocal)
! 	fprintf (file, ", points-to non-local");
! 
!       if (pi->pt.escaped)
! 	fprintf (file, ", points-to escaped");
! 
!       if (pi->pt.null)
  	fprintf (file, ", points-to NULL");
  
!       if (pi->pt.vars)
  	{
  	  fprintf (file, ", points-to vars: ");
! 	  dump_decl_set (file, pi->pt.vars);
! 	  if (pi->pt.vars_contains_global)
! 	    fprintf (file, " (includes global vars)");
  	}
      }
  
*************** debug_points_to_info_for (tree var)
*** 982,1051 ****
  }
  
  
- /* Dump points-to information into FILE.  NOTE: This function is slow, as
-    it needs to traverse the whole CFG looking for pointer SSA_NAMEs.  */
- 
- void
- dump_points_to_info (FILE *file ATTRIBUTE_UNUSED)
- {
-   basic_block bb;
-   gimple_stmt_iterator si;
-   ssa_op_iter iter;
-   const char *fname =
-     lang_hooks.decl_printable_name (current_function_decl, 2);
-   referenced_var_iterator rvi;
-   tree var;
- 
-   fprintf (file, "\n\nPointed-to sets for pointers in %s\n\n", fname);
- 
-   /* First dump points-to information for the default definitions of
-      pointer variables.  This is necessary because default definitions are
-      not part of the code.  */
-   FOR_EACH_REFERENCED_VAR (var, rvi)
-     {
-       if (POINTER_TYPE_P (TREE_TYPE (var)))
- 	{
- 	  tree def = gimple_default_def (cfun, var);
- 	  if (def)
- 	    dump_points_to_info_for (file, def);
- 	}
-     }
- 
-   /* Dump points-to information for every pointer defined in the program.  */
-   FOR_EACH_BB (bb)
-     {
-       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
- 	{
- 	  gimple phi = gsi_stmt (si);
- 	  tree ptr = PHI_RESULT (phi);
- 	  if (POINTER_TYPE_P (TREE_TYPE (ptr)))
- 	    dump_points_to_info_for (file, ptr);
- 	}
- 
- 	for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
- 	  {
- 	    gimple stmt = gsi_stmt (si);
- 	    tree def;
- 	    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
- 	      if (TREE_CODE (def) == SSA_NAME
- 		  && POINTER_TYPE_P (TREE_TYPE (def)))
- 		dump_points_to_info_for (file, def);
- 	  }
-     }
- 
-   fprintf (file, "\n");
- }
- 
- 
- /* Dump points-to info pointed to by PTO into STDERR.  */
- 
- void
- debug_points_to_info (void)
- {
-   dump_points_to_info (stderr);
- }
- 
- 
  /* ???  Remove me.
     For now just a quick verification run on sane initial properties.  */
  
--- 984,989 ----
Index: alias-improvements/gcc/tree-ssanames.c
===================================================================
*** alias-improvements.orig/gcc/tree-ssanames.c	2008-12-31 15:08:57.000000000 +0100
--- alias-improvements/gcc/tree-ssanames.c	2008-12-31 15:43:15.000000000 +0100
*************** duplicate_ssa_name_ptr_info (tree name, 
*** 268,279 ****
    new_ptr_info = GGC_NEW (struct ptr_info_def);
    *new_ptr_info = *ptr_info;
  
-   if (ptr_info->pt_vars)
-     {
-       new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
-       bitmap_copy (new_ptr_info->pt_vars, ptr_info->pt_vars);
-     }
- 
    SSA_NAME_PTR_INFO (name) = new_ptr_info;
  }
  
--- 268,273 ----
Index: alias-improvements/gcc/tree-ssa-alias.h
===================================================================
*** alias-improvements.orig/gcc/tree-ssa-alias.h	2008-12-31 15:43:14.000000000 +0100
--- alias-improvements/gcc/tree-ssa-alias.h	2009-01-01 16:55:34.000000000 +0100
***************
*** 24,29 ****
--- 24,30 ----
  #include "coretypes.h"
  
  /* In tree-ssa-alias.c  */
+ bool may_point_to_decl (tree, tree);
  void *walk_non_aliased_vuses (tree, tree,
  			      void *(*)(tree, tree, void *), void *);
  gimple get_vop_def_for_ref (tree, tree);
Index: alias-improvements/gcc/tree-ssa-structalias.c
===================================================================
*** alias-improvements.orig/gcc/tree-ssa-structalias.c	2008-12-31 15:08:57.000000000 +0100
--- alias-improvements/gcc/tree-ssa-structalias.c	2009-01-01 16:57:14.000000000 +0100
*************** shared_bitmap_add (bitmap pt_vars)
*** 4646,4653 ****
  
  static unsigned
  set_uids_in_ptset (tree ptr, bitmap into, bitmap from,
! 		   struct ptr_info_def *pi,
! 		   bool no_tbaa_pruning)
  {
    unsigned int i;
    bitmap_iterator bi;
--- 4646,4652 ----
  
  static unsigned
  set_uids_in_ptset (tree ptr, bitmap into, bitmap from,
! 		   struct pt_solution *pt, bool do_tbaa_pruning)
  {
    unsigned int i;
    bitmap_iterator bi;
*************** set_uids_in_ptset (tree ptr, bitmap into
*** 4672,4679 ****
  	     for pointers that have not been dereferenced or with
  	     type-based pruning disabled.  */
  	  if (!vi->is_artificial_var
! 	      && pi->is_dereferenced
! 	      && !no_tbaa_pruning)
  	    {
  	      alias_set_type var_alias_set, mem_alias_set;
  	      var_alias_set = get_alias_set (vi->decl);
--- 4671,4677 ----
  	     for pointers that have not been dereferenced or with
  	     type-based pruning disabled.  */
  	  if (!vi->is_artificial_var
! 	      && do_tbaa_pruning)
  	    {
  	      alias_set_type var_alias_set, mem_alias_set;
  	      var_alias_set = get_alias_set (vi->decl);
*************** set_uids_in_ptset (tree ptr, bitmap into
*** 4690,4696 ****
  	     set contains global variables.  */
  	  bitmap_set_bit (into, DECL_UID (vi->decl));
  	  if (is_global_var (vi->decl))
! 	    pi->pt_global_mem = true;
  	}
      }
  
--- 4688,4694 ----
  	     set contains global variables.  */
  	  bitmap_set_bit (into, DECL_UID (vi->decl));
  	  if (is_global_var (vi->decl))
! 	    pt->vars_contains_global = true;
  	}
      }
  
*************** emit_alias_warning (tree ptr)
*** 4786,4791 ****
--- 4784,4864 ----
      }
  }
  
+ /* Compute the points-to solution *PT for the variable VI.
+    Prunes the points-to set based on TBAA rules if DO_TBAA_PRUNING
+    is true.  Returns the number of TBAA pruned variables from the
+    points-to set.  */
+ 
+ static unsigned int
+ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt,
+ 			 bool do_tbaa_pruning)
+ {
+   unsigned int i, pruned;
+   bitmap_iterator bi;
+   bitmap finished_solution;
+   bitmap result;
+   tree ptr = vi->decl;
+ 
+   memset (pt, 0, sizeof (struct pt_solution));
+ 
+   /* This variable may have been collapsed, let's get the real
+      variable.  */
+   vi = get_varinfo (find (vi->id));
+ 
+   /* Translate artificial variables into SSA_NAME_PTR_INFO
+      attributes.  */
+   EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
+     {
+       varinfo_t vi = get_varinfo (i);
+ 
+       if (vi->is_artificial_var)
+ 	{
+ 	  if (vi->id == nothing_id)
+ 	    pt->null = 1;
+ 	  else if (vi->id == escaped_id)
+ 	    {
+ 	      pt->escaped = 1;
+ 	      /* ???  We need to compute the escaped solution and store
+ 	         it somewhere.  */
+ 	      pt->anything = 1;
+ 	    }
+ 	  else if (vi->id == nonlocal_id
+ 		   || vi->is_heap_var)
+ 	    pt->nonlocal = 1;
+ 	  else if (vi->id == anything_id
+ 		   || vi->id == callused_id
+ 		   || vi->id == readonly_id
+ 		   || vi->id == integer_id)
+ 	    pt->anything = 1;
+ 	}
+     }
+ 
+   /* Instead of doing extra work, simply do not create
+      elaborate points-to information for pt_anything pointers.  */
+   if (pt->anything)
+     return 0;
+ 
+   /* Share the final set of variables when possible.  */
+   finished_solution = BITMAP_GGC_ALLOC ();
+   stats.points_to_sets_created++;
+ 
+   pruned = set_uids_in_ptset (ptr, finished_solution, vi->solution,
+ 			      pt, do_tbaa_pruning && !vi->no_tbaa_pruning);
+   result = shared_bitmap_lookup (finished_solution);
+   if (!result)
+     {
+       shared_bitmap_add (finished_solution);
+       pt->vars = finished_solution;
+     }
+   else
+     {
+       pt->vars = result;
+       bitmap_clear (finished_solution);
+     }
+ 
+   return pruned;
+ }
+ 
  /* Given a pointer variable P, fill in its points-to set, or return
     false if we can't.
     Rather than return false for variables that point-to anything, we
*************** emit_alias_warning (tree ptr)
*** 4797,4811 ****
     SMT's in the points-to set of the variable, we'd end up with
     statements that do not conflict but should.  */
  
! bool
  find_what_p_points_to (tree p)
  {
    tree lookup_p = p;
    varinfo_t vi;
  
-   if (!have_alias_info)
-     return false;
- 
    /* For parameters, get at the points-to set for the actual parm
       decl.  */
    if (TREE_CODE (p) == SSA_NAME
--- 4870,4883 ----
     SMT's in the points-to set of the variable, we'd end up with
     statements that do not conflict but should.  */
  
! static void
  find_what_p_points_to (tree p)
  {
+   struct ptr_info_def *pi;
+   unsigned int pruned;
    tree lookup_p = p;
    varinfo_t vi;
  
    /* For parameters, get at the points-to set for the actual parm
       decl.  */
    if (TREE_CODE (p) == SSA_NAME
*************** find_what_p_points_to (tree p)
*** 4814,4923 ****
      lookup_p = SSA_NAME_VAR (p);
  
    vi = lookup_vi_for_tree (lookup_p);
!   if (vi)
!     {
!       if (vi->is_artificial_var)
! 	return false;
! 
!       /* See if this is a field or a structure.  */
!       if (vi->size != vi->fullsize)
! 	{
! 	  /* Nothing currently asks about structure fields directly,
! 	     but when they do, we need code here to hand back the
! 	     points-to set.  */
! 	  return false;
! 	}
!       else
! 	{
! 	  struct ptr_info_def *pi = get_ptr_info (p);
! 	  unsigned int i, pruned;
! 	  bitmap_iterator bi;
! 	  bool was_pt_anything = false;
! 	  bitmap finished_solution;
! 	  bitmap result;
! 
! 	  /* This variable may have been collapsed, let's get the real
! 	     variable.  */
! 	  vi = get_varinfo (find (vi->id));
! 
! 	  /* Translate artificial variables into SSA_NAME_PTR_INFO
! 	     attributes.  */
! 	  EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
! 	    {
! 	      varinfo_t vi = get_varinfo (i);
! 
! 	      if (vi->is_artificial_var)
! 		{
! 		  /* FIXME.  READONLY should be handled better so that
! 		     flow insensitive aliasing can disregard writable
! 		     aliases.  */
! 		  if (vi->id == nothing_id)
! 		    pi->pt_null = 1;
! 		  else if (vi->id == anything_id
! 			   || vi->id == nonlocal_id
! 			   || vi->id == escaped_id
! 			   || vi->id == callused_id)
! 		    was_pt_anything = 1;
! 		  else if (vi->id == readonly_id)
! 		    was_pt_anything = 1;
! 		  else if (vi->id == integer_id)
! 		    was_pt_anything = 1;
! 		  else if (vi->is_heap_var)
! 		    pi->pt_global_mem = 1;
! 		}
! 	    }
! 
! 	  /* Instead of doing extra work, simply do not create
! 	     points-to information for pt_anything pointers.  This
! 	     will cause the operand scanner to fall back to the
! 	     type-based SMT and its aliases.  Which is the best
! 	     we could do here for the points-to set as well.  */
! 	  if (was_pt_anything)
! 	    return false;
! 
! 	  /* Share the final set of variables when possible.  */
! 	  finished_solution = BITMAP_GGC_ALLOC ();
! 	  stats.points_to_sets_created++;
! 
! 	  pruned = set_uids_in_ptset (p, finished_solution, vi->solution,
! 				      pi,
! 				      vi->no_tbaa_pruning);
! 	  result = shared_bitmap_lookup (finished_solution);
! 
! 	  if (!result)
! 	    {
! 	      shared_bitmap_add (finished_solution);
! 	      pi->pt_vars = finished_solution;
! 	    }
! 	  else
! 	    {
! 	      pi->pt_vars = result;
! 	      bitmap_clear (finished_solution);
! 	    }
  
! 	  if (bitmap_empty_p (pi->pt_vars))
! 	    {
! 	      pi->pt_vars = NULL;
! 	      if (pruned > 0
! 		  && pi->is_dereferenced
! 		  && warn_strict_aliasing > 0
! 		  && !SSA_NAME_IS_DEFAULT_DEF (p))
! 		{
! 		  if (dump_file && dump_flags & TDF_DETAILS)
! 		    {
! 		      fprintf (dump_file, "alias warning for ");
! 		      print_generic_expr (dump_file, p, 0);
! 		      fprintf (dump_file, "\n");
! 		    }
! 		  emit_alias_warning (p);
! 		}
! 	    }
  
! 	  return true;
  	}
      }
- 
-   return false;
  }
  
  /* Mark the ESCAPED solution as call clobbered.  Returns false if
--- 4886,4912 ----
      lookup_p = SSA_NAME_VAR (p);
  
    vi = lookup_vi_for_tree (lookup_p);
!   if (!vi)
!     return;
  
!   pi = get_ptr_info (p);
!   pruned = find_what_var_points_to (vi, &pi->pt, pi->is_dereferenced);
  
!   if (!(pi->pt.anything || pi->pt.nonlocal || pi->pt.escaped)
!       && bitmap_empty_p (pi->pt.vars)
!       && pruned > 0
!       && pi->is_dereferenced
!       && warn_strict_aliasing > 0
!       && !SSA_NAME_IS_DEFAULT_DEF (p))
!     {
!       if (dump_file && dump_flags & TDF_DETAILS)
! 	{
! 	  fprintf (dump_file, "alias warning for ");
! 	  print_generic_expr (dump_file, p, 0);
! 	  fprintf (dump_file, "\n");
  	}
+       emit_alias_warning (p);
      }
  }
  
  /* Mark the ESCAPED solution as call clobbered.  Returns false if
*************** compute_points_to_sets (void)
*** 5448,5453 ****
--- 5437,5443 ----
  {
    struct scc_info *si;
    basic_block bb;
+   unsigned i;
  
    timevar_push (TV_TREE_PTA);
  
*************** compute_points_to_sets (void)
*** 5565,5573 ****
    if (dump_file)
      dump_sa_points_to_info (dump_file);
  
!   have_alias_info = true;
  
    timevar_pop (TV_TREE_PTA);
  }
  
  
--- 5555,5571 ----
    if (dump_file)
      dump_sa_points_to_info (dump_file);
  
!   for (i = 0; i < num_ssa_names; ++i)
!     {
!       tree ptr = ssa_name (i);
!       if (ptr
! 	  && POINTER_TYPE_P (TREE_TYPE (ptr)))
! 	find_what_p_points_to (ptr);
!     }
  
    timevar_pop (TV_TREE_PTA);
+ 
+   have_alias_info = true;
  }
  
  



More information about the Gcc-patches mailing list