diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 3 | ||||
-rw-r--r-- | gcc/opts.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c | 27 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 42 |
6 files changed, 87 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3c6b76c..9655811 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-07-04 Richard Guenther <rguenther@suse.de> + + * tree-ssa-structalias.c (lookup_vi_for_tree): Declare. + (do_sd_constraint): Handle a dereference of ESCAPED and CALLUSED + properly to compute the reachability set if we do field-sensitive PTA. + * invoke.texi (max-fields-for-field-sensitive): Document default. + * opts.c (decode_options): Set max-fields-for-field-sensitive to + 100 for optimize >= 2. + 2008-07-04 Kai Tietz <kai.tietz@onevision.com> * config.gcc (extra_headers): Add cross-stdarg.h for target diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 31d931e..5732d98 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -7323,7 +7323,8 @@ duplicated when threading jumps. @item max-fields-for-field-sensitive Maximum number of fields in a structure we will treat in -a field sensitive manner during pointer analysis. +a field sensitive manner during pointer analysis. The default is zero +for -O0, and -O1 and 100 for -Os, -O2, and -O3. @item prefetch-latency Estimate on average number of instructions that are executed before @@ -903,6 +903,9 @@ decode_options (unsigned int argc, const char **argv) /* Allow more virtual operators to increase alias precision. */ set_param_value ("max-aliased-vops", 500); + + /* Track fields in field-sensitive alias analysis. */ + set_param_value ("max-fields-for-field-sensitive", 100); } if (optimize >= 3) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef05b67..923bd13 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-07-04 Richard Guenther <rguenther@suse.de> + + * gcc.dg/tree-ssa/pta-callused.c: New testcase. + 2008-07-04 Kai Tietz <kai.tietz@onevision.com> * gcc.dg/callabi/callabi.h: New. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c new file mode 100644 index 0000000..44d095a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --param max-fields-for-field-sensitive=2 -fdump-tree-alias" } */ + +struct Foo { + int *p, *q; +}; + +int foo (int ***x) __attribute__((pure)); + +int bar (int b) +{ + int i; + struct Foo f; + int *p, **q; + p = &i; + f.p = &i; + f.q = f.p; + if (b) + q = &f.p; + else + q = &f.q; + return foo (&q); +} + +/* { dg-final { scan-tree-dump "CALLUSED = { f f.q i q }" "alias" } } */ +/* { dg-final { cleanup-tree-dump "alias" } } */ + diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 5531256..0b68b84 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -262,6 +262,7 @@ struct variable_info typedef struct variable_info *varinfo_t; static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); +static varinfo_t lookup_vi_for_tree (tree); /* Pool of variable info structures. */ static alloc_pool variable_info_pool; @@ -1406,6 +1407,47 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, goto done; } + /* For x = *ESCAPED and x = *CALLUSED we want to compute the + reachability set of the rhs var. As a pointer to a sub-field + of a variable can also reach all other fields of the variable + we simply have to expand the solution to contain all sub-fields + if one sub-field is contained. */ + if (c->rhs.var == escaped_id + || c->rhs.var == callused_id) + { + bitmap vars = NULL; + /* In a first pass record all variables we need to add all + sub-fields off. This avoids quadratic behavior. */ + EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) + { + varinfo_t v = lookup_vi_for_tree (get_varinfo (j)->decl); + if (v->next != NULL) + { + if (vars == NULL) + vars = BITMAP_ALLOC (NULL); + bitmap_set_bit (vars, v->id); + } + } + /* In the second pass now do the addition to the solution and + to speed up solving add it to the delta as well. */ + if (vars != NULL) + { + EXECUTE_IF_SET_IN_BITMAP (vars, 0, j, bi) + { + varinfo_t v = get_varinfo (j); + for (; v != NULL; v = v->next) + { + if (bitmap_set_bit (sol, v->id)) + { + flag = true; + bitmap_set_bit (delta, v->id); + } + } + } + BITMAP_FREE (vars); + } + } + /* For each variable j in delta (Sol(y)), add an edge in the graph from j to x, and union Sol(j) into Sol(x). */ EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) |