Re: [PATCH] Fix PR52406
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
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
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
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
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
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 =