Hi Richard,

We have improved reporting of our benchmarking CI.  Any feedback on the below 
report format?

Regards,

--
Maxim Kuvyrkov
https://www.linaro.org

> On 22 Sep 2021, at 01:58, ci_not...@linaro.org wrote:
> 
> After gcc commit f92901a508305f291fcf2acae0825379477724de
> Author: Richard Biener <rguent...@suse.de>
> 
>    tree-optimization/65206 - dependence analysis on mixed pointer/array
> 
> the following benchmarks slowed down by more than 2%:
> - 482.sphinx3 slowed down by 4% from 20816 to 21661 perf samples
> 
> Below reproducer instructions can be used to re-build both "first_bad" and 
> "last_good" cross-toolchains used in this bisection.  Naturally, the scripts 
> will fail when triggerring benchmarking jobs if you don't have access to 
> Linaro TCWG CI.
> 
> For your convenience, we have uploaded tarballs with pre-processed source and 
> assembly files at:
> - First_bad save-temps: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-f92901a508305f291fcf2acae0825379477724de/save-temps/
> - Last_good save-temps: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-abdf63d782cba82b5ecf264248518cbb065650ed/save-temps/
> - Baseline save-temps: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-baseline/save-temps/
> 
> Configuration:
> - Benchmark: SPEC CPU2006
> - Toolchain: GCC + Glibc + GNU Linker
> - Version: all components were built from their tip of trunk
> - Target: aarch64-linux-gnu
> - Compiler flags: -O3
> - Hardware: NVidia TX1 4x Cortex-A57
> 
> This benchmarking CI is work-in-progress, and we welcome feedback and 
> suggestions at linaro-toolchain@lists.linaro.org .  In our improvement plans 
> is to add support for SPEC CPU2017 benchmarks and provide "perf 
> report/annotate" data behind these reports.
> 
> THIS IS THE END OF INTERESTING STUFF.  BELOW ARE LINKS TO BUILDS, 
> REPRODUCTION INSTRUCTIONS, AND THE RAW COMMIT.
> 
> This commit has regressed these CI configurations:
> - tcwg_bmk_gnu_tx1/gnu-master-aarch64-spec2k6-O3
> 
> First_bad build: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-f92901a508305f291fcf2acae0825379477724de/
> Last_good build: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-abdf63d782cba82b5ecf264248518cbb065650ed/
> Baseline build: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/build-baseline/
> Even more details: 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/
> 
> Reproduce builds:
> <cut>
> mkdir investigate-gcc-f92901a508305f291fcf2acae0825379477724de
> cd investigate-gcc-f92901a508305f291fcf2acae0825379477724de
> 
> # Fetch scripts
> git clone https://git.linaro.org/toolchain/jenkins-scripts
> 
> # Fetch manifests and test.sh script
> mkdir -p artifacts/manifests
> curl -o artifacts/manifests/build-baseline.sh 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/manifests/build-baseline.sh
>  --fail
> curl -o artifacts/manifests/build-parameters.sh 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/manifests/build-parameters.sh
>  --fail
> curl -o artifacts/test.sh 
> https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aarch64-spec2k6-O3/34/artifact/artifacts/test.sh
>  --fail
> chmod +x artifacts/test.sh
> 
> # Reproduce the baseline build (build all pre-requisites)
> ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
> 
> # Save baseline build state (which is then restored in artifacts/test.sh)
> mkdir -p ./bisect
> rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ 
> --exclude /gcc/ ./ ./bisect/baseline/
> 
> cd gcc
> 
> # Reproduce first_bad build
> git checkout --detach f92901a508305f291fcf2acae0825379477724de
> ../artifacts/test.sh
> 
> # Reproduce last_good build
> git checkout --detach abdf63d782cba82b5ecf264248518cbb065650ed
> ../artifacts/test.sh
> 
> cd ..
> </cut>
> 
> Full commit (up to 1000 lines):
> <cut>
> commit f92901a508305f291fcf2acae0825379477724de
> Author: Richard Biener <rguent...@suse.de>
> Date:   Wed Sep 8 14:42:31 2021 +0200
> 
>    tree-optimization/65206 - dependence analysis on mixed pointer/array
> 
>    This adds the capability to analyze the dependence of mixed
>    pointer/array accesses.  The example is from where using a masked
>    load/store creates the pointer-based access when an otherwise
>    unconditional access is array based.  Other examples would include
>    accesses to an array mixed with accesses from inlined helpers
>    that work on pointers.
> 
>    The idea is quite simple and old - analyze the data-ref indices
>    as if the reference was pointer-based.  The following change does
>    this by changing dr_analyze_indices to work on the indices
>    sub-structure and storing an alternate indices substructure in
>    each data reference.  That alternate set of indices is analyzed
>    lazily by initialize_data_dependence_relation when it fails to
>    match-up the main set of indices of two data references.
>    initialize_data_dependence_relation is refactored into a head
>    and a tail worker and changed to work on one of the indices
>    structures and thus away from using DR_* access macros which
>    continue to reference the main indices substructure.
> 
>    There are quite some vectorization and loop distribution opportunities
>    unleashed in SPEC CPU 2017, notably 520.omnetpp_r, 548.exchange2_r,
>    510.parest_r, 511.povray_r, 521.wrf_r, 526.blender_r, 527.cam4_r and
>    544.nab_r see amendments in what they report with -fopt-info-loop while
>    the rest of the specrate set sees no changes there.  Measuring runtime
>    for the set where changes were reported reveals nothing off-noise
>    besides 511.povray_r which seems to regress slightly for me
>    (on a Zen2 machine with -Ofast -march=native).
> 
>    2021-09-08  Richard Biener  <rguent...@suse.de>
> 
>            PR tree-optimization/65206
>            * tree-data-ref.h (struct data_reference): Add alt_indices,
>            order it last.
>            * tree-data-ref.c (free_data_ref): Release alt_indices.
>            (dr_analyze_indices): Work on struct indices and get DR_REF as 
> tree.
>            (create_data_ref): Adjust.
>            (initialize_data_dependence_relation): Split into head
>            and tail.  When the base objects fail to match up try
>            again with pointer-based analysis of indices.
>            * tree-vectorizer.c (vec_info_shared::check_datarefs): Do
>            not compare the lazily computed alternate set of indices.
> 
>            * gcc.dg/torture/20210916.c: New testcase.
>            * gcc.dg/vect/pr65206.c: Likewise.
> ---
> gcc/testsuite/gcc.dg/torture/20210916.c |  20 ++++
> gcc/testsuite/gcc.dg/vect/pr65206.c     |  22 ++++
> gcc/tree-data-ref.c                     | 174 +++++++++++++++++++++-----------
> gcc/tree-data-ref.h                     |   9 +-
> gcc/tree-vectorizer.c                   |   3 +-
> 5 files changed, 168 insertions(+), 60 deletions(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/torture/20210916.c 
> b/gcc/testsuite/gcc.dg/torture/20210916.c
> new file mode 100644
> index 00000000000..0ea6d45e463
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/20210916.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +
> +typedef union tree_node *tree;
> +struct tree_base {
> +  unsigned : 1;
> +  unsigned lang_flag_2 : 1;
> +};
> +struct tree_type {
> +  tree main_variant;
> +};
> +union tree_node {
> +  struct tree_base base;
> +  struct tree_type type;
> +};
> +tree finish_struct_t, finish_struct_x;
> +void finish_struct()
> +{
> +  for (; finish_struct_t->type.main_variant;)
> +    finish_struct_x->base.lang_flag_2 = 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/vect/pr65206.c 
> b/gcc/testsuite/gcc.dg/vect/pr65206.c
> new file mode 100644
> index 00000000000..3b6262622c0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/pr65206.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_double } */
> +/* { dg-additional-options "-fno-trapping-math -fno-allow-store-data-races" 
> } */
> +/* { dg-additional-options "-mavx" { target avx } } */
> +
> +#define N 1024
> +
> +double a[N], b[N];
> +
> +void foo ()
> +{
> +  for (int i = 0; i < N; ++i)
> +    if (b[i] < 3.)
> +      a[i] += b[i];
> +}
> +
> +/* We get a .MASK_STORE because while the load of a[i] does not trap
> +   the store would introduce store data races.  Make sure we still
> +   can handle the data dependence with zero distance.  */
> +
> +/* { dg-final { scan-tree-dump-not "versioning for alias required" "vect" { 
> target { vect_masked_store || avx } } } } */
> +/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" { 
> target { vect_masked_store || avx } } } } */
> diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
> index e061baa7c20..18307a554fc 100644
> --- a/gcc/tree-data-ref.c
> +++ b/gcc/tree-data-ref.c
> @@ -99,6 +99,7 @@ along with GCC; see the file COPYING3.  If not see
> #include "internal-fn.h"
> #include "vr-values.h"
> #include "range-op.h"
> +#include "tree-ssa-loop-ivopts.h"
> 
> static struct datadep_stats
> {
> @@ -1300,22 +1301,18 @@ base_supports_access_fn_components_p (tree base)
>    DR, analyzed in LOOP and instantiated before NEST.  */
> 
> static void
> -dr_analyze_indices (struct data_reference *dr, edge nest, loop_p loop)
> +dr_analyze_indices (struct indices *dri, tree ref, edge nest, loop_p loop)
> {
> -  vec<tree> access_fns = vNULL;
> -  tree ref, op;
> -  tree base, off, access_fn;
> -
>   /* If analyzing a basic-block there are no indices to analyze
>      and thus no access functions.  */
>   if (!nest)
>     {
> -      DR_BASE_OBJECT (dr) = DR_REF (dr);
> -      DR_ACCESS_FNS (dr).create (0);
> +      dri->base_object = ref;
> +      dri->access_fns.create (0);
>       return;
>     }
> 
> -  ref = DR_REF (dr);
> +  vec<tree> access_fns = vNULL;
> 
>   /* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses
>      into a two element array with a constant index.  The base is
> @@ -1338,8 +1335,8 @@ dr_analyze_indices (struct data_reference *dr, edge 
> nest, loop_p loop)
>     {
>       if (TREE_CODE (ref) == ARRAY_REF)
>       {
> -       op = TREE_OPERAND (ref, 1);
> -       access_fn = analyze_scalar_evolution (loop, op);
> +       tree op = TREE_OPERAND (ref, 1);
> +       tree access_fn = analyze_scalar_evolution (loop, op);
>         access_fn = instantiate_scev (nest, loop, access_fn);
>         access_fns.safe_push (access_fn);
>       }
> @@ -1370,16 +1367,16 @@ dr_analyze_indices (struct data_reference *dr, edge 
> nest, loop_p loop)
>      analyzed nest, add it as an additional independent access-function.  */
>   if (TREE_CODE (ref) == MEM_REF)
>     {
> -      op = TREE_OPERAND (ref, 0);
> -      access_fn = analyze_scalar_evolution (loop, op);
> +      tree op = TREE_OPERAND (ref, 0);
> +      tree access_fn = analyze_scalar_evolution (loop, op);
>       access_fn = instantiate_scev (nest, loop, access_fn);
>       if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
>       {
> -       tree orig_type;
>         tree memoff = TREE_OPERAND (ref, 1);
> -       base = initial_condition (access_fn);
> -       orig_type = TREE_TYPE (base);
> +       tree base = initial_condition (access_fn);
> +       tree orig_type = TREE_TYPE (base);
>         STRIP_USELESS_TYPE_CONVERSION (base);
> +       tree off;
>         split_constant_offset (base, &base, &off);
>         STRIP_USELESS_TYPE_CONVERSION (base);
>         /* Fold the MEM_REF offset into the evolutions initial
> @@ -1424,7 +1421,7 @@ dr_analyze_indices (struct data_reference *dr, edge 
> nest, loop_p loop)
>                                base, memoff);
>         MR_DEPENDENCE_CLIQUE (ref) = MR_DEPENDENCE_CLIQUE (old);
>         MR_DEPENDENCE_BASE (ref) = MR_DEPENDENCE_BASE (old);
> -       DR_UNCONSTRAINED_BASE (dr) = true;
> +       dri->unconstrained_base = true;
>         access_fns.safe_push (access_fn);
>       }
>     }
> @@ -1436,8 +1433,8 @@ dr_analyze_indices (struct data_reference *dr, edge 
> nest, loop_p loop)
>                   build_int_cst (reference_alias_ptr_type (ref), 0));
>     }
> 
> -  DR_BASE_OBJECT (dr) = ref;
> -  DR_ACCESS_FNS (dr) = access_fns;
> +  dri->base_object = ref;
> +  dri->access_fns = access_fns;
> }
> 
> /* Extracts the alias analysis information from the memory reference DR.  */
> @@ -1463,6 +1460,8 @@ void
> free_data_ref (data_reference_p dr)
> {
>   DR_ACCESS_FNS (dr).release ();
> +  if (dr->alt_indices.base_object)
> +    dr->alt_indices.access_fns.release ();
>   free (dr);
> }
> 
> @@ -1497,7 +1496,7 @@ create_data_ref (edge nest, loop_p loop, tree memref, 
> gimple *stmt,
> 
>   dr_analyze_innermost (&DR_INNERMOST (dr), memref,
>                       nest != NULL ? loop : NULL, stmt);
> -  dr_analyze_indices (dr, nest, loop);
> +  dr_analyze_indices (&dr->indices, DR_REF (dr), nest, loop);
>   dr_analyze_alias (dr);
> 
>   if (dump_file && (dump_flags & TDF_DETAILS))
> @@ -3066,41 +3065,30 @@ access_fn_components_comparable_p (tree ref_a, tree 
> ref_b)
>                            TREE_TYPE (TREE_OPERAND (ref_b, 0)));
> }
> 
> -/* Initialize a data dependence relation between data accesses A and
> -   B.  NB_LOOPS is the number of loops surrounding the references: the
> -   size of the classic distance/direction vectors.  */
> +/* Initialize a data dependence relation RES in LOOP_NEST.  USE_ALT_INDICES
> +   is true when the main indices of A and B were not comparable so we try 
> again
> +   with alternate indices computed on an indirect reference.  */
> 
> struct data_dependence_relation *
> -initialize_data_dependence_relation (struct data_reference *a,
> -                                  struct data_reference *b,
> -                                  vec<loop_p> loop_nest)
> +initialize_data_dependence_relation (struct data_dependence_relation *res,
> +                                  vec<loop_p> loop_nest,
> +                                  bool use_alt_indices)
> {
> -  struct data_dependence_relation *res;
> +  struct data_reference *a = DDR_A (res);
> +  struct data_reference *b = DDR_B (res);
>   unsigned int i;
> 
> -  res = XCNEW (struct data_dependence_relation);
> -  DDR_A (res) = a;
> -  DDR_B (res) = b;
> -  DDR_LOOP_NEST (res).create (0);
> -  DDR_SUBSCRIPTS (res).create (0);
> -  DDR_DIR_VECTS (res).create (0);
> -  DDR_DIST_VECTS (res).create (0);
> -
> -  if (a == NULL || b == NULL)
> +  struct indices *indices_a = &a->indices;
> +  struct indices *indices_b = &b->indices;
> +  if (use_alt_indices)
>     {
> -      DDR_ARE_DEPENDENT (res) = chrec_dont_know;
> -      return res;
> +      if (TREE_CODE (DR_REF (a)) != MEM_REF)
> +     indices_a = &a->alt_indices;
> +      if (TREE_CODE (DR_REF (b)) != MEM_REF)
> +     indices_b = &b->alt_indices;
>     }
> -
> -  /* If the data references do not alias, then they are independent.  */
> -  if (!dr_may_alias_p (a, b, loop_nest.exists () ? loop_nest[0] : NULL))
> -    {
> -      DDR_ARE_DEPENDENT (res) = chrec_known;
> -      return res;
> -    }
> -
> -  unsigned int num_dimensions_a = DR_NUM_DIMENSIONS (a);
> -  unsigned int num_dimensions_b = DR_NUM_DIMENSIONS (b);
> +  unsigned int num_dimensions_a = indices_a->access_fns.length ();
> +  unsigned int num_dimensions_b = indices_b->access_fns.length ();
>   if (num_dimensions_a == 0 || num_dimensions_b == 0)
>     {
>       DDR_ARE_DEPENDENT (res) = chrec_dont_know;
> @@ -3125,9 +3113,9 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
> 
>      the a and b accesses have a single ARRAY_REF component reference [0]
>      but have two subscripts.  */
> -  if (DR_UNCONSTRAINED_BASE (a))
> +  if (indices_a->unconstrained_base)
>     num_dimensions_a -= 1;
> -  if (DR_UNCONSTRAINED_BASE (b))
> +  if (indices_b->unconstrained_base)
>     num_dimensions_b -= 1;
> 
>   /* These structures describe sequences of component references in
> @@ -3210,6 +3198,10 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>         B: [3, 4]  (i.e. s.e)  */
>   while (index_a < num_dimensions_a && index_b < num_dimensions_b)
>     {
> +      /* The alternate indices form always has a single dimension
> +      with unconstrained base.  */
> +      gcc_assert (!use_alt_indices);
> +
>       /* REF_A and REF_B must be one of the component access types
>        allowed by dr_analyze_indices.  */
>       gcc_checking_assert (access_fn_component_p (ref_a));
> @@ -3280,11 +3272,12 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>   /* See whether FULL_SEQ ends at the base and whether the two bases
>      are equal.  We do not care about TBAA or alignment info so we can
>      use OEP_ADDRESS_OF to avoid false negatives.  */
> -  tree base_a = DR_BASE_OBJECT (a);
> -  tree base_b = DR_BASE_OBJECT (b);
> +  tree base_a = indices_a->base_object;
> +  tree base_b = indices_b->base_object;
>   bool same_base_p = (full_seq.start_a + full_seq.length == num_dimensions_a
>                     && full_seq.start_b + full_seq.length == num_dimensions_b
> -                   && DR_UNCONSTRAINED_BASE (a) == DR_UNCONSTRAINED_BASE (b)
> +                   && (indices_a->unconstrained_base
> +                       == indices_b->unconstrained_base)
>                     && operand_equal_p (base_a, base_b, OEP_ADDRESS_OF)
>                     && (types_compatible_p (TREE_TYPE (base_a),
>                                             TREE_TYPE (base_b))
> @@ -3323,7 +3316,7 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>      both lvalues are distinct from the object's declared type.  */
>   if (same_base_p)
>     {
> -      if (DR_UNCONSTRAINED_BASE (a))
> +      if (indices_a->unconstrained_base)
>       full_seq.length += 1;
>     }
>   else
> @@ -3332,8 +3325,41 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>   /* Punt if we didn't find a suitable sequence.  */
>   if (full_seq.length == 0)
>     {
> -      DDR_ARE_DEPENDENT (res) = chrec_dont_know;
> -      return res;
> +      if (use_alt_indices
> +       || (TREE_CODE (DR_REF (a)) == MEM_REF
> +           && TREE_CODE (DR_REF (b)) == MEM_REF)
> +       || may_be_nonaddressable_p (DR_REF (a))
> +       || may_be_nonaddressable_p (DR_REF (b)))
> +     {
> +       /* Fully exhausted possibilities.  */
> +       DDR_ARE_DEPENDENT (res) = chrec_dont_know;
> +       return res;
> +     }
> +
> +      /* Try evaluating both DRs as dereferences of pointers.  */
> +      if (!a->alt_indices.base_object
> +       && TREE_CODE (DR_REF (a)) != MEM_REF)
> +     {
> +       tree alt_ref = build2 (MEM_REF, TREE_TYPE (DR_REF (a)),
> +                              build1 (ADDR_EXPR, ptr_type_node, DR_REF (a)),
> +                              build_int_cst
> +                                (reference_alias_ptr_type (DR_REF (a)), 0));
> +       dr_analyze_indices (&a->alt_indices, alt_ref,
> +                           loop_preheader_edge (loop_nest[0]),
> +                           loop_containing_stmt (DR_STMT (a)));
> +     }
> +      if (!b->alt_indices.base_object
> +       && TREE_CODE (DR_REF (b)) != MEM_REF)
> +     {
> +       tree alt_ref = build2 (MEM_REF, TREE_TYPE (DR_REF (b)),
> +                              build1 (ADDR_EXPR, ptr_type_node, DR_REF (b)),
> +                              build_int_cst
> +                                (reference_alias_ptr_type (DR_REF (b)), 0));
> +       dr_analyze_indices (&b->alt_indices, alt_ref,
> +                           loop_preheader_edge (loop_nest[0]),
> +                           loop_containing_stmt (DR_STMT (b)));
> +     }
> +      return initialize_data_dependence_relation (res, loop_nest, true);
>     }
> 
>   if (!same_base_p)
> @@ -3381,8 +3407,8 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>       struct subscript *subscript;
> 
>       subscript = XNEW (struct subscript);
> -      SUB_ACCESS_FN (subscript, 0) = DR_ACCESS_FN (a, full_seq.start_a + i);
> -      SUB_ACCESS_FN (subscript, 1) = DR_ACCESS_FN (b, full_seq.start_b + i);
> +      SUB_ACCESS_FN (subscript, 0) = indices_a->access_fns[full_seq.start_a 
> + i];
> +      SUB_ACCESS_FN (subscript, 1) = indices_b->access_fns[full_seq.start_b 
> + i];
>       SUB_CONFLICTS_IN_A (subscript) = conflict_fn_not_known ();
>       SUB_CONFLICTS_IN_B (subscript) = conflict_fn_not_known ();
>       SUB_LAST_CONFLICT (subscript) = chrec_dont_know;
> @@ -3393,6 +3419,40 @@ initialize_data_dependence_relation (struct 
> data_reference *a,
>   return res;
> }
> 
> +/* Initialize a data dependence relation between data accesses A and
> +   B.  NB_LOOPS is the number of loops surrounding the references: the
> +   size of the classic distance/direction vectors.  */
> +
> +struct data_dependence_relation *
> +initialize_data_dependence_relation (struct data_reference *a,
> +                                  struct data_reference *b,
> +                                  vec<loop_p> loop_nest)
> +{
> +  data_dependence_relation *res = XCNEW (struct data_dependence_relation);
> +  DDR_A (res) = a;
> +  DDR_B (res) = b;
> +  DDR_LOOP_NEST (res).create (0);
> +  DDR_SUBSCRIPTS (res).create (0);
> +  DDR_DIR_VECTS (res).create (0);
> +  DDR_DIST_VECTS (res).create (0);
> +
> +  if (a == NULL || b == NULL)
> +    {
> +      DDR_ARE_DEPENDENT (res) = chrec_dont_know;
> +      return res;
> +    }
> +
> +  /* If the data references do not alias, then they are independent.  */
> +  if (!dr_may_alias_p (a, b, loop_nest.exists () ? loop_nest[0] : NULL))
> +    {
> +      DDR_ARE_DEPENDENT (res) = chrec_known;
> +      return res;
> +    }
> +
> +  return initialize_data_dependence_relation (res, loop_nest, false);
> +}
> +
> +
> /* Frees memory used by the conflict function F.  */
> 
> static void
> diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
> index 685f33d85ae..74f579c9f3f 100644
> --- a/gcc/tree-data-ref.h
> +++ b/gcc/tree-data-ref.h
> @@ -166,14 +166,19 @@ struct data_reference
>      and runs to completion.  */
>   bool is_conditional_in_stmt;
> 
> +  /* Alias information for the data reference.  */
> +  struct dr_alias alias;
> +
>   /* Behavior of the memory reference in the innermost loop.  */
>   struct innermost_loop_behavior innermost;
> 
>   /* Subscripts of this data reference.  */
>   struct indices indices;
> 
> -  /* Alias information for the data reference.  */
> -  struct dr_alias alias;
> +  /* Alternate subscripts initialized lazily and used by data-dependence
> +     analysis only when the main indices of two DRs are not comparable.
> +     Keep last to keep vec_info_shared::check_datarefs happy.  */
> +  struct indices alt_indices;
> };
> 
> #define DR_STMT(DR)                (DR)->stmt
> diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
> index 3aa3e2a6783..20daa31187d 100644
> --- a/gcc/tree-vectorizer.c
> +++ b/gcc/tree-vectorizer.c
> @@ -507,7 +507,8 @@ vec_info_shared::check_datarefs ()
>     return;
>   gcc_assert (datarefs.length () == datarefs_copy.length ());
>   for (unsigned i = 0; i < datarefs.length (); ++i)
> -    if (memcmp (&datarefs_copy[i], datarefs[i], sizeof (data_reference)) != 
> 0)
> +    if (memcmp (&datarefs_copy[i], datarefs[i],
> +             offsetof (data_reference, alt_indices)) != 0)
>       gcc_unreachable ();
> }
> 
> </cut>

_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to