[PATCH][alias-improvements] Simplify CALLUSED processing

Richard Guenther rguenther@suse.de
Wed Feb 4 14:45:00 GMT 2009


In the patch introducing UNKNOWN_OFFSET handing to PTA I forgot to
add a proper CALLUSED = CALLUSED + UNKNOWN constraint.  The following
patch fixes that.  It also makes CALLUSED immune to the *CALLUSED = x
problem by not using it as a placeholder but fully propagating it.
The CALLUSED set should be small and this considerably simplifies code.

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

Richard.

2009-02-04  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-structalias.c (find_what_var_points_to): CALLUSED
	shall not appear in poins-to solutions.
	(pt_solution_empty_p): Remove code dealing with CALLUSED
	in points-to solutions.
	(pt_solution_includes): Likewise.
	(pt_solutions_intersect): Likewise.
	(pt_solution_merge_into): Remove.
	(compute_points_to_sets): Do not merge escaped/callused solutions.
	(do_sd_constraint): Do not use CALLUSED as a representative.
	(solve_graph): Do propagate CALLUSED.
	(handle_pure_call): Use a scalar constraint from CALLUSED for
	the return value.
	(init_base_vars): Add CALLUSED = CALLUSED + UNKNOWN constraint.
	* tree-ssa-alias.c (dump_points_to_info_for): Do not dump
	callused flag.
	* tree-ssa-alias.h (struct pt_solution): Remove callused flag.

	* gcc.dg/torture/pta-callused-1.c: New testcase.
	* gcc.dg/torture/ssa-pta-fn-1.c: Adjust.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2009-02-04 13:08:45.000000000 +0100
--- gcc/tree-ssa-structalias.c	2009-02-04 14:34:56.000000000 +0100
*************** do_sd_constraint (constraint_graph_t gra
*** 1585,1594 ****
  	  if (get_varinfo (t)->is_special_var)
  	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
  	  /* Merging the solution from ESCAPED needlessly increases
! 	     the set.  Use ESCAPED as representative instead.
! 	     Same for CALLUSED.  */
! 	  else if (get_varinfo (t)->id == escaped_id
! 		   || get_varinfo (t)->id == callused_id)
  	    flag |= bitmap_set_bit (sol, get_varinfo (t)->id);
  	  else if (add_graph_edge (graph, lhs, t))
  	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
--- 1585,1592 ----
  	  if (get_varinfo (t)->is_special_var)
  	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
  	  /* Merging the solution from ESCAPED needlessly increases
! 	     the set.  Use ESCAPED as representative instead.  */
! 	  else if (get_varinfo (t)->id == escaped_id)
  	    flag |= bitmap_set_bit (sol, get_varinfo (t)->id);
  	  else if (add_graph_edge (graph, lhs, t))
  	    flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
*************** solve_graph (constraint_graph_t graph)
*** 2558,2566 ****
  	      solution_empty = bitmap_empty_p (solution);
  
  	      if (!solution_empty
! 		  /* Do not propagate the ESCAPED/CALLUSED solutions.  */
! 		  && i != escaped_id
! 		  && i != callused_id)
  		{
  		  bitmap_iterator bi;
  
--- 2556,2563 ----
  	      solution_empty = bitmap_empty_p (solution);
  
  	      if (!solution_empty
! 		  /* Do not propagate the ESCAPED solution.  */
! 		  && i != escaped_id)
  		{
  		  bitmap_iterator bi;
  
*************** handle_pure_call (gimple stmt)
*** 3700,3706 ****
           and globals will be dealt with in handle_lhs_call.  */
        rhsc.var = callused_id;
        rhsc.offset = 0;
!       rhsc.type = ADDRESSOF;
        for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
  	process_constraint (new_constraint (*lhsp, rhsc));
        VEC_free (ce_s, heap, lhsc);
--- 3697,3703 ----
           and globals will be dealt with in handle_lhs_call.  */
        rhsc.var = callused_id;
        rhsc.offset = 0;
!       rhsc.type = SCALAR;
        for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
  	process_constraint (new_constraint (*lhsp, rhsc));
        VEC_free (ce_s, heap, lhsc);
*************** find_what_var_points_to (varinfo_t vi, s
*** 5028,5034 ****
  	  else if (vi->id == escaped_id)
  	    pt->escaped = 1;
  	  else if (vi->id == callused_id)
! 	    pt->callused = 1;
  	  else if (vi->id == nonlocal_id)
  	    pt->nonlocal = 1;
  	  else if (vi->is_heap_var)
--- 5025,5031 ----
  	  else if (vi->id == escaped_id)
  	    pt->escaped = 1;
  	  else if (vi->id == callused_id)
! 	    gcc_unreachable ();
  	  else if (vi->id == nonlocal_id)
  	    pt->nonlocal = 1;
  	  else if (vi->is_heap_var)
*************** pt_solution_empty_p (struct pt_solution
*** 5148,5159 ****
        && !pt_solution_empty_p (&cfun->gimple_df->escaped))
      return false;
  
-   /* If this isn't already the callused solution, check if that is empty.  */
-   if (pt->callused
-       && &cfun->gimple_df->callused != pt
-       && !pt_solution_empty_p (&cfun->gimple_df->callused))
-     return false;
- 
    return true;
  }
  
--- 5145,5150 ----
*************** pt_solution_includes (struct pt_solution
*** 5179,5190 ****
        && pt_solution_includes (&cfun->gimple_df->escaped, decl))
      return true;
  
-   /* If this isn't already the callused solution, union it with that.  */
-   if (pt->callused
-       && &cfun->gimple_df->callused != pt
-       && pt_solution_includes (&cfun->gimple_df->callused, decl))
-     return true;
- 
    return false;
  }
  
--- 5170,5175 ----
*************** pt_solutions_intersect (struct pt_soluti
*** 5226,5274 ****
  	return true;
      }
  
-   /* Check the callused solution if required.  */
-   if ((pt1->callused || pt1 == &cfun->gimple_df->callused
-        || pt2->callused || pt2 == &cfun->gimple_df->callused)
-       && !pt_solution_empty_p (&cfun->gimple_df->callused))
-     {
-       /* If both point to callused memory and that solution
- 	 is not empty they alias.  */
-       if ((pt1->callused || pt1 == &cfun->gimple_df->callused)
- 	  && (pt2->callused || pt2 == &cfun->gimple_df->callused))
- 	  return true;
- 
-       /* If either points to callused memory see if the callused solution
- 	 intersects.  */
-       if (((pt1->callused || pt1 == &cfun->gimple_df->callused)
- 	   && pt_solutions_intersect (&cfun->gimple_df->callused, pt1))
- 	  || ((pt2->callused || pt2 == &cfun->gimple_df->callused)
- 	      && pt_solutions_intersect (&cfun->gimple_df->callused, pt2)))
- 	return true;
-     }
- 
    /* Now both pointers alias if their points-to solution intersects.  */
    return (pt1->vars
  	  && pt2->vars
  	  && bitmap_intersect_p (pt1->vars, pt2->vars));
  }
  
- /* Merge the solution SRC into the solution DEST.  */
- 
- static void
- pt_solution_merge_into (struct pt_solution *dest, struct pt_solution *src)
- {
-   dest->anything |= src->anything;
-   dest->nonlocal |= src->nonlocal;
-   dest->escaped |= src->escaped;
-   dest->callused |= src->callused;
-   dest->null |= src->null;
-   dest->vars_contains_global |= src->vars_contains_global;
-   if (src->vars && dest->vars)
-     bitmap_ior_into (dest->vars, src->vars);
-   else if (src->vars)
-     dest->vars = src->vars;
- }
- 
  
  /* Dump points-to information to OUTFILE.  */
  
--- 5211,5222 ----
*************** init_base_vars (void)
*** 5472,5477 ****
--- 5420,5435 ----
    rhs.offset = 0;
    process_constraint (new_constraint (lhs, rhs));
  
+   /* CALLUSED = CALLUSED + UNKNOWN, because if a sub-field is call-used the
+      whole variable is call-used.  */
+   lhs.type = SCALAR;
+   lhs.var = callused_id;
+   lhs.offset = 0;
+   rhs.type = SCALAR;
+   rhs.var = callused_id;
+   rhs.offset = UNKNOWN_OFFSET;
+   process_constraint (new_constraint (lhs, rhs));
+ 
    /* Create the INTEGER variable, used to represent that a variable points
       to what an INTEGER "points to".  */
    integer_tree = create_tmp_var_raw (ptr_type_node, "INTEGER");
*************** compute_points_to_sets (void)
*** 5854,5870 ****
       call-clobber analysis.  */
    find_what_var_points_to (var_escaped, &cfun->gimple_df->escaped, false);
    find_what_var_points_to (var_callused, &cfun->gimple_df->callused, false);
-   /* If both include each other merge and separate them to avoid running
-      in circles during queries of these placeholder solutions.  */
-   if (cfun->gimple_df->escaped.callused
-       && cfun->gimple_df->callused.escaped)
-     {
-       pt_solution_merge_into (&cfun->gimple_df->escaped,
- 			      &cfun->gimple_df->callused);
-       cfun->gimple_df->callused = cfun->gimple_df->escaped;
-       cfun->gimple_df->escaped.callused = false;
-       cfun->gimple_df->callused.escaped = false;
-     }
  
    timevar_pop (TV_TREE_PTA);
  
--- 5812,5817 ----
Index: gcc/testsuite/gcc.dg/torture/pta-callused-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/torture/pta-callused-1.c	2009-02-04 13:08:53.000000000 +0100
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do run } */
+ /* { dg-options "-fdump-tree-alias" } */
+ /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+ 
+ volatile int i;
+ int ** __attribute__((noinline,pure)) foo(int **p) { i; return p; }
+ int bar(void)
+ {
+   int i = 0, j = 1;
+   int *p, **q;
+   p = &i;
+   q = foo(&p);
+   *q = &j;
+   return *p;
+ }
+ extern void abort (void);
+ int main()
+ {
+   if (bar() != 1)
+     abort ();
+   return 0;
+ }
+ 
+ /* { dg-final { scan-tree-dump "p.._., is dereferenced, points-to vars: { i j }" "alias" } } */
+ /* { dg-final { cleanup-tree-dump "alias" } } */
Index: gcc/testsuite/gcc.dg/torture/ssa-pta-fn-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/ssa-pta-fn-1.c.orig	2009-02-04 12:46:21.000000000 +0100
--- gcc/testsuite/gcc.dg/torture/ssa-pta-fn-1.c	2009-02-04 13:08:53.000000000 +0100
***************
*** 1,5 ****
  /* { dg-do run } */
! /* { dg-options "-O -fdump-tree-alias" } */
  
  extern void abort (void);
  int *glob;
--- 1,6 ----
  /* { dg-do run } */
! /* { dg-options "-fdump-tree-alias" } */
! /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
  
  extern void abort (void);
  int *glob;
*************** int main()
*** 55,60 ****
  }
  
  /* { dg-final { scan-tree-dump "q_const_., is dereferenced, points-to non-local, points-to vars: { i }" "alias" } } */
! /* { dg-final { scan-tree-dump "q_pure_., is dereferenced, points-to non-local, points-to escaped, points-to call-used, points-to vars: { }" "alias" } } */
  /* { dg-final { scan-tree-dump "q_normal_., is dereferenced, points-to non-local, points-to escaped, points-to vars: { }" "alias" } } */
  /* { dg-final { cleanup-tree-dump "alias" } } */
--- 56,61 ----
  }
  
  /* { dg-final { scan-tree-dump "q_const_., is dereferenced, points-to non-local, points-to vars: { i }" "alias" } } */
! /* { dg-final { scan-tree-dump "q_pure_., is dereferenced, points-to non-local, points-to escaped, points-to vars: { i }" "alias" } } */
  /* { dg-final { scan-tree-dump "q_normal_., is dereferenced, points-to non-local, points-to escaped, points-to vars: { }" "alias" } } */
  /* { dg-final { cleanup-tree-dump "alias" } } */
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2009-02-01 12:19:33.000000000 +0100
--- gcc/tree-ssa-alias.c	2009-02-04 14:24:12.000000000 +0100
*************** dump_points_to_info_for (FILE *file, tre
*** 330,338 ****
        if (pi->pt.escaped)
  	fprintf (file, ", points-to escaped");
  
-       if (pi->pt.callused)
- 	fprintf (file, ", points-to call-used");
- 
        if (pi->pt.null)
  	fprintf (file, ", points-to NULL");
  
--- 330,335 ----
Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h.orig	2009-02-01 12:19:33.000000000 +0100
--- gcc/tree-ssa-alias.h	2009-02-04 14:23:13.000000000 +0100
*************** struct pt_solution GTY(())
*** 61,69 ****
    /* Nonzero if the points-to set includes any escaped local variable.  */
    unsigned int escaped : 1;
  
-   /* Nonzero if the points-to set includes any callused variable.  */
-   unsigned int callused : 1;
- 
    /* Nonzero if the points-to set includes 'nothing', the points-to set
       includes memory at address NULL.  */
    unsigned int null : 1;
--- 61,66 ----



More information about the Gcc-patches mailing list