OSDN Git Service

2006-08-17 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
[pf3gnuchains/gcc-fork.git] / gcc / sched-ebb.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5    and currently maintained by, Jim Wilson (wilson@cygnus.com)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.  */
23 \f
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "toplev.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 "toplev.h"
39 #include "recog.h"
40 #include "cfglayout.h"
41 #include "params.h"
42 #include "sched-int.h"
43 #include "target.h"
44 #include "output.h"
45 \f
46 /* The number of insns scheduled so far.  */
47 static int sched_n_insns;
48
49 /* The number of insns to be scheduled in total.  */
50 static int n_insns;
51
52 /* Set of blocks, that already have their dependencies calculated.  */
53 static bitmap_head dont_calc_deps;
54 /* Set of basic blocks, that are ebb heads of tails respectively.  */
55 static bitmap_head ebb_head, ebb_tail;
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, rtx);
63 static int schedule_more_p (void);
64 static const char *ebb_print_insn (rtx, int);
65 static int rank (rtx, rtx);
66 static int contributes_to_priority (rtx, rtx);
67 static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
68 static basic_block earliest_block_with_similiar_load (basic_block, rtx);
69 static void add_deps_for_risky_insns (rtx, rtx);
70 static basic_block schedule_ebb (rtx, rtx);
71
72 static void add_remove_insn (rtx, int);
73 static void add_block1 (basic_block, basic_block);
74 static basic_block advance_target_bb (basic_block, rtx);
75 static void fix_recovery_cfg (int, int, int);
76
77 #ifdef ENABLE_CHECKING
78 static int ebb_head_or_leaf_p (basic_block, int);
79 #endif
80
81 /* Return nonzero if there are more insns that should be scheduled.  */
82
83 static int
84 schedule_more_p (void)
85 {
86   return sched_n_insns < n_insns;
87 }
88
89 /* Add all insns that are initially ready to the ready list READY.  Called
90    once before scheduling a set of insns.  */
91
92 static void
93 init_ready_list (void)
94 {
95   int n = 0;
96   rtx prev_head = current_sched_info->prev_head;
97   rtx next_tail = current_sched_info->next_tail;
98   rtx insn;
99
100   sched_n_insns = 0;
101
102 #if 0
103   /* Print debugging information.  */
104   if (sched_verbose >= 5)
105     debug_dependencies ();
106 #endif
107
108   /* Initialize ready list with all 'ready' insns in target block.
109      Count number of insns in the target block being scheduled.  */
110   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
111     {
112       try_ready (insn);
113       n++;
114     }
115
116   gcc_assert (n == n_insns);
117 }
118
119 /* INSN is being scheduled after LAST.  Update counters.  */
120 static void
121 begin_schedule_ready (rtx insn, rtx last)
122 {
123   sched_n_insns++;
124
125   if (BLOCK_FOR_INSN (insn) == last_bb
126       /* INSN is a jump in the last block, ...  */
127       && control_flow_insn_p (insn)
128       /* that is going to be moved over some instructions.  */
129       && last != PREV_INSN (insn))
130     {
131       edge e;
132       edge_iterator ei;
133       basic_block bb;
134
135       /* An obscure special case, where we do have partially dead
136          instruction scheduled after last control flow instruction.
137          In this case we can create new basic block.  It is
138          always exactly one basic block last in the sequence.  */
139       
140       FOR_EACH_EDGE (e, ei, last_bb->succs)
141         if (e->flags & EDGE_FALLTHRU)
142           break;
143
144 #ifdef ENABLE_CHECKING
145       gcc_assert (!e || !(e->flags & EDGE_COMPLEX));        
146
147       gcc_assert (BLOCK_FOR_INSN (insn) == last_bb
148                   && !RECOVERY_BLOCK (insn)
149                   && BB_HEAD (last_bb) != insn
150                   && BB_END (last_bb) == insn);
151
152       {
153         rtx x;
154
155         x = NEXT_INSN (insn);
156         if (e)
157           gcc_assert (NOTE_P (x) || LABEL_P (x));
158         else
159           gcc_assert (BARRIER_P (x));
160       }
161 #endif
162
163       if (e)
164         {
165           bb = split_edge (e);
166           gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_END (bb)));
167         }
168       else
169         /* Create an empty unreachable block after the INSN.  */
170         bb = create_basic_block (NEXT_INSN (insn), NULL_RTX, last_bb);
171       
172       /* split_edge () creates BB before E->DEST.  Keep in mind, that
173          this operation extends scheduling region till the end of BB.
174          Hence, we need to shift NEXT_TAIL, so haifa-sched.c won't go out
175          of the scheduling region.  */
176       current_sched_info->next_tail = NEXT_INSN (BB_END (bb));
177       gcc_assert (current_sched_info->next_tail);
178
179       add_block (bb, last_bb);
180       gcc_assert (last_bb == bb);
181     }
182 }
183
184 /* Return a string that contains the insn uid and optionally anything else
185    necessary to identify this insn in an output.  It's valid to use a
186    static buffer for this.  The ALIGNED parameter should cause the string
187    to be formatted so that multiple output lines will line up nicely.  */
188
189 static const char *
190 ebb_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
191 {
192   static char tmp[80];
193
194   sprintf (tmp, "%4d", INSN_UID (insn));
195   return tmp;
196 }
197
198 /* Compare priority of two insns.  Return a positive number if the second
199    insn is to be preferred for scheduling, and a negative one if the first
200    is to be preferred.  Zero if they are equally good.  */
201
202 static int
203 rank (rtx insn1, rtx insn2)
204 {
205   basic_block bb1 = BLOCK_FOR_INSN (insn1);
206   basic_block bb2 = BLOCK_FOR_INSN (insn2);
207
208   if (bb1->count > bb2->count
209       || bb1->frequency > bb2->frequency)
210     return -1;
211   if (bb1->count < bb2->count
212       || bb1->frequency < bb2->frequency)
213     return 1;
214   return 0;
215 }
216
217 /* NEXT is an instruction that depends on INSN (a backward dependence);
218    return nonzero if we should include this dependence in priority
219    calculations.  */
220
221 static int
222 contributes_to_priority (rtx next ATTRIBUTE_UNUSED,
223                          rtx insn ATTRIBUTE_UNUSED)
224 {
225   return 1;
226 }
227
228  /* INSN is a JUMP_INSN, COND_SET is the set of registers that are
229     conditionally set before INSN.  Store the set of registers that
230     must be considered as used by this jump in USED and that of
231     registers that must be considered as set in SET.  */
232
233 static void
234 compute_jump_reg_dependencies (rtx insn, regset cond_set, regset used,
235                                regset set)
236 {
237   basic_block b = BLOCK_FOR_INSN (insn);
238   edge e;
239   edge_iterator ei;
240
241   FOR_EACH_EDGE (e, ei, b->succs)
242     if (e->flags & EDGE_FALLTHRU)
243       /* The jump may be a by-product of a branch that has been merged
244          in the main codepath after being conditionalized.  Therefore
245          it may guard the fallthrough block from using a value that has
246          conditionally overwritten that of the main codepath.  So we
247          consider that it restores the value of the main codepath.  */
248       bitmap_and (set, glat_start [e->dest->index], cond_set);
249     else
250       bitmap_ior_into (used, glat_start [e->dest->index]);
251 }
252
253 /* Used in schedule_insns to initialize current_sched_info for scheduling
254    regions (or single basic blocks).  */
255
256 static struct sched_info ebb_sched_info =
257 {
258   init_ready_list,
259   NULL,
260   schedule_more_p,
261   NULL,
262   rank,
263   ebb_print_insn,
264   contributes_to_priority,
265   compute_jump_reg_dependencies,
266
267   NULL, NULL,
268   NULL, NULL,
269   0, 1, 0,
270
271   add_remove_insn,
272   begin_schedule_ready,
273   add_block1,
274   advance_target_bb,
275   fix_recovery_cfg,
276 #ifdef ENABLE_CHECKING
277   ebb_head_or_leaf_p,
278 #endif
279   /* We need to DETACH_LIVE_INFO to be able to create new basic blocks.
280      See begin_schedule_ready ().  */
281   SCHED_EBB | USE_GLAT | DETACH_LIFE_INFO
282 };
283 \f
284 /* Returns the earliest block in EBB currently being processed where a
285    "similar load" 'insn2' is found, and hence LOAD_INSN can move
286    speculatively into the found block.  All the following must hold:
287
288    (1) both loads have 1 base register (PFREE_CANDIDATEs).
289    (2) load_insn and load2 have a def-use dependence upon
290    the same insn 'insn1'.
291
292    From all these we can conclude that the two loads access memory
293    addresses that differ at most by a constant, and hence if moving
294    load_insn would cause an exception, it would have been caused by
295    load2 anyhow.
296
297    The function uses list (given by LAST_BLOCK) of already processed
298    blocks in EBB.  The list is formed in `add_deps_for_risky_insns'.  */
299
300 static basic_block
301 earliest_block_with_similiar_load (basic_block last_block, rtx load_insn)
302 {
303   rtx back_link;
304   basic_block bb, earliest_block = NULL;
305
306   for (back_link = LOG_LINKS (load_insn);
307        back_link;
308        back_link = XEXP (back_link, 1))
309     {
310       rtx insn1 = XEXP (back_link, 0);
311
312       if (GET_MODE (back_link) == VOIDmode)
313         {
314           /* Found a DEF-USE dependence (insn1, load_insn).  */
315           rtx fore_link;
316
317           for (fore_link = INSN_DEPEND (insn1);
318                fore_link;
319                fore_link = XEXP (fore_link, 1))
320             {
321               rtx insn2 = XEXP (fore_link, 0);
322               basic_block insn2_block = BLOCK_FOR_INSN (insn2);
323
324               if (GET_MODE (fore_link) == VOIDmode)
325                 {
326                   if (earliest_block != NULL
327                       && earliest_block->index < insn2_block->index)
328                     continue;
329
330                   /* Found a DEF-USE dependence (insn1, insn2).  */
331                   if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
332                     /* insn2 not guaranteed to be a 1 base reg load.  */
333                     continue;
334
335                   for (bb = last_block; bb; bb = bb->aux)
336                     if (insn2_block == bb)
337                       break;
338
339                   if (!bb)
340                     /* insn2 is the similar load.  */
341                     earliest_block = insn2_block;
342                 }
343             }
344         }
345     }
346
347   return earliest_block;
348 }
349
350 /* The following function adds dependencies between jumps and risky
351    insns in given ebb.  */
352
353 static void
354 add_deps_for_risky_insns (rtx head, rtx tail)
355 {
356   rtx insn, prev;
357   int class;
358   rtx last_jump = NULL_RTX;
359   rtx next_tail = NEXT_INSN (tail);
360   basic_block last_block = NULL, bb;
361
362   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
363     if (control_flow_insn_p (insn))
364       {
365         bb = BLOCK_FOR_INSN (insn);
366         bb->aux = last_block;
367         last_block = bb;
368         last_jump = insn;
369       }
370     else if (INSN_P (insn) && last_jump != NULL_RTX)
371       {
372         class = haifa_classify_insn (insn);
373         prev = last_jump;
374         switch (class)
375           {
376           case PFREE_CANDIDATE:
377             if (flag_schedule_speculative_load)
378               {
379                 bb = earliest_block_with_similiar_load (last_block, insn);
380                 if (bb)
381                   {
382                     bb = bb->aux;
383                     if (!bb)
384                       break;
385                     prev = BB_END (bb);
386                   }
387               }
388             /* Fall through.  */
389           case TRAP_RISKY:
390           case IRISKY:
391           case PRISKY_CANDIDATE:
392             /* ??? We could implement better checking PRISKY_CANDIDATEs
393                analogous to sched-rgn.c.  */
394             /* We can not change the mode of the backward
395                dependency because REG_DEP_ANTI has the lowest
396                rank.  */
397             if (! sched_insns_conditions_mutex_p (insn, prev))
398               {
399                 if (!(current_sched_info->flags & DO_SPECULATION))
400                   {
401                     enum DEPS_ADJUST_RESULT res;
402                     
403                     res = add_or_update_back_dep (insn, prev,
404                                                   REG_DEP_ANTI, DEP_ANTI);
405
406                     if (res == DEP_CREATED)
407                       add_forw_dep (insn, LOG_LINKS (insn));
408                     else
409                       gcc_assert (res != DEP_CHANGED);
410                   }
411                 else
412                   add_or_update_back_forw_dep (insn, prev, REG_DEP_ANTI,
413                                                set_dep_weak (DEP_ANTI,
414                                                              BEGIN_CONTROL,
415                                                              MAX_DEP_WEAK));
416               }
417
418             break;
419
420           default:
421             break;
422           }
423       }
424   /* Maintain the invariant that bb->aux is clear after use.  */
425   while (last_block)
426     {
427       bb = last_block->aux;
428       last_block->aux = NULL;
429       last_block = bb;
430     }
431 }
432
433 /* Schedule a single extended basic block, defined by the boundaries HEAD
434    and TAIL.  */
435
436 static basic_block
437 schedule_ebb (rtx head, rtx tail)
438 {
439   basic_block first_bb, target_bb;
440   struct deps tmp_deps;
441   
442   first_bb = BLOCK_FOR_INSN (head);
443   last_bb = BLOCK_FOR_INSN (tail);
444
445   if (no_real_insns_p (head, tail))
446     return BLOCK_FOR_INSN (tail);
447
448   gcc_assert (INSN_P (head) && INSN_P (tail));
449
450   if (!bitmap_bit_p (&dont_calc_deps, first_bb->index))
451     {
452       init_deps_global ();
453
454       /* Compute LOG_LINKS.  */
455       init_deps (&tmp_deps);
456       sched_analyze (&tmp_deps, head, tail);
457       free_deps (&tmp_deps);
458
459       /* Compute INSN_DEPEND.  */
460       compute_forward_dependences (head, tail);
461
462       add_deps_for_risky_insns (head, tail);
463
464       if (targetm.sched.dependencies_evaluation_hook)
465         targetm.sched.dependencies_evaluation_hook (head, tail);
466
467       finish_deps_global ();
468     }
469   else
470     /* Only recovery blocks can have their dependencies already calculated,
471        and they always are single block ebbs.  */       
472     gcc_assert (first_bb == last_bb);
473
474   /* Set priorities.  */
475   current_sched_info->sched_max_insns_priority = 0;
476   n_insns = set_priorities (head, tail);
477   current_sched_info->sched_max_insns_priority++;
478
479   current_sched_info->prev_head = PREV_INSN (head);
480   current_sched_info->next_tail = NEXT_INSN (tail);
481
482   if (write_symbols != NO_DEBUG)
483     {
484       save_line_notes (first_bb->index, head, tail);
485       rm_line_notes (head, tail);
486     }
487
488   /* rm_other_notes only removes notes which are _inside_ the
489      block---that is, it won't remove notes before the first real insn
490      or after the last real insn of the block.  So if the first insn
491      has a REG_SAVE_NOTE which would otherwise be emitted before the
492      insn, it is redundant with the note before the start of the
493      block, and so we have to take it out.  */
494   if (INSN_P (head))
495     {
496       rtx note;
497
498       for (note = REG_NOTES (head); note; note = XEXP (note, 1))
499         if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
500           remove_note (head, note);
501     }
502
503   /* Remove remaining note insns from the block, save them in
504      note_list.  These notes are restored at the end of
505      schedule_block ().  */
506   rm_other_notes (head, tail);
507
508   unlink_bb_notes (first_bb, last_bb);
509
510   current_sched_info->queue_must_finish_empty = 1;
511
512   target_bb = first_bb;
513   schedule_block (&target_bb, n_insns);
514
515   /* We might pack all instructions into fewer blocks,
516      so we may made some of them empty.  Can't assert (b == last_bb).  */
517   
518   /* Sanity check: verify that all region insns were scheduled.  */
519   gcc_assert (sched_n_insns == n_insns);
520   head = current_sched_info->head;
521   tail = current_sched_info->tail;
522
523   if (write_symbols != NO_DEBUG)
524     restore_line_notes (head, tail);
525
526   if (EDGE_COUNT (last_bb->preds) == 0)
527     /* LAST_BB is unreachable.  */
528     {
529       gcc_assert (first_bb != last_bb
530                   && EDGE_COUNT (last_bb->succs) == 0);
531       last_bb = last_bb->prev_bb;
532       delete_basic_block (last_bb->next_bb);
533     }
534
535   return last_bb;
536 }
537
538 /* The one entry point in this file.  */
539
540 void
541 schedule_ebbs (void)
542 {
543   basic_block bb;
544   int probability_cutoff;
545   rtx tail;
546   sbitmap large_region_blocks, blocks;
547   int any_large_regions;
548
549   if (profile_info && flag_branch_probabilities)
550     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
551   else
552     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
553   probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
554
555   /* Taking care of this degenerate case makes the rest of
556      this code simpler.  */
557   if (n_basic_blocks == NUM_FIXED_BLOCKS)
558     return;
559
560   /* We need current_sched_info in init_dependency_caches, which is
561      invoked via sched_init.  */
562   current_sched_info = &ebb_sched_info;
563
564   sched_init ();
565
566   compute_bb_for_insn ();
567
568   /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers.  */
569   bitmap_initialize (&dont_calc_deps, 0);
570   bitmap_clear (&dont_calc_deps);
571   bitmap_initialize (&ebb_head, 0);
572   bitmap_clear (&ebb_head);
573   bitmap_initialize (&ebb_tail, 0);
574   bitmap_clear (&ebb_tail);
575
576   /* Schedule every region in the subroutine.  */
577   FOR_EACH_BB (bb)
578     {
579       rtx head = BB_HEAD (bb);
580
581       for (;;)
582         {
583           edge e;
584           edge_iterator ei;
585           tail = BB_END (bb);
586           if (bb->next_bb == EXIT_BLOCK_PTR
587               || LABEL_P (BB_HEAD (bb->next_bb)))
588             break;
589           FOR_EACH_EDGE (e, ei, bb->succs)
590             if ((e->flags & EDGE_FALLTHRU) != 0)
591               break;
592           if (! e)
593             break;
594           if (e->probability <= probability_cutoff)
595             break;
596           bb = bb->next_bb;
597         }
598
599       /* Blah.  We should fix the rest of the code not to get confused by
600          a note or two.  */
601       while (head != tail)
602         {
603           if (NOTE_P (head))
604             head = NEXT_INSN (head);
605           else if (NOTE_P (tail))
606             tail = PREV_INSN (tail);
607           else if (LABEL_P (head))
608             head = NEXT_INSN (head);
609           else
610             break;
611         }
612
613       bitmap_set_bit (&ebb_head, BLOCK_NUM (head));
614       bb = schedule_ebb (head, tail);
615       bitmap_set_bit (&ebb_tail, bb->index);
616     }
617   bitmap_clear (&dont_calc_deps);
618
619   gcc_assert (current_sched_info->flags & DETACH_LIFE_INFO);
620   /* We can create new basic blocks during scheduling, and
621      attach_life_info () will create regsets for them
622      (along with attaching existing info back).  */
623   attach_life_info ();
624
625   /* Updating register live information.  */
626   allocate_reg_life_data ();
627
628   any_large_regions = 0;
629   large_region_blocks = sbitmap_alloc (last_basic_block);
630   sbitmap_zero (large_region_blocks);
631   FOR_EACH_BB (bb)
632     SET_BIT (large_region_blocks, bb->index);
633
634   blocks = sbitmap_alloc (last_basic_block);
635   sbitmap_zero (blocks);
636
637   /* Update life information.  For regions consisting of multiple blocks
638      we've possibly done interblock scheduling that affects global liveness.
639      For regions consisting of single blocks we need to do only local
640      liveness.  */
641   FOR_EACH_BB (bb)
642     {
643       int bbi;
644       
645       bbi = bb->index;
646
647       if (!bitmap_bit_p (&ebb_head, bbi)
648           || !bitmap_bit_p (&ebb_tail, bbi)
649           /* New blocks (e.g. recovery blocks) should be processed
650              as parts of large regions.  */
651           || !glat_start[bbi])
652         any_large_regions = 1;
653       else
654         {
655           SET_BIT (blocks, bbi);
656           RESET_BIT (large_region_blocks, bbi);
657         }
658     }
659
660   update_life_info (blocks, UPDATE_LIFE_LOCAL, 0);
661   sbitmap_free (blocks);
662   
663   if (any_large_regions)
664     {
665       update_life_info (large_region_blocks, UPDATE_LIFE_GLOBAL, 0);
666
667 #ifdef ENABLE_CHECKING
668       /* !!! We can't check reg_live_info here because of the fact,
669          that destination registers of COND_EXEC's may be dead
670          before scheduling (while they should be alive).  Don't know why.  */
671       /*check_reg_live (true);*/
672 #endif
673     }
674   sbitmap_free (large_region_blocks);
675
676   bitmap_clear (&ebb_head);
677   bitmap_clear (&ebb_tail);
678
679   /* Reposition the prologue and epilogue notes in case we moved the
680      prologue/epilogue insns.  */
681   if (reload_completed)
682     reposition_prologue_and_epilogue_notes (get_insns ());
683
684   if (write_symbols != NO_DEBUG)
685     rm_redundant_line_notes ();
686
687   sched_finish ();
688 }
689
690 /* INSN has been added to/removed from current ebb.  */
691 static void
692 add_remove_insn (rtx insn ATTRIBUTE_UNUSED, int remove_p)
693 {
694   if (!remove_p)
695     n_insns++;
696   else
697     n_insns--;
698 }
699
700 /* BB was added to ebb after AFTER.  */
701 static void
702 add_block1 (basic_block bb, basic_block after)
703 {
704   /* Recovery blocks are always bounded by BARRIERS, 
705      therefore, they always form single block EBB,
706      therefore, we can use rec->index to identify such EBBs.  */
707   if (after == EXIT_BLOCK_PTR)
708     bitmap_set_bit (&dont_calc_deps, bb->index);
709   else if (after == last_bb)
710     last_bb = bb;
711 }
712
713 /* Return next block in ebb chain.  For parameter meaning please refer to
714    sched-int.h: struct sched_info: advance_target_bb.  */
715 static basic_block
716 advance_target_bb (basic_block bb, rtx insn)
717 {
718   if (insn)
719     {
720       if (BLOCK_FOR_INSN (insn) != bb
721           && control_flow_insn_p (insn)
722           && !RECOVERY_BLOCK (insn)
723           && !RECOVERY_BLOCK (BB_END (bb)))
724         {
725           gcc_assert (!control_flow_insn_p (BB_END (bb))
726                       && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
727           return bb;
728         }
729       else
730         return 0;
731     }
732   else
733     /* Return next non empty block.  */
734     {
735       do
736         {
737           gcc_assert (bb != last_bb);
738
739           bb = bb->next_bb;
740         }
741       while (bb_note (bb) == BB_END (bb));
742
743       return bb;
744     }
745 }
746
747 /* Fix internal data after interblock movement of jump instruction.
748    For parameter meaning please refer to
749    sched-int.h: struct sched_info: fix_recovery_cfg.  */
750 static void
751 fix_recovery_cfg (int bbi ATTRIBUTE_UNUSED, int jump_bbi, int jump_bb_nexti)
752 {
753   gcc_assert (last_bb->index != bbi);
754
755   if (jump_bb_nexti == last_bb->index)
756     last_bb = BASIC_BLOCK (jump_bbi);
757 }
758
759 #ifdef ENABLE_CHECKING
760 /* Return non zero, if BB is first or last (depending of LEAF_P) block in
761    current ebb.  For more information please refer to
762    sched-int.h: struct sched_info: region_head_or_leaf_p.  */
763 static int
764 ebb_head_or_leaf_p (basic_block bb, int leaf_p)
765 {
766   if (!leaf_p)    
767     return bitmap_bit_p (&ebb_head, bb->index);
768   else
769     return bitmap_bit_p (&ebb_tail, bb->index);
770 }
771 #endif /* ENABLE_CHECKING  */