[tree-ssa-branch]: PATCH to add intraprocedural call handling to points-to analysis

Daniel Berlin dberlin@dberlin.org
Tue Aug 20 19:10:00 GMT 2002


Committed.

I'll finish adding restrict support next.

(I know the comments aren't quite correct, pretend the words "while 
both are within scope" are there, since in that context, it's only looking at things that are 
within scope).


--Dan

2002-08-20  Daniel Berlin  <dberlin@dberlin.org>

	* tree-alias-steen.h (struct tree_alias_ops): Add flag for interprocedural.

	* tree-alias-steen.c (steen_alias_ops): Set interprocedural to 0
	for now.
	(intra_function_call): New function to handle intraprocedural calling.
	(finc_func_aliases): Use it.
	Handle *x = *y, *x = &y, and *x = (cast) y.
	(display_points_to_set_helper): New function, split from ...
	(display_points_to_set): Here.
	(create_alias_vars): Try to print all alias vars we find in the
	alias_vars array, rather than just those that are linked directly to
	trees.
	Clear arrays when we finish if we aren't interprocedural.

Index: tree-alias-steen.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-steen.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -w -B -b -r1.1.2.4 tree-alias-steen.c
*** tree-alias-steen.c	24 Jul 2002 14:05:44 -0000	1.1.2.4
--- tree-alias-steen.c	21 Aug 2002 02:09:22 -0000
*************** Foundation, Inc., 59 Temple Place, Suite
*** 69,75 ****
  */
  
  /* Todo list:
-    * Intraprocedural call handling.
     * Create SSA may/must def variables.
     * Reduce memory usage (mainly due to fragmentation, not leakage).
     * Don't pass alias ops as first argument, just have a global 
--- 69,74 ----
*************** static tree find_func_decls PARAMS ((tre
*** 112,117 ****
--- 113,119 ----
  static alias_typevar create_fun_alias_var_ptf PARAMS ((tree, tree));
  static alias_typevar create_fun_alias_var PARAMS ((tree, int));
  static alias_typevar create_alias_var PARAMS ((tree));
+ static void intra_function_call PARAMS ((varray_type));
  
  static struct tree_alias_ops steen_ops = {
    steen_init,
*************** static struct tree_alias_ops steen_ops =
*** 126,132 ****
    steen_assign_ptr,
    steen_function_def,
    steen_function_call,
!   0
  };
  struct tree_alias_ops *steen_alias_ops = &steen_ops;
  
--- 128,135 ----
    steen_assign_ptr,
    steen_function_def,
    steen_function_call,
!   0, /* data */
!   0 /* Currently non-interprocedural */
  };
  struct tree_alias_ops *steen_alias_ops = &steen_ops;
  
*************** get_alias_var (expr)
*** 748,753 ****
--- 751,804 ----
        }
      }
  }
+ static void
+ intra_function_call (args)
+      varray_type args;
+ {
+   size_t l = VARRAY_ACTIVE_SIZE (args);
+   size_t i;
+   tree globvar = getdecls();
+ 
+   /* We assume that an actual parameter can point to any global. */
+   while (globvar)
+     {
+       if (TREE_CODE (globvar) == VAR_DECL)
+ 	{
+ 	  alias_typevar av = get_alias_var (globvar);
+ 	  for (i = 0; i < l; i++)
+ 	    {
+ 	      alias_typevar argav = VARRAY_GENERIC_PTR (args, i);
+ 	      
+ 	      /* Restricted pointers can't be aliased with other
+ 		 restricted pointers. */	      
+ 	      if (!TYPE_RESTRICT (TREE_TYPE (argav->decl)) 
+ 		  || !TYPE_RESTRICT (TREE_TYPE (av->decl)))
+ 		steen_alias_ops->addr_assign (steen_alias_ops, argav, av);
+ 	    }
+ 	}
+       globvar = TREE_CHAIN (globvar);
+     }
+ 
+   /* We assume assignments among the actual parameters. */
+   for (i = 0; i < l; i++) 
+     {
+       alias_typevar argi = VARRAY_GENERIC_PTR (args, i);
+       size_t j;
+       for (j = 0; j < l; j++)
+ 	{
+ 	  alias_typevar argj;
+ 	  if (i == j)
+ 	    continue;
+ 	  argj = VARRAY_GENERIC_PTR (args, j);
+ 
+ 	  /* Restricted pointers can't be aliased with other
+ 	     restricted pointers. */
+ 	  if (!TYPE_RESTRICT (TREE_TYPE (argi->decl)) 
+ 	      || !TYPE_RESTRICT (TREE_TYPE (argj->decl)))
+ 	    steen_alias_ops->simple_assign (steen_alias_ops, argi, argj);
+ 	}
+     }
+ }
  static tree
  find_func_aliases (tp, walk_subtrees, data)
       tree *tp;
*************** find_func_aliases (tp, walk_subtrees, da
*** 768,776 ****
  
        *walk_subtrees = 0;
        op0 = TREE_OPERAND (*tp, 0);
-       STRIP_NOPS (op0);
        op1 = TREE_OPERAND (*tp, 1);
-       STRIP_NOPS (op1);
  
        /* lhsAV should always have an alias variable */
        lhsAV = get_alias_var (op0);
--- 819,825 ----
*************** find_func_aliases (tp, walk_subtrees, da
*** 840,852 ****
  		  steen_alias_ops->function_call (steen_alias_ops, lhsAV, 
  						  get_alias_var (callop0),
  						  args);
! 		  /* FIXME: If this is the non-interprocedural
! 		     version, or we don't have the alias info for the
! 		     called function, we need to handle it.
! 		     In particular, the actual arguments can alias
! 		     each other, and could take the address of any
! 		     global. */
! 
  		}
  
  	    }
--- 889,896 ----
  		  steen_alias_ops->function_call (steen_alias_ops, lhsAV, 
  						  get_alias_var (callop0),
  						  args);		  
! 		  if (!steen_alias_ops->ip)
! 		    intra_function_call (args);
  		}
  
  	    }
*************** find_func_aliases (tp, walk_subtrees, da
*** 901,906 ****
--- 945,989 ----
  		steen_alias_ops->assign_ptr (steen_alias_ops, lhsAV, 
  					     rhsAV);
  	    }
+ 	  /* *x = &y */
+ 	  else if (TREE_CODE (op0) == INDIRECT_REF
+ 		   && TREE_CODE (op1) == ADDR_EXPR)
+ 	    {
+ 	      /* This becomes temp = &y and *x = temp . */
+ 	      alias_typevar tempvar = steen_alias_ops->add_var (steen_alias_ops,
+ 								create_tmp_alias_var
+ 								(void_type_node,
+ 								 "aliastmp"));   
+ 	      steen_alias_ops->addr_assign (steen_alias_ops, tempvar, rhsAV);
+ 	      steen_alias_ops->assign_ptr (steen_alias_ops, lhsAV, tempvar);
+ 	    }
+ 	  
+ 	  /* *x = *y */
+ 	  else if (TREE_CODE (op0) == INDIRECT_REF
+ 		   && TREE_CODE (op1) == INDIRECT_REF)
+ 	    {
+ 	      /* This becomes temp = *y and *x = temp . */
+ 	      alias_typevar tempvar = steen_alias_ops->add_var (steen_alias_ops,
+ 								create_tmp_alias_var
+ 								(void_type_node,
+ 								 "aliastmp"));   
+ 	      steen_alias_ops->ptr_assign (steen_alias_ops, tempvar, rhsAV);
+ 	      steen_alias_ops->assign_ptr (steen_alias_ops, lhsAV, tempvar);
+ 	    }
+ 	  
+ 	  /* *x = (cast) y */
+ 	  else if (TREE_CODE (op0) == INDIRECT_REF
+ 		   && is_simple_cast (op1))
+ 	    {
+ 	      /* This becomes temp = (cast) y and  *x = temp. */
+ 	      alias_typevar tempvar = steen_alias_ops->add_var (steen_alias_ops,
+ 								create_tmp_alias_var
+ 								(void_type_node,
+ 								 "aliastmp"));
+ 	      
+ 	      steen_alias_ops->simple_assign (steen_alias_ops, tempvar, rhsAV);
+ 	      steen_alias_ops->assign_ptr (steen_alias_ops, lhsAV, tempvar);
+ 	    }
  	  /* *x = <something else */
  	  else
  	    {
*************** find_func_aliases (tp, walk_subtrees, da
*** 926,933 ****
        steen_alias_ops->function_call (steen_alias_ops, NULL, 
  				      get_alias_var (TREE_OPERAND (*tp, 0)),
  				      args);
!       /* FIXME: Same caveats as above for calls to functions we have no
! 	alias variables for. */
  
      }
        
--- 1009,1017 ----
        steen_alias_ops->function_call (steen_alias_ops, NULL, 
  				      get_alias_var (TREE_OPERAND (*tp, 0)),
  				      args);
!       if (!steen_alias_ops->ip)
! 	intra_function_call (args);
! 
  
      }
        
*************** find_func_decls (tp, walk_subtrees, data
*** 962,967 ****
--- 1046,1055 ----
     2. The arguments.
     3. The locals.
     4. The return value.
+    
+    DECL is the function declaration.
+    FORCE determines whether we force creation of the alias variable,
+    regardless of whether one exists or not. 
  */
  static alias_typevar
  create_fun_alias_var (decl, force)
*************** create_alias_var (decl)
*** 1127,1148 ****
  static unsigned int splaycount = 0;
  static int splay_tree_count PARAMS ((splay_tree_node, void *));
  static int display_points_to_set PARAMS ((splay_tree_node, void *));
  unsigned int splay_tree_size PARAMS ((splay_tree));
! 
! /* Display the points to set for the given alias_typevar (in the
!    splay tree node.) */
! static int
! display_points_to_set (node, data)
!      splay_tree_node node;
!      void *data ATTRIBUTE_UNUSED;
  {
-   varray_type tmp;
    size_t i;
!   
!   tmp = alias_tvar_pointsto ((alias_typevar) node->value);
    if (VARRAY_ACTIVE_SIZE (tmp) <= 0)
!     return 0;
!   print_c_node (stderr, (tree) node->key);
    fprintf (stderr, " => { ");
    for (i = 0; i < VARRAY_ACTIVE_SIZE (tmp); i++)
      {
--- 1215,1232 ----
  static unsigned int splaycount = 0;
  static int splay_tree_count PARAMS ((splay_tree_node, void *));
  static int display_points_to_set PARAMS ((splay_tree_node, void *));
+ static void display_points_to_set_helper PARAMS ((alias_typevar));
  unsigned int splay_tree_size PARAMS ((splay_tree));
! static void
! display_points_to_set_helper (tvar)
! 	alias_typevar tvar;
  {
    size_t i;
!   varray_type tmp;
!   tmp = alias_tvar_pointsto (tvar);
    if (VARRAY_ACTIVE_SIZE (tmp) <= 0)
!     return;
!   print_c_node (stderr, tvar->decl);
    fprintf (stderr, " => { ");
    for (i = 0; i < VARRAY_ACTIVE_SIZE (tmp); i++)
      {
*************** display_points_to_set (node, data)
*** 1151,1156 ****
--- 1235,1249 ----
        fprintf (stderr, ", ");
      }
    fprintf (stderr, " }\n");
+ }
+ static int
+ display_points_to_set (node, data)
+      splay_tree_node node;
+      void *data ATTRIBUTE_UNUSED;
+ {
+ /* Display the points to set for the given alias_typevar (in the
+    splay tree node.) */
+   display_points_to_set_helper ((alias_typevar)node->value); 
    return 0;
  }
  
*************** create_alias_vars ()
*** 1192,1202 ****
        find_func_decls, NULL);*/
    walk_tree_without_duplicates (&DECL_SAVED_TREE (current_function_decl),
  				find_func_aliases, NULL);
!   splay_tree_foreach (alias_annot, display_points_to_set, NULL);
    for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_vars); i++)
       splay_tree_remove (alias_annot, (splay_tree_key) VARRAY_GENERIC_PTR (local_alias_vars, i));
    for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_varnums); i ++)
      VARRAY_GENERIC_PTR (alias_vars, VARRAY_INT (local_alias_varnums, i)) = NULL;
  }
  void
  init_alias_vars ()
--- 1285,1305 ----
        find_func_decls, NULL);*/
    walk_tree_without_duplicates (&DECL_SAVED_TREE (current_function_decl),
  				find_func_aliases, NULL);
!   fprintf (stderr, "\nPoints to sets for function %s:\n",
! 	   IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
!   for (i = 0; i < VARRAY_ACTIVE_SIZE (alias_vars); i++)
!      display_points_to_set_helper (VARRAY_GENERIC_PTR (alias_vars, i));
    for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_vars); i++)
       splay_tree_remove (alias_annot, (splay_tree_key) VARRAY_GENERIC_PTR (local_alias_vars, i));
    for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_varnums); i ++)
      VARRAY_GENERIC_PTR (alias_vars, VARRAY_INT (local_alias_varnums, i)) = NULL;
+   if (!steen_alias_ops->ip)
+     {
+       splay_tree_delete (alias_annot);
+       VARRAY_CLEAR (alias_vars);
+       VARRAY_CLEAR (local_alias_vars);
+       VARRAY_CLEAR (local_alias_varnums);
+     }
  }
  void
  init_alias_vars ()
*************** init_alias_vars ()
*** 1204,1212 ****
    init_alias_type ();
    VARRAY_GENERIC_PTR_INIT (local_alias_vars, 10, "Local alias vars");
    VARRAY_INT_INIT (local_alias_varnums, 10, "Local alias varnums");
!   if (alias_vars == NULL)
      VARRAY_GENERIC_PTR_INIT (alias_vars, 10, "Alias vars");
!   if (alias_annot == NULL)
      alias_annot = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
  }
  #include "gt-tree-alias-steen.h"
--- 1307,1315 ----
    init_alias_type ();
    VARRAY_GENERIC_PTR_INIT (local_alias_vars, 10, "Local alias vars");
    VARRAY_INT_INIT (local_alias_varnums, 10, "Local alias varnums");
!   if (!steen_alias_ops->ip || alias_vars == NULL)
      VARRAY_GENERIC_PTR_INIT (alias_vars, 10, "Alias vars");
!   if (!steen_alias_ops->ip || alias_annot == NULL)
      alias_annot = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
  }
  #include "gt-tree-alias-steen.h"
Index: tree-alias-steen.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-steen.h,v
retrieving revision 1.1.2.1
diff -c -3 -p -w -B -b -r1.1.2.1 tree-alias-steen.h
*** tree-alias-steen.h	17 Jul 2002 14:06:20 -0000	1.1.2.1
--- tree-alias-steen.h	21 Aug 2002 02:09:22 -0000
*************** struct tree_alias_ops
*** 21,26 ****
--- 21,27 ----
    void (*function_call) (struct tree_alias_ops *, alias_typevar,
  			 alias_typevar, varray_type);
    void *data;
+   int ip:1; /*Interprocedural */
  };
  extern struct tree_alias_ops *steen_alias_ops;
  extern void create_alias_vars PARAMS ((void));



More information about the Gcc-patches mailing list