[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