From e6c961dde1572f17ecb50594c5858ab22c92d4a0 Mon Sep 17 00:00:00 2001 From: irar Date: Sun, 17 Sep 2006 09:17:51 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117003 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/vect/pr21591.c | 35 ++++++++++++++++ gcc/tree-data-ref.c | 84 ++++++++++++++++++++++++++++++------- 4 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr21591.c 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 + + 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 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 + + PR tree-opt/21591 + * gcc.dg/vect/pr21591.c: New test. + 2006-09-16 Andrew Pinski 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; } -- 2.7.4