OSDN Git Service

Delete remaining references to sparc little-endian support.
[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                   if ((current_sched_info->flags & DO_SPECULATION)
435                       && (spec_info->mask & BEGIN_CONTROL))
436                     {
437                       dep_def _dep, *dep = &_dep;
438
439                       init_dep (dep, prev, insn, REG_DEP_ANTI);
440
441                       if (current_sched_info->flags & USE_DEPS_LIST)
442                         {
443                           DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
444                                                            MAX_DEP_WEAK);
445
446                         }
447                       sd_add_or_update_dep (dep, false);
448                     }
449                   else
450                     add_dependence (insn, prev, REG_DEP_CONTROL);
451                 }
452
453               break;
454
455             default:
456               break;
457             }
458         }
459     }
460   /* Maintain the invariant that bb->aux is clear after use.  */
461   while (last_block)
462     {
463       bb = (basic_block) last_block->aux;
464       last_block->aux = NULL;
465       last_block = bb;
466     }
467 }
468
469 /* Schedule a single extended basic block, defined by the boundaries
470    HEAD and TAIL.
471
472    We change our expectations about scheduler behaviour depending on
473    whether MODULO_SCHEDULING is true.  If it is, we expect that the
474    caller has already called set_modulo_params and created delay pairs
475    as appropriate.  If the modulo schedule failed, we return
476    NULL_RTX.  */
477
478 basic_block
479 schedule_ebb (rtx head, rtx tail, bool modulo_scheduling)
480 {
481   basic_block first_bb, target_bb;
482   struct deps_desc tmp_deps;
483   bool success;
484
485   /* Blah.  We should fix the rest of the code not to get confused by
486      a note or two.  */
487   while (head != tail)
488     {
489       if (NOTE_P (head) || DEBUG_INSN_P (head))
490         head = NEXT_INSN (head);
491       else if (NOTE_P (tail) || DEBUG_INSN_P (tail))
492         tail = PREV_INSN (tail);
493       else if (LABEL_P (head))
494         head = NEXT_INSN (head);
495       else
496         break;
497     }
498
499   first_bb = BLOCK_FOR_INSN (head);
500   last_bb = BLOCK_FOR_INSN (tail);
501
502   if (no_real_insns_p (head, tail))
503     return BLOCK_FOR_INSN (tail);
504
505   gcc_assert (INSN_P (head) && INSN_P (tail));
506
507   if (!bitmap_bit_p (&dont_calc_deps, first_bb->index))
508     {
509       init_deps_global ();
510
511       /* Compute dependencies.  */
512       init_deps (&tmp_deps, false);
513       sched_analyze (&tmp_deps, head, tail);
514       free_deps (&tmp_deps);
515
516       add_deps_for_risky_insns (head, tail);
517
518       if (targetm.sched.dependencies_evaluation_hook)
519         targetm.sched.dependencies_evaluation_hook (head, tail);
520
521       finish_deps_global ();
522     }
523   else
524     /* Only recovery blocks can have their dependencies already calculated,
525        and they always are single block ebbs.  */
526     gcc_assert (first_bb == last_bb);
527
528   /* Set priorities.  */
529   current_sched_info->sched_max_insns_priority = 0;
530   rgn_n_insns = set_priorities (head, tail);
531   current_sched_info->sched_max_insns_priority++;
532
533   current_sched_info->prev_head = PREV_INSN (head);
534   current_sched_info->next_tail = NEXT_INSN (tail);
535
536   remove_notes (head, tail);
537
538   unlink_bb_notes (first_bb, last_bb);
539
540   target_bb = first_bb;
541
542   /* Make ready list big enough to hold all the instructions from the ebb.  */
543   sched_extend_ready_list (rgn_n_insns);
544   success = schedule_block (&target_bb);
545   gcc_assert (success || modulo_scheduling);
546
547   /* Free ready list.  */
548   sched_finish_ready_list ();
549
550   /* We might pack all instructions into fewer blocks,
551      so we may made some of them empty.  Can't assert (b == last_bb).  */
552
553   /* Sanity check: verify that all region insns were scheduled.  */
554   gcc_assert (modulo_scheduling || sched_rgn_n_insns == rgn_n_insns);
555
556   /* Free dependencies.  */
557   sched_free_deps (current_sched_info->head, current_sched_info->tail, true);
558
559   gcc_assert (haifa_recovery_bb_ever_added_p
560               || deps_pools_are_empty_p ());
561
562   if (EDGE_COUNT (last_bb->preds) == 0)
563     /* LAST_BB is unreachable.  */
564     {
565       gcc_assert (first_bb != last_bb
566                   && EDGE_COUNT (last_bb->succs) == 0);
567       last_bb = last_bb->prev_bb;
568       delete_basic_block (last_bb->next_bb);
569     }
570
571   return success ? last_bb : NULL;
572 }
573
574 /* Perform initializations before running schedule_ebbs or a single
575    schedule_ebb.  */
576 void
577 schedule_ebbs_init (void)
578 {
579   /* Setup infos.  */
580   {
581     memcpy (&ebb_common_sched_info, &haifa_common_sched_info,
582             sizeof (ebb_common_sched_info));
583
584     ebb_common_sched_info.fix_recovery_cfg = ebb_fix_recovery_cfg;
585     ebb_common_sched_info.add_block = ebb_add_block;
586     ebb_common_sched_info.sched_pass_id = SCHED_EBB_PASS;
587
588     common_sched_info = &ebb_common_sched_info;
589     sched_deps_info = &ebb_sched_deps_info;
590     current_sched_info = &ebb_sched_info;
591   }
592
593   haifa_sched_init ();
594
595   compute_bb_for_insn ();
596
597   /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers.  */
598   bitmap_initialize (&dont_calc_deps, 0);
599   bitmap_clear (&dont_calc_deps);
600 }
601
602 /* Perform cleanups after scheduling using schedules_ebbs or schedule_ebb.  */
603 void
604 schedule_ebbs_finish (void)
605 {
606   bitmap_clear (&dont_calc_deps);
607
608   /* Reposition the prologue and epilogue notes in case we moved the
609      prologue/epilogue insns.  */
610   if (reload_completed)
611     reposition_prologue_and_epilogue_notes ();
612
613   haifa_sched_finish ();
614 }
615
616 /* The main entry point in this file.  */
617
618 void
619 schedule_ebbs (void)
620 {
621   basic_block bb;
622   int probability_cutoff;
623   rtx tail;
624
625   /* Taking care of this degenerate case makes the rest of
626      this code simpler.  */
627   if (n_basic_blocks == NUM_FIXED_BLOCKS)
628     return;
629
630   if (profile_info && flag_branch_probabilities)
631     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
632   else
633     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
634   probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
635
636   schedule_ebbs_init ();
637
638   /* Schedule every region in the subroutine.  */
639   FOR_EACH_BB (bb)
640     {
641       rtx head = BB_HEAD (bb);
642
643       if (bb->flags & BB_DISABLE_SCHEDULE)
644         continue;
645
646       for (;;)
647         {
648           edge e;
649           tail = BB_END (bb);
650           if (bb->next_bb == EXIT_BLOCK_PTR
651               || LABEL_P (BB_HEAD (bb->next_bb)))
652             break;
653           e = find_fallthru_edge (bb->succs);
654           if (! e)
655             break;
656           if (e->probability <= probability_cutoff)
657             break;
658           if (e->dest->flags & BB_DISABLE_SCHEDULE)
659             break;
660           bb = bb->next_bb;
661         }
662
663       bb = schedule_ebb (head, tail, false);
664     }
665   schedule_ebbs_finish ();
666 }
667
668 /* INSN has been added to/removed from current ebb.  */
669 static void
670 ebb_add_remove_insn (rtx insn ATTRIBUTE_UNUSED, int remove_p)
671 {
672   if (!remove_p)
673     rgn_n_insns++;
674   else
675     rgn_n_insns--;
676 }
677
678 /* BB was added to ebb after AFTER.  */
679 static void
680 ebb_add_block (basic_block bb, basic_block after)
681 {
682   /* Recovery blocks are always bounded by BARRIERS,
683      therefore, they always form single block EBB,
684      therefore, we can use rec->index to identify such EBBs.  */
685   if (after == EXIT_BLOCK_PTR)
686     bitmap_set_bit (&dont_calc_deps, bb->index);
687   else if (after == last_bb)
688     last_bb = bb;
689 }
690
691 /* Return next block in ebb chain.  For parameter meaning please refer to
692    sched-int.h: struct sched_info: advance_target_bb.  */
693 static basic_block
694 advance_target_bb (basic_block bb, rtx insn)
695 {
696   if (insn)
697     {
698       if (BLOCK_FOR_INSN (insn) != bb
699           && control_flow_insn_p (insn)
700           /* We handle interblock movement of the speculation check
701              or over a speculation check in
702              haifa-sched.c: move_block_after_check ().  */
703           && !IS_SPECULATION_BRANCHY_CHECK_P (insn)
704           && !IS_SPECULATION_BRANCHY_CHECK_P (BB_END (bb)))
705         {
706           /* Assert that we don't move jumps across blocks.  */
707           gcc_assert (!control_flow_insn_p (BB_END (bb))
708                       && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
709           return bb;
710         }
711       else
712         return 0;
713     }
714   else
715     /* Return next non empty block.  */
716     {
717       do
718         {
719           gcc_assert (bb != last_bb);
720
721           bb = bb->next_bb;
722         }
723       while (bb_note (bb) == BB_END (bb));
724
725       return bb;
726     }
727 }
728
729 /* Fix internal data after interblock movement of jump instruction.
730    For parameter meaning please refer to
731    sched-int.h: struct sched_info: fix_recovery_cfg.  */
732 static void
733 ebb_fix_recovery_cfg (int bbi ATTRIBUTE_UNUSED, int jump_bbi,
734                       int jump_bb_nexti)
735 {
736   gcc_assert (last_bb->index != bbi);
737
738   if (jump_bb_nexti == last_bb->index)
739     last_bb = BASIC_BLOCK (jump_bbi);
740 }
741
742 #endif /* INSN_SCHEDULING */