Re: [PATCH] Fix PR52406

2012-03-02 Thread Richard Guenther
On Thu, 1 Mar 2012, Richard Guenther wrote:

 On Wed, 29 Feb 2012, Richard Guenther wrote:
 
  On Wed, 29 Feb 2012, Michael Matz wrote:
  
   Hi,
   
   On Wed, 29 Feb 2012, Richard Guenther wrote:
   
the whole base object - instead I mark the base MEM_REF of such 
accesses 
with TREE_NO_WARNING (ugh) and special-case for them in dr_may_alias_p. 
 
   
   At least use a flag that isn't currently used for MEM_REF.  E.g. 
   addressable_flag, and make a new macro that checks for the tree being a 
   MEMREF to access it.
  
  Ok, I'll use TREE_VISITED.  The alternative is to increase the size of
  struct indices (and thus all data-refs) and have a separate flag.
 
 As follows (also removes an unused entry in all data-refs and updates
 the docs).
 
 Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1 / 
 4.7.1.

And after more complaints I have just added a new flag to the dataref
instead.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-02  Richard Guenther  rguent...@suse.de

PR tree-optimization/52406
* tree-data-ref.h: Update documentation about DR_BASE_OBJECT.
(struct indices): Add unconstrained_base member.
(struct dr_alias): Remove unused vops member.
(DR_UNCONSTRAINED_BASE): New define.
* tree-data-ref.c (dr_analyze_indices): For COMPONENT_REFs
add indices to allow their disambiguation.  Make DR_BASE_OBJECT
be an artificial access that covers the whole indexed object,
or mark it with DR_UNCONSTRAINED_BASE if we cannot do so.  Canonicalize
plain decl base-objects to their MEM_REF variant.
(dr_may_alias_p): When the base-object of either data reference
has unknown size use only points-to information.
(compute_affine_dependence): Make dumps easier to read and
more verbose.
* tree-vect-data-ref.c (vector_alignment_reachable_p): Use
DR_REF when looking for packed references.
(vect_supportable_dr_alignment): Likewise.

* gcc.dg/torture/pr52406.c: New testcase.

Index: gcc/tree-data-ref.h
===
*** gcc/tree-data-ref.h (revision 184782)
--- gcc/tree-data-ref.h (working copy)
*** struct innermost_loop_behavior
*** 60,75 
  };
  
  /* Describes the evolutions of indices of the memory reference.  The indices
!are indices of the ARRAY_REFs and the operands of INDIRECT_REFs.
!For ARRAY_REFs, BASE_OBJECT is the reference with zeroed indices
!(note that this reference does not have to be valid, if zero does not
!belong to the range of the array; hence it is not recommended to use
!BASE_OBJECT in any code generation).  For INDIRECT_REFs, the address is
!set to the loop-invariant part of the address of the object, except for
!the constant offset.  For the examples above,
  
!base_object:a[0].b[0][0]   *(p + x + 4B * j_0)
 indices:{j_0, +, 1}_2  {16, +, 4}_2
   {i_0, +, 1}_1
   {j_0, +, 1}_2
  */
--- 60,76 
  };
  
  /* Describes the evolutions of indices of the memory reference.  The indices
!are indices of the ARRAY_REFs, indexes in artificial dimensions
!added for member selection of records and the operands of MEM_REFs.
!BASE_OBJECT is the part of the reference that is loop-invariant
!(note that this reference does not have to cover the whole object
!being accessed, in which case UNCONSTRAINED_BASE is set; hence it is
!not recommended to use BASE_OBJECT in any code generation).
!For the examples above,
  
!base_object:a  *(p + x + 4B * j_0)
 indices:{j_0, +, 1}_2  {16, +, 4}_2
+  4
   {i_0, +, 1}_1
   {j_0, +, 1}_2
  */
*** struct indices
*** 81,98 
  
/* A list of chrecs.  Access functions of the indices.  */
VEC(tree,heap) *access_fns;
  };
  
  struct dr_alias
  {
/* The alias information that should be used for new pointers to this
!  location.  SYMBOL_TAG is either a DECL or a SYMBOL_MEMORY_TAG.  */
struct ptr_info_def *ptr_info;
- 
-   /* The set of virtual operands corresponding to this memory reference,
-  serving as a description of the alias information for the memory
-  reference.  This could be eliminated if we had alias oracle.  */
-   bitmap vops;
  };
  
  /* An integer vector.  A vector formally consists of an element of a vector
--- 82,98 
  
/* A list of chrecs.  Access functions of the indices.  */
VEC(tree,heap) *access_fns;
+ 
+   /* Whether BASE_OBJECT is an access representing the whole object
+  or whether the access could not be constrained.  */
+   bool unconstrained_base;
  };
  
  struct dr_alias
  {
/* The alias information that should be used 

Re: [PATCH] Fix PR52406

2012-03-01 Thread Richard Guenther
On Wed, 29 Feb 2012, Richard Guenther wrote:

 On Wed, 29 Feb 2012, Michael Matz wrote:
 
  Hi,
  
  On Wed, 29 Feb 2012, Richard Guenther wrote:
  
   the whole base object - instead I mark the base MEM_REF of such accesses 
   with TREE_NO_WARNING (ugh) and special-case for them in dr_may_alias_p.  
  
  At least use a flag that isn't currently used for MEM_REF.  E.g. 
  addressable_flag, and make a new macro that checks for the tree being a 
  MEMREF to access it.
 
 Ok, I'll use TREE_VISITED.  The alternative is to increase the size of
 struct indices (and thus all data-refs) and have a separate flag.

As follows (also removes an unused entry in all data-refs and updates
the docs).

Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1 / 
4.7.1.

Richard.

2012-02-29  Richard Guenther  rguent...@suse.de

PR tree-optimization/52406
* tree-data-ref.h: Update documentation about DR_BASE_OBJECT.
(struct dr_alias): Remove unused vops member.
* tree-data-ref.c (dr_analyze_indices): For COMPONENT_REFs
add indices to allow their disambiguation.  Make DR_BASE_OBJECT
be an artificial access that covers the whole indexed object,
or mark it with TREE_VISITED if we cannot do so.  Canonicalize
plain decl base-objects to their MEM_REF variant.
(dr_may_alias_p): When the base-object of either data reference
has unknown size use only points-to information.
(compute_affine_dependence): Make dumps easier to read and
more verbose.
* tree-vect-data-ref.c (vector_alignment_reachable_p): Use
DR_REF when looking for packed references.
(vect_supportable_dr_alignment): Likewise.

* gcc.dg/torture/pr52406.c: New testcase.

Index: gcc/tree-data-ref.h
===
*** gcc/tree-data-ref.h (revision 184656)
--- gcc/tree-data-ref.h (working copy)
*** struct innermost_loop_behavior
*** 60,75 
  };
  
  /* Describes the evolutions of indices of the memory reference.  The indices
!are indices of the ARRAY_REFs and the operands of INDIRECT_REFs.
!For ARRAY_REFs, BASE_OBJECT is the reference with zeroed indices
!(note that this reference does not have to be valid, if zero does not
!belong to the range of the array; hence it is not recommended to use
!BASE_OBJECT in any code generation).  For INDIRECT_REFs, the address is
!set to the loop-invariant part of the address of the object, except for
!the constant offset.  For the examples above,
  
!base_object:a[0].b[0][0]   *(p + x + 4B * j_0)
 indices:{j_0, +, 1}_2  {16, +, 4}_2
   {i_0, +, 1}_1
   {j_0, +, 1}_2
  */
--- 60,76 
  };
  
  /* Describes the evolutions of indices of the memory reference.  The indices
!are indices of the ARRAY_REFs, indexes in artificial dimensions
!added for member selection of records and the operands of MEM_REFs.
!BASE_OBJECT is the part of the reference that is loop-invariant
!(note that this reference does not have to cover the whole object
!being accessed, in which case TREE_VISITED is set on it; hence it is
!not recommended to use BASE_OBJECT in any code generation).
!For the examples above,
  
!base_object:a  *(p + x + 4B * j_0)
 indices:{j_0, +, 1}_2  {16, +, 4}_2
+  4
   {i_0, +, 1}_1
   {j_0, +, 1}_2
  */
*** struct indices
*** 86,98 
  struct dr_alias
  {
/* The alias information that should be used for new pointers to this
!  location.  SYMBOL_TAG is either a DECL or a SYMBOL_MEMORY_TAG.  */
struct ptr_info_def *ptr_info;
- 
-   /* The set of virtual operands corresponding to this memory reference,
-  serving as a description of the alias information for the memory
-  reference.  This could be eliminated if we had alias oracle.  */
-   bitmap vops;
  };
  
  /* An integer vector.  A vector formally consists of an element of a vector
--- 87,94 
  struct dr_alias
  {
/* The alias information that should be used for new pointers to this
!  location.  */
struct ptr_info_def *ptr_info;
  };
  
  /* An integer vector.  A vector formally consists of an element of a vector
Index: gcc/tree-data-ref.c
===
*** gcc/tree-data-ref.c (revision 184656)
--- gcc/tree-data-ref.c (working copy)
*** static void
*** 856,862 
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
VEC (tree, heap) *access_fns = NULL;
!   tree ref, *aref, op;
tree base, off, access_fn;
basic_block before_loop;
  
--- 856,862 
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
VEC (tree, heap) 

Re: [PATCH] Fix PR52406

2012-02-29 Thread Richard Guenther
On Tue, 28 Feb 2012, Richard Guenther wrote:

 
 I am testing the following patch to fix PR52406.  We cannot simply
 feed DR_BASE_OBJECT to the alias-oracle as it does not reflect
 a real memory access.  Only if we query two 'structurally compatible'
 references we may do this.  So the following patch reverts to
 using DR_REF instead and improves data-ref index disambiguation
 by handling COMPONENT_REFs as extra access dimension (similar to how
 we handle REALPART/IMAGPART_EXPR).

So, this didn't exactly work out.  The following instead tries
to make sure we have the real base object in DR_BASE_OBJECT
so we _can_ use the tree alias-oracle to disambiguate different
ones (so DR_BASE_OBJECT has to have a meaningful size, and
a.b[0].c cannot simply be the base-object for a.b[i].c, instead
a or a.b would be valid base-objects for it).  Now, things
get interesting if you consider *(p + i) style accesses where
we cannot really create an artificial access that covers the
whole base object - instead I mark the base MEM_REF of such
accesses with TREE_NO_WARNING (ugh) and special-case for them
in dr_may_alias_p.  Fortunately there are almost no users of
DR_BASE_OBJECT, and the ones in the vectorizer are even wrong.

The patch has become quite invasive so I am considering to delay
it until after 4.7.0 and eventually backport it.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Richard.

2012-02-29  Richard Guenther  rguent...@suse.de

PR tree-optimization/52406
* tree-data-ref.c (dr_analyze_indices): For COMPONENT_REFs
add indices to allow their disambiguation.  Make DR_BASE_OBJECT
be an artificial access that covers the whole indexed object,
or mark it with TREE_NO_WARNING if we cannot do so.  Canonicalize
plain decl base-objects to their MEM_REF variant.
(dr_may_alias_p): When the base-object of either data reference
has unknown size use only points-to information.
(compute_affine_dependence): Make dumps easier to read and
more verbose.
* tree-vect-data-ref.c (vector_alignment_reachable_p): Use
DR_REF when looking for packed references.
(vect_supportable_dr_alignment): Likewise.

* gcc.dg/torture/pr52406.c: New testcase.

Index: gcc/tree-data-ref.c
===
*** gcc/tree-data-ref.c (revision 184656)
--- gcc/tree-data-ref.c (working copy)
*** static void
*** 856,862 
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
VEC (tree, heap) *access_fns = NULL;
!   tree ref, *aref, op;
tree base, off, access_fn;
basic_block before_loop;
  
--- 856,862 
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
VEC (tree, heap) *access_fns = NULL;
!   tree ref, op;
tree base, off, access_fn;
basic_block before_loop;
  
*** dr_analyze_indices (struct data_referenc
*** 869,875 
return;
  }
  
!   ref = unshare_expr (DR_REF (dr));
before_loop = block_before_loop (nest);
  
/* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses
--- 869,875 
return;
  }
  
!   ref = DR_REF (dr);
before_loop = block_before_loop (nest);
  
/* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses
*** dr_analyze_indices (struct data_referenc
*** 887,947 
  }
  
/* Analyze access functions of dimensions we know to be independent.  */
!   aref = ref;
!   while (handled_component_p (*aref))
  {
!   if (TREE_CODE (*aref) == ARRAY_REF)
{
! op = TREE_OPERAND (*aref, 1);
  access_fn = analyze_scalar_evolution (loop, op);
  access_fn = instantiate_scev (before_loop, loop, access_fn);
  VEC_safe_push (tree, heap, access_fns, access_fn);
- /* For ARRAY_REFs the base is the reference with the index replaced
-by zero if we can not strip it as the outermost component.  */
- if (*aref == ref)
-   {
- *aref = TREE_OPERAND (*aref, 0);
- continue;
-   }
- else
-   TREE_OPERAND (*aref, 1) = build_int_cst (TREE_TYPE (op), 0);
}
  
!   aref = TREE_OPERAND (*aref, 0);
  }
  
/* If the address operand of a MEM_REF base has an evolution in the
   analyzed nest, add it as an additional independent access-function.  */
!   if (TREE_CODE (*aref) == MEM_REF)
  {
!   op = TREE_OPERAND (*aref, 0);
access_fn = analyze_scalar_evolution (loop, op);
access_fn = instantiate_scev (before_loop, loop, access_fn);
if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
{
  tree orig_type;
  base = initial_condition (access_fn);
  orig_type = TREE_TYPE (base);
  STRIP_USELESS_TYPE_CONVERSION (base);
  split_constant_offset (base, base, off);
  /* Fold the MEM_REF offset into the evolutions initial

Re: [PATCH] Fix PR52406

2012-02-29 Thread Michael Matz
Hi,

On Wed, 29 Feb 2012, Richard Guenther wrote:

 the whole base object - instead I mark the base MEM_REF of such accesses 
 with TREE_NO_WARNING (ugh) and special-case for them in dr_may_alias_p.  

At least use a flag that isn't currently used for MEM_REF.  E.g. 
addressable_flag, and make a new macro that checks for the tree being a 
MEMREF to access it.


Ciao,
Michael.


Re: [PATCH] Fix PR52406

2012-02-29 Thread Richard Guenther
On Wed, 29 Feb 2012, Michael Matz wrote:

 Hi,
 
 On Wed, 29 Feb 2012, Richard Guenther wrote:
 
  the whole base object - instead I mark the base MEM_REF of such accesses 
  with TREE_NO_WARNING (ugh) and special-case for them in dr_may_alias_p.  
 
 At least use a flag that isn't currently used for MEM_REF.  E.g. 
 addressable_flag, and make a new macro that checks for the tree being a 
 MEMREF to access it.

Ok, I'll use TREE_VISITED.  The alternative is to increase the size of
struct indices (and thus all data-refs) and have a separate flag.

Richard.


[PATCH] Fix PR52406

2012-02-28 Thread Richard Guenther

I am testing the following patch to fix PR52406.  We cannot simply
feed DR_BASE_OBJECT to the alias-oracle as it does not reflect
a real memory access.  Only if we query two 'structurally compatible'
references we may do this.  So the following patch reverts to
using DR_REF instead and improves data-ref index disambiguation
by handling COMPONENT_REFs as extra access dimension (similar to how
we handle REALPART/IMAGPART_EXPR).

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

2012-02-28  Richard Guenther  rguent...@suse.de

PR tree-optimization/52406
* tree-data-ref.c (dr_analyze_indices): For outer COMPONENT_REFs
add indices to allow their disambiguation.
(dr_may_alias_p): Use DR_REF for querying the alias oracle.
(compute_affine_dependence): Make dumps easier to read and
more verbose.

* gcc.dg/torture/pr52406.c: New testcase.

Index: gcc/tree-data-ref.c
===
*** gcc/tree-data-ref.c (revision 184622)
--- gcc/tree-data-ref.c (working copy)
*** dr_analyze_indices (struct data_referenc
*** 886,891 
--- 886,908 
VEC_safe_push (tree, heap, access_fns, integer_one_node);
  }
  
+   /* For outermost COMPONENT_REFs of records (but not unions!) use the
+  FIELD_DECL offset as constant access function so we can
+  disambiguate a[i].f1 and a[i].f2.  */
+   while (TREE_CODE (ref) == COMPONENT_REF
+ TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+ {
+   tree off = component_ref_field_offset (ref);
+   off = size_binop (PLUS_EXPR,
+   size_binop (MULT_EXPR,
+   fold_convert (bitsizetype, off),
+   bitsize_int (BITS_PER_UNIT)),
+   DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)));
+   ref = TREE_OPERAND (ref, 0);
+   VEC_safe_push (tree, heap, access_fns, off);
+   continue;
+ }
+ 
/* Analyze access functions of dimensions we know to be independent.  */
aref = ref;
while (handled_component_p (*aref))
*** bool
*** 1325,1332 
  dr_may_alias_p (const struct data_reference *a, const struct data_reference 
*b,
bool loop_nest)
  {
!   tree addr_a = DR_BASE_OBJECT (a);
!   tree addr_b = DR_BASE_OBJECT (b);
  
/* If we are not processing a loop nest but scalar code we
   do not need to care about possible cross-iteration dependences
--- 1342,1349 
  dr_may_alias_p (const struct data_reference *a, const struct data_reference 
*b,
bool loop_nest)
  {
!   tree addr_a = DR_REF (a);
!   tree addr_b = DR_REF (b);
  
/* If we are not processing a loop nest but scalar code we
   do not need to care about possible cross-iteration dependences
*** compute_affine_dependence (struct data_d
*** 4049,4059 
if (dump_file  (dump_flags  TDF_DETAILS))
  {
fprintf (dump_file, (compute_affine_dependence\n);
!   fprintf (dump_file,   (stmt_a = \n);
!   print_gimple_stmt (dump_file, DR_STMT (dra), 0, 0);
!   fprintf (dump_file, )\n  (stmt_b = \n);
!   print_gimple_stmt (dump_file, DR_STMT (drb), 0, 0);
!   fprintf (dump_file, )\n);
  }
  
/* Analyze only when the dependence relation is not yet known.  */
--- 4066,4075 
if (dump_file  (dump_flags  TDF_DETAILS))
  {
fprintf (dump_file, (compute_affine_dependence\n);
!   fprintf (dump_file,   stmt_a: );
!   print_gimple_stmt (dump_file, DR_STMT (dra), 0, TDF_SLIM);
!   fprintf (dump_file,   stmt_b: );
!   print_gimple_stmt (dump_file, DR_STMT (drb), 0, TDF_SLIM);
  }
  
/* Analyze only when the dependence relation is not yet known.  */
*** compute_affine_dependence (struct data_d
*** 4129,4135 
  }
  
if (dump_file  (dump_flags  TDF_DETAILS))
! fprintf (dump_file, )\n);
  }
  
  /* Compute in DEPENDENCE_RELATIONS the data dependence graph for all
--- 4145,4158 
  }
  
if (dump_file  (dump_flags  TDF_DETAILS))
! {
!   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
!   fprintf (dump_file, ) - no dependence\n);
!   else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
!   fprintf (dump_file, ) - dependence analysis failed\n);
!   else
!   fprintf (dump_file, )\n);
! }
  }
  
  /* Compute in DEPENDENCE_RELATIONS the data dependence graph for all
Index: gcc/testsuite/gcc.dg/torture/pr52406.c
===
*** gcc/testsuite/gcc.dg/torture/pr52406.c  (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr52406.c  (revision 0)
***
*** 0 
--- 1,29 
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ struct { int f1; } a[2];
+ 
+ int *b, *const k = a[1].f1;
+ static int **c = b;
+ 
+ int e, f, d;
+ 
+ int
+ main ()
+ {
+   int **l = b;
+   *l = k;
+   for (; d =