diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 174e5b42fdc..8c57f97564d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-02-19 Maxim Kuvyrkov + + * haifa-sched.c (enum rfs_decision, rfs_str): Remove RFS_DEBUG. + (rank_for_schedule_debug): Update. + (ready_sort): Make static. Move sorting logic to ... + (ready_sort_debug, ready_sort_real): New static functions. + (schedule_block): Sort both debug insns and real insns in preparation + for ready list trimming. Improve debug output. + * sched-int.h (ready_sort): Remove global declaration. + 2015-02-18 Trevor Saunders * ipa-icf.c (sem_function::equals_private): Adjust. diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 7aeedc339d5..ad2450b7da1 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -2573,7 +2573,7 @@ model_set_excess_costs (rtx_insn **insns, int count) /* Enum of rank_for_schedule heuristic decisions. */ enum rfs_decision { - RFS_DEBUG, RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2, + RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2, RFS_SCHED_GROUP, RFS_PRESSURE_DELAY, RFS_PRESSURE_TICK, RFS_FEEDS_BACKTRACK_INSN, RFS_PRIORITY, RFS_SPECULATION, RFS_SCHED_RANK, RFS_LAST_INSN, RFS_PRESSURE_INDEX, @@ -2581,7 +2581,7 @@ enum rfs_decision { /* Corresponding strings for print outs. */ static const char *rfs_str[RFS_N] = { - "RFS_DEBUG", "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2", + "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2", "RFS_SCHED_GROUP", "RFS_PRESSURE_DELAY", "RFS_PRESSURE_TICK", "RFS_FEEDS_BACKTRACK_INSN", "RFS_PRIORITY", "RFS_SPECULATION", "RFS_SCHED_RANK", "RFS_LAST_INSN", "RFS_PRESSURE_INDEX", @@ -2617,12 +2617,11 @@ rank_for_schedule_debug (const void *x, const void *y) /* Schedule debug insns as early as possible. */ if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2)) - return rfs_result (RFS_DEBUG, -1, tmp, tmp2); + return -1; else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2)) - return rfs_result (RFS_DEBUG, 1, tmp, tmp2); + return 1; else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2)) - return rfs_result (RFS_DEBUG, INSN_LUID (tmp) - INSN_LUID (tmp2), - tmp, tmp2); + return INSN_LUID (tmp) - INSN_LUID (tmp2); else return INSN_RFS_DEBUG_ORIG_ORDER (tmp2) - INSN_RFS_DEBUG_ORIG_ORDER (tmp); } @@ -3085,48 +3084,45 @@ print_rank_for_schedule_stats (const char *prefix, } } -/* Sort the ready list READY by ascending priority, using the SCHED_SORT - macro. */ - -void -ready_sort (struct ready_list *ready) +/* Separate DEBUG_INSNS from normal insns. DEBUG_INSNs go to the end + of array. */ +static void +ready_sort_debug (struct ready_list *ready) { int i; rtx_insn **first = ready_lastpos (ready); - int n_ready_non_debug = ready->n_ready; for (i = 0; i < ready->n_ready; ++i) - { - if (DEBUG_INSN_P (first[i])) - --n_ready_non_debug; - else - { - INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i; + if (!DEBUG_INSN_P (first[i])) + INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i; - if (sched_pressure == SCHED_PRESSURE_WEIGHTED) - setup_insn_reg_pressure_info (first[i]); - } - } + qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug); +} - if (sched_pressure == SCHED_PRESSURE_MODEL - && model_curr_point < model_num_insns) - model_set_excess_costs (first, ready->n_ready); +/* Sort non-debug insns in the ready list READY by ascending priority. + Assumes that all debug insns are separated from the real insns. */ +static void +ready_sort_real (struct ready_list *ready) +{ + int i; + rtx_insn **first = ready_lastpos (ready); + int n_ready_real = ready->n_ready - ready->n_debug; + + if (sched_pressure == SCHED_PRESSURE_WEIGHTED) + for (i = 0; i < n_ready_real; ++i) + setup_insn_reg_pressure_info (first[i]); + else if (sched_pressure == SCHED_PRESSURE_MODEL + && model_curr_point < model_num_insns) + model_set_excess_costs (first, n_ready_real); rank_for_schedule_stats_t stats1; if (sched_verbose >= 4) stats1 = rank_for_schedule_stats; - if (n_ready_non_debug < ready->n_ready) - /* Separate DEBUG_INSNS from normal insns. DEBUG_INSNs go to the end - of array. */ - qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug); - else - { - if (n_ready_non_debug == 2) - swap_sort (first, n_ready_non_debug); - else if (n_ready_non_debug > 2) - qsort (first, n_ready_non_debug, sizeof (rtx), rank_for_schedule); - } + if (n_ready_real == 2) + swap_sort (first, n_ready_real); + else if (n_ready_real > 2) + qsort (first, n_ready_real, sizeof (rtx), rank_for_schedule); if (sched_verbose >= 4) { @@ -3135,6 +3131,16 @@ ready_sort (struct ready_list *ready) } } +/* Sort the ready list READY by ascending priority. */ +static void +ready_sort (struct ready_list *ready) +{ + if (ready->n_debug > 0) + ready_sort_debug (ready); + else + ready_sort_real (ready); +} + /* PREV is an insn that is ready to execute. Adjust its priority if that will help shorten or lengthen register lifetimes as appropriate. Also provide a hook for the target to tweak itself. */ @@ -6495,7 +6501,8 @@ schedule_block (basic_block *target_bb, state_t init_state) if (!reload_completed && ready.n_ready - ready.n_debug > MAX_SCHED_READY_INSNS) { - ready_sort (&ready); + ready_sort_debug (&ready); + ready_sort_real (&ready); /* Find first free-standing insn past MAX_SCHED_READY_INSNS. If there are debug insns, we know they're first. */ @@ -6506,7 +6513,8 @@ schedule_block (basic_block *target_bb, state_t init_state) if (sched_verbose >= 2) { fprintf (sched_dump, - ";;\t\tReady list on entry: %d insns\n", ready.n_ready); + ";;\t\tReady list on entry: %d insns: ", ready.n_ready); + debug_ready_list (&ready); fprintf (sched_dump, ";;\t\t before reload => truncated to %d insns\n", i); } diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 1b9f8d1d74f..1cb0e2d344d 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -1400,7 +1400,6 @@ extern int dfa_lookahead; extern int autopref_multipass_dfa_lookahead_guard (rtx_insn *, int); -extern void ready_sort (struct ready_list *); extern rtx_insn *ready_element (struct ready_list *, int); extern rtx_insn **ready_lastpos (struct ready_list *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 32544ea2953..9c3570c1cab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-02-19 Maxim Kuvyrkov + + * gcc.dg/pr64935-1.c, gcc.dg/pr64935-2.c: New tests. + 2015-02-19 Maxim Kuvyrkov * testsuite/lib/target-supports.exp (check_compile): Save/restore diff --git a/gcc/testsuite/gcc.dg/pr64935-1.c b/gcc/testsuite/gcc.dg/pr64935-1.c new file mode 100644 index 00000000000..0fc6b58caed --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64935-1.c @@ -0,0 +1,54 @@ +/* PR rtl-optimization/64935 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89 -Wno-shift-count-overflow -O2 -fcompare-debug" } */ + +int a[] = {}, b[] = {}, c[] = {}, d[] = {}, e[] = {}, f[] = {}, h[] = {}; +int g[] = { 0 }; +int i, l, s, w, x, y, z, t2, t3, t5; +unsigned long j, m, o, t4; +long k, n, p, q, r, t, u, v, t1; +fn1 () +{ + int t6; + for (; i; i++) + { + t5 = a[q] ^ b[p >> 1] ^ c[o >> 1 & 1] ^ d[n >> 1 & 1] ^ e[m >> 1 & 1] + ^ f[l >> 1 & 1] ^ g[0] ^ h[j & 1]; + t4 = a[j] ^ b[q >> 1] ^ c[p] ^ d[o] ^ e[n] ^ f[m] ^ g[l >> 8] ^ h[k]; + t3 = a[k >> 1] ^ b[j & 5] ^ d[p >> 32] ^ e[o >> 4] ^ f[n >> 6] + ^ g[m >> 8] ^ h[l]; + t2 = a[l >> 6] ^ b[k & 1] ^ c[j >> 1] ^ d[q >> 32] ^ e[p >> 4] + ^ f[o >> 6] ^ g[n >> 8] ^ h[m & 1]; + t1 = a[m >> 6] ^ b[l & 1] ^ c[k & 15] ^ d[j >> 2] ^ e[q >> 4] ^ f[p >> 6] + ^ g[o >> 8] ^ h[n & 1]; + z = a[n >> 56] ^ b[m & 15] ^ c[l & 15] ^ d[k >> 2] ^ e[j >> 4] + ^ f[q >> 6] ^ g[p >> 8] ^ h[o & 1]; + y = a[o >> 56] ^ b[n & 15] ^ c[m >> 40] ^ d[l >> 2] ^ e[k >> 4] + ^ f[j >> 6] ^ g[q >> 8] ^ h[p & 1]; + x = a[p >> 56] ^ b[o & 15] ^ c[n >> 40] ^ d[m >> 2] ^ e[l >> 4] + ^ f[k >> 6] ^ g[j >> 8] ^ h[q & 1]; + q = j = t4; + k = t3; + l = t2; + m = t1; + n = z; + o = y; + p = a[t6] ^ b[0] ^ c[w] ^ d[v] ^ e[u] ^ f[t] ^ g[s] ^ h[r]; + t4 = a[r >> 1] ^ b[t6 & 1] ^ d[w >> 1] ^ e[v >> 1] ^ f[u >> 1] + ^ g[t >> 1] ^ h[s]; + t3 = a[s >> 6] ^ b[r & 1] ^ c[t6 & 5] ^ d[0] ^ e[w >> 4] ^ f[v >> 6] + ^ g[u >> 8] ^ h[t & 1]; + t2 = a[t >> 6] ^ b[s] ^ c[r & 15] ^ d[t6 >> 1] ^ e[0] ^ f[w >> 6] + ^ g[v >> 8] ^ h[u & 1]; + t1 = a[u >> 6] ^ b[t & 15] ^ c[s & 5] ^ d[r >> 32] ^ e[t6 >> 4] + ^ g[w >> 8] ^ h[v & 1]; + z = a[v >> 56] ^ b[u >> 48 & 1] ^ c[t >> 40 & 1] ^ d[s] ^ e[r >> 1 & 1] + ^ f[t6 >> 1 & 1] ^ g[0] ^ h[w & 1] ^ z; + t6 = t5; + r = t4; + s = 0; + t = u = t1; + v = z; + w = y; + } +} diff --git a/gcc/testsuite/gcc.dg/pr64935-2.c b/gcc/testsuite/gcc.dg/pr64935-2.c new file mode 100644 index 00000000000..6921a21d76a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64935-2.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/64935 */ +/* { dg-do compile } */ +/* { dg-options "-O -fschedule-insns --param=max-sched-ready-insns=0 -fcompare-debug" } */ + +void +foo (int *data, unsigned len, const int qlp_coeff[], + unsigned order, int lp, int residual[], int i) +{ + int sum; + sum = 0; + sum += qlp_coeff[1] * data[i - 2]; + sum += qlp_coeff[0] * data[i - 1]; + residual[i] = data[i] - (sum >> lp); +}