Mercurial > hg > CbC > CbC_gcc
diff gcc/haifa-sched.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/haifa-sched.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/haifa-sched.c Tue Mar 22 17:18:12 2011 +0900 @@ -128,7 +128,7 @@ #include "system.h" #include "coretypes.h" #include "tm.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "rtl.h" #include "tm_p.h" #include "hard-reg-set.h" @@ -138,7 +138,6 @@ #include "insn-config.h" #include "insn-attr.h" #include "except.h" -#include "toplev.h" #include "recog.h" #include "sched-int.h" #include "target.h" @@ -148,6 +147,7 @@ #include "dbgcnt.h" #include "cfgloop.h" #include "ira.h" +#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */ #ifdef INSN_SCHEDULING @@ -166,25 +166,12 @@ N=3: rtl at abort point, control-flow, regions info. N=5: dependences info. */ -static int sched_verbose_param = 0; int sched_verbose = 0; /* Debugging file. All printouts are sent to dump, which is always set, either to stderr, or to the dump listing file (-dRS). */ FILE *sched_dump = 0; -/* fix_sched_param() is called from toplev.c upon detection - of the -fsched-verbose=N option. */ - -void -fix_sched_param (const char *param, const char *val) -{ - if (!strcmp (param, "verbose")) - sched_verbose_param = atoi (val); - else - warning (0, "fix_sched_param: unknown param: %s", param); -} - /* This is a placeholder for the scheduler parameters common to all schedulers. */ struct common_sched_info_def *common_sched_info; @@ -198,10 +185,6 @@ /* The minimal value of the INSN_TICK of an instruction. */ #define MIN_TICK (-max_insn_queue_index) -/* Issue points are used to distinguish between instructions in max_issue (). - For now, all instructions are equally good. */ -#define ISSUE_POINTS(INSN) 1 - /* List of important notes we must keep around. This is a pointer to the last element in the list. */ rtx note_list; @@ -531,6 +514,7 @@ static void ready_add (struct ready_list *, rtx, bool); static rtx ready_remove_first (struct ready_list *); +static rtx ready_remove_first_dispatch (struct ready_list *ready); static void queue_to_ready (struct ready_list *); static int early_queue_to_ready (state_t, struct ready_list *); @@ -542,8 +526,6 @@ static rtx ready_remove (struct ready_list *, int); static void ready_remove_insn (rtx); -static int choose_ready (struct ready_list *, rtx *); - static void fix_inter_tick (rtx, rtx); static int fix_tick_ready (rtx); static void change_queue_index (rtx, int); @@ -713,7 +695,7 @@ static void initiate_bb_reg_pressure_info (basic_block bb) { - unsigned int i; + unsigned int i ATTRIBUTE_UNUSED; rtx insn; if (current_nr_blocks > 1) @@ -1123,6 +1105,8 @@ struct reg_use_data *use; static int death[N_REG_CLASSES]; + gcc_checking_assert (!DEBUG_INSN_P (insn)); + excess_cost_change = 0; for (i = 0; i < ira_reg_class_cover_size; i++) death[ira_reg_class_cover[i]] = 0; @@ -1499,7 +1483,8 @@ if (sched_pressure_p) { for (i = 0; i < ready->n_ready; i++) - setup_insn_reg_pressure_info (first[i]); + if (!DEBUG_INSN_P (first[i])) + setup_insn_reg_pressure_info (first[i]); } SCHED_SORT (first, ready->n_ready); } @@ -1563,6 +1548,8 @@ struct reg_use_data *use; struct reg_set_data *set; + gcc_checking_assert (!DEBUG_INSN_P (insn)); + for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use) if (dying_use_p (use) && bitmap_bit_p (curr_reg_live, use->regno)) mark_regno_birth_or_death (use->regno, false); @@ -1683,7 +1670,7 @@ fputc ('\n', sched_dump); } - if (sched_pressure_p) + if (sched_pressure_p && !DEBUG_INSN_P (insn)) update_reg_and_insn_max_reg_pressure (insn); /* Scheduling instruction should have all its dependencies resolved and @@ -1792,7 +1779,7 @@ forward dependencies for INSN anymore. Nevertheless they are used in heuristics in rank_for_schedule (), early_queue_to_ready () and in some targets (e.g. rs6000). Thus the earliest place where we *can* - remove dependencies is after targetm.sched.md_finish () call in + remove dependencies is after targetm.sched.finish () call in schedule_block (). But, on the other side, the safest place to remove dependencies is when we are finishing scheduling entire region. As we don't generate [many] dependencies during scheduling itself, we won't @@ -1913,8 +1900,33 @@ beg_head = NEXT_INSN (beg_head); while (beg_head != beg_tail) - if (NOTE_P (beg_head) || BOUNDARY_DEBUG_INSN_P (beg_head)) + if (NOTE_P (beg_head)) beg_head = NEXT_INSN (beg_head); + else if (DEBUG_INSN_P (beg_head)) + { + rtx note, next; + + for (note = NEXT_INSN (beg_head); + note != beg_tail; + note = next) + { + next = NEXT_INSN (note); + if (NOTE_P (note)) + { + if (sched_verbose >= 9) + fprintf (sched_dump, "reorder %i\n", INSN_UID (note)); + + reorder_insns_nobb (note, note, PREV_INSN (beg_head)); + + if (BLOCK_FOR_INSN (note) != beg) + df_insn_change_bb (note, beg); + } + else if (!DEBUG_INSN_P (note)) + break; + } + + break; + } else break; @@ -1926,8 +1938,36 @@ end_head = NEXT_INSN (end_head); while (end_head != end_tail) - if (NOTE_P (end_tail) || BOUNDARY_DEBUG_INSN_P (end_tail)) + if (NOTE_P (end_tail)) end_tail = PREV_INSN (end_tail); + else if (DEBUG_INSN_P (end_tail)) + { + rtx note, prev; + + for (note = PREV_INSN (end_tail); + note != end_head; + note = prev) + { + prev = PREV_INSN (note); + if (NOTE_P (note)) + { + if (sched_verbose >= 9) + fprintf (sched_dump, "reorder %i\n", INSN_UID (note)); + + reorder_insns_nobb (note, note, end_tail); + + if (end_tail == BB_END (end)) + BB_END (end) = note; + + if (BLOCK_FOR_INSN (note) != end) + df_insn_change_bb (note, end); + } + else if (!DEBUG_INSN_P (note)) + break; + } + + break; + } else break; @@ -1941,8 +1981,7 @@ { while (head != NEXT_INSN (tail)) { - if (!NOTE_P (head) && !LABEL_P (head) - && !BOUNDARY_DEBUG_INSN_P (head)) + if (!NOTE_P (head) && !LABEL_P (head)) return 0; head = NEXT_INSN (head); } @@ -1997,13 +2036,9 @@ q_ptr = NEXT_Q (q_ptr); if (dbg_cnt (sched_insn) == false) - { - /* If debug counter is activated do not requeue insn next after - last_scheduled_insn. */ - skip_insn = next_nonnote_insn (last_scheduled_insn); - while (skip_insn && DEBUG_INSN_P (skip_insn)) - skip_insn = next_nonnote_insn (skip_insn); - } + /* If debug counter is activated do not requeue insn next after + last_scheduled_insn. */ + skip_insn = next_nonnote_nondebug_insn (last_scheduled_insn); else skip_insn = NULL_RTX; @@ -2391,6 +2426,12 @@ return false; } +/* Define type for target data used in multipass scheduling. */ +#ifndef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T +# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T int +#endif +typedef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T first_cycle_multipass_data_t; + /* The following structure describe an entry of the stack of choices. */ struct choice_entry { @@ -2402,6 +2443,8 @@ int n; /* State after issuing the insn. */ state_t state; + /* Target-specific data. */ + first_cycle_multipass_data_t target_data; }; /* The following array is used to implement a stack of choices used in @@ -2441,8 +2484,7 @@ insns is insns with the best rank (the first insn in READY). To make this function tries different samples of ready insns. READY is current queue `ready'. Global array READY_TRY reflects what - insns are already issued in this try. MAX_POINTS is the sum of points - of all instructions in READY. The function stops immediately, + insns are already issued in this try. The function stops immediately, if it reached the such a solution, that all instruction can be issued. INDEX will contain index of the best insn in READY. The following function is used only for first cycle multipass scheduling. @@ -2453,9 +2495,9 @@ CLOBBERs, etc must be filtered elsewhere. */ int max_issue (struct ready_list *ready, int privileged_n, state_t state, - int *index) + bool first_cycle_insn_p, int *index) { - int n, i, all, n_ready, best, delay, tries_num, max_points; + int n, i, all, n_ready, best, delay, tries_num; int more_issue; struct choice_entry *top; rtx insn; @@ -2474,25 +2516,8 @@ } /* Init max_points. */ - max_points = 0; more_issue = issue_rate - cycle_issued_insns; - - /* ??? We used to assert here that we never issue more insns than issue_rate. - However, some targets (e.g. MIPS/SB1) claim lower issue rate than can be - achieved to get better performance. Until these targets are fixed to use - scheduler hooks to manipulate insns priority instead, the assert should - be disabled. - - gcc_assert (more_issue >= 0); */ - - for (i = 0; i < n_ready; i++) - if (!ready_try [i]) - { - if (more_issue-- > 0) - max_points += ISSUE_POINTS (ready_element (ready, i)); - else - break; - } + gcc_assert (more_issue >= 0); /* The number of the issued insns in the best solution. */ best = 0; @@ -2503,6 +2528,10 @@ memcpy (top->state, state, dfa_state_size); top->rest = dfa_lookahead; top->n = 0; + if (targetm.sched.first_cycle_multipass_begin) + targetm.sched.first_cycle_multipass_begin (&top->target_data, + ready_try, n_ready, + first_cycle_insn_p); /* Count the number of the insns to search among. */ for (all = i = 0; i < n_ready; i++) @@ -2517,12 +2546,17 @@ if (/* If we've reached a dead end or searched enough of what we have been asked... */ top->rest == 0 - /* Or have nothing else to try. */ - || i >= n_ready) + /* or have nothing else to try... */ + || i >= n_ready + /* or should not issue more. */ + || top->n >= more_issue) { /* ??? (... || i == n_ready). */ gcc_assert (i <= n_ready); + /* We should not issue more than issue_rate instructions. */ + gcc_assert (top->n <= more_issue); + if (top == choice_stack) break; @@ -2545,7 +2579,7 @@ /* This is the index of the insn issued first in this solution. */ *index = choice_stack [1].index; - if (top->n == max_points || best == all) + if (top->n == more_issue || best == all) break; } } @@ -2556,6 +2590,11 @@ /* Backtrack. */ ready_try [i] = 0; + + if (targetm.sched.first_cycle_multipass_backtrack) + targetm.sched.first_cycle_multipass_backtrack (&top->target_data, + ready_try, n_ready); + top--; memcpy (state, top->state, dfa_state_size); } @@ -2578,7 +2617,7 @@ n = top->n; if (memcmp (top->state, state, dfa_state_size) != 0) - n += ISSUE_POINTS (insn); + n++; /* Advance to the next choice_entry. */ top++; @@ -2587,8 +2626,15 @@ top->index = i; top->n = n; memcpy (top->state, state, dfa_state_size); - ready_try [i] = 1; + + if (targetm.sched.first_cycle_multipass_issue) + targetm.sched.first_cycle_multipass_issue (&top->target_data, + ready_try, n_ready, + insn, + &((top - 1) + ->target_data)); + i = -1; } } @@ -2597,6 +2643,11 @@ i++; } + if (targetm.sched.first_cycle_multipass_end) + targetm.sched.first_cycle_multipass_end (best != 0 + ? &choice_stack[1].target_data + : NULL); + /* Restore the original state of the DFA. */ memcpy (state, choice_stack->state, dfa_state_size); @@ -2611,7 +2662,8 @@ 0 if INSN_PTR is set to point to the desirable insn, 1 if choose_ready () should be restarted without advancing the cycle. */ static int -choose_ready (struct ready_list *ready, rtx *insn_ptr) +choose_ready (struct ready_list *ready, bool first_cycle_insn_p, + rtx *insn_ptr) { int lookahead; @@ -2640,7 +2692,11 @@ if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)) || DEBUG_INSN_P (ready_element (ready, 0))) { - *insn_ptr = ready_remove_first (ready); + if (targetm.sched.dispatch (NULL_RTX, IS_DISPATCH_ON)) + *insn_ptr = ready_remove_first_dispatch (ready); + else + *insn_ptr = ready_remove_first (ready); + return 0; } else @@ -2720,14 +2776,12 @@ { insn = ready_element (ready, i); -#ifdef ENABLE_CHECKING /* If this insn is recognizable we should have already recognized it earlier. ??? Not very clear where this is supposed to be done. See dep_cost_1. */ - gcc_assert (INSN_CODE (insn) >= 0 - || recog_memoized (insn) < 0); -#endif + gcc_checking_assert (INSN_CODE (insn) >= 0 + || recog_memoized (insn) < 0); ready_try [i] = (/* INSN_CODE check can be omitted here as it is also done later @@ -2738,7 +2792,7 @@ (insn))); } - if (max_issue (ready, 1, curr_state, &index) == 0) + if (max_issue (ready, 1, curr_state, first_cycle_insn_p, &index) == 0) { *insn_ptr = ready_remove_first (ready); if (sched_verbose >= 4) @@ -2766,7 +2820,8 @@ void schedule_block (basic_block *target_bb) { - int i, first_cycle_insn_p; + int i; + bool first_cycle_insn_p; int can_issue_more; state_t temp_state = NULL; /* It is used for multipass scheduling. */ int sort_p, advance, start_clock_var; @@ -2802,14 +2857,14 @@ /* It is used for first cycle multipass scheduling. */ temp_state = alloca (dfa_state_size); - if (targetm.sched.md_init) - targetm.sched.md_init (sched_dump, sched_verbose, ready.veclen); + if (targetm.sched.init) + targetm.sched.init (sched_dump, sched_verbose, ready.veclen); /* We start inserting insns after PREV_HEAD. */ last_scheduled_insn = prev_head; gcc_assert ((NOTE_P (last_scheduled_insn) - || BOUNDARY_DEBUG_INSN_P (last_scheduled_insn)) + || DEBUG_INSN_P (last_scheduled_insn)) && BLOCK_FOR_INSN (last_scheduled_insn) == *target_bb); /* Initialize INSN_QUEUE. Q_SIZE is the total number of insns in the @@ -2972,7 +3027,7 @@ else can_issue_more = issue_rate; - first_cycle_insn_p = 1; + first_cycle_insn_p = true; cycle_issued_insns = 0; for (;;) { @@ -3015,7 +3070,7 @@ int res; insn = NULL_RTX; - res = choose_ready (&ready, &insn); + res = choose_ready (&ready, first_cycle_insn_p, &insn); if (res < 0) /* Finish cycle. */ @@ -3138,6 +3193,10 @@ last_scheduled_insn); move_insn (insn, last_scheduled_insn, current_sched_info->next_tail); + + if (targetm.sched.dispatch (NULL_RTX, IS_DISPATCH_ON)) + targetm.sched.dispatch_do (insn, ADD_TO_DISPATCH_WINDOW); + reemit_notes (insn); last_scheduled_insn = insn; @@ -3164,7 +3223,7 @@ if (advance != 0) break; - first_cycle_insn_p = 0; + first_cycle_insn_p = false; /* Sort the ready list based on priority. This must be redone here, as schedule_insn may have readied additional @@ -3277,9 +3336,9 @@ fix_inter_tick (NEXT_INSN (prev_head), last_scheduled_insn); } - if (targetm.sched.md_finish) + if (targetm.sched.finish) { - targetm.sched.md_finish (sched_dump, sched_verbose); + targetm.sched.finish (sched_dump, sched_verbose); /* Target might have added some instructions to the scheduled block in its md_finish () hook. These new insns don't have any data initialized and to identify them we extend h_i_d so that they'll @@ -3312,7 +3371,7 @@ current_sched_info->sched_max_insns_priority; rtx prev_head; - if (head == tail && (! INSN_P (head) || BOUNDARY_DEBUG_INSN_P (head))) + if (head == tail && ! INSN_P (head)) gcc_unreachable (); n_insn = 0; @@ -3362,8 +3421,12 @@ flag_schedule_speculative_load = 0; #endif + if (targetm.sched.dispatch (NULL_RTX, IS_DISPATCH_ON)) + targetm.sched.dispatch_do (NULL_RTX, DISPATCH_INIT); + sched_pressure_p = (flag_sched_pressure && ! reload_completed && common_sched_info->sched_pass_id == SCHED_RGN_PASS); + if (sched_pressure_p) ira_setup_eliminable_regset (); @@ -3438,9 +3501,8 @@ regstat_compute_calls_crossed (); - if (targetm.sched.md_init_global) - targetm.sched.md_init_global (sched_dump, sched_verbose, - get_max_uid () + 1); + if (targetm.sched.init_global) + targetm.sched.init_global (sched_dump, sched_verbose, get_max_uid () + 1); if (sched_pressure_p) { @@ -3565,8 +3627,8 @@ } free (curr_state); - if (targetm.sched.md_finish_global) - targetm.sched.md_finish_global (sched_dump, sched_verbose); + if (targetm.sched.finish_global) + targetm.sched.finish_global (sched_dump, sched_verbose); end_alias_analysis (); @@ -3612,9 +3674,8 @@ gcc_assert (tick >= MIN_TICK); /* Fix INSN_TICK of instruction from just scheduled block. */ - if (!bitmap_bit_p (&processed, INSN_LUID (head))) + if (bitmap_set_bit (&processed, INSN_LUID (head))) { - bitmap_set_bit (&processed, INSN_LUID (head)); tick -= next_clock; if (tick < MIN_TICK) @@ -3634,9 +3695,8 @@ /* If NEXT has its INSN_TICK calculated, fix it. If not - it will be properly calculated from scratch later in fix_tick_ready. */ - && !bitmap_bit_p (&processed, INSN_LUID (next))) + && bitmap_set_bit (&processed, INSN_LUID (next))) { - bitmap_set_bit (&processed, INSN_LUID (next)); tick -= next_clock; if (tick < MIN_TICK) @@ -3843,7 +3903,7 @@ { int tick, delay; - if (!sd_lists_empty_p (next, SD_LIST_RES_BACK)) + if (!DEBUG_INSN_P (next) && !sd_lists_empty_p (next, SD_LIST_RES_BACK)) { int full_p; sd_iterator_def sd_it; @@ -3959,7 +4019,13 @@ new_sched_ready_n_insns + 1); for (; i <= new_sched_ready_n_insns; i++) - choice_stack[i].state = xmalloc (dfa_state_size); + { + choice_stack[i].state = xmalloc (dfa_state_size); + + if (targetm.sched.first_cycle_multipass_init) + targetm.sched.first_cycle_multipass_init (&(choice_stack[i] + .target_data)); + } sched_ready_n_insns = new_sched_ready_n_insns; } @@ -3978,7 +4044,13 @@ ready_try = NULL; for (i = 0; i <= sched_ready_n_insns; i++) - free (choice_stack [i].state); + { + if (targetm.sched.first_cycle_multipass_fini) + targetm.sched.first_cycle_multipass_fini (&(choice_stack[i] + .target_data)); + + free (choice_stack [i].state); + } free (choice_stack); choice_stack = NULL; @@ -4235,10 +4307,9 @@ /* Helper function. Find fallthru edge from PRED. */ edge -find_fallthru_edge (basic_block pred) +find_fallthru_edge_from (basic_block pred) { edge e; - edge_iterator ei; basic_block succ; succ = pred->next_bb; @@ -4246,21 +4317,23 @@ if (EDGE_COUNT (pred->succs) <= EDGE_COUNT (succ->preds)) { - FOR_EACH_EDGE (e, ei, pred->succs) - if (e->flags & EDGE_FALLTHRU) - { - gcc_assert (e->dest == succ); - return e; - } + e = find_fallthru_edge (pred->succs); + + if (e) + { + gcc_assert (e->dest == succ); + return e; + } } else { - FOR_EACH_EDGE (e, ei, succ->preds) - if (e->flags & EDGE_FALLTHRU) - { - gcc_assert (e->src == pred); - return e; - } + e = find_fallthru_edge (succ->preds); + + if (e) + { + gcc_assert (e->src == pred); + return e; + } } return NULL; @@ -4302,7 +4375,7 @@ edge e; last = EXIT_BLOCK_PTR->prev_bb; - e = find_fallthru_edge (last); + e = find_fallthru_edge_from (last); if (e) { @@ -4446,6 +4519,8 @@ edge_flags = 0; make_single_succ_edge (rec, second_bb, edge_flags); + if (dom_info_available_p (CDI_DOMINATORS)) + set_immediate_dominator (CDI_DOMINATORS, rec, first_bb); } /* This function creates recovery code for INSN. If MUTATE_P is nonzero, @@ -4755,11 +4830,8 @@ { sd_delete_dep (sd_it); - if (!bitmap_bit_p (&in_ready, INSN_LUID (consumer))) - { - ready_list = alloc_INSN_LIST (consumer, ready_list); - bitmap_set_bit (&in_ready, INSN_LUID (consumer)); - } + if (bitmap_set_bit (&in_ready, INSN_LUID (consumer))) + ready_list = alloc_INSN_LIST (consumer, ready_list); } else { @@ -5097,7 +5169,7 @@ int i; rtx insn; - for (i = 0; VEC_iterate (rtx, roots, i, insn); i++) + FOR_EACH_VEC_ELT (rtx, roots, i, insn) priority (insn); } @@ -5325,7 +5397,7 @@ unsigned i; basic_block x; - for (i = 0; VEC_iterate (basic_block, bbs, i, x); i++) + FOR_EACH_VEC_ELT (basic_block, bbs, i, x) init_bb (x); } @@ -5340,7 +5412,7 @@ unsigned i; basic_block x; - for (i = 0; VEC_iterate (basic_block, bbs, i, x); i++) + FOR_EACH_VEC_ELT (basic_block, bbs, i, x) init_insns_in_bb (x); } @@ -5352,7 +5424,7 @@ unsigned i; rtx x; - for (i = 0; VEC_iterate (rtx, insns, i, x); i++) + FOR_EACH_VEC_ELT (rtx, insns, i, x) init_insn (x); } @@ -5482,7 +5554,7 @@ haifa_insn_data_t data; struct reg_use_data *use, *next; - for (i = 0; VEC_iterate (haifa_insn_data_def, h_i_d, i, data); i++) + FOR_EACH_VEC_ELT (haifa_insn_data_def, h_i_d, i, data) { if (data->reg_pressure != NULL) free (data->reg_pressure); @@ -5561,4 +5633,73 @@ return insn; } +/* This function returns a candidate satisfying dispatch constraints from + the ready list. */ + +static rtx +ready_remove_first_dispatch (struct ready_list *ready) +{ + int i; + rtx insn = ready_element (ready, 0); + + if (ready->n_ready == 1 + || INSN_CODE (insn) < 0 + || !INSN_P (insn) + || !active_insn_p (insn) + || targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW)) + return ready_remove_first (ready); + + for (i = 1; i < ready->n_ready; i++) + { + insn = ready_element (ready, i); + + if (INSN_CODE (insn) < 0 + || !INSN_P (insn) + || !active_insn_p (insn)) + continue; + + if (targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW)) + { + /* Return ith element of ready. */ + insn = ready_remove (ready, i); + return insn; + } + } + + if (targetm.sched.dispatch (NULL_RTX, DISPATCH_VIOLATION)) + return ready_remove_first (ready); + + for (i = 1; i < ready->n_ready; i++) + { + insn = ready_element (ready, i); + + if (INSN_CODE (insn) < 0 + || !INSN_P (insn) + || !active_insn_p (insn)) + continue; + + /* Return i-th element of ready. */ + if (targetm.sched.dispatch (insn, IS_CMP)) + return ready_remove (ready, i); + } + + return ready_remove_first (ready); +} + +/* Get number of ready insn in the ready list. */ + +int +number_in_ready (void) +{ + return ready.n_ready; +} + +/* Get number of ready's in the ready list. */ + +rtx +get_ready_element (int i) +{ + return ready_element (&ready, i); +} + #endif /* INSN_SCHEDULING */