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;