diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/vect.exp | 10 | ||||
-rw-r--r-- | gcc/tree-flow.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 122 | ||||
-rw-r--r-- | gcc/tree-vect-transform.c | 2 |
7 files changed, 137 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1497429fbc2..ddd2e67edce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2006-08-10 Dorit Nuzman <dorit@il.ibm.com> + + PR tree-optimization/26197 + * tree-ssa-alias.c (new_type_alias): Takes additional argument. Calls + get_ref_base_and_extent and overlap_subvar to add only relevant + subvars as may-aliases. + (add_may_alias_for_new_tag): New function, factored out of + new_type_alias. + * tree-vect-transform.c (vect_create_data_ref_ptr): Call new_type_alias + with additional argument. + * tree-flow.h (new_type_alias): Takes additional argument. + 2006-08-09 Nathan Sidwell <nathan@codesourcery.com> * gcov.c (no_data_file): New flag. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 26af1f4959c..55c187cad32 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-08-10 Dorit Nuzman <dorit@il.ibm.com> + + PR tree-optimization/26197 + * g++.dg/vect/param-max-aliased-pr26197.cc: New test. + * g++.dg/vect/vect.exp: Compile the new testxs with --param max-aliased-vops=0. + 2006-08-09 Lee Millward <lee.millward@codesourcery.com> PR c++/28637 diff --git a/gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc b/gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc new file mode 100644 index 00000000000..198cd6b53ac --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +void g(const void*); +struct B +{ + int* x[2]; + int *p; + B() + { + for (int** p=x; p<x+4; ++p) + *p = 0; + } + ~B() + { + g(p); + } +}; +void bar() +{ + const B &b = B(); + g(&b); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/g++.dg/vect/vect.exp b/gcc/testsuite/g++.dg/vect/vect.exp index 1d9e4eb0f84..ce51c8a4f25 100644 --- a/gcc/testsuite/g++.dg/vect/vect.exp +++ b/gcc/testsuite/g++.dg/vect/vect.exp @@ -89,6 +89,16 @@ dg-init dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{c,cc,S} ]] \ "" $DEFAULT_VECTCFLAGS +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# --param max-aliased-vops=0 +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param max-aliased-vops=0" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/param-max-aliased*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + # Clean up. set dg-do-what-default ${save-dg-do-what-default} diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index d0c81515a26..46966663fe5 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -667,7 +667,7 @@ extern void debug_points_to_info_for (tree); extern bool may_be_aliased (tree); extern bool is_aliased_with (tree, tree); extern struct ptr_info_def *get_ptr_info (tree); -extern void new_type_alias (tree, tree); +extern void new_type_alias (tree, tree, tree); extern void count_uses_and_derefs (tree, tree, unsigned *, unsigned *, bool *); static inline subvar_t get_subvars_for_var (tree); static inline tree get_subvar_at (tree, unsigned HOST_WIDE_INT); diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 1607c71257a..6bfa4bb6063 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2691,79 +2691,123 @@ is_aliased_with (tree tag, tree sym) return false; } +/* The following is based on code in add_stmt_operand to ensure that the + same defs/uses/vdefs/vuses will be found after replacing a reference + to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value + is the address of var. Return a memtag for the ptr, after adding the + proper may_aliases to it (which are the aliases of var, if it has any, + or var itself). */ + +static tree +add_may_alias_for_new_tag (tree tag, tree var) +{ + var_ann_t v_ann = var_ann (var); + VEC(tree, gc) *aliases = v_ann->may_aliases; + + /* Case 1: |aliases| == 1 */ + if ((aliases != NULL) + && (VEC_length (tree, aliases) == 1)) + { + tree ali = VEC_index (tree, aliases, 0); + + if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG) + return ali; + } + + /* Case 2: |aliases| == 0 */ + if (aliases == NULL) + add_may_alias (tag, var); + else + { + /* Case 3: |aliases| > 1 */ + unsigned i; + tree al; + + for (i = 0; VEC_iterate (tree, aliases, i, al); i++) + add_may_alias (tag, al); + } + + return tag; +} /* Create a new symbol tag for PTR. Construct the may-alias list of this type - tag so that it has the aliasing of VAR. + tag so that it has the aliasing of VAR, or of the relevant subvars of VAR + according to the location accessed by EXPR. Note, the set of aliases represented by the new symbol tag are not marked for renaming. */ void -new_type_alias (tree ptr, tree var) +new_type_alias (tree ptr, tree var, tree expr) { var_ann_t p_ann = var_ann (ptr); tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); - var_ann_t v_ann = var_ann (var); tree tag; subvar_t svars; + tree ali = NULL_TREE; + HOST_WIDE_INT offset, size, maxsize; + tree ref; gcc_assert (p_ann->symbol_mem_tag == NULL_TREE); gcc_assert (!MTAG_P (var)); + ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize); + gcc_assert (ref); + + tag = create_memory_tag (tag_type, true); + p_ann->symbol_mem_tag = tag; + /* Add VAR to the may-alias set of PTR's new symbol tag. If VAR has subvars, add the subvars to the tag instead of the actual var. */ if (var_can_have_subvars (var) && (svars = get_subvars_for_var (var))) { subvar_t sv; - - tag = create_memory_tag (tag_type, true); - p_ann->symbol_mem_tag = tag; + VEC (tree, heap) *overlaps = NULL; + unsigned int len; for (sv = svars; sv; sv = sv->next) - add_may_alias (tag, sv->var); - } - else - { - /* The following is based on code in add_stmt_operand to ensure that the - same defs/uses/vdefs/vuses will be found after replacing a reference - to var (or ARRAY_REF to var) with an INDIRECT_REF to ptr whose value - is the address of var. */ - VEC(tree, gc) *aliases = v_ann->may_aliases; - - if ((aliases != NULL) - && (VEC_length (tree, aliases) == 1)) { - tree ali = VEC_index (tree, aliases, 0); + bool exact; - if (TREE_CODE (ali) == SYMBOL_MEMORY_TAG) + if (overlap_subvar (offset, maxsize, sv->var, &exact)) + VEC_safe_push (tree, heap, overlaps, sv->var); + } + len = VEC_length (tree, overlaps); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nnumber of overlapping subvars = %u\n", len); + gcc_assert (len); + + if (len == 1) + ali = add_may_alias_for_new_tag (tag, VEC_index (tree, overlaps, 0)); + else if (len > 1) + { + unsigned int k; + tree sv_var; + + for (k = 0; VEC_iterate (tree, overlaps, k, sv_var); k++) { - p_ann->symbol_mem_tag = ali; - return; - } - } - - tag = create_memory_tag (tag_type, true); - p_ann->symbol_mem_tag = tag; - - if (aliases == NULL) - add_may_alias (tag, var); - else - { - unsigned i; - tree al; + ali = add_may_alias_for_new_tag (tag, sv_var); - for (i = 0; VEC_iterate (tree, aliases, i, al); i++) - add_may_alias (tag, al); + if (ali != tag) + { + /* Can happen only if 'Case 1' of add_may_alias_for_new_tag + took place. Since more than one svar was found, we add + 'ali' as one of the may_aliases of the new tag. */ + add_may_alias (tag, ali); + ali = tag; + } + } } - } + } + else + ali = add_may_alias_for_new_tag (tag, var); + p_ann->symbol_mem_tag = ali; TREE_READONLY (tag) = TREE_READONLY (var); MTAG_GLOBAL (tag) = is_global_var (var); } - - /* This represents the used range of a variable. */ typedef struct used_part diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 746e9067e47..5f1b2069ceb 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -303,7 +303,7 @@ vect_create_data_ref_ptr (tree stmt, /* If tag is a variable (and NOT_A_TAG) than a new symbol memory tag must be created with tag added to its may alias list. */ if (!MTAG_P (tag)) - new_type_alias (vect_ptr, tag); + new_type_alias (vect_ptr, tag, DR_REF (dr)); else var_ann (vect_ptr)->symbol_mem_tag = tag; |