diff options
Diffstat (limited to 'gcc/haifa-sched.c')
-rw-r--r-- | gcc/haifa-sched.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index ef4f4f709ca..6368ec6b666 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -1655,9 +1655,22 @@ queue_to_ready (struct ready_list *ready) fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ", (*current_sched_info->print_insn) (insn, 0)); - ready_add (ready, insn, false); - if (sched_verbose >= 2) - fprintf (sched_dump, "moving to ready without stalls\n"); + /* If the ready list is full, delay the insn for 1 cycle. + See the comment in schedule_block for the rationale. */ + if (!reload_completed + && ready->n_ready > MAX_SCHED_READY_INSNS + && !SCHED_GROUP_P (insn)) + { + if (sched_verbose >= 2) + fprintf (sched_dump, "requeued because ready full\n"); + queue_insn (insn, 1); + } + else + { + ready_add (ready, insn, false); + if (sched_verbose >= 2) + fprintf (sched_dump, "moving to ready without stalls\n"); + } } free_INSN_LIST_list (&insn_queue[q_ptr]); @@ -2292,6 +2305,31 @@ schedule_block (basic_block *target_bb, int rgn_n_insns1) in try_ready () (which is called through init_ready_list ()). */ (*current_sched_info->init_ready_list) (); + /* The algorithm is O(n^2) in the number of ready insns at any given + time in the worst case. Before reload we are more likely to have + big lists so truncate them to a reasonable size. */ + if (!reload_completed && ready.n_ready > MAX_SCHED_READY_INSNS) + { + ready_sort (&ready); + + /* Find first free-standing insn past MAX_SCHED_READY_INSNS. */ + for (i = MAX_SCHED_READY_INSNS; i < ready.n_ready; i++) + if (!SCHED_GROUP_P (ready_element (&ready, i))) + break; + + if (sched_verbose >= 2) + { + fprintf (sched_dump, + ";;\t\tReady list on entry: %d insns\n", ready.n_ready); + fprintf (sched_dump, + ";;\t\t before reload => truncated to %d insns\n", i); + } + + /* Delay all insns past it for 1 cycle. */ + while (i < ready.n_ready) + queue_insn (ready_remove (&ready, i), 1); + } + /* Now we can restore basic block notes and maintain precise cfg. */ restore_bb_notes (*target_bb); |