summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/vect/param-max-aliased-pr26197.cc24
-rw-r--r--gcc/testsuite/g++.dg/vect/vect.exp10
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-ssa-alias.c122
-rw-r--r--gcc/tree-vect-transform.c2
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;
OpenPOWER on IntegriCloud