diff options
author | Wilco Dijkstra <wdijkstr@arm.com> | 2017-10-04 16:40:44 +0000 |
---|---|---|
committer | Wilco Dijkstra <wilco@gcc.gnu.org> | 2017-10-04 16:40:44 +0000 |
commit | 748d9390b9739dadc48a775c7ea869c42b3f39a9 (patch) | |
tree | 5d6dbb016f15373dd739a59f704264c9bb2024ab /gcc/haifa-sched.c | |
parent | 420db57431715a5aed988c5ba600c913dc779f0e (diff) | |
download | gcc-748d9390b9739dadc48a775c7ea869c42b3f39a9.zip gcc-748d9390b9739dadc48a775c7ea869c42b3f39a9.tar.gz gcc-748d9390b9739dadc48a775c7ea869c42b3f39a9.tar.bz2 |
Revert r253399:
PR rtl-optimization/82396
* haifa-sched.c (autopref_multipass_init): Simplify
initialization.
(autopref_rank_data): Simplify sort order.
* sched-int.h (autopref_multipass_data_): Remove
multi_mem_insn_p, min_offset and max_offset.
From-SVN: r253419
Diffstat (limited to 'gcc/haifa-sched.c')
-rw-r--r-- | gcc/haifa-sched.c | 101 |
1 files changed, 88 insertions, 13 deletions
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 77ba8c5..549e896 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -5568,7 +5568,9 @@ autopref_multipass_init (const rtx_insn *insn, int write) gcc_assert (data->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED); data->base = NULL_RTX; - data->offset = 0; + data->min_offset = 0; + data->max_offset = 0; + data->multi_mem_insn_p = false; /* Set insn entry initialized, but not relevant for auto-prefetcher. */ data->status = AUTOPREF_MULTIPASS_DATA_IRRELEVANT; @@ -5583,9 +5585,10 @@ autopref_multipass_init (const rtx_insn *insn, int write) { int n_elems = XVECLEN (pat, 0); - int i, offset; - rtx base, prev_base = NULL_RTX; - int min_offset = INT_MAX; + int i = 0; + rtx prev_base = NULL_RTX; + int min_offset = 0; + int max_offset = 0; for (i = 0; i < n_elems; i++) { @@ -5593,23 +5596,38 @@ 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. */ - if (i > 0 && REGNO (base) != REGNO (prev_base)) + else if (REGNO (base) != REGNO (prev_base)) return; - prev_base = base; - min_offset = MIN (min_offset, offset); + else + { + min_offset = MIN (min_offset, offset); + max_offset = MAX (max_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 containing the 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. */ gcc_assert (prev_base); data->base = prev_base; - data->offset = min_offset; + data->min_offset = min_offset; + data->max_offset = max_offset; + data->multi_mem_insn_p = true; data->status = AUTOPREF_MULTIPASS_DATA_NORMAL; + return; } @@ -5619,7 +5637,7 @@ autopref_multipass_init (const rtx_insn *insn, int write) return; if (!analyze_set_insn_for_autopref (set, write, &data->base, - &data->offset)) + &data->min_offset)) return; /* This insn is relevant for the auto-prefetcher. @@ -5628,6 +5646,63 @@ 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) @@ -5650,7 +5725,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 = data1->offset - data2->offset; + r = autopref_rank_data (data1, data2); else r = irrel2 - irrel1; } @@ -5678,7 +5753,7 @@ autopref_multipass_dfa_lookahead_guard_1 (const rtx_insn *insn1, return 0; if (rtx_equal_p (data1->base, data2->base) - && data1->offset > data2->offset) + && autopref_rank_data (data1, data2) > 0) { if (sched_verbose >= 2) { |