On 3 October 2017 at 18:34, Wilco Dijkstra <wilco.dijks...@arm.com> wrote:
> r253236 broke AArch64 bootstrap. Earlier revision r253071 changed scheduling
> behaviour on AArch64 as autopref scheduling no longer checks the base.
>
> This patch fixes the bootstrap failure and cleans up autopref scheduling.
> The code is greatly simplified.  Sort accesses on the offset first, and
> only if the offsets are the same fall back to other comparisons in
> rank_for_schedule.  This doesn't at all restore the original behaviour
> since we no longer compare the base address, but it now defines a total
> sorting order.  More work will be required to improve the sorting so
> that only loads/stores with the same base are affected.
>
> AArch64 bootstrap completes. I'd like to commit this ASAP as the AArch64
> bootstrap has been broken for days now.
>
> ChangeLog:
> 2017-10-03  Wilco Dijkstra  <wdijk...@arm.com>
>
>         PR rtl-optimization/82396
>         * gcc/haifa-sched.c (autopref_multipass_init): Simplify
>         initialization.
>         (autopref_rank_data): Simplify sort order.
>         * gcc/sched-int.h (autopref_multipass_data_): Remove
>         multi_mem_insn_p, min_offset and max_offset.
> --
>

Hi,

FWIW, I confirm that this patch fixes the build failure I reported at:
https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01980.html

Thanks,

Christophe

> diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
> index 
> 549e8961411ecd0a04ac3b24ba78b5d53e63258a..77ba8c5292a0801bbbcb35ed61ab3040015f6677
>  100644
> --- a/gcc/haifa-sched.c
> +++ b/gcc/haifa-sched.c
> @@ -5568,9 +5568,7 @@ autopref_multipass_init (const rtx_insn *insn, int 
> write)
>
>    gcc_assert (data->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED);
>    data->base = NULL_RTX;
> -  data->min_offset = 0;
> -  data->max_offset = 0;
> -  data->multi_mem_insn_p = false;
> +  data->offset = 0;
>    /* Set insn entry initialized, but not relevant for auto-prefetcher.  */
>    data->status = AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
>
> @@ -5585,10 +5583,9 @@ autopref_multipass_init (const rtx_insn *insn, int 
> write)
>      {
>        int n_elems = XVECLEN (pat, 0);
>
> -      int i = 0;
> -      rtx prev_base = NULL_RTX;
> -      int min_offset = 0;
> -      int max_offset = 0;
> +      int i, offset;
> +      rtx base, prev_base = NULL_RTX;
> +      int min_offset = INT_MAX;
>
>        for (i = 0; i < n_elems; i++)
>         {
> @@ -5596,38 +5593,23 @@ autopref_multipass_init (const rtx_insn *insn, int 
> write)
>           if (GET_CODE (set) != SET)
>             return;
>
> -         rtx base = NULL_RTX;
> -         int offset = 0;
>           if (!analyze_set_insn_for_autopref (set, write, &base, &offset))
>             return;
>
> -         if (i == 0)
> -           {
> -             prev_base = base;
> -             min_offset = offset;
> -             max_offset = offset;
> -           }
>           /* Ensure that all memory operations in the PARALLEL use the same
>              base register.  */
> -         else if (REGNO (base) != REGNO (prev_base))
> +         if (i > 0 && REGNO (base) != REGNO (prev_base))
>             return;
> -         else
> -           {
> -             min_offset = MIN (min_offset, offset);
> -             max_offset = MAX (max_offset, offset);
> -           }
> +         prev_base = base;
> +         min_offset = MIN (min_offset, offset);
>         }
>
> -      /* If we reached here then we have a valid PARALLEL of multiple memory
> -        ops with prev_base as the base and min_offset and max_offset
> -        containing the offsets range.  */
> +      /* If we reached here then we have a valid PARALLEL of multiple memory 
> ops
> +        with prev_base as the base and min_offset containing the offset.  */
>        gcc_assert (prev_base);
>        data->base = prev_base;
> -      data->min_offset = min_offset;
> -      data->max_offset = max_offset;
> -      data->multi_mem_insn_p = true;
> +      data->offset = min_offset;
>        data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
> -
>        return;
>      }
>
> @@ -5637,7 +5619,7 @@ autopref_multipass_init (const rtx_insn *insn, int 
> write)
>      return;
>
>    if (!analyze_set_insn_for_autopref (set, write, &data->base,
> -                                      &data->min_offset))
> +                                      &data->offset))
>      return;
>
>    /* This insn is relevant for the auto-prefetcher.
> @@ -5646,63 +5628,6 @@ autopref_multipass_init (const rtx_insn *insn, int 
> write)
>    data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
>  }
>
> -
> -/* Helper for autopref_rank_for_schedule.  Given the data of two
> -   insns relevant to the auto-prefetcher modelling code DATA1 and DATA2
> -   return their comparison result.  Return 0 if there is no sensible
> -   ranking order for the two insns.  */
> -
> -static int
> -autopref_rank_data (autopref_multipass_data_t data1,
> -                    autopref_multipass_data_t data2)
> -{
> -  /* Simple case when both insns are simple single memory ops.  */
> -  if (!data1->multi_mem_insn_p && !data2->multi_mem_insn_p)
> -    return data1->min_offset - data2->min_offset;
> -
> -  /* Two load/store multiple insns.  Return 0 if the offset ranges
> -     overlap and the difference between the minimum offsets otherwise.  */
> -  else if (data1->multi_mem_insn_p && data2->multi_mem_insn_p)
> -    {
> -      int min1 = data1->min_offset;
> -      int max1 = data1->max_offset;
> -      int min2 = data2->min_offset;
> -      int max2 = data2->max_offset;
> -
> -      if (max1 < min2 || min1 > max2)
> -       return min1 - min2;
> -      else
> -       return 0;
> -    }
> -
> -  /* The other two cases is a pair of a load/store multiple and
> -     a simple memory op.  Return 0 if the single op's offset is within the
> -     range of the multi-op insn and the difference between the single offset
> -     and the minimum offset of the multi-set insn otherwise.  */
> -  else if (data1->multi_mem_insn_p && !data2->multi_mem_insn_p)
> -    {
> -      int max1 = data1->max_offset;
> -      int min1 = data1->min_offset;
> -
> -      if (data2->min_offset >= min1
> -         && data2->min_offset <= max1)
> -       return 0;
> -      else
> -       return min1 - data2->min_offset;
> -    }
> -  else
> -    {
> -      int max2 = data2->max_offset;
> -      int min2 = data2->min_offset;
> -
> -      if (data1->min_offset >= min2
> -         && data1->min_offset <= max2)
> -       return 0;
> -      else
> -       return data1->min_offset - min2;
> -    }
> -}
> -
>  /* Helper function for rank_for_schedule sorting.  */
>  static int
>  autopref_rank_for_schedule (const rtx_insn *insn1, const rtx_insn *insn2)
> @@ -5725,7 +5650,7 @@ autopref_rank_for_schedule (const rtx_insn *insn1, 
> const rtx_insn *insn2)
>        int irrel2 = data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
>
>        if (!irrel1 && !irrel2)
> -       r = autopref_rank_data (data1, data2);
> +       r = data1->offset - data2->offset;
>        else
>         r = irrel2 - irrel1;
>      }
> @@ -5753,7 +5678,7 @@ autopref_multipass_dfa_lookahead_guard_1 (const 
> rtx_insn *insn1,
>      return 0;
>
>    if (rtx_equal_p (data1->base, data2->base)
> -      && autopref_rank_data (data1, data2) > 0)
> +      && data1->offset > data2->offset)
>      {
>        if (sched_verbose >= 2)
>         {
> diff --git a/gcc/sched-int.h b/gcc/sched-int.h
> index 
> 2af8f9fc32c0085c18511bbc83ad52c6ec31f671..6832589e3d0ad9ed5937ab3e81f3573c2560fe67
>  100644
> --- a/gcc/sched-int.h
> +++ b/gcc/sched-int.h
> @@ -819,15 +819,8 @@ struct autopref_multipass_data_
>    /* Base part of memory address.  */
>    rtx base;
>
> -  /* Memory offsets from the base.  For single simple sets
> -     only min_offset is valid.  For multi-set insns min_offset
> -     and max_offset record the minimum and maximum offsets from the same
> -     base among the sets inside the PARALLEL.  */
> -  int min_offset;
> -  int max_offset;
> -
> -  /* True if this is a load/store-multiple instruction.  */
> -  bool multi_mem_insn_p;
> +  /* Memory offsets from the base.  */
> +  int offset;
>
>    /* Entry status.  */
>    enum autopref_multipass_data_status status;

Reply via email to