OSDN Git Service

* sched-ebb.c (schedule_ebb): No longer static. Remove declaration.
[pf3gnuchains/gcc-fork.git] / gcc / sched-ebb.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4    Free Software Foundation, Inc.
5    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
6    and currently maintained by, Jim Wilson (wilson@cygnus.com)
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23 \f
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "diagnostic-core.h"
29 #include "rtl.h"
30 #include "tm_p.h"
31 #include "hard-reg-set.h"
32 #include "regs.h"
33 #include "function.h"
34 #include "flags.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "except.h"
38 #include "recog.h"
39 #include "cfglayout.h"
40 #include "params.h"
41 #include "sched-int.h"
42 #include "target.h"
43 #include "output.h"
44
45 \f
46 #ifdef INSN_SCHEDULING
47
48 /* The number of insns to be scheduled in total.  */
49 static int rgn_n_insns;
50
51 /* The number of insns scheduled so far.  */
52 static int sched_rgn_n_insns;
53
54 /* Set of blocks, that already have their dependencies calculated.  */
55 static bitmap_head dont_calc_deps;
56
57 /* Last basic block in current ebb.  */
58 static basic_block last_bb;
59
60 /* Implementations of the sched_info functions for region scheduling.  */
61 static void init_ready_list (void);
62 static void begin_schedule_ready (rtx);
63 static int schedule_more_p (void);
64 static const char *ebb_print_insn (const_rtx, int);
65 static int rank (rtx, rtx);
66 static int ebb_contributes_to_priority (rtx, rtx);
67 static basic_block earliest_block_with_similiar_load (basic_block, rtx);
68 static void add_deps_for_risky_insns (rtx, rtx);
69 static void debug_ebb_dependencies (rtx, rtx);
70
71 static void ebb_add_remove_insn (rtx, int);
72 static void ebb_add_block (basic_block, basic_block);
73 static basic_block advance_target_bb (basic_block, rtx);
74 static void ebb_fix_recovery_cfg (int, int, int);
75
76 /* Allocate memory and store the state of the frontend.  Return the allocated
77    memory.  */
78 static void *
79 save_ebb_state (void)
80 {
81   int *p = XNEW (int);
82   *p = sched_rgn_n_insns;
83   return p;
84 }
85
86 /* Restore the state of the frontend from P_, then free it.  */
87 static void
88 restore_ebb_state (void *p_)
89 {
90   int *p = (int *)p_;
91   sched_rgn_n_insns = *p;
92   free (p_);
93 }
94
95 /* Return nonzero if there are more insns that should be scheduled.  */
96
97 static int
98 schedule_more_p (void)
99 {
100   return sched_rgn_n_insns < rgn_n_insns;
101 }
102
103 /* Print dependency information about ebb between HEAD and TAIL.  */
104 static void
105 debug_ebb_dependencies (rtx head, rtx tail)
106 {
107   fprintf (sched_dump,
108            ";;   --------------- forward dependences: ------------ \n");
109
110   fprintf (sched_dump, "\n;;   --- EBB Dependences --- from bb%d to bb%d \n",
111            BLOCK_NUM (head), BLOCK_NUM (tail));
112
113   debug_dependencies (head, tail);
114 }
115
116 /* Add all insns that are initially ready to the ready list READY.  Called
117    once before scheduling a set of insns.  */
118
119 static void
120 init_ready_list (void)
121 {
122   int n = 0;
123   rtx prev_head = current_sched_info->prev_head;
124   rtx next_tail = current_sched_info->next_tail;
125   rtx insn;
126
127   sched_rgn_n_insns = 0;
128
129   /* Print debugging information.  */
130   if (sched_verbose >= 5)
131     debug_ebb_dependencies (NEXT_INSN (prev_head), PREV_INSN (next_tail));
132
133   /* Initialize ready list with all 'ready' insns in target block.
134      Count number of insns in the target block being scheduled.  */
135   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
136     {
137       try_ready (insn);
138       n++;
139     }
140
141   gcc_assert (n == rgn_n_insns);
142 }
143
144 /* INSN is being scheduled after LAST.  Update counters.  */
145 static void
146 begin_schedule_ready (rtx insn ATTRIBUTE_UNUSED)
147 {
148   sched_rgn_n_insns++;
149 }
150
151 /* INSN is being moved to its place in the schedule, after LAST.  */
152 static void
153 begin_move_insn (rtx insn, rtx last)
154 {
155   if (BLOCK_FOR_INSN (insn) == last_bb
156       /* INSN is a jump in the last block, ...  */
157       && control_flow_insn_p (insn)
158       /* that is going to be moved over some instructions.  */
159       && last != PREV_INSN (insn))
160     {
161       edge e;
162       basic_block bb;
163
164       /* An obscure special case, where we do have partially dead
165          instruction scheduled after last control flow instruction.
166          In this case we can create new basic block.  It is
167          always exactly one basic block last in the sequence.  */
168
169       e = find_fallthru_edge (last_bb->succs);
170
171       gcc_checking_assert (!e || !(e->flags & EDGE_COMPLEX));
172
173       gcc_checking_assert (BLOCK_FOR_INSN (insn) == last_bb
174                            && !IS_SPECULATION_CHECK_P (insn)
175                            && BB_HEAD (last_bb) != insn
176                            && BB_END (last_bb) == insn);
177
178       {
179         rtx x;
180
181         x = NEXT_INSN (insn);
182         if (e)
183           gcc_checking_assert (NOTE_P (x) || LABEL_P (x));
184         else
185           gcc_checking_assert (BARRIER_P (x));
186       }
187
188       if (e)
189         {
190           bb = split_edge (e);
191           gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_END (bb)));
192         }
193       else
194         /* Create an empty unreachable block after the INSN.  */
195         bb = create_basic_block (NEXT_INSN (insn), NULL_RTX, last_bb);
196
197       /* split_edge () creates BB before E->DEST.  Keep in mind, that
198          this operation extends scheduling region till the end of BB.
199          Hence, we need to shift NEXT_TAIL, so haifa-sched.c won't go out
200          of the scheduling region.  */
201       current_sched_info->next_tail = NEXT_INSN (BB_END (bb));
202       gcc_assert (current_sched_info->next_tail);
203
204       /* Append new basic block to the end of the ebb.  */
205       sched_init_only_bb (bb, last_bb);
206       gcc_assert (last_bb == bb);
207     }
208 }
209
210 /* Return a string that contains the insn uid and optionally anything else
211    necessary to identify this insn in an output.  It's valid to use a
212    static buffer for this.  The ALIGNED parameter should cause the string
213    to be formatted so that multiple output lines will line up nicely.  */
214
215 static const char *
216 ebb_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED)
217 {
218   static char tmp[80];
219
220   /* '+' before insn means it is a new cycle start.  */
221   if (GET_MODE (insn) == TImode)
222     sprintf (tmp, "+ %4d", INSN_UID (insn));
223   else
224     sprintf (tmp, "  %4d", INSN_UID (insn));
225
226   return tmp;
227 }
228
229 /* Compare priority of two insns.  Return a positive number if the second
230    insn is to be preferred for scheduling, and a negative one if the first
231    is to be preferred.  Zero if they are equally good.  */
232
233 static int
234 rank (rtx insn1, rtx insn2)
235 {
236   basic_block bb1 = BLOCK_FOR_INSN (insn1);
237   basic_block bb2 = BLOCK_FOR_INSN (insn2);
238
239   if (bb1->count > bb2->count
240       || bb1->frequency > bb2->frequency)
241     return -1;
242   if (bb1->count < bb2->count
243       || bb1->frequency < bb2->frequency)
244     return 1;
245   return 0;
246 }
247
248 /* NEXT is an instruction that depends on INSN (a backward dependence);
249    return nonzero if we should include this dependence in priority
250    calculations.  */
251
252 static int
253 ebb_contributes_to_priority (rtx next ATTRIBUTE_UNUSED,
254                              rtx insn ATTRIBUTE_UNUSED)
255 {
256   return 1;
257 }
258
259  /* INSN is a JUMP_INSN.  Store the set of registers that
260     must be considered as used by this jump in USED.  */
261
262 void
263 ebb_compute_jump_reg_dependencies (rtx insn, regset used)
264 {
265   basic_block b = BLOCK_FOR_INSN (insn);
266   edge e;
267   edge_iterator ei;
268
269   FOR_EACH_EDGE (e, ei, b->succs)
270     if ((e->flags & EDGE_FALLTHRU) == 0)
271       bitmap_ior_into (used, df_get_live_in (e->dest));
272 }
273
274 /* Used in schedule_insns to initialize current_sched_info for scheduling
275    regions (or single basic blocks).  */
276
277 static struct common_sched_info_def ebb_common_sched_info;
278
279 static struct sched_deps_info_def ebb_sched_deps_info =
280   {
281     ebb_compute_jump_reg_dependencies,
282     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
283     NULL,
284     1, 0, 0
285   };
286
287 static struct haifa_sched_info ebb_sched_info =
288 {
289   init_ready_list,
290   NULL,
291   schedule_more_p,
292   NULL,
293   rank,
294   ebb_print_insn,
295   ebb_contributes_to_priority,
296   NULL, /* insn_finishes_block_p */
297
298   NULL, NULL,
299   NULL, NULL,
300   1, 0,
301
302   ebb_add_remove_insn,
303   begin_schedule_ready,
304   begin_move_insn,
305   advance_target_bb,
306
307   save_ebb_state,
308   restore_ebb_state,
309
310   SCHED_EBB
311   /* We can create new blocks in begin_schedule_ready ().  */
312   | NEW_BBS
313 };
314 \f
315 /* Returns the earliest block in EBB currently being processed where a
316    "similar load" 'insn2' is found, and hence LOAD_INSN can move
317    speculatively into the found block.  All the following must hold:
318
319    (1) both loads have 1 base register (PFREE_CANDIDATEs).
320    (2) load_insn and load2 have a def-use dependence upon
321    the same insn 'insn1'.
322
323    From all these we can conclude that the two loads access memory
324    addresses that differ at most by a constant, and hence if moving
325    load_insn would cause an exception, it would have been caused by
326    load2 anyhow.
327
328    The function uses list (given by LAST_BLOCK) of already processed
329    blocks in EBB.  The list is formed in `add_deps_for_risky_insns'.  */
330
331 static basic_block
332 earliest_block_with_similiar_load (basic_block last_block, rtx load_insn)
333 {
334   sd_iterator_def back_sd_it;
335   dep_t back_dep;
336   basic_block bb, earliest_block = NULL;
337
338   FOR_EACH_DEP (load_insn, SD_LIST_BACK, back_sd_it, back_dep)
339     {
340       rtx insn1 = DEP_PRO (back_dep);
341
342       if (DEP_TYPE (back_dep) == REG_DEP_TRUE)
343         /* Found a DEF-USE dependence (insn1, load_insn).  */
344         {
345           sd_iterator_def fore_sd_it;
346           dep_t fore_dep;
347
348           FOR_EACH_DEP (insn1, SD_LIST_FORW, fore_sd_it, fore_dep)
349             {
350               rtx insn2 = DEP_CON (fore_dep);
351               basic_block insn2_block = BLOCK_FOR_INSN (insn2);
352
353               if (DEP_TYPE (fore_dep) == REG_DEP_TRUE)
354                 {
355                   if (earliest_block != NULL
356                       && earliest_block->index < insn2_block->index)
357                     continue;
358
359                   /* Found a DEF-USE dependence (insn1, insn2).  */
360                   if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
361                     /* insn2 not guaranteed to be a 1 base reg load.  */
362                     continue;
363
364                   for (bb = last_block; bb; bb = (basic_block) bb->aux)
365                     if (insn2_block == bb)
366                       break;
367
368                   if (!bb)
369                     /* insn2 is the similar load.  */
370                     earliest_block = insn2_block;
371                 }
372             }
373         }
374     }
375
376   return earliest_block;
377 }
378
379 /* The following function adds dependencies between jumps and risky
380    insns in given ebb.  */
381
382 static void
383 add_deps_for_risky_insns (rtx head, rtx tail)
384 {
385   rtx insn, prev;
386   int classification;
387   rtx last_jump = NULL_RTX;
388   rtx next_tail = NEXT_INSN (tail);
389   basic_block last_block = NULL, bb;
390
391   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
392     {
393       add_delay_dependencies (insn);
394       if (control_flow_insn_p (insn))
395         {
396           bb = BLOCK_FOR_INSN (insn);
397           bb->aux = last_block;
398           last_block = bb;
399           /* Ensure blocks stay in the same order.  */
400           if (last_jump)
401             add_dependence (insn, last_jump, REG_DEP_ANTI);
402           last_jump = insn;
403         }
404       else if (INSN_P (insn) && last_jump != NULL_RTX)
405         {
406           classification = haifa_classify_insn (insn);
407           prev = last_jump;
408
409           switch (classification)
410             {
411             case PFREE_CANDIDATE:
412               if (flag_schedule_speculative_load)
413                 {
414                   bb = earliest_block_with_similiar_load (last_block, insn);
415                   if (bb)
416                     {
417                       bb = (basic_block) bb->aux;
418                       if (!bb)
419                         break;
420                       prev = BB_END (bb);
421                     }
422                 }
423               /* Fall through.  */
424             case TRAP_RISKY:
425             case IRISKY:
426             case PRISKY_CANDIDATE:
427               /* ??? We could implement better checking PRISKY_CANDIDATEs
428                  analogous to sched-rgn.c.  */
429               /* We can not change the mode of the backward
430                  dependency because REG_DEP_ANTI has the lowest
431                  rank.  */
432               if (! sched_insns_conditions_mutex_p (insn, prev))
433                 {
434                   dep_def _dep, *dep = &_dep;
435
436                   init_dep (dep, prev, insn, REG_DEP_ANTI);
437
438                   if (!(current_sched_info->flags & USE_DEPS_LIST))
439                     {
440                       enum DEPS_ADJUST_RESULT res;
441
442                       res = sd_add_or_update_dep (dep, false);
443
444                       /* We can't change an existing dependency with
445                          DEP_ANTI.  */
446                       gcc_assert (res != DEP_CHANGED);
447                     }
448                   else
449                     {
450                       if ((current_sched_info->flags & DO_SPECULATION)
451                           && (spec_info->mask & BEGIN_CONTROL))
452                         DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
453                                                          MAX_DEP_WEAK);
454
455                       sd_add_or_update_dep (dep, false);
456
457                       /* Dep_status could have been changed.
458                          No assertion here.  */
459                     }
460                 }
461
462               break;
463
464             default:
465               break;
466             }
467         }
468     }
469   /* Maintain the invariant that bb->aux is clear after use.  */
470   while (last_block)
471     {
472       bb = (basic_block) last_block->aux;
473       last_block->aux = NULL;
474       last_block = bb;
475     }
476 }
477
478 /* Schedule a single extended basic block, defined by the boundaries
479    HEAD and TAIL.
480
481    We change our expectations about scheduler behaviour depending on
482    whether MODULO_SCHEDULING is true.  If it is, we expect that the
483    caller has already called set_modulo_params and created delay pairs
484    as appropriate.  If the modulo schedule failed, we return
485    NULL_RTX.  */
486
487 basic_block
488 schedule_ebb (rtx head, rtx tail, bool modulo_scheduling)
489 {
490   basic_block first_bb, target_bb;
491   struct deps_desc tmp_deps;
492   bool success;
493
494   /* Blah.  We should fix the rest of the code not to get confused by
495      a note or two.  */
496   while (head != tail)
497     {
498       if (NOTE_P (head) || DEBUG_INSN_P (head))
499         head = NEXT_INSN (head);
500       else if (NOTE_P (tail) || DEBUG_INSN_P (tail))
501         tail = PREV_INSN (tail);
502       else if (LABEL_P (head))
503         head = NEXT_INSN (head);
504       else
505         break;
506     }
507
508   first_bb = BLOCK_FOR_INSN (head);
509   last_bb = BLOCK_FOR_INSN (tail);
510
511   if (no_real_insns_p (head, tail))
512     return BLOCK_FOR_INSN (tail);
513
514   gcc_assert (INSN_P (head) && INSN_P (tail));
515
516   if (!bitmap_bit_p (&dont_calc_deps, first_bb->index))
517     {
518       init_deps_global ();
519
520       /* Compute dependencies.  */
521       init_deps (&tmp_deps, false);
522       sched_analyze (&tmp_deps, head, tail);
523       free_deps (&tmp_deps);
524
525       add_deps_for_risky_insns (head, tail);
526
527       if (targetm.sched.dependencies_evaluation_hook)
528         targetm.sched.dependencies_evaluation_hook (head, tail);
529
530       finish_deps_global ();
531     }
532   else
533     /* Only recovery blocks can have their dependencies already calculated,
534        and they always are single block ebbs.  */
535     gcc_assert (first_bb == last_bb);
536
537   /* Set priorities.  */
538   current_sched_info->sched_max_insns_priority = 0;
539   rgn_n_insns = set_priorities (head, tail);
540   current_sched_info->sched_max_insns_priority++;
541
542   current_sched_info->prev_head = PREV_INSN (head);
543   current_sched_info->next_tail = NEXT_INSN (tail);
544
545   remove_notes (head, tail);
546
547   unlink_bb_notes (first_bb, last_bb);
548
549   target_bb = first_bb;
550
551   /* Make ready list big enough to hold all the instructions from the ebb.  */
552   sched_extend_ready_list (rgn_n_insns);
553   success = schedule_block (&target_bb);
554   gcc_assert (success || modulo_scheduling);
555
556   /* Free ready list.  */
557   sched_finish_ready_list ();
558
559   /* We might pack all instructions into fewer blocks,
560      so we may made some of them empty.  Can't assert (b == last_bb).  */
561
562   /* Sanity check: verify that all region insns were scheduled.  */
563   gcc_assert (modulo_scheduling || sched_rgn_n_insns == rgn_n_insns);
564
565   /* Free dependencies.  */
566   sched_free_deps (current_sched_info->head, current_sched_info->tail, true);
567
568   gcc_assert (haifa_recovery_bb_ever_added_p
569               || deps_pools_are_empty_p ());
570
571   if (EDGE_COUNT (last_bb->preds) == 0)
572     /* LAST_BB is unreachable.  */
573     {
574       gcc_assert (first_bb != last_bb
575                   && EDGE_COUNT (last_bb->succs) == 0);
576       last_bb = last_bb->prev_bb;
577       delete_basic_block (last_bb->next_bb);
578     }
579
580   return success ? last_bb : NULL;
581 }
582
583 /* Perform initializations before running schedule_ebbs or a single
584    schedule_ebb.  */
585 void
586 schedule_ebbs_init (void)
587 {
588   /* Setup infos.  */
589   {
590     memcpy (&ebb_common_sched_info, &haifa_common_sched_info,
591             sizeof (ebb_common_sched_info));
592
593     ebb_common_sched_info.fix_recovery_cfg = ebb_fix_recovery_cfg;
594     ebb_common_sched_info.add_block = ebb_add_block;
595     ebb_common_sched_info.sched_pass_id = SCHED_EBB_PASS;
596
597     common_sched_info = &ebb_common_sched_info;
598     sched_deps_info = &ebb_sched_deps_info;
599     current_sched_info = &ebb_sched_info;
600   }
601
602   haifa_sched_init ();
603
604   compute_bb_for_insn ();
605
606   /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers.  */
607   bitmap_initialize (&dont_calc_deps, 0);
608   bitmap_clear (&dont_calc_deps);
609 }
610
611 /* Perform cleanups after scheduling using schedules_ebbs or schedule_ebb.  */
612 void
613 schedule_ebbs_finish (void)
614 {
615   bitmap_clear (&dont_calc_deps);
616
617   /* Reposition the prologue and epilogue notes in case we moved the
618      prologue/epilogue insns.  */
619   if (reload_completed)
620     reposition_prologue_and_epilogue_notes ();
621
622   haifa_sched_finish ();
623 }
624
625 /* The main entry point in this file.  */
626
627 void
628 schedule_ebbs (void)
629 {
630   basic_block bb;
631   int probability_cutoff;
632   rtx tail;
633
634   /* Taking care of this degenerate case makes the rest of
635      this code simpler.  */
636   if (n_basic_blocks == NUM_FIXED_BLOCKS)
637     return;
638
639   if (profile_info && flag_branch_probabilities)
640     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
641   else
642     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
643   probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
644
645   schedule_ebbs_init ();
646
647   /* Schedule every region in the subroutine.  */
648   FOR_EACH_BB (bb)
649     {
650       rtx head = BB_HEAD (bb);
651
652       if (bb->flags & BB_DISABLE_SCHEDULE)
653         continue;
654
655       for (;;)
656         {
657           edge e;
658           tail = BB_END (bb);
659           if (bb->next_bb == EXIT_BLOCK_PTR
660               || LABEL_P (BB_HEAD (bb->next_bb)))
661             break;
662           e = find_fallthru_edge (bb->succs);
663           if (! e)
664             break;
665           if (e->probability <= probability_cutoff)
666             break;
667           if (e->dest->flags & BB_DISABLE_SCHEDULE)
668             break;
669           bb = bb->next_bb;
670         }
671
672       bb = schedule_ebb (head, tail, false);
673     }
674   schedule_ebbs_finish ();
675 }
676
677 /* INSN has been added to/removed from current ebb.  */
678 static void
679 ebb_add_remove_insn (rtx insn ATTRIBUTE_UNUSED, int remove_p)
680 {
681   if (!remove_p)
682     rgn_n_insns++;
683   else
684     rgn_n_insns--;
685 }
686
687 /* BB was added to ebb after AFTER.  */
688 static void
689 ebb_add_block (basic_block bb, basic_block after)
690 {
691   /* Recovery blocks are always bounded by BARRIERS,
692      therefore, they always form single block EBB,
693      therefore, we can use rec->index to identify such EBBs.  */
694   if (after == EXIT_BLOCK_PTR)
695     bitmap_set_bit (&dont_calc_deps, bb->index);
696   else if (after == last_bb)
697     last_bb = bb;
698 }
699
700 /* Return next block in ebb chain.  For parameter meaning please refer to
701    sched-int.h: struct sched_info: advance_target_bb.  */
702 static basic_block
703 advance_target_bb (basic_block bb, rtx insn)
704 {
705   if (insn)
706     {
707       if (BLOCK_FOR_INSN (insn) != bb
708           && control_flow_insn_p (insn)
709           /* We handle interblock movement of the speculation check
710              or over a speculation check in
711              haifa-sched.c: move_block_after_check ().  */
712           && !IS_SPECULATION_BRANCHY_CHECK_P (insn)
713           && !IS_SPECULATION_BRANCHY_CHECK_P (BB_END (bb)))
714         {
715           /* Assert that we don't move jumps across blocks.  */
716           gcc_assert (!control_flow_insn_p (BB_END (bb))
717                       && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
718           return bb;
719         }
720       else
721         return 0;
722     }
723   else
724     /* Return next non empty block.  */
725     {
726       do
727         {
728           gcc_assert (bb != last_bb);
729
730           bb = bb->next_bb;
731         }
732       while (bb_note (bb) == BB_END (bb));
733
734       return bb;
735     }
736 }
737
738 /* Fix internal data after interblock movement of jump instruction.
739    For parameter meaning please refer to
740    sched-int.h: struct sched_info: fix_recovery_cfg.  */
741 static void
742 ebb_fix_recovery_cfg (int bbi ATTRIBUTE_UNUSED, int jump_bbi,
743                       int jump_bb_nexti)
744 {
745   gcc_assert (last_bb->index != bbi);
746
747   if (jump_bb_nexti == last_bb->index)
748     last_bb = BASIC_BLOCK (jump_bbi);
749 }
750
751 #endif /* INSN_SCHEDULING */