aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr21591.c35
-rw-r--r--gcc/tree-data-ref.c84
4 files changed, 118 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5c2cf3d..261926a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2006-09-17 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-opt/21591
+ * tree-data-ref.c (ptr_decl_may_alias_p): Look for the name memory
+ tag first.
+ (ptr_ptr_may_alias_p): Likewise.
+ (record_record_differ_p): New function.
+ (base_object_differ_p): Call record_record_differ_p.
+
2006-09-16 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/29059
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6a27b73..89cc01b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-17 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-opt/21591
+ * gcc.dg/vect/pr21591.c: New test.
+
2006-09-16 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/29059
diff --git a/gcc/testsuite/gcc.dg/vect/pr21591.c b/gcc/testsuite/gcc.dg/vect/pr21591.c
new file mode 100644
index 0000000..8a8e30f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr21591.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+
+struct a
+{
+ int length;
+ int a1[256];
+};
+
+struct a *malloc1(__SIZE_TYPE__) __attribute__((malloc));
+void free(void*);
+
+void f(void)
+{
+ struct a *a = malloc1(sizeof(struct a));
+ struct a *b = malloc1(sizeof(struct a));
+ struct a *c = malloc1(sizeof(struct a));
+ int i;
+
+ for (i = 0; i < 256; i++)
+ {
+ b->a1[i] = i;
+ c->a1[i] = i;
+ }
+ for (i = 0; i < 256; i++)
+ {
+ a->a1[i] = b->a1[i] + c->a1[i];
+ }
+ free(a);
+ free(b);
+ free(c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index d3758ef..30d745a 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -140,16 +140,20 @@ ptr_decl_may_alias_p (tree ptr, tree decl,
struct data_reference *ptr_dr,
bool *aliased)
{
- tree tag;
-
+ tree tag = NULL_TREE;
+ struct ptr_info_def *pi = DR_PTR_INFO (ptr_dr);
+
gcc_assert (TREE_CODE (ptr) == SSA_NAME && DECL_P (decl));
- tag = get_var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
+ if (pi)
+ tag = pi->name_mem_tag;
+ if (!tag)
+ tag = get_var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
if (!tag)
tag = DR_MEMTAG (ptr_dr);
if (!tag)
return false;
-
+
*aliased = is_aliased_with (tag, decl);
return true;
}
@@ -164,18 +168,29 @@ ptr_ptr_may_alias_p (tree ptr_a, tree ptr_b,
struct data_reference *drb,
bool *aliased)
{
- tree tag_a, tag_b;
+ tree tag_a = NULL_TREE, tag_b = NULL_TREE;
+ struct ptr_info_def *pi_a = DR_PTR_INFO (dra);
+ struct ptr_info_def *pi_b = DR_PTR_INFO (drb);
- tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->symbol_mem_tag;
- if (!tag_a)
- tag_a = DR_MEMTAG (dra);
- if (!tag_a)
- return false;
- tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->symbol_mem_tag;
- if (!tag_b)
- tag_b = DR_MEMTAG (drb);
- if (!tag_b)
- return false;
+ if (pi_a && pi_a->name_mem_tag && pi_b && pi_b->name_mem_tag)
+ {
+ tag_a = pi_a->name_mem_tag;
+ tag_b = pi_b->name_mem_tag;
+ }
+ else
+ {
+ tag_a = get_var_ann (SSA_NAME_VAR (ptr_a))->symbol_mem_tag;
+ if (!tag_a)
+ tag_a = DR_MEMTAG (dra);
+ if (!tag_a)
+ return false;
+
+ tag_b = get_var_ann (SSA_NAME_VAR (ptr_b))->symbol_mem_tag;
+ if (!tag_b)
+ tag_b = DR_MEMTAG (drb);
+ if (!tag_b)
+ return false;
+ }
*aliased = (tag_a == tag_b);
return true;
}
@@ -244,6 +259,38 @@ record_ptr_differ_p (struct data_reference *dra,
return false;
}
+/* Determine if two record/union accesses are aliased. Return TRUE if they
+ differ. */
+static bool
+record_record_differ_p (struct data_reference *dra,
+ struct data_reference *drb)
+{
+ bool aliased;
+ tree base_a = DR_BASE_OBJECT (dra);
+ tree base_b = DR_BASE_OBJECT (drb);
+
+ if (TREE_CODE (base_b) != COMPONENT_REF
+ || TREE_CODE (base_a) != COMPONENT_REF)
+ return false;
+
+ /* Peel COMPONENT_REFs to get to the base. Do not peel INDIRECT_REFs.
+ For a.b.c.d[i] we will get a, and for a.b->c.d[i] we will get a.b.
+ Probably will be unnecessary with struct alias analysis. */
+ while (TREE_CODE (base_b) == COMPONENT_REF)
+ base_b = TREE_OPERAND (base_b, 0);
+ while (TREE_CODE (base_a) == COMPONENT_REF)
+ base_a = TREE_OPERAND (base_a, 0);
+
+ if (TREE_CODE (base_a) == INDIRECT_REF
+ && TREE_CODE (base_b) == INDIRECT_REF
+ && ptr_ptr_may_alias_p (TREE_OPERAND (base_a, 0),
+ TREE_OPERAND (base_b, 0),
+ dra, drb, &aliased)
+ && !aliased)
+ return true;
+ else
+ return false;
+}
/* Determine if an array access (BASE_A) and a record/union access (BASE_B)
are not aliased. Return TRUE if they differ. */
@@ -408,6 +455,13 @@ base_object_differ_p (struct data_reference *a,
return true;
}
+ /* Compare two record/union accesses (b.c[i] or p->c[i]). */
+ if (record_record_differ_p (a, b))
+ {
+ *differ_p = true;
+ return true;
+ }
+
return false;
}