OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / haifa-sched.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2001, 2002, 2003, 2004, 2005, 2006, 2007 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
24 /* Instruction scheduling pass.  This file, along with sched-deps.c,
25    contains the generic parts.  The actual entry point is found for
26    the normal instruction scheduling pass is found in sched-rgn.c.
27
28    We compute insn priorities based on data dependencies.  Flow
29    analysis only creates a fraction of the data-dependencies we must
30    observe: namely, only those dependencies which the combiner can be
31    expected to use.  For this pass, we must therefore create the
32    remaining dependencies we need to observe: register dependencies,
33    memory dependencies, dependencies to keep function calls in order,
34    and the dependence between a conditional branch and the setting of
35    condition codes are all dealt with here.
36
37    The scheduler first traverses the data flow graph, starting with
38    the last instruction, and proceeding to the first, assigning values
39    to insn_priority as it goes.  This sorts the instructions
40    topologically by data dependence.
41
42    Once priorities have been established, we order the insns using
43    list scheduling.  This works as follows: starting with a list of
44    all the ready insns, and sorted according to priority number, we
45    schedule the insn from the end of the list by placing its
46    predecessors in the list according to their priority order.  We
47    consider this insn scheduled by setting the pointer to the "end" of
48    the list to point to the previous insn.  When an insn has no
49    predecessors, we either queue it until sufficient time has elapsed
50    or add it to the ready list.  As the instructions are scheduled or
51    when stalls are introduced, the queue advances and dumps insns into
52    the ready list.  When all insns down to the lowest priority have
53    been scheduled, the critical path of the basic block has been made
54    as short as possible.  The remaining insns are then scheduled in
55    remaining slots.
56
57    The following list shows the order in which we want to break ties
58    among insns in the ready list:
59
60    1.  choose insn with the longest path to end of bb, ties
61    broken by
62    2.  choose insn with least contribution to register pressure,
63    ties broken by
64    3.  prefer in-block upon interblock motion, ties broken by
65    4.  prefer useful upon speculative motion, ties broken by
66    5.  choose insn with largest control flow probability, ties
67    broken by
68    6.  choose insn with the least dependences upon the previously
69    scheduled insn, or finally
70    7   choose the insn which has the most insns dependent on it.
71    8.  choose insn with lowest UID.
72
73    Memory references complicate matters.  Only if we can be certain
74    that memory references are not part of the data dependency graph
75    (via true, anti, or output dependence), can we move operations past
76    memory references.  To first approximation, reads can be done
77    independently, while writes introduce dependencies.  Better
78    approximations will yield fewer dependencies.
79
80    Before reload, an extended analysis of interblock data dependences
81    is required for interblock scheduling.  This is performed in
82    compute_block_backward_dependences ().
83
84    Dependencies set up by memory references are treated in exactly the
85    same way as other dependencies, by using insn backward dependences
86    INSN_BACK_DEPS.  INSN_BACK_DEPS are translated into forward dependences
87    INSN_FORW_DEPS the purpose of forward list scheduling.
88
89    Having optimized the critical path, we may have also unduly
90    extended the lifetimes of some registers.  If an operation requires
91    that constants be loaded into registers, it is certainly desirable
92    to load those constants as early as necessary, but no earlier.
93    I.e., it will not do to load up a bunch of registers at the
94    beginning of a basic block only to use them at the end, if they
95    could be loaded later, since this may result in excessive register
96    utilization.
97
98    Note that since branches are never in basic blocks, but only end
99    basic blocks, this pass will not move branches.  But that is ok,
100    since we can use GNU's delayed branch scheduling pass to take care
101    of this case.
102
103    Also note that no further optimizations based on algebraic
104    identities are performed, so this pass would be a good one to
105    perform instruction splitting, such as breaking up a multiply
106    instruction into shifts and adds where that is profitable.
107
108    Given the memory aliasing analysis that this pass should perform,
109    it should be possible to remove redundant stores to memory, and to
110    load values from registers instead of hitting memory.
111
112    Before reload, speculative insns are moved only if a 'proof' exists
113    that no exception will be caused by this, and if no live registers
114    exist that inhibit the motion (live registers constraints are not
115    represented by data dependence edges).
116
117    This pass must update information that subsequent passes expect to
118    be correct.  Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
119    reg_n_calls_crossed, and reg_live_length.  Also, BB_HEAD, BB_END.
120
121    The information in the line number notes is carefully retained by
122    this pass.  Notes that refer to the starting and ending of
123    exception regions are also carefully retained by this pass.  All
124    other NOTE insns are grouped in their same relative order at the
125    beginning of basic blocks and regions that have been scheduled.  */
126 \f
127 #include "config.h"
128 #include "system.h"
129 #include "coretypes.h"
130 #include "tm.h"
131 #include "toplev.h"
132 #include "rtl.h"
133 #include "tm_p.h"
134 #include "hard-reg-set.h"
135 #include "regs.h"
136 #include "function.h"
137 #include "flags.h"
138 #include "insn-config.h"
139 #include "insn-attr.h"
140 #include "except.h"
141 #include "toplev.h"
142 #include "recog.h"
143 #include "sched-int.h"
144 #include "target.h"
145 #include "output.h"
146 #include "params.h"
147
148 #ifdef INSN_SCHEDULING
149
150 /* issue_rate is the number of insns that can be scheduled in the same
151    machine cycle.  It can be defined in the config/mach/mach.h file,
152    otherwise we set it to 1.  */
153
154 static int issue_rate;
155
156 /* sched-verbose controls the amount of debugging output the
157    scheduler prints.  It is controlled by -fsched-verbose=N:
158    N>0 and no -DSR : the output is directed to stderr.
159    N>=10 will direct the printouts to stderr (regardless of -dSR).
160    N=1: same as -dSR.
161    N=2: bb's probabilities, detailed ready list info, unit/insn info.
162    N=3: rtl at abort point, control-flow, regions info.
163    N=5: dependences info.  */
164
165 static int sched_verbose_param = 0;
166 int sched_verbose = 0;
167
168 /* Debugging file.  All printouts are sent to dump, which is always set,
169    either to stderr, or to the dump listing file (-dRS).  */
170 FILE *sched_dump = 0;
171
172 /* Highest uid before scheduling.  */
173 static int old_max_uid;
174
175 /* fix_sched_param() is called from toplev.c upon detection
176    of the -fsched-verbose=N option.  */
177
178 void
179 fix_sched_param (const char *param, const char *val)
180 {
181   if (!strcmp (param, "verbose"))
182     sched_verbose_param = atoi (val);
183   else
184     warning (0, "fix_sched_param: unknown param: %s", param);
185 }
186
187 struct haifa_insn_data *h_i_d;
188
189 #define INSN_TICK(INSN)         (h_i_d[INSN_UID (INSN)].tick)
190 #define INTER_TICK(INSN)        (h_i_d[INSN_UID (INSN)].inter_tick)
191
192 /* If INSN_TICK of an instruction is equal to INVALID_TICK,
193    then it should be recalculated from scratch.  */
194 #define INVALID_TICK (-(max_insn_queue_index + 1))
195 /* The minimal value of the INSN_TICK of an instruction.  */
196 #define MIN_TICK (-max_insn_queue_index)
197
198 /* Issue points are used to distinguish between instructions in max_issue ().
199    For now, all instructions are equally good.  */
200 #define ISSUE_POINTS(INSN) 1
201
202 /* List of important notes we must keep around.  This is a pointer to the
203    last element in the list.  */
204 static rtx note_list;
205
206 static struct spec_info_def spec_info_var;
207 /* Description of the speculative part of the scheduling.
208    If NULL - no speculation.  */
209 static spec_info_t spec_info;
210
211 /* True, if recovery block was added during scheduling of current block.
212    Used to determine, if we need to fix INSN_TICKs.  */
213 static bool added_recovery_block_p;
214
215 /* Counters of different types of speculative instructions.  */
216 static int nr_begin_data, nr_be_in_data, nr_begin_control, nr_be_in_control;
217
218 /* Pointers to GLAT data.  See init_glat for more information.  */
219 regset *glat_start, *glat_end;
220
221 /* Array used in {unlink, restore}_bb_notes.  */
222 static rtx *bb_header = 0;
223
224 /* Number of basic_blocks.  */
225 static int old_last_basic_block;
226
227 /* Basic block after which recovery blocks will be created.  */
228 static basic_block before_recovery;
229
230 /* Queues, etc.  */
231
232 /* An instruction is ready to be scheduled when all insns preceding it
233    have already been scheduled.  It is important to ensure that all
234    insns which use its result will not be executed until its result
235    has been computed.  An insn is maintained in one of four structures:
236
237    (P) the "Pending" set of insns which cannot be scheduled until
238    their dependencies have been satisfied.
239    (Q) the "Queued" set of insns that can be scheduled when sufficient
240    time has passed.
241    (R) the "Ready" list of unscheduled, uncommitted insns.
242    (S) the "Scheduled" list of insns.
243
244    Initially, all insns are either "Pending" or "Ready" depending on
245    whether their dependencies are satisfied.
246
247    Insns move from the "Ready" list to the "Scheduled" list as they
248    are committed to the schedule.  As this occurs, the insns in the
249    "Pending" list have their dependencies satisfied and move to either
250    the "Ready" list or the "Queued" set depending on whether
251    sufficient time has passed to make them ready.  As time passes,
252    insns move from the "Queued" set to the "Ready" list.
253
254    The "Pending" list (P) are the insns in the INSN_FORW_DEPS of the
255    unscheduled insns, i.e., those that are ready, queued, and pending.
256    The "Queued" set (Q) is implemented by the variable `insn_queue'.
257    The "Ready" list (R) is implemented by the variables `ready' and
258    `n_ready'.
259    The "Scheduled" list (S) is the new insn chain built by this pass.
260
261    The transition (R->S) is implemented in the scheduling loop in
262    `schedule_block' when the best insn to schedule is chosen.
263    The transitions (P->R and P->Q) are implemented in `schedule_insn' as
264    insns move from the ready list to the scheduled list.
265    The transition (Q->R) is implemented in 'queue_to_insn' as time
266    passes or stalls are introduced.  */
267
268 /* Implement a circular buffer to delay instructions until sufficient
269    time has passed.  For the new pipeline description interface,
270    MAX_INSN_QUEUE_INDEX is a power of two minus one which is not less
271    than maximal time of instruction execution computed by genattr.c on
272    the base maximal time of functional unit reservations and getting a
273    result.  This is the longest time an insn may be queued.  */
274
275 static rtx *insn_queue;
276 static int q_ptr = 0;
277 static int q_size = 0;
278 #define NEXT_Q(X) (((X)+1) & max_insn_queue_index)
279 #define NEXT_Q_AFTER(X, C) (((X)+C) & max_insn_queue_index)
280
281 #define QUEUE_SCHEDULED (-3)
282 #define QUEUE_NOWHERE   (-2)
283 #define QUEUE_READY     (-1)
284 /* QUEUE_SCHEDULED - INSN is scheduled.
285    QUEUE_NOWHERE   - INSN isn't scheduled yet and is neither in
286    queue or ready list.
287    QUEUE_READY     - INSN is in ready list.
288    N >= 0 - INSN queued for X [where NEXT_Q_AFTER (q_ptr, X) == N] cycles.  */
289    
290 #define QUEUE_INDEX(INSN) (h_i_d[INSN_UID (INSN)].queue_index)
291
292 /* The following variable value refers for all current and future
293    reservations of the processor units.  */
294 state_t curr_state;
295
296 /* The following variable value is size of memory representing all
297    current and future reservations of the processor units.  */
298 static size_t dfa_state_size;
299
300 /* The following array is used to find the best insn from ready when
301    the automaton pipeline interface is used.  */
302 static char *ready_try;
303
304 /* Describe the ready list of the scheduler.
305    VEC holds space enough for all insns in the current region.  VECLEN
306    says how many exactly.
307    FIRST is the index of the element with the highest priority; i.e. the
308    last one in the ready list, since elements are ordered by ascending
309    priority.
310    N_READY determines how many insns are on the ready list.  */
311
312 struct ready_list
313 {
314   rtx *vec;
315   int veclen;
316   int first;
317   int n_ready;
318 };
319
320 /* The pointer to the ready list.  */
321 static struct ready_list *readyp;
322
323 /* Scheduling clock.  */
324 static int clock_var;
325
326 /* Number of instructions in current scheduling region.  */
327 static int rgn_n_insns;
328
329 static int may_trap_exp (rtx, int);
330
331 /* Nonzero iff the address is comprised from at most 1 register.  */
332 #define CONST_BASED_ADDRESS_P(x)                        \
333   (REG_P (x)                                    \
334    || ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS   \
335         || (GET_CODE (x) == LO_SUM))                    \
336        && (CONSTANT_P (XEXP (x, 0))                     \
337            || CONSTANT_P (XEXP (x, 1)))))
338
339 /* Returns a class that insn with GET_DEST(insn)=x may belong to,
340    as found by analyzing insn's expression.  */
341
342 static int
343 may_trap_exp (rtx x, int is_store)
344 {
345   enum rtx_code code;
346
347   if (x == 0)
348     return TRAP_FREE;
349   code = GET_CODE (x);
350   if (is_store)
351     {
352       if (code == MEM && may_trap_p (x))
353         return TRAP_RISKY;
354       else
355         return TRAP_FREE;
356     }
357   if (code == MEM)
358     {
359       /* The insn uses memory:  a volatile load.  */
360       if (MEM_VOLATILE_P (x))
361         return IRISKY;
362       /* An exception-free load.  */
363       if (!may_trap_p (x))
364         return IFREE;
365       /* A load with 1 base register, to be further checked.  */
366       if (CONST_BASED_ADDRESS_P (XEXP (x, 0)))
367         return PFREE_CANDIDATE;
368       /* No info on the load, to be further checked.  */
369       return PRISKY_CANDIDATE;
370     }
371   else
372     {
373       const char *fmt;
374       int i, insn_class = TRAP_FREE;
375
376       /* Neither store nor load, check if it may cause a trap.  */
377       if (may_trap_p (x))
378         return TRAP_RISKY;
379       /* Recursive step: walk the insn...  */
380       fmt = GET_RTX_FORMAT (code);
381       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
382         {
383           if (fmt[i] == 'e')
384             {
385               int tmp_class = may_trap_exp (XEXP (x, i), is_store);
386               insn_class = WORST_CLASS (insn_class, tmp_class);
387             }
388           else if (fmt[i] == 'E')
389             {
390               int j;
391               for (j = 0; j < XVECLEN (x, i); j++)
392                 {
393                   int tmp_class = may_trap_exp (XVECEXP (x, i, j), is_store);
394                   insn_class = WORST_CLASS (insn_class, tmp_class);
395                   if (insn_class == TRAP_RISKY || insn_class == IRISKY)
396                     break;
397                 }
398             }
399           if (insn_class == TRAP_RISKY || insn_class == IRISKY)
400             break;
401         }
402       return insn_class;
403     }
404 }
405
406 /* Classifies insn for the purpose of verifying that it can be
407    moved speculatively, by examining it's patterns, returning:
408    TRAP_RISKY: store, or risky non-load insn (e.g. division by variable).
409    TRAP_FREE: non-load insn.
410    IFREE: load from a globally safe location.
411    IRISKY: volatile load.
412    PFREE_CANDIDATE, PRISKY_CANDIDATE: load that need to be checked for
413    being either PFREE or PRISKY.  */
414
415 int
416 haifa_classify_insn (rtx insn)
417 {
418   rtx pat = PATTERN (insn);
419   int tmp_class = TRAP_FREE;
420   int insn_class = TRAP_FREE;
421   enum rtx_code code;
422
423   if (GET_CODE (pat) == PARALLEL)
424     {
425       int i, len = XVECLEN (pat, 0);
426
427       for (i = len - 1; i >= 0; i--)
428         {
429           code = GET_CODE (XVECEXP (pat, 0, i));
430           switch (code)
431             {
432             case CLOBBER:
433               /* Test if it is a 'store'.  */
434               tmp_class = may_trap_exp (XEXP (XVECEXP (pat, 0, i), 0), 1);
435               break;
436             case SET:
437               /* Test if it is a store.  */
438               tmp_class = may_trap_exp (SET_DEST (XVECEXP (pat, 0, i)), 1);
439               if (tmp_class == TRAP_RISKY)
440                 break;
441               /* Test if it is a load.  */
442               tmp_class
443                 = WORST_CLASS (tmp_class,
444                                may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
445                                              0));
446               break;
447             case COND_EXEC:
448             case TRAP_IF:
449               tmp_class = TRAP_RISKY;
450               break;
451             default:
452               ;
453             }
454           insn_class = WORST_CLASS (insn_class, tmp_class);
455           if (insn_class == TRAP_RISKY || insn_class == IRISKY)
456             break;
457         }
458     }
459   else
460     {
461       code = GET_CODE (pat);
462       switch (code)
463         {
464         case CLOBBER:
465           /* Test if it is a 'store'.  */
466           tmp_class = may_trap_exp (XEXP (pat, 0), 1);
467           break;
468         case SET:
469           /* Test if it is a store.  */
470           tmp_class = may_trap_exp (SET_DEST (pat), 1);
471           if (tmp_class == TRAP_RISKY)
472             break;
473           /* Test if it is a load.  */
474           tmp_class =
475             WORST_CLASS (tmp_class,
476                          may_trap_exp (SET_SRC (pat), 0));
477           break;
478         case COND_EXEC:
479         case TRAP_IF:
480           tmp_class = TRAP_RISKY;
481           break;
482         default:;
483         }
484       insn_class = tmp_class;
485     }
486
487   return insn_class;
488 }
489
490 /* A typedef for rtx vector.  */
491 typedef VEC(rtx, heap) *rtx_vec_t;
492
493 /* Forward declarations.  */
494
495 static int priority (rtx);
496 static int rank_for_schedule (const void *, const void *);
497 static void swap_sort (rtx *, int);
498 static void queue_insn (rtx, int);
499 static int schedule_insn (rtx);
500 static int find_set_reg_weight (rtx);
501 static void find_insn_reg_weight (basic_block);
502 static void find_insn_reg_weight1 (rtx);
503 static void adjust_priority (rtx);
504 static void advance_one_cycle (void);
505
506 /* Notes handling mechanism:
507    =========================
508    Generally, NOTES are saved before scheduling and restored after scheduling.
509    The scheduler distinguishes between two types of notes:
510
511    (1) LOOP_BEGIN, LOOP_END, SETJMP, EHREGION_BEG, EHREGION_END notes:
512    Before scheduling a region, a pointer to the note is added to the insn
513    that follows or precedes it.  (This happens as part of the data dependence
514    computation).  After scheduling an insn, the pointer contained in it is
515    used for regenerating the corresponding note (in reemit_notes).
516
517    (2) All other notes (e.g. INSN_DELETED):  Before scheduling a block,
518    these notes are put in a list (in rm_other_notes() and
519    unlink_other_notes ()).  After scheduling the block, these notes are
520    inserted at the beginning of the block (in schedule_block()).  */
521
522 static rtx unlink_other_notes (rtx, rtx);
523 static void reemit_notes (rtx);
524
525 static rtx *ready_lastpos (struct ready_list *);
526 static void ready_add (struct ready_list *, rtx, bool);
527 static void ready_sort (struct ready_list *);
528 static rtx ready_remove_first (struct ready_list *);
529
530 static void queue_to_ready (struct ready_list *);
531 static int early_queue_to_ready (state_t, struct ready_list *);
532
533 static void debug_ready_list (struct ready_list *);
534
535 static void move_insn (rtx);
536
537 /* The following functions are used to implement multi-pass scheduling
538    on the first cycle.  */
539 static rtx ready_element (struct ready_list *, int);
540 static rtx ready_remove (struct ready_list *, int);
541 static void ready_remove_insn (rtx);
542 static int max_issue (struct ready_list *, int *, int);
543
544 static rtx choose_ready (struct ready_list *);
545
546 static void fix_inter_tick (rtx, rtx);
547 static int fix_tick_ready (rtx);
548 static void change_queue_index (rtx, int);
549
550 /* The following functions are used to implement scheduling of data/control
551    speculative instructions.  */
552
553 static void extend_h_i_d (void);
554 static void extend_ready (int);
555 static void extend_global (rtx);
556 static void extend_all (rtx);
557 static void init_h_i_d (rtx);
558 static void generate_recovery_code (rtx);
559 static void process_insn_forw_deps_be_in_spec (deps_list_t, rtx, ds_t);
560 static void begin_speculative_block (rtx);
561 static void add_to_speculative_block (rtx);
562 static dw_t dep_weak (ds_t);
563 static edge find_fallthru_edge (basic_block);
564 static void init_before_recovery (void);
565 static basic_block create_recovery_block (void);
566 static void create_check_block_twin (rtx, bool);
567 static void fix_recovery_deps (basic_block);
568 static void change_pattern (rtx, rtx);
569 static int speculate_insn (rtx, ds_t, rtx *);
570 static void dump_new_block_header (int, basic_block, rtx, rtx);
571 static void restore_bb_notes (basic_block);
572 static void extend_bb (void);
573 static void fix_jump_move (rtx);
574 static void move_block_after_check (rtx);
575 static void move_succs (VEC(edge,gc) **, basic_block);
576 static void init_glat (void);
577 static void init_glat1 (basic_block);
578 static void attach_life_info1 (basic_block);
579 static void free_glat (void);
580 static void sched_remove_insn (rtx);
581 static void clear_priorities (rtx, rtx_vec_t *);
582 static void calc_priorities (rtx_vec_t);
583 static void add_jump_dependencies (rtx, rtx);
584 #ifdef ENABLE_CHECKING
585 static int has_edge_p (VEC(edge,gc) *, int);
586 static void check_cfg (rtx, rtx);
587 static void check_sched_flags (void);
588 #endif
589
590 #endif /* INSN_SCHEDULING */
591 \f
592 /* Point to state used for the current scheduling pass.  */
593 struct sched_info *current_sched_info;
594 \f
595 #ifndef INSN_SCHEDULING
596 void
597 schedule_insns (void)
598 {
599 }
600 #else
601
602 /* Working copy of frontend's sched_info variable.  */
603 static struct sched_info current_sched_info_var;
604
605 /* Pointer to the last instruction scheduled.  Used by rank_for_schedule,
606    so that insns independent of the last scheduled insn will be preferred
607    over dependent instructions.  */
608
609 static rtx last_scheduled_insn;
610
611 /* Cached cost of the instruction.  Use below function to get cost of the
612    insn.  -1 here means that the field is not initialized.  */
613 #define INSN_COST(INSN)         (h_i_d[INSN_UID (INSN)].cost)
614
615 /* Compute cost of executing INSN.
616    This is the number of cycles between instruction issue and
617    instruction results.  */
618 HAIFA_INLINE int
619 insn_cost (rtx insn)
620 {
621   int cost = INSN_COST (insn);
622
623   if (cost < 0)
624     {
625       /* A USE insn, or something else we don't need to
626          understand.  We can't pass these directly to
627          result_ready_cost or insn_default_latency because it will
628          trigger a fatal error for unrecognizable insns.  */
629       if (recog_memoized (insn) < 0)
630         {
631           INSN_COST (insn) = 0;
632           return 0;
633         }
634       else
635         {
636           cost = insn_default_latency (insn);
637           if (cost < 0)
638             cost = 0;
639
640           INSN_COST (insn) = cost;
641         }
642     }
643
644   return cost;
645 }
646
647 /* Compute cost of dependence LINK.
648    This is the number of cycles between instruction issue and
649    instruction results.  */
650 int
651 dep_cost (dep_t link)
652 {
653   rtx used = DEP_CON (link);
654   int cost;
655
656   /* A USE insn should never require the value used to be computed.
657      This allows the computation of a function's result and parameter
658      values to overlap the return and call.  */
659   if (recog_memoized (used) < 0)
660     cost = 0;
661   else
662     {
663       rtx insn = DEP_PRO (link);
664       enum reg_note dep_type = DEP_KIND (link);
665
666       cost = insn_cost (insn);
667
668       if (INSN_CODE (insn) >= 0)
669         {
670           if (dep_type == REG_DEP_ANTI)
671             cost = 0;
672           else if (dep_type == REG_DEP_OUTPUT)
673             {
674               cost = (insn_default_latency (insn)
675                       - insn_default_latency (used));
676               if (cost <= 0)
677                 cost = 1;
678             }
679           else if (bypass_p (insn))
680             cost = insn_latency (insn, used);
681         }
682
683       if (targetm.sched.adjust_cost != NULL)
684         {
685           /* This variable is used for backward compatibility with the
686              targets.  */
687           rtx dep_cost_rtx_link = alloc_INSN_LIST (NULL_RTX, NULL_RTX);
688
689           /* Make it self-cycled, so that if some tries to walk over this
690              incomplete list he/she will be caught in an endless loop.  */
691           XEXP (dep_cost_rtx_link, 1) = dep_cost_rtx_link;
692
693           /* Targets use only REG_NOTE_KIND of the link.  */
694           PUT_REG_NOTE_KIND (dep_cost_rtx_link, DEP_KIND (link));
695
696           cost = targetm.sched.adjust_cost (used, dep_cost_rtx_link,
697                                             insn, cost);
698
699           free_INSN_LIST_node (dep_cost_rtx_link);
700         }
701
702       if (cost < 0)
703         cost = 0;
704     }
705
706   return cost;
707 }
708
709 /* Return 'true' if DEP should be included in priority calculations.  */
710 static bool
711 contributes_to_priority_p (dep_t dep)
712 {
713   /* Critical path is meaningful in block boundaries only.  */
714   if (!current_sched_info->contributes_to_priority (DEP_CON (dep),
715                                                     DEP_PRO (dep)))
716     return false;
717
718   /* If flag COUNT_SPEC_IN_CRITICAL_PATH is set,
719      then speculative instructions will less likely be
720      scheduled.  That is because the priority of
721      their producers will increase, and, thus, the
722      producers will more likely be scheduled, thus,
723      resolving the dependence.  */
724   if ((current_sched_info->flags & DO_SPECULATION)
725       && !(spec_info->flags & COUNT_SPEC_IN_CRITICAL_PATH)
726       && (DEP_STATUS (dep) & SPECULATIVE))
727     return false;
728
729   return true;
730 }
731
732 /* Compute the priority number for INSN.  */
733 static int
734 priority (rtx insn)
735 {
736   dep_link_t link;
737
738   if (! INSN_P (insn))
739     return 0;
740
741   /* We should not be insterested in priority of an already scheduled insn.  */
742   gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
743
744   if (!INSN_PRIORITY_KNOWN (insn))
745     {
746       int this_priority = 0;
747
748       if (deps_list_empty_p (INSN_FORW_DEPS (insn)))
749         /* ??? We should set INSN_PRIORITY to insn_cost when and insn has
750            some forward deps but all of them are ignored by
751            contributes_to_priority hook.  At the moment we set priority of
752            such insn to 0.  */
753         this_priority = insn_cost (insn);
754       else
755         {
756           rtx prev_first, twin;
757           basic_block rec;
758
759           /* For recovery check instructions we calculate priority slightly
760              different than that of normal instructions.  Instead of walking
761              through INSN_FORW_DEPS (check) list, we walk through
762              INSN_FORW_DEPS list of each instruction in the corresponding
763              recovery block.  */ 
764
765           rec = RECOVERY_BLOCK (insn);
766           if (!rec || rec == EXIT_BLOCK_PTR)
767             {
768               prev_first = PREV_INSN (insn);
769               twin = insn;
770             }
771           else
772             {
773               prev_first = NEXT_INSN (BB_HEAD (rec));
774               twin = PREV_INSN (BB_END (rec));
775             }
776
777           do
778             {
779               FOR_EACH_DEP_LINK (link, INSN_FORW_DEPS (twin))
780                 {
781                   rtx next;
782                   int next_priority;
783                   dep_t dep = DEP_LINK_DEP (link);
784
785                   next = DEP_CON (dep);
786
787                   if (BLOCK_FOR_INSN (next) != rec)
788                     {
789                       int cost;
790
791                       if (!contributes_to_priority_p (dep))
792                         continue;
793
794                       if (twin == insn)
795                         cost = dep_cost (dep);
796                       else
797                         {
798                           struct _dep _dep1, *dep1 = &_dep1;
799
800                           init_dep (dep1, insn, next, REG_DEP_ANTI);
801
802                           cost = dep_cost (dep1);
803                         }
804
805                       next_priority = cost + priority (next);
806
807                       if (next_priority > this_priority)
808                         this_priority = next_priority;
809                     }
810                 }
811               
812               twin = PREV_INSN (twin);
813             }
814           while (twin != prev_first);
815         }
816       INSN_PRIORITY (insn) = this_priority;
817       INSN_PRIORITY_STATUS (insn) = 1;
818     }
819
820   return INSN_PRIORITY (insn);
821 }
822 \f
823 /* Macros and functions for keeping the priority queue sorted, and
824    dealing with queuing and dequeuing of instructions.  */
825
826 #define SCHED_SORT(READY, N_READY)                                   \
827 do { if ((N_READY) == 2)                                             \
828        swap_sort (READY, N_READY);                                   \
829      else if ((N_READY) > 2)                                         \
830          qsort (READY, N_READY, sizeof (rtx), rank_for_schedule); }  \
831 while (0)
832
833 /* Returns a positive value if x is preferred; returns a negative value if
834    y is preferred.  Should never return 0, since that will make the sort
835    unstable.  */
836
837 static int
838 rank_for_schedule (const void *x, const void *y)
839 {
840   rtx tmp = *(const rtx *) y;
841   rtx tmp2 = *(const rtx *) x;
842   dep_link_t link1, link2;
843   int tmp_class, tmp2_class;
844   int val, priority_val, weight_val, info_val;
845
846   /* The insn in a schedule group should be issued the first.  */
847   if (SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
848     return SCHED_GROUP_P (tmp2) ? 1 : -1;
849
850   /* Make sure that priority of TMP and TMP2 are initialized.  */
851   gcc_assert (INSN_PRIORITY_KNOWN (tmp) && INSN_PRIORITY_KNOWN (tmp2));
852
853   /* Prefer insn with higher priority.  */
854   priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
855
856   if (priority_val)
857     return priority_val;
858
859   /* Prefer speculative insn with greater dependencies weakness.  */
860   if (spec_info)
861     {
862       ds_t ds1, ds2;
863       dw_t dw1, dw2;
864       int dw;
865
866       ds1 = TODO_SPEC (tmp) & SPECULATIVE;
867       if (ds1)
868         dw1 = dep_weak (ds1);
869       else
870         dw1 = NO_DEP_WEAK;
871       
872       ds2 = TODO_SPEC (tmp2) & SPECULATIVE;
873       if (ds2)
874         dw2 = dep_weak (ds2);
875       else
876         dw2 = NO_DEP_WEAK;
877
878       dw = dw2 - dw1;
879       if (dw > (NO_DEP_WEAK / 8) || dw < -(NO_DEP_WEAK / 8))
880         return dw;
881     }
882
883   /* Prefer an insn with smaller contribution to registers-pressure.  */
884   if (!reload_completed &&
885       (weight_val = INSN_REG_WEIGHT (tmp) - INSN_REG_WEIGHT (tmp2)))
886     return weight_val;
887
888   info_val = (*current_sched_info->rank) (tmp, tmp2);
889   if (info_val)
890     return info_val;
891
892   /* Compare insns based on their relation to the last-scheduled-insn.  */
893   if (INSN_P (last_scheduled_insn))
894     {
895       /* Classify the instructions into three classes:
896          1) Data dependent on last schedule insn.
897          2) Anti/Output dependent on last scheduled insn.
898          3) Independent of last scheduled insn, or has latency of one.
899          Choose the insn from the highest numbered class if different.  */
900       link1
901         = find_link_by_con_in_deps_list (INSN_FORW_DEPS (last_scheduled_insn),
902                                          tmp);
903
904       if (link1 == NULL || dep_cost (DEP_LINK_DEP (link1)) == 1)
905         tmp_class = 3;
906       else if (/* Data dependence.  */
907                DEP_LINK_KIND (link1) == REG_DEP_TRUE)
908         tmp_class = 1;
909       else
910         tmp_class = 2;
911
912       link2
913         = find_link_by_con_in_deps_list (INSN_FORW_DEPS (last_scheduled_insn),
914                                          tmp2);
915
916       if (link2 == NULL || dep_cost (DEP_LINK_DEP (link2))  == 1)
917         tmp2_class = 3;
918       else if (/* Data dependence.  */
919                DEP_LINK_KIND (link2) == REG_DEP_TRUE)
920         tmp2_class = 1;
921       else
922         tmp2_class = 2;
923
924       if ((val = tmp2_class - tmp_class))
925         return val;
926     }
927
928   /* Prefer the insn which has more later insns that depend on it.
929      This gives the scheduler more freedom when scheduling later
930      instructions at the expense of added register pressure.  */
931
932   link1 = DEPS_LIST_FIRST (INSN_FORW_DEPS (tmp));
933   link2 = DEPS_LIST_FIRST (INSN_FORW_DEPS (tmp2));
934
935   while (link1 != NULL && link2 != NULL)
936     {
937       link1 = DEP_LINK_NEXT (link1);
938       link2 = DEP_LINK_NEXT (link2);
939     }
940
941   if (link1 != NULL && link2 == NULL)
942     /* TMP (Y) has more insns that depend on it.  */
943     return -1;
944   if (link1 == NULL && link2 != NULL)
945     /* TMP2 (X) has more insns that depend on it.  */
946     return 1;
947
948   /* If insns are equally good, sort by INSN_LUID (original insn order),
949      so that we make the sort stable.  This minimizes instruction movement,
950      thus minimizing sched's effect on debugging and cross-jumping.  */
951   return INSN_LUID (tmp) - INSN_LUID (tmp2);
952 }
953
954 /* Resort the array A in which only element at index N may be out of order.  */
955
956 HAIFA_INLINE static void
957 swap_sort (rtx *a, int n)
958 {
959   rtx insn = a[n - 1];
960   int i = n - 2;
961
962   while (i >= 0 && rank_for_schedule (a + i, &insn) >= 0)
963     {
964       a[i + 1] = a[i];
965       i -= 1;
966     }
967   a[i + 1] = insn;
968 }
969
970 /* Add INSN to the insn queue so that it can be executed at least
971    N_CYCLES after the currently executing insn.  Preserve insns
972    chain for debugging purposes.  */
973
974 HAIFA_INLINE static void
975 queue_insn (rtx insn, int n_cycles)
976 {
977   int next_q = NEXT_Q_AFTER (q_ptr, n_cycles);
978   rtx link = alloc_INSN_LIST (insn, insn_queue[next_q]);
979
980   gcc_assert (n_cycles <= max_insn_queue_index);
981
982   insn_queue[next_q] = link;
983   q_size += 1;
984
985   if (sched_verbose >= 2)
986     {
987       fprintf (sched_dump, ";;\t\tReady-->Q: insn %s: ",
988                (*current_sched_info->print_insn) (insn, 0));
989
990       fprintf (sched_dump, "queued for %d cycles.\n", n_cycles);
991     }
992   
993   QUEUE_INDEX (insn) = next_q;
994 }
995
996 /* Remove INSN from queue.  */
997 static void
998 queue_remove (rtx insn)
999 {
1000   gcc_assert (QUEUE_INDEX (insn) >= 0);
1001   remove_free_INSN_LIST_elem (insn, &insn_queue[QUEUE_INDEX (insn)]);
1002   q_size--;
1003   QUEUE_INDEX (insn) = QUEUE_NOWHERE;
1004 }
1005
1006 /* Return a pointer to the bottom of the ready list, i.e. the insn
1007    with the lowest priority.  */
1008
1009 HAIFA_INLINE static rtx *
1010 ready_lastpos (struct ready_list *ready)
1011 {
1012   gcc_assert (ready->n_ready >= 1);
1013   return ready->vec + ready->first - ready->n_ready + 1;
1014 }
1015
1016 /* Add an element INSN to the ready list so that it ends up with the
1017    lowest/highest priority depending on FIRST_P.  */
1018
1019 HAIFA_INLINE static void
1020 ready_add (struct ready_list *ready, rtx insn, bool first_p)
1021 {
1022   if (!first_p)
1023     {
1024       if (ready->first == ready->n_ready)
1025         {
1026           memmove (ready->vec + ready->veclen - ready->n_ready,
1027                    ready_lastpos (ready),
1028                    ready->n_ready * sizeof (rtx));
1029           ready->first = ready->veclen - 1;
1030         }
1031       ready->vec[ready->first - ready->n_ready] = insn;
1032     }
1033   else
1034     {
1035       if (ready->first == ready->veclen - 1)
1036         {
1037           if (ready->n_ready)
1038             /* ready_lastpos() fails when called with (ready->n_ready == 0).  */
1039             memmove (ready->vec + ready->veclen - ready->n_ready - 1,
1040                      ready_lastpos (ready),
1041                      ready->n_ready * sizeof (rtx));
1042           ready->first = ready->veclen - 2;
1043         }
1044       ready->vec[++(ready->first)] = insn;
1045     }
1046
1047   ready->n_ready++;
1048
1049   gcc_assert (QUEUE_INDEX (insn) != QUEUE_READY);
1050   QUEUE_INDEX (insn) = QUEUE_READY;
1051 }
1052
1053 /* Remove the element with the highest priority from the ready list and
1054    return it.  */
1055
1056 HAIFA_INLINE static rtx
1057 ready_remove_first (struct ready_list *ready)
1058 {
1059   rtx t;
1060   
1061   gcc_assert (ready->n_ready);
1062   t = ready->vec[ready->first--];
1063   ready->n_ready--;
1064   /* If the queue becomes empty, reset it.  */
1065   if (ready->n_ready == 0)
1066     ready->first = ready->veclen - 1;
1067
1068   gcc_assert (QUEUE_INDEX (t) == QUEUE_READY);
1069   QUEUE_INDEX (t) = QUEUE_NOWHERE;
1070
1071   return t;
1072 }
1073
1074 /* The following code implements multi-pass scheduling for the first
1075    cycle.  In other words, we will try to choose ready insn which
1076    permits to start maximum number of insns on the same cycle.  */
1077
1078 /* Return a pointer to the element INDEX from the ready.  INDEX for
1079    insn with the highest priority is 0, and the lowest priority has
1080    N_READY - 1.  */
1081
1082 HAIFA_INLINE static rtx
1083 ready_element (struct ready_list *ready, int index)
1084 {
1085   gcc_assert (ready->n_ready && index < ready->n_ready);
1086   
1087   return ready->vec[ready->first - index];
1088 }
1089
1090 /* Remove the element INDEX from the ready list and return it.  INDEX
1091    for insn with the highest priority is 0, and the lowest priority
1092    has N_READY - 1.  */
1093
1094 HAIFA_INLINE static rtx
1095 ready_remove (struct ready_list *ready, int index)
1096 {
1097   rtx t;
1098   int i;
1099
1100   if (index == 0)
1101     return ready_remove_first (ready);
1102   gcc_assert (ready->n_ready && index < ready->n_ready);
1103   t = ready->vec[ready->first - index];
1104   ready->n_ready--;
1105   for (i = index; i < ready->n_ready; i++)
1106     ready->vec[ready->first - i] = ready->vec[ready->first - i - 1];
1107   QUEUE_INDEX (t) = QUEUE_NOWHERE;
1108   return t;
1109 }
1110
1111 /* Remove INSN from the ready list.  */
1112 static void
1113 ready_remove_insn (rtx insn)
1114 {
1115   int i;
1116
1117   for (i = 0; i < readyp->n_ready; i++)
1118     if (ready_element (readyp, i) == insn)
1119       {
1120         ready_remove (readyp, i);
1121         return;
1122       }
1123   gcc_unreachable ();
1124 }
1125
1126 /* Sort the ready list READY by ascending priority, using the SCHED_SORT
1127    macro.  */
1128
1129 HAIFA_INLINE static void
1130 ready_sort (struct ready_list *ready)
1131 {
1132   rtx *first = ready_lastpos (ready);
1133   SCHED_SORT (first, ready->n_ready);
1134 }
1135
1136 /* PREV is an insn that is ready to execute.  Adjust its priority if that
1137    will help shorten or lengthen register lifetimes as appropriate.  Also
1138    provide a hook for the target to tweek itself.  */
1139
1140 HAIFA_INLINE static void
1141 adjust_priority (rtx prev)
1142 {
1143   /* ??? There used to be code here to try and estimate how an insn
1144      affected register lifetimes, but it did it by looking at REG_DEAD
1145      notes, which we removed in schedule_region.  Nor did it try to
1146      take into account register pressure or anything useful like that.
1147
1148      Revisit when we have a machine model to work with and not before.  */
1149
1150   if (targetm.sched.adjust_priority)
1151     INSN_PRIORITY (prev) =
1152       targetm.sched.adjust_priority (prev, INSN_PRIORITY (prev));
1153 }
1154
1155 /* Advance time on one cycle.  */
1156 HAIFA_INLINE static void
1157 advance_one_cycle (void)
1158 {
1159   if (targetm.sched.dfa_pre_cycle_insn)
1160     state_transition (curr_state,
1161                       targetm.sched.dfa_pre_cycle_insn ());
1162
1163   state_transition (curr_state, NULL);
1164   
1165   if (targetm.sched.dfa_post_cycle_insn)
1166     state_transition (curr_state,
1167                       targetm.sched.dfa_post_cycle_insn ());
1168 }
1169
1170 /* Clock at which the previous instruction was issued.  */
1171 static int last_clock_var;
1172
1173 /* INSN is the "currently executing insn".  Launch each insn which was
1174    waiting on INSN.  READY is the ready list which contains the insns
1175    that are ready to fire.  CLOCK is the current cycle.  The function
1176    returns necessary cycle advance after issuing the insn (it is not
1177    zero for insns in a schedule group).  */
1178
1179 static int
1180 schedule_insn (rtx insn)
1181 {
1182   dep_link_t link;
1183   int advance = 0;
1184
1185   if (sched_verbose >= 1)
1186     {
1187       char buf[2048];
1188
1189       print_insn (buf, insn, 0);
1190       buf[40] = 0;
1191       fprintf (sched_dump, ";;\t%3i--> %-40s:", clock_var, buf);
1192
1193       if (recog_memoized (insn) < 0)
1194         fprintf (sched_dump, "nothing");
1195       else
1196         print_reservation (sched_dump, insn);
1197       fputc ('\n', sched_dump);
1198     }
1199
1200   /* Scheduling instruction should have all its dependencies resolved and
1201      should have been removed from the ready list.  */
1202   gcc_assert (INSN_DEP_COUNT (insn) == 0
1203               && deps_list_empty_p (INSN_BACK_DEPS (insn)));
1204   free_deps_list (INSN_BACK_DEPS (insn));
1205
1206   /* Now we can free INSN_RESOLVED_BACK_DEPS list.  */
1207   delete_deps_list (INSN_RESOLVED_BACK_DEPS (insn));
1208
1209   gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
1210   QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
1211
1212   gcc_assert (INSN_TICK (insn) >= MIN_TICK);
1213   if (INSN_TICK (insn) > clock_var)
1214     /* INSN has been prematurely moved from the queue to the ready list.
1215        This is possible only if following flag is set.  */
1216     gcc_assert (flag_sched_stalled_insns);    
1217
1218   /* ??? Probably, if INSN is scheduled prematurely, we should leave
1219      INSN_TICK untouched.  This is a machine-dependent issue, actually.  */
1220   INSN_TICK (insn) = clock_var;
1221
1222   /* Update dependent instructions.  */
1223   FOR_EACH_DEP_LINK (link, INSN_FORW_DEPS (insn))
1224     {
1225       rtx next = DEP_LINK_CON (link);
1226
1227       /* Resolve the dependence between INSN and NEXT.  */
1228
1229       INSN_DEP_COUNT (next)--;
1230
1231       move_dep_link (DEP_NODE_BACK (DEP_LINK_NODE (link)),
1232                         INSN_RESOLVED_BACK_DEPS (next));
1233
1234       gcc_assert ((INSN_DEP_COUNT (next) == 0)
1235                   == deps_list_empty_p (INSN_BACK_DEPS (next)));
1236
1237       if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
1238         {
1239           int effective_cost;      
1240           
1241           effective_cost = try_ready (next);
1242           
1243           if (effective_cost >= 0
1244               && SCHED_GROUP_P (next)
1245               && advance < effective_cost)
1246             advance = effective_cost;
1247         }
1248       else
1249         /* Check always has only one forward dependence (to the first insn in
1250            the recovery block), therefore, this will be executed only once.  */
1251         {
1252           gcc_assert (DEP_LINK_NEXT (link) == NULL);
1253           fix_recovery_deps (RECOVERY_BLOCK (insn));
1254         }
1255     }
1256
1257   /* Annotate the instruction with issue information -- TImode
1258      indicates that the instruction is expected not to be able
1259      to issue on the same cycle as the previous insn.  A machine
1260      may use this information to decide how the instruction should
1261      be aligned.  */
1262   if (issue_rate > 1
1263       && GET_CODE (PATTERN (insn)) != USE
1264       && GET_CODE (PATTERN (insn)) != CLOBBER)
1265     {
1266       if (reload_completed)
1267         PUT_MODE (insn, clock_var > last_clock_var ? TImode : VOIDmode);
1268       last_clock_var = clock_var;
1269     }
1270
1271   return advance;
1272 }
1273
1274 /* Functions for handling of notes.  */
1275
1276 /* Delete notes beginning with INSN and put them in the chain
1277    of notes ended by NOTE_LIST.
1278    Returns the insn following the notes.  */
1279
1280 static rtx
1281 unlink_other_notes (rtx insn, rtx tail)
1282 {
1283   rtx prev = PREV_INSN (insn);
1284
1285   while (insn != tail && NOTE_NOT_BB_P (insn))
1286     {
1287       rtx next = NEXT_INSN (insn);
1288       basic_block bb = BLOCK_FOR_INSN (insn);
1289
1290       /* Delete the note from its current position.  */
1291       if (prev)
1292         NEXT_INSN (prev) = next;
1293       if (next)
1294         PREV_INSN (next) = prev;
1295
1296       if (bb)
1297         {
1298           /* Basic block can begin with either LABEL or
1299              NOTE_INSN_BASIC_BLOCK.  */
1300           gcc_assert (BB_HEAD (bb) != insn);
1301
1302           /* Check if we are removing last insn in the BB.  */
1303           if (BB_END (bb) == insn)
1304             BB_END (bb) = prev;
1305         }
1306
1307       /* See sched_analyze to see how these are handled.  */
1308       if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
1309           && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END)
1310         {
1311           /* Insert the note at the end of the notes list.  */
1312           PREV_INSN (insn) = note_list;
1313           if (note_list)
1314             NEXT_INSN (note_list) = insn;
1315           note_list = insn;
1316         }
1317
1318       insn = next;
1319     }
1320   return insn;
1321 }
1322
1323 /* Return the head and tail pointers of ebb starting at BEG and ending
1324    at END.  */
1325
1326 void
1327 get_ebb_head_tail (basic_block beg, basic_block end, rtx *headp, rtx *tailp)
1328 {
1329   rtx beg_head = BB_HEAD (beg);
1330   rtx beg_tail = BB_END (beg);
1331   rtx end_head = BB_HEAD (end);
1332   rtx end_tail = BB_END (end);
1333
1334   /* Don't include any notes or labels at the beginning of the BEG
1335      basic block, or notes at the end of the END basic blocks.  */
1336
1337   if (LABEL_P (beg_head))
1338     beg_head = NEXT_INSN (beg_head);
1339
1340   while (beg_head != beg_tail)
1341     if (NOTE_P (beg_head))
1342       beg_head = NEXT_INSN (beg_head);
1343     else
1344       break;
1345
1346   *headp = beg_head;
1347
1348   if (beg == end)
1349     end_head = beg_head;
1350   else if (LABEL_P (end_head))
1351     end_head = NEXT_INSN (end_head);
1352
1353   while (end_head != end_tail)
1354     if (NOTE_P (end_tail))
1355       end_tail = PREV_INSN (end_tail);
1356     else
1357       break;
1358
1359   *tailp = end_tail;
1360 }
1361
1362 /* Return nonzero if there are no real insns in the range [ HEAD, TAIL ].  */
1363
1364 int
1365 no_real_insns_p (rtx head, rtx tail)
1366 {
1367   while (head != NEXT_INSN (tail))
1368     {
1369       if (!NOTE_P (head) && !LABEL_P (head))
1370         return 0;
1371       head = NEXT_INSN (head);
1372     }
1373   return 1;
1374 }
1375
1376 /* Delete notes between HEAD and TAIL and put them in the chain
1377    of notes ended by NOTE_LIST.  */
1378
1379 void
1380 rm_other_notes (rtx head, rtx tail)
1381 {
1382   rtx next_tail;
1383   rtx insn;
1384
1385   note_list = 0;
1386   if (head == tail && (! INSN_P (head)))
1387     return;
1388
1389   next_tail = NEXT_INSN (tail);
1390   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1391     {
1392       rtx prev;
1393
1394       /* Farm out notes, and maybe save them in NOTE_LIST.
1395          This is needed to keep the debugger from
1396          getting completely deranged.  */
1397       if (NOTE_NOT_BB_P (insn))
1398         {
1399           prev = insn;
1400
1401           insn = unlink_other_notes (insn, next_tail);
1402
1403           gcc_assert (prev != tail && prev != head && insn != next_tail);
1404         }
1405     }
1406 }
1407
1408 /* Functions for computation of registers live/usage info.  */
1409
1410 /* This function looks for a new register being defined.
1411    If the destination register is already used by the source,
1412    a new register is not needed.  */
1413
1414 static int
1415 find_set_reg_weight (rtx x)
1416 {
1417   if (GET_CODE (x) == CLOBBER
1418       && register_operand (SET_DEST (x), VOIDmode))
1419     return 1;
1420   if (GET_CODE (x) == SET
1421       && register_operand (SET_DEST (x), VOIDmode))
1422     {
1423       if (REG_P (SET_DEST (x)))
1424         {
1425           if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
1426             return 1;
1427           else
1428             return 0;
1429         }
1430       return 1;
1431     }
1432   return 0;
1433 }
1434
1435 /* Calculate INSN_REG_WEIGHT for all insns of a block.  */
1436
1437 static void
1438 find_insn_reg_weight (basic_block bb)
1439 {
1440   rtx insn, next_tail, head, tail;
1441
1442   get_ebb_head_tail (bb, bb, &head, &tail);
1443   next_tail = NEXT_INSN (tail);
1444
1445   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1446     find_insn_reg_weight1 (insn);    
1447 }
1448
1449 /* Calculate INSN_REG_WEIGHT for single instruction.
1450    Separated from find_insn_reg_weight because of need
1451    to initialize new instruction in generate_recovery_code.  */
1452 static void
1453 find_insn_reg_weight1 (rtx insn)
1454 {
1455   int reg_weight = 0;
1456   rtx x;
1457   
1458   /* Handle register life information.  */
1459   if (! INSN_P (insn))
1460     return;
1461   
1462   /* Increment weight for each register born here.  */
1463   x = PATTERN (insn);
1464   reg_weight += find_set_reg_weight (x);
1465   if (GET_CODE (x) == PARALLEL)
1466     {
1467       int j;
1468       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
1469         {
1470           x = XVECEXP (PATTERN (insn), 0, j);
1471           reg_weight += find_set_reg_weight (x);
1472         }
1473     }
1474   /* Decrement weight for each register that dies here.  */
1475   for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
1476     {
1477       if (REG_NOTE_KIND (x) == REG_DEAD
1478           || REG_NOTE_KIND (x) == REG_UNUSED)
1479         reg_weight--;
1480     }
1481   
1482   INSN_REG_WEIGHT (insn) = reg_weight;
1483 }
1484
1485 /* Move insns that became ready to fire from queue to ready list.  */
1486
1487 static void
1488 queue_to_ready (struct ready_list *ready)
1489 {
1490   rtx insn;
1491   rtx link;
1492
1493   q_ptr = NEXT_Q (q_ptr);
1494
1495   /* Add all pending insns that can be scheduled without stalls to the
1496      ready list.  */
1497   for (link = insn_queue[q_ptr]; link; link = XEXP (link, 1))
1498     {
1499       insn = XEXP (link, 0);
1500       q_size -= 1;
1501
1502       if (sched_verbose >= 2)
1503         fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
1504                  (*current_sched_info->print_insn) (insn, 0));
1505
1506       /* If the ready list is full, delay the insn for 1 cycle.
1507          See the comment in schedule_block for the rationale.  */
1508       if (!reload_completed
1509           && ready->n_ready > MAX_SCHED_READY_INSNS
1510           && !SCHED_GROUP_P (insn))
1511         {
1512           if (sched_verbose >= 2)
1513             fprintf (sched_dump, "requeued because ready full\n");
1514           queue_insn (insn, 1);
1515         }
1516       else
1517         {
1518           ready_add (ready, insn, false);
1519           if (sched_verbose >= 2)
1520             fprintf (sched_dump, "moving to ready without stalls\n");
1521         }
1522     }
1523   free_INSN_LIST_list (&insn_queue[q_ptr]);
1524
1525   /* If there are no ready insns, stall until one is ready and add all
1526      of the pending insns at that point to the ready list.  */
1527   if (ready->n_ready == 0)
1528     {
1529       int stalls;
1530
1531       for (stalls = 1; stalls <= max_insn_queue_index; stalls++)
1532         {
1533           if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
1534             {
1535               for (; link; link = XEXP (link, 1))
1536                 {
1537                   insn = XEXP (link, 0);
1538                   q_size -= 1;
1539
1540                   if (sched_verbose >= 2)
1541                     fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
1542                              (*current_sched_info->print_insn) (insn, 0));
1543
1544                   ready_add (ready, insn, false);
1545                   if (sched_verbose >= 2)
1546                     fprintf (sched_dump, "moving to ready with %d stalls\n", stalls);
1547                 }
1548               free_INSN_LIST_list (&insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]);
1549
1550               advance_one_cycle ();
1551
1552               break;
1553             }
1554
1555           advance_one_cycle ();
1556         }
1557
1558       q_ptr = NEXT_Q_AFTER (q_ptr, stalls);
1559       clock_var += stalls;
1560     }
1561 }
1562
1563 /* Used by early_queue_to_ready.  Determines whether it is "ok" to
1564    prematurely move INSN from the queue to the ready list.  Currently, 
1565    if a target defines the hook 'is_costly_dependence', this function 
1566    uses the hook to check whether there exist any dependences which are
1567    considered costly by the target, between INSN and other insns that 
1568    have already been scheduled.  Dependences are checked up to Y cycles
1569    back, with default Y=1; The flag -fsched-stalled-insns-dep=Y allows
1570    controlling this value. 
1571    (Other considerations could be taken into account instead (or in 
1572    addition) depending on user flags and target hooks.  */
1573
1574 static bool 
1575 ok_for_early_queue_removal (rtx insn)
1576 {
1577   int n_cycles;
1578   rtx prev_insn = last_scheduled_insn;
1579
1580   if (targetm.sched.is_costly_dependence)
1581     {
1582       for (n_cycles = flag_sched_stalled_insns_dep; n_cycles; n_cycles--)
1583         {
1584           for ( ; prev_insn; prev_insn = PREV_INSN (prev_insn))
1585             {
1586               int cost;
1587
1588               if (!NOTE_P (prev_insn))
1589                 {
1590                   dep_link_t dep_link;
1591
1592                   dep_link = (find_link_by_con_in_deps_list
1593                               (INSN_FORW_DEPS (prev_insn), insn));
1594
1595                   if (dep_link)
1596                     {
1597                       dep_t dep = DEP_LINK_DEP (dep_link);
1598
1599                       cost = dep_cost (dep);
1600
1601                       if (targetm.sched.is_costly_dependence (dep, cost,
1602                                 flag_sched_stalled_insns_dep - n_cycles))
1603                         return false;
1604                     }
1605                 }
1606
1607               if (GET_MODE (prev_insn) == TImode) /* end of dispatch group */
1608                 break;
1609             }
1610
1611           if (!prev_insn) 
1612             break;
1613           prev_insn = PREV_INSN (prev_insn);     
1614         }
1615     }
1616
1617   return true;
1618 }
1619
1620
1621 /* Remove insns from the queue, before they become "ready" with respect
1622    to FU latency considerations.  */
1623
1624 static int 
1625 early_queue_to_ready (state_t state, struct ready_list *ready)
1626 {
1627   rtx insn;
1628   rtx link;
1629   rtx next_link;
1630   rtx prev_link;
1631   bool move_to_ready;
1632   int cost;
1633   state_t temp_state = alloca (dfa_state_size);
1634   int stalls;
1635   int insns_removed = 0;
1636
1637   /*
1638      Flag '-fsched-stalled-insns=X' determines the aggressiveness of this 
1639      function: 
1640
1641      X == 0: There is no limit on how many queued insns can be removed          
1642              prematurely.  (flag_sched_stalled_insns = -1).
1643
1644      X >= 1: Only X queued insns can be removed prematurely in each 
1645              invocation.  (flag_sched_stalled_insns = X).
1646
1647      Otherwise: Early queue removal is disabled.
1648          (flag_sched_stalled_insns = 0)
1649   */
1650
1651   if (! flag_sched_stalled_insns)   
1652     return 0;
1653
1654   for (stalls = 0; stalls <= max_insn_queue_index; stalls++)
1655     {
1656       if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
1657         {
1658           if (sched_verbose > 6)
1659             fprintf (sched_dump, ";; look at index %d + %d\n", q_ptr, stalls);
1660
1661           prev_link = 0;
1662           while (link)
1663             {
1664               next_link = XEXP (link, 1);
1665               insn = XEXP (link, 0);
1666               if (insn && sched_verbose > 6)
1667                 print_rtl_single (sched_dump, insn);
1668
1669               memcpy (temp_state, state, dfa_state_size);
1670               if (recog_memoized (insn) < 0) 
1671                 /* non-negative to indicate that it's not ready
1672                    to avoid infinite Q->R->Q->R... */
1673                 cost = 0;
1674               else
1675                 cost = state_transition (temp_state, insn);
1676
1677               if (sched_verbose >= 6)
1678                 fprintf (sched_dump, "transition cost = %d\n", cost);
1679
1680               move_to_ready = false;
1681               if (cost < 0) 
1682                 {
1683                   move_to_ready = ok_for_early_queue_removal (insn);
1684                   if (move_to_ready == true)
1685                     {
1686                       /* move from Q to R */
1687                       q_size -= 1;
1688                       ready_add (ready, insn, false);
1689
1690                       if (prev_link)   
1691                         XEXP (prev_link, 1) = next_link;
1692                       else
1693                         insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = next_link;
1694
1695                       free_INSN_LIST_node (link);
1696
1697                       if (sched_verbose >= 2)
1698                         fprintf (sched_dump, ";;\t\tEarly Q-->Ready: insn %s\n",
1699                                  (*current_sched_info->print_insn) (insn, 0));
1700
1701                       insns_removed++;
1702                       if (insns_removed == flag_sched_stalled_insns)
1703                         /* Remove no more than flag_sched_stalled_insns insns
1704                            from Q at a time.  */
1705                         return insns_removed;
1706                     }
1707                 }
1708
1709               if (move_to_ready == false)
1710                 prev_link = link;
1711
1712               link = next_link;
1713             } /* while link */
1714         } /* if link */    
1715
1716     } /* for stalls.. */
1717
1718   return insns_removed; 
1719 }
1720
1721
1722 /* Print the ready list for debugging purposes.  Callable from debugger.  */
1723
1724 static void
1725 debug_ready_list (struct ready_list *ready)
1726 {
1727   rtx *p;
1728   int i;
1729
1730   if (ready->n_ready == 0)
1731     {
1732       fprintf (sched_dump, "\n");
1733       return;
1734     }
1735
1736   p = ready_lastpos (ready);
1737   for (i = 0; i < ready->n_ready; i++)
1738     fprintf (sched_dump, "  %s", (*current_sched_info->print_insn) (p[i], 0));
1739   fprintf (sched_dump, "\n");
1740 }
1741
1742 /* Search INSN for REG_SAVE_NOTE note pairs for
1743    NOTE_INSN_EHREGION_{BEG,END}; and convert them back into
1744    NOTEs.  The REG_SAVE_NOTE note following first one is contains the
1745    saved value for NOTE_BLOCK_NUMBER which is useful for
1746    NOTE_INSN_EH_REGION_{BEG,END} NOTEs.  */
1747
1748 static void
1749 reemit_notes (rtx insn)
1750 {
1751   rtx note, last = insn;
1752
1753   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1754     {
1755       if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
1756         {
1757           enum insn_note note_type = INTVAL (XEXP (note, 0));
1758
1759           last = emit_note_before (note_type, last);
1760           remove_note (insn, note);
1761         }
1762     }
1763 }
1764
1765 /* Move INSN.  Reemit notes if needed.  Update CFG, if needed.  */
1766 static void
1767 move_insn (rtx insn)
1768 {
1769   rtx last = last_scheduled_insn;
1770
1771   if (PREV_INSN (insn) != last)
1772     {
1773       basic_block bb;
1774       rtx note;
1775       int jump_p = 0;
1776
1777       bb = BLOCK_FOR_INSN (insn);
1778  
1779       /* BB_HEAD is either LABEL or NOTE.  */
1780       gcc_assert (BB_HEAD (bb) != insn);      
1781
1782       if (BB_END (bb) == insn)
1783         /* If this is last instruction in BB, move end marker one
1784            instruction up.  */
1785         {
1786           /* Jumps are always placed at the end of basic block.  */
1787           jump_p = control_flow_insn_p (insn);
1788
1789           gcc_assert (!jump_p
1790                       || ((current_sched_info->flags & SCHED_RGN)
1791                           && IS_SPECULATION_BRANCHY_CHECK_P (insn))
1792                       || (current_sched_info->flags & SCHED_EBB));
1793           
1794           gcc_assert (BLOCK_FOR_INSN (PREV_INSN (insn)) == bb);
1795
1796           BB_END (bb) = PREV_INSN (insn);
1797         }
1798
1799       gcc_assert (BB_END (bb) != last);
1800
1801       if (jump_p)
1802         /* We move the block note along with jump.  */
1803         {
1804           /* NT is needed for assertion below.  */
1805           rtx nt = current_sched_info->next_tail;
1806
1807           note = NEXT_INSN (insn);
1808           while (NOTE_NOT_BB_P (note) && note != nt)
1809             note = NEXT_INSN (note);
1810
1811           if (note != nt
1812               && (LABEL_P (note)
1813                   || BARRIER_P (note)))
1814             note = NEXT_INSN (note);
1815       
1816           gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
1817         }
1818       else
1819         note = insn;
1820
1821       NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (note);
1822       PREV_INSN (NEXT_INSN (note)) = PREV_INSN (insn);
1823
1824       NEXT_INSN (note) = NEXT_INSN (last);
1825       PREV_INSN (NEXT_INSN (last)) = note;
1826
1827       NEXT_INSN (last) = insn;
1828       PREV_INSN (insn) = last;
1829
1830       bb = BLOCK_FOR_INSN (last);
1831
1832       if (jump_p)
1833         {
1834           fix_jump_move (insn);
1835
1836           if (BLOCK_FOR_INSN (insn) != bb)
1837             move_block_after_check (insn);
1838
1839           gcc_assert (BB_END (bb) == last);
1840         }
1841
1842       set_block_for_insn (insn, bb);    
1843   
1844       /* Update BB_END, if needed.  */
1845       if (BB_END (bb) == last)
1846         BB_END (bb) = insn;  
1847     }
1848   
1849   reemit_notes (insn);
1850
1851   SCHED_GROUP_P (insn) = 0;  
1852 }
1853
1854 /* The following structure describe an entry of the stack of choices.  */
1855 struct choice_entry
1856 {
1857   /* Ordinal number of the issued insn in the ready queue.  */
1858   int index;
1859   /* The number of the rest insns whose issues we should try.  */
1860   int rest;
1861   /* The number of issued essential insns.  */
1862   int n;
1863   /* State after issuing the insn.  */
1864   state_t state;
1865 };
1866
1867 /* The following array is used to implement a stack of choices used in
1868    function max_issue.  */
1869 static struct choice_entry *choice_stack;
1870
1871 /* The following variable value is number of essential insns issued on
1872    the current cycle.  An insn is essential one if it changes the
1873    processors state.  */
1874 static int cycle_issued_insns;
1875
1876 /* The following variable value is maximal number of tries of issuing
1877    insns for the first cycle multipass insn scheduling.  We define
1878    this value as constant*(DFA_LOOKAHEAD**ISSUE_RATE).  We would not
1879    need this constraint if all real insns (with non-negative codes)
1880    had reservations because in this case the algorithm complexity is
1881    O(DFA_LOOKAHEAD**ISSUE_RATE).  Unfortunately, the dfa descriptions
1882    might be incomplete and such insn might occur.  For such
1883    descriptions, the complexity of algorithm (without the constraint)
1884    could achieve DFA_LOOKAHEAD ** N , where N is the queue length.  */
1885 static int max_lookahead_tries;
1886
1887 /* The following value is value of hook
1888    `first_cycle_multipass_dfa_lookahead' at the last call of
1889    `max_issue'.  */
1890 static int cached_first_cycle_multipass_dfa_lookahead = 0;
1891
1892 /* The following value is value of `issue_rate' at the last call of
1893    `sched_init'.  */
1894 static int cached_issue_rate = 0;
1895
1896 /* The following function returns maximal (or close to maximal) number
1897    of insns which can be issued on the same cycle and one of which
1898    insns is insns with the best rank (the first insn in READY).  To
1899    make this function tries different samples of ready insns.  READY
1900    is current queue `ready'.  Global array READY_TRY reflects what
1901    insns are already issued in this try.  MAX_POINTS is the sum of points
1902    of all instructions in READY.  The function stops immediately,
1903    if it reached the such a solution, that all instruction can be issued.
1904    INDEX will contain index of the best insn in READY.  The following
1905    function is used only for first cycle multipass scheduling.  */
1906 static int
1907 max_issue (struct ready_list *ready, int *index, int max_points)
1908 {
1909   int n, i, all, n_ready, best, delay, tries_num, points = -1;
1910   struct choice_entry *top;
1911   rtx insn;
1912
1913   best = 0;
1914   memcpy (choice_stack->state, curr_state, dfa_state_size);
1915   top = choice_stack;
1916   top->rest = cached_first_cycle_multipass_dfa_lookahead;
1917   top->n = 0;
1918   n_ready = ready->n_ready;
1919   for (all = i = 0; i < n_ready; i++)
1920     if (!ready_try [i])
1921       all++;
1922   i = 0;
1923   tries_num = 0;
1924   for (;;)
1925     {
1926       if (top->rest == 0 || i >= n_ready)
1927         {
1928           if (top == choice_stack)
1929             break;
1930           if (best < top - choice_stack && ready_try [0])
1931             {
1932               best = top - choice_stack;
1933               *index = choice_stack [1].index;
1934               points = top->n;
1935               if (top->n == max_points || best == all)
1936                 break;
1937             }
1938           i = top->index;
1939           ready_try [i] = 0;
1940           top--;
1941           memcpy (curr_state, top->state, dfa_state_size);
1942         }
1943       else if (!ready_try [i])
1944         {
1945           tries_num++;
1946           if (tries_num > max_lookahead_tries)
1947             break;
1948           insn = ready_element (ready, i);
1949           delay = state_transition (curr_state, insn);
1950           if (delay < 0)
1951             {
1952               if (state_dead_lock_p (curr_state))
1953                 top->rest = 0;
1954               else
1955                 top->rest--;
1956               n = top->n;
1957               if (memcmp (top->state, curr_state, dfa_state_size) != 0)
1958                 n += ISSUE_POINTS (insn);
1959               top++;
1960               top->rest = cached_first_cycle_multipass_dfa_lookahead;
1961               top->index = i;
1962               top->n = n;
1963               memcpy (top->state, curr_state, dfa_state_size);
1964               ready_try [i] = 1;
1965               i = -1;
1966             }
1967         }
1968       i++;
1969     }
1970   while (top != choice_stack)
1971     {
1972       ready_try [top->index] = 0;
1973       top--;
1974     }
1975   memcpy (curr_state, choice_stack->state, dfa_state_size);  
1976
1977   if (sched_verbose >= 4)    
1978     fprintf (sched_dump, ";;\t\tChoosed insn : %s; points: %d/%d\n",
1979              (*current_sched_info->print_insn) (ready_element (ready, *index),
1980                                                 0), 
1981              points, max_points);
1982   
1983   return best;
1984 }
1985
1986 /* The following function chooses insn from READY and modifies
1987    *N_READY and READY.  The following function is used only for first
1988    cycle multipass scheduling.  */
1989
1990 static rtx
1991 choose_ready (struct ready_list *ready)
1992 {
1993   int lookahead = 0;
1994
1995   if (targetm.sched.first_cycle_multipass_dfa_lookahead)
1996     lookahead = targetm.sched.first_cycle_multipass_dfa_lookahead ();
1997   if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)))
1998     return ready_remove_first (ready);
1999   else
2000     {
2001       /* Try to choose the better insn.  */
2002       int index = 0, i, n;
2003       rtx insn;
2004       int more_issue, max_points, try_data = 1, try_control = 1;
2005       
2006       if (cached_first_cycle_multipass_dfa_lookahead != lookahead)
2007         {
2008           cached_first_cycle_multipass_dfa_lookahead = lookahead;
2009           max_lookahead_tries = 100;
2010           for (i = 0; i < issue_rate; i++)
2011             max_lookahead_tries *= lookahead;
2012         }
2013       insn = ready_element (ready, 0);
2014       if (INSN_CODE (insn) < 0)
2015         return ready_remove_first (ready);
2016
2017       if (spec_info
2018           && spec_info->flags & (PREFER_NON_DATA_SPEC
2019                                  | PREFER_NON_CONTROL_SPEC))
2020         {
2021           for (i = 0, n = ready->n_ready; i < n; i++)
2022             {
2023               rtx x;
2024               ds_t s;
2025
2026               x = ready_element (ready, i);
2027               s = TODO_SPEC (x);
2028               
2029               if (spec_info->flags & PREFER_NON_DATA_SPEC
2030                   && !(s & DATA_SPEC))
2031                 {                 
2032                   try_data = 0;
2033                   if (!(spec_info->flags & PREFER_NON_CONTROL_SPEC)
2034                       || !try_control)
2035                     break;
2036                 }
2037               
2038               if (spec_info->flags & PREFER_NON_CONTROL_SPEC
2039                   && !(s & CONTROL_SPEC))
2040                 {
2041                   try_control = 0;
2042                   if (!(spec_info->flags & PREFER_NON_DATA_SPEC) || !try_data)
2043                     break;
2044                 }
2045             }
2046         }
2047
2048       if ((!try_data && (TODO_SPEC (insn) & DATA_SPEC))
2049           || (!try_control && (TODO_SPEC (insn) & CONTROL_SPEC))
2050           || (targetm.sched.first_cycle_multipass_dfa_lookahead_guard_spec
2051               && !targetm.sched.first_cycle_multipass_dfa_lookahead_guard_spec
2052               (insn)))
2053         /* Discard speculative instruction that stands first in the ready
2054            list.  */
2055         {
2056           change_queue_index (insn, 1);
2057           return 0;
2058         }
2059
2060       max_points = ISSUE_POINTS (insn);
2061       more_issue = issue_rate - cycle_issued_insns - 1;
2062
2063       for (i = 1; i < ready->n_ready; i++)
2064         {
2065           insn = ready_element (ready, i);
2066           ready_try [i]
2067             = (INSN_CODE (insn) < 0
2068                || (!try_data && (TODO_SPEC (insn) & DATA_SPEC))
2069                || (!try_control && (TODO_SPEC (insn) & CONTROL_SPEC))
2070                || (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
2071                    && !targetm.sched.first_cycle_multipass_dfa_lookahead_guard
2072                    (insn)));
2073
2074           if (!ready_try [i] && more_issue-- > 0)
2075             max_points += ISSUE_POINTS (insn);
2076         }
2077
2078       if (max_issue (ready, &index, max_points) == 0)
2079         return ready_remove_first (ready);
2080       else
2081         return ready_remove (ready, index);
2082     }
2083 }
2084
2085 /* Use forward list scheduling to rearrange insns of block pointed to by
2086    TARGET_BB, possibly bringing insns from subsequent blocks in the same
2087    region.  */
2088
2089 void
2090 schedule_block (basic_block *target_bb, int rgn_n_insns1)
2091 {
2092   struct ready_list ready;
2093   int i, first_cycle_insn_p;
2094   int can_issue_more;
2095   state_t temp_state = NULL;  /* It is used for multipass scheduling.  */
2096   int sort_p, advance, start_clock_var;
2097
2098   /* Head/tail info for this block.  */
2099   rtx prev_head = current_sched_info->prev_head;
2100   rtx next_tail = current_sched_info->next_tail;
2101   rtx head = NEXT_INSN (prev_head);
2102   rtx tail = PREV_INSN (next_tail);
2103
2104   /* We used to have code to avoid getting parameters moved from hard
2105      argument registers into pseudos.
2106
2107      However, it was removed when it proved to be of marginal benefit
2108      and caused problems because schedule_block and compute_forward_dependences
2109      had different notions of what the "head" insn was.  */
2110
2111   gcc_assert (head != tail || INSN_P (head));
2112
2113   added_recovery_block_p = false;
2114
2115   /* Debug info.  */
2116   if (sched_verbose)
2117     dump_new_block_header (0, *target_bb, head, tail);
2118
2119   state_reset (curr_state);
2120
2121   /* Allocate the ready list.  */
2122   readyp = &ready;
2123   ready.vec = NULL;
2124   ready_try = NULL;
2125   choice_stack = NULL;
2126
2127   rgn_n_insns = -1;
2128   extend_ready (rgn_n_insns1 + 1);
2129
2130   ready.first = ready.veclen - 1;
2131   ready.n_ready = 0;
2132
2133   /* It is used for first cycle multipass scheduling.  */
2134   temp_state = alloca (dfa_state_size);
2135
2136   if (targetm.sched.md_init)
2137     targetm.sched.md_init (sched_dump, sched_verbose, ready.veclen);
2138
2139   /* We start inserting insns after PREV_HEAD.  */
2140   last_scheduled_insn = prev_head;
2141
2142   gcc_assert (NOTE_P (last_scheduled_insn)
2143               && BLOCK_FOR_INSN (last_scheduled_insn) == *target_bb);
2144
2145   /* Initialize INSN_QUEUE.  Q_SIZE is the total number of insns in the
2146      queue.  */
2147   q_ptr = 0;
2148   q_size = 0;
2149
2150   insn_queue = alloca ((max_insn_queue_index + 1) * sizeof (rtx));
2151   memset (insn_queue, 0, (max_insn_queue_index + 1) * sizeof (rtx));
2152
2153   /* Start just before the beginning of time.  */
2154   clock_var = -1;
2155
2156   /* We need queue and ready lists and clock_var be initialized 
2157      in try_ready () (which is called through init_ready_list ()).  */
2158   (*current_sched_info->init_ready_list) ();
2159
2160   /* The algorithm is O(n^2) in the number of ready insns at any given
2161      time in the worst case.  Before reload we are more likely to have
2162      big lists so truncate them to a reasonable size.  */
2163   if (!reload_completed && ready.n_ready > MAX_SCHED_READY_INSNS)
2164     {
2165       ready_sort (&ready);
2166
2167       /* Find first free-standing insn past MAX_SCHED_READY_INSNS.  */
2168       for (i = MAX_SCHED_READY_INSNS; i < ready.n_ready; i++)
2169         if (!SCHED_GROUP_P (ready_element (&ready, i)))
2170           break;
2171
2172       if (sched_verbose >= 2)
2173         {
2174           fprintf (sched_dump,
2175                    ";;\t\tReady list on entry: %d insns\n", ready.n_ready);
2176           fprintf (sched_dump,
2177                    ";;\t\t before reload => truncated to %d insns\n", i);
2178         }
2179
2180       /* Delay all insns past it for 1 cycle.  */
2181       while (i < ready.n_ready)
2182         queue_insn (ready_remove (&ready, i), 1);
2183     }
2184
2185   /* Now we can restore basic block notes and maintain precise cfg.  */
2186   restore_bb_notes (*target_bb);
2187
2188   last_clock_var = -1;
2189
2190   advance = 0;
2191
2192   sort_p = TRUE;
2193   /* Loop until all the insns in BB are scheduled.  */
2194   while ((*current_sched_info->schedule_more_p) ())
2195     {
2196       do
2197         {
2198           start_clock_var = clock_var;
2199
2200           clock_var++;
2201
2202           advance_one_cycle ();
2203
2204           /* Add to the ready list all pending insns that can be issued now.
2205              If there are no ready insns, increment clock until one
2206              is ready and add all pending insns at that point to the ready
2207              list.  */
2208           queue_to_ready (&ready);
2209
2210           gcc_assert (ready.n_ready);
2211
2212           if (sched_verbose >= 2)
2213             {
2214               fprintf (sched_dump, ";;\t\tReady list after queue_to_ready:  ");
2215               debug_ready_list (&ready);
2216             }
2217           advance -= clock_var - start_clock_var;
2218         }
2219       while (advance > 0);
2220
2221       if (sort_p)
2222         {
2223           /* Sort the ready list based on priority.  */
2224           ready_sort (&ready);
2225
2226           if (sched_verbose >= 2)
2227             {
2228               fprintf (sched_dump, ";;\t\tReady list after ready_sort:  ");
2229               debug_ready_list (&ready);
2230             }
2231         }
2232
2233       /* Allow the target to reorder the list, typically for
2234          better instruction bundling.  */
2235       if (sort_p && targetm.sched.reorder
2236           && (ready.n_ready == 0
2237               || !SCHED_GROUP_P (ready_element (&ready, 0))))
2238         can_issue_more =
2239           targetm.sched.reorder (sched_dump, sched_verbose,
2240                                  ready_lastpos (&ready),
2241                                  &ready.n_ready, clock_var);
2242       else
2243         can_issue_more = issue_rate;
2244
2245       first_cycle_insn_p = 1;
2246       cycle_issued_insns = 0;
2247       for (;;)
2248         {
2249           rtx insn;
2250           int cost;
2251           bool asm_p = false;
2252
2253           if (sched_verbose >= 2)
2254             {
2255               fprintf (sched_dump, ";;\tReady list (t = %3d):  ",
2256                        clock_var);
2257               debug_ready_list (&ready);
2258             }
2259
2260           if (ready.n_ready == 0 
2261               && can_issue_more 
2262               && reload_completed) 
2263             {
2264               /* Allow scheduling insns directly from the queue in case
2265                  there's nothing better to do (ready list is empty) but
2266                  there are still vacant dispatch slots in the current cycle.  */
2267               if (sched_verbose >= 6)
2268                 fprintf (sched_dump,";;\t\tSecond chance\n");
2269               memcpy (temp_state, curr_state, dfa_state_size);
2270               if (early_queue_to_ready (temp_state, &ready))
2271                 ready_sort (&ready);
2272             }
2273
2274           if (ready.n_ready == 0 || !can_issue_more
2275               || state_dead_lock_p (curr_state)
2276               || !(*current_sched_info->schedule_more_p) ())
2277             break;
2278
2279           /* Select and remove the insn from the ready list.  */
2280           if (sort_p)
2281             {
2282               insn = choose_ready (&ready);
2283               if (!insn)
2284                 continue;
2285             }
2286           else
2287             insn = ready_remove_first (&ready);
2288
2289           if (targetm.sched.dfa_new_cycle
2290               && targetm.sched.dfa_new_cycle (sched_dump, sched_verbose,
2291                                               insn, last_clock_var,
2292                                               clock_var, &sort_p))
2293             /* SORT_P is used by the target to override sorting
2294                of the ready list.  This is needed when the target
2295                has modified its internal structures expecting that
2296                the insn will be issued next.  As we need the insn
2297                to have the highest priority (so it will be returned by
2298                the ready_remove_first call above), we invoke
2299                ready_add (&ready, insn, true).
2300                But, still, there is one issue: INSN can be later 
2301                discarded by scheduler's front end through 
2302                current_sched_info->can_schedule_ready_p, hence, won't
2303                be issued next.  */ 
2304             {
2305               ready_add (&ready, insn, true);
2306               break;
2307             }
2308
2309           sort_p = TRUE;
2310           memcpy (temp_state, curr_state, dfa_state_size);
2311           if (recog_memoized (insn) < 0)
2312             {
2313               asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
2314                        || asm_noperands (PATTERN (insn)) >= 0);
2315               if (!first_cycle_insn_p && asm_p)
2316                 /* This is asm insn which is tryed to be issued on the
2317                    cycle not first.  Issue it on the next cycle.  */
2318                 cost = 1;
2319               else
2320                 /* A USE insn, or something else we don't need to
2321                    understand.  We can't pass these directly to
2322                    state_transition because it will trigger a
2323                    fatal error for unrecognizable insns.  */
2324                 cost = 0;
2325             }
2326           else
2327             {
2328               cost = state_transition (temp_state, insn);
2329               if (cost < 0)
2330                 cost = 0;
2331               else if (cost == 0)
2332                 cost = 1;
2333             }
2334
2335           if (cost >= 1)
2336             {
2337               queue_insn (insn, cost);
2338               if (SCHED_GROUP_P (insn))
2339                 {
2340                   advance = cost;
2341                   break;
2342                 }
2343  
2344               continue;
2345             }
2346
2347           if (current_sched_info->can_schedule_ready_p
2348               && ! (*current_sched_info->can_schedule_ready_p) (insn))
2349             /* We normally get here only if we don't want to move
2350                insn from the split block.  */
2351             {
2352               TODO_SPEC (insn) = (TODO_SPEC (insn) & ~SPECULATIVE) | HARD_DEP;
2353               continue;
2354             }
2355
2356           /* DECISION is made.  */      
2357   
2358           if (TODO_SPEC (insn) & SPECULATIVE)
2359             generate_recovery_code (insn);
2360
2361           if (control_flow_insn_p (last_scheduled_insn)      
2362               /* This is used to to switch basic blocks by request
2363                  from scheduler front-end (actually, sched-ebb.c only).
2364                  This is used to process blocks with single fallthru
2365                  edge.  If succeeding block has jump, it [jump] will try
2366                  move at the end of current bb, thus corrupting CFG.  */
2367               || current_sched_info->advance_target_bb (*target_bb, insn))
2368             {
2369               *target_bb = current_sched_info->advance_target_bb
2370                 (*target_bb, 0);
2371               
2372               if (sched_verbose)
2373                 {
2374                   rtx x;
2375
2376                   x = next_real_insn (last_scheduled_insn);
2377                   gcc_assert (x);
2378                   dump_new_block_header (1, *target_bb, x, tail);
2379                 }
2380
2381               last_scheduled_insn = bb_note (*target_bb);
2382             }
2383  
2384           /* Update counters, etc in the scheduler's front end.  */
2385           (*current_sched_info->begin_schedule_ready) (insn,
2386                                                        last_scheduled_insn);
2387  
2388           move_insn (insn);
2389           last_scheduled_insn = insn;
2390           
2391           if (memcmp (curr_state, temp_state, dfa_state_size) != 0)
2392             {
2393               cycle_issued_insns++;
2394               memcpy (curr_state, temp_state, dfa_state_size);
2395             }
2396
2397           if (targetm.sched.variable_issue)
2398             can_issue_more =
2399               targetm.sched.variable_issue (sched_dump, sched_verbose,
2400                                                insn, can_issue_more);
2401           /* A naked CLOBBER or USE generates no instruction, so do
2402              not count them against the issue rate.  */
2403           else if (GET_CODE (PATTERN (insn)) != USE
2404                    && GET_CODE (PATTERN (insn)) != CLOBBER)
2405             can_issue_more--;
2406
2407           advance = schedule_insn (insn);
2408
2409           /* After issuing an asm insn we should start a new cycle.  */
2410           if (advance == 0 && asm_p)
2411             advance = 1;
2412           if (advance != 0)
2413             break;
2414
2415           first_cycle_insn_p = 0;
2416
2417           /* Sort the ready list based on priority.  This must be
2418              redone here, as schedule_insn may have readied additional
2419              insns that will not be sorted correctly.  */
2420           if (ready.n_ready > 0)
2421             ready_sort (&ready);
2422
2423           if (targetm.sched.reorder2
2424               && (ready.n_ready == 0
2425                   || !SCHED_GROUP_P (ready_element (&ready, 0))))
2426             {
2427               can_issue_more =
2428                 targetm.sched.reorder2 (sched_dump, sched_verbose,
2429                                         ready.n_ready
2430                                         ? ready_lastpos (&ready) : NULL,
2431                                         &ready.n_ready, clock_var);
2432             }
2433         }
2434     }
2435
2436   /* Debug info.  */
2437   if (sched_verbose)
2438     {
2439       fprintf (sched_dump, ";;\tReady list (final):  ");
2440       debug_ready_list (&ready);
2441     }
2442
2443   if (current_sched_info->queue_must_finish_empty)
2444     /* Sanity check -- queue must be empty now.  Meaningless if region has
2445        multiple bbs.  */
2446     gcc_assert (!q_size && !ready.n_ready);
2447   else 
2448     {
2449       /* We must maintain QUEUE_INDEX between blocks in region.  */
2450       for (i = ready.n_ready - 1; i >= 0; i--)
2451         {
2452           rtx x;
2453           
2454           x = ready_element (&ready, i);
2455           QUEUE_INDEX (x) = QUEUE_NOWHERE;
2456           TODO_SPEC (x) = (TODO_SPEC (x) & ~SPECULATIVE) | HARD_DEP;
2457         }
2458
2459       if (q_size)   
2460         for (i = 0; i <= max_insn_queue_index; i++)
2461           {
2462             rtx link;
2463             for (link = insn_queue[i]; link; link = XEXP (link, 1))
2464               {
2465                 rtx x;
2466
2467                 x = XEXP (link, 0);
2468                 QUEUE_INDEX (x) = QUEUE_NOWHERE;
2469                 TODO_SPEC (x) = (TODO_SPEC (x) & ~SPECULATIVE) | HARD_DEP;
2470               }
2471             free_INSN_LIST_list (&insn_queue[i]);
2472           }
2473     }
2474
2475   if (!current_sched_info->queue_must_finish_empty
2476       || added_recovery_block_p)
2477     {
2478       /* INSN_TICK (minimum clock tick at which the insn becomes
2479          ready) may be not correct for the insn in the subsequent
2480          blocks of the region.  We should use a correct value of
2481          `clock_var' or modify INSN_TICK.  It is better to keep
2482          clock_var value equal to 0 at the start of a basic block.
2483          Therefore we modify INSN_TICK here.  */
2484       fix_inter_tick (NEXT_INSN (prev_head), last_scheduled_insn);
2485     }
2486
2487   if (targetm.sched.md_finish)
2488     targetm.sched.md_finish (sched_dump, sched_verbose);
2489
2490   /* Update head/tail boundaries.  */
2491   head = NEXT_INSN (prev_head);
2492   tail = last_scheduled_insn;
2493
2494   /* Restore-other-notes: NOTE_LIST is the end of a chain of notes
2495      previously found among the insns.  Insert them at the beginning
2496      of the insns.  */
2497   if (note_list != 0)
2498     {
2499       basic_block head_bb = BLOCK_FOR_INSN (head);
2500       rtx note_head = note_list;
2501
2502       while (PREV_INSN (note_head))
2503         {
2504           set_block_for_insn (note_head, head_bb);
2505           note_head = PREV_INSN (note_head);
2506         }
2507       /* In the above cycle we've missed this note:  */
2508       set_block_for_insn (note_head, head_bb);
2509
2510       PREV_INSN (note_head) = PREV_INSN (head);
2511       NEXT_INSN (PREV_INSN (head)) = note_head;
2512       PREV_INSN (head) = note_list;
2513       NEXT_INSN (note_list) = head;
2514       head = note_head;
2515     }
2516
2517   /* Debugging.  */
2518   if (sched_verbose)
2519     {
2520       fprintf (sched_dump, ";;   total time = %d\n;;   new head = %d\n",
2521                clock_var, INSN_UID (head));
2522       fprintf (sched_dump, ";;   new tail = %d\n\n",
2523                INSN_UID (tail));
2524     }
2525
2526   current_sched_info->head = head;
2527   current_sched_info->tail = tail;
2528
2529   free (ready.vec);
2530
2531   free (ready_try);
2532   for (i = 0; i <= rgn_n_insns; i++)
2533     free (choice_stack [i].state);
2534   free (choice_stack);
2535 }
2536 \f
2537 /* Set_priorities: compute priority of each insn in the block.  */
2538
2539 int
2540 set_priorities (rtx head, rtx tail)
2541 {
2542   rtx insn;
2543   int n_insn;
2544   int sched_max_insns_priority = 
2545         current_sched_info->sched_max_insns_priority;
2546   rtx prev_head;
2547
2548   if (head == tail && (! INSN_P (head)))
2549     return 0;
2550
2551   n_insn = 0;
2552
2553   prev_head = PREV_INSN (head);
2554   for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
2555     {
2556       if (!INSN_P (insn))
2557         continue;
2558
2559       n_insn++;
2560       (void) priority (insn);
2561
2562       gcc_assert (INSN_PRIORITY_KNOWN (insn));
2563
2564       sched_max_insns_priority = MAX (sched_max_insns_priority,
2565                                       INSN_PRIORITY (insn));
2566     }
2567
2568   current_sched_info->sched_max_insns_priority = sched_max_insns_priority;
2569
2570   return n_insn;
2571 }
2572
2573 /* Next LUID to assign to an instruction.  */
2574 static int luid;
2575
2576 /* Initialize some global state for the scheduler.  */
2577
2578 void
2579 sched_init (void)
2580 {
2581   basic_block b;
2582   rtx insn;
2583   int i;
2584
2585   /* Switch to working copy of sched_info.  */
2586   memcpy (&current_sched_info_var, current_sched_info,
2587           sizeof (current_sched_info_var));
2588   current_sched_info = &current_sched_info_var;
2589       
2590   /* Disable speculative loads in their presence if cc0 defined.  */
2591 #ifdef HAVE_cc0
2592   flag_schedule_speculative_load = 0;
2593 #endif
2594
2595   /* Set dump and sched_verbose for the desired debugging output.  If no
2596      dump-file was specified, but -fsched-verbose=N (any N), print to stderr.
2597      For -fsched-verbose=N, N>=10, print everything to stderr.  */
2598   sched_verbose = sched_verbose_param;
2599   if (sched_verbose_param == 0 && dump_file)
2600     sched_verbose = 1;
2601   sched_dump = ((sched_verbose_param >= 10 || !dump_file)
2602                 ? stderr : dump_file);
2603
2604   /* Initialize SPEC_INFO.  */
2605   if (targetm.sched.set_sched_flags)
2606     {
2607       spec_info = &spec_info_var;
2608       targetm.sched.set_sched_flags (spec_info);
2609       if (current_sched_info->flags & DO_SPECULATION)
2610         spec_info->weakness_cutoff =
2611           (PARAM_VALUE (PARAM_SCHED_SPEC_PROB_CUTOFF) * MAX_DEP_WEAK) / 100;
2612       else
2613         /* So we won't read anything accidentally.  */
2614         spec_info = 0;
2615 #ifdef ENABLE_CHECKING
2616       check_sched_flags ();
2617 #endif
2618     }
2619   else
2620     /* So we won't read anything accidentally.  */
2621     spec_info = 0;
2622
2623   /* Initialize issue_rate.  */
2624   if (targetm.sched.issue_rate)
2625     issue_rate = targetm.sched.issue_rate ();
2626   else
2627     issue_rate = 1;
2628
2629   if (cached_issue_rate != issue_rate)
2630     {
2631       cached_issue_rate = issue_rate;
2632       /* To invalidate max_lookahead_tries:  */
2633       cached_first_cycle_multipass_dfa_lookahead = 0;
2634     }
2635
2636   old_max_uid = 0;
2637   h_i_d = 0;
2638   extend_h_i_d ();
2639
2640   for (i = 0; i < old_max_uid; i++)
2641     {
2642       h_i_d[i].cost = -1;
2643       h_i_d[i].todo_spec = HARD_DEP;
2644       h_i_d[i].queue_index = QUEUE_NOWHERE;
2645       h_i_d[i].tick = INVALID_TICK;
2646       h_i_d[i].inter_tick = INVALID_TICK;
2647     }
2648
2649   if (targetm.sched.init_dfa_pre_cycle_insn)
2650     targetm.sched.init_dfa_pre_cycle_insn ();
2651
2652   if (targetm.sched.init_dfa_post_cycle_insn)
2653     targetm.sched.init_dfa_post_cycle_insn ();
2654
2655   dfa_start ();
2656   dfa_state_size = state_size ();
2657   curr_state = xmalloc (dfa_state_size);
2658
2659   h_i_d[0].luid = 0;
2660   luid = 1;
2661   FOR_EACH_BB (b)
2662     for (insn = BB_HEAD (b); ; insn = NEXT_INSN (insn))
2663       {
2664         INSN_LUID (insn) = luid;
2665
2666         /* Increment the next luid, unless this is a note.  We don't
2667            really need separate IDs for notes and we don't want to
2668            schedule differently depending on whether or not there are
2669            line-number notes, i.e., depending on whether or not we're
2670            generating debugging information.  */
2671         if (!NOTE_P (insn))
2672           ++luid;
2673
2674         if (insn == BB_END (b))
2675           break;
2676       }
2677
2678   init_dependency_caches (luid);
2679
2680   init_alias_analysis ();
2681
2682   old_last_basic_block = 0;
2683   glat_start = 0;  
2684   glat_end = 0;
2685   extend_bb ();
2686
2687   if (current_sched_info->flags & USE_GLAT)
2688     init_glat ();
2689
2690   /* Compute INSN_REG_WEIGHT for all blocks.  We must do this before
2691      removing death notes.  */
2692   FOR_EACH_BB_REVERSE (b)
2693     find_insn_reg_weight (b);
2694
2695   if (targetm.sched.md_init_global)
2696       targetm.sched.md_init_global (sched_dump, sched_verbose, old_max_uid);
2697
2698   nr_begin_data = nr_begin_control = nr_be_in_data = nr_be_in_control = 0;
2699   before_recovery = 0;
2700
2701 #ifdef ENABLE_CHECKING
2702   /* This is used preferably for finding bugs in check_cfg () itself.  */
2703   check_cfg (0, 0);
2704 #endif
2705 }
2706
2707 /* Free global data used during insn scheduling.  */
2708
2709 void
2710 sched_finish (void)
2711 {
2712   free (h_i_d);
2713   free (curr_state);
2714   dfa_finish ();
2715   free_dependency_caches ();
2716   end_alias_analysis ();
2717   free_glat ();
2718
2719   if (targetm.sched.md_finish_global)
2720     targetm.sched.md_finish_global (sched_dump, sched_verbose);
2721   
2722   if (spec_info && spec_info->dump)
2723     {
2724       char c = reload_completed ? 'a' : 'b';
2725
2726       fprintf (spec_info->dump,
2727                ";; %s:\n", current_function_name ());
2728
2729       fprintf (spec_info->dump,
2730                ";; Procedure %cr-begin-data-spec motions == %d\n",
2731                c, nr_begin_data);
2732       fprintf (spec_info->dump,
2733                ";; Procedure %cr-be-in-data-spec motions == %d\n",
2734                c, nr_be_in_data);
2735       fprintf (spec_info->dump,
2736                ";; Procedure %cr-begin-control-spec motions == %d\n",
2737                c, nr_begin_control);
2738       fprintf (spec_info->dump,
2739                ";; Procedure %cr-be-in-control-spec motions == %d\n",
2740                c, nr_be_in_control);
2741     }
2742
2743 #ifdef ENABLE_CHECKING
2744   /* After reload ia64 backend clobbers CFG, so can't check anything.  */
2745   if (!reload_completed)
2746     check_cfg (0, 0);
2747 #endif
2748
2749   current_sched_info = NULL;
2750 }
2751
2752 /* Fix INSN_TICKs of the instructions in the current block as well as
2753    INSN_TICKs of their dependents.
2754    HEAD and TAIL are the begin and the end of the current scheduled block.  */
2755 static void
2756 fix_inter_tick (rtx head, rtx tail)
2757 {
2758   /* Set of instructions with corrected INSN_TICK.  */
2759   bitmap_head processed;
2760   int next_clock = clock_var + 1;
2761
2762   bitmap_initialize (&processed, 0);
2763   
2764   /* Iterates over scheduled instructions and fix their INSN_TICKs and
2765      INSN_TICKs of dependent instructions, so that INSN_TICKs are consistent
2766      across different blocks.  */
2767   for (tail = NEXT_INSN (tail); head != tail; head = NEXT_INSN (head))
2768     {
2769       if (INSN_P (head))
2770         {
2771           int tick;
2772           dep_link_t link;
2773                   
2774           tick = INSN_TICK (head);
2775           gcc_assert (tick >= MIN_TICK);
2776           
2777           /* Fix INSN_TICK of instruction from just scheduled block.  */
2778           if (!bitmap_bit_p (&processed, INSN_LUID (head)))
2779             {
2780               bitmap_set_bit (&processed, INSN_LUID (head));
2781               tick -= next_clock;
2782               
2783               if (tick < MIN_TICK)
2784                 tick = MIN_TICK;
2785               
2786               INSN_TICK (head) = tick;           
2787             }
2788           
2789           FOR_EACH_DEP_LINK (link, INSN_FORW_DEPS (head))
2790             {
2791               rtx next;
2792               
2793               next = DEP_LINK_CON (link);
2794               tick = INSN_TICK (next);
2795
2796               if (tick != INVALID_TICK
2797                   /* If NEXT has its INSN_TICK calculated, fix it.
2798                      If not - it will be properly calculated from
2799                      scratch later in fix_tick_ready.  */
2800                   && !bitmap_bit_p (&processed, INSN_LUID (next)))
2801                 {
2802                   bitmap_set_bit (&processed, INSN_LUID (next));
2803                   tick -= next_clock;
2804                   
2805                   if (tick < MIN_TICK)
2806                     tick = MIN_TICK;
2807                   
2808                   if (tick > INTER_TICK (next))
2809                     INTER_TICK (next) = tick;
2810                   else
2811                     tick = INTER_TICK (next);
2812                   
2813                   INSN_TICK (next) = tick;
2814                 }
2815             }
2816         }
2817     }
2818   bitmap_clear (&processed);
2819 }
2820   
2821 /* Check if NEXT is ready to be added to the ready or queue list.
2822    If "yes", add it to the proper list.
2823    Returns:
2824       -1 - is not ready yet,
2825        0 - added to the ready list,
2826    0 < N - queued for N cycles.  */
2827 int
2828 try_ready (rtx next)
2829 {  
2830   ds_t old_ts, *ts;
2831   dep_link_t link;
2832
2833   ts = &TODO_SPEC (next);
2834   old_ts = *ts;
2835
2836   gcc_assert (!(old_ts & ~(SPECULATIVE | HARD_DEP))
2837               && ((old_ts & HARD_DEP)
2838                   || (old_ts & SPECULATIVE)));
2839   
2840   if (!(current_sched_info->flags & DO_SPECULATION))
2841     {
2842       if (deps_list_empty_p (INSN_BACK_DEPS (next)))
2843         *ts &= ~HARD_DEP;
2844     }
2845   else
2846     {
2847       *ts &= ~SPECULATIVE & ~HARD_DEP;
2848
2849       link = DEPS_LIST_FIRST (INSN_BACK_DEPS (next));
2850
2851       if (link != NULL)
2852         {
2853           ds_t ds = DEP_LINK_STATUS (link) & SPECULATIVE;
2854
2855           /* Backward dependencies of the insn are maintained sorted. 
2856              So if DEP_STATUS of the first dep is SPECULATIVE,
2857              than all other deps are speculative too.  */
2858           if (ds != 0)
2859             {          
2860               /* Now we've got NEXT with speculative deps only.
2861                  1. Look at the deps to see what we have to do.
2862                  2. Check if we can do 'todo'.  */
2863               *ts = ds;
2864
2865               while ((link = DEP_LINK_NEXT (link)) != NULL)
2866                 {
2867                   ds = DEP_LINK_STATUS (link) & SPECULATIVE;
2868                   *ts = ds_merge (*ts, ds);
2869                 }
2870
2871               if (dep_weak (*ts) < spec_info->weakness_cutoff)
2872                 /* Too few points.  */
2873                 *ts = (*ts & ~SPECULATIVE) | HARD_DEP;
2874             }
2875           else
2876             *ts |= HARD_DEP;
2877         }
2878     }
2879
2880   if (*ts & HARD_DEP)
2881     gcc_assert (*ts == old_ts
2882                 && QUEUE_INDEX (next) == QUEUE_NOWHERE);
2883   else if (current_sched_info->new_ready)
2884     *ts = current_sched_info->new_ready (next, *ts);
2885
2886   /* * if !(old_ts & SPECULATIVE) (e.g. HARD_DEP or 0), then insn might
2887      have its original pattern or changed (speculative) one.  This is due
2888      to changing ebb in region scheduling.
2889      * But if (old_ts & SPECULATIVE), then we are pretty sure that insn
2890      has speculative pattern.
2891
2892      We can't assert (!(*ts & HARD_DEP) || *ts == old_ts) here because
2893      control-speculative NEXT could have been discarded by sched-rgn.c
2894      (the same case as when discarded by can_schedule_ready_p ()).  */
2895
2896   if ((*ts & SPECULATIVE)
2897       /* If (old_ts == *ts), then (old_ts & SPECULATIVE) and we don't
2898          need to change anything.  */
2899       && *ts != old_ts)
2900     {
2901       int res;
2902       rtx new_pat;
2903       
2904       gcc_assert ((*ts & SPECULATIVE) && !(*ts & ~SPECULATIVE));
2905       
2906       res = speculate_insn (next, *ts, &new_pat);
2907         
2908       switch (res)
2909         {
2910         case -1:
2911           /* It would be nice to change DEP_STATUS of all dependences,
2912              which have ((DEP_STATUS & SPECULATIVE) == *ts) to HARD_DEP,
2913              so we won't reanalyze anything.  */
2914           *ts = (*ts & ~SPECULATIVE) | HARD_DEP;
2915           break;
2916           
2917         case 0:
2918           /* We follow the rule, that every speculative insn
2919              has non-null ORIG_PAT.  */
2920           if (!ORIG_PAT (next))
2921             ORIG_PAT (next) = PATTERN (next);
2922           break;
2923           
2924         case 1:                  
2925           if (!ORIG_PAT (next))
2926             /* If we gonna to overwrite the original pattern of insn,
2927                save it.  */
2928             ORIG_PAT (next) = PATTERN (next);
2929           
2930           change_pattern (next, new_pat);
2931           break;
2932           
2933         default:
2934           gcc_unreachable ();
2935         }
2936     }
2937   
2938   /* We need to restore pattern only if (*ts == 0), because otherwise it is
2939      either correct (*ts & SPECULATIVE),
2940      or we simply don't care (*ts & HARD_DEP).  */
2941   
2942   gcc_assert (!ORIG_PAT (next)
2943               || !IS_SPECULATION_BRANCHY_CHECK_P (next));
2944   
2945   if (*ts & HARD_DEP)
2946     {
2947       /* We can't assert (QUEUE_INDEX (next) == QUEUE_NOWHERE) here because
2948          control-speculative NEXT could have been discarded by sched-rgn.c
2949          (the same case as when discarded by can_schedule_ready_p ()).  */
2950       /*gcc_assert (QUEUE_INDEX (next) == QUEUE_NOWHERE);*/
2951       
2952       change_queue_index (next, QUEUE_NOWHERE);
2953       return -1;
2954     }
2955   else if (!(*ts & BEGIN_SPEC) && ORIG_PAT (next) && !IS_SPECULATION_CHECK_P (next))
2956     /* We should change pattern of every previously speculative 
2957        instruction - and we determine if NEXT was speculative by using
2958        ORIG_PAT field.  Except one case - speculation checks have ORIG_PAT
2959        pat too, so skip them.  */
2960     {
2961       change_pattern (next, ORIG_PAT (next));
2962       ORIG_PAT (next) = 0;
2963     }
2964
2965   if (sched_verbose >= 2)
2966     {         
2967       int s = TODO_SPEC (next);
2968           
2969       fprintf (sched_dump, ";;\t\tdependencies resolved: insn %s",
2970                (*current_sched_info->print_insn) (next, 0));
2971           
2972       if (spec_info && spec_info->dump)
2973         {
2974           if (s & BEGIN_DATA)
2975             fprintf (spec_info->dump, "; data-spec;");
2976           if (s & BEGIN_CONTROL)
2977             fprintf (spec_info->dump, "; control-spec;");
2978           if (s & BE_IN_CONTROL)
2979             fprintf (spec_info->dump, "; in-control-spec;");
2980         }
2981
2982       fprintf (sched_dump, "\n");
2983     }          
2984   
2985   adjust_priority (next);
2986         
2987   return fix_tick_ready (next);
2988 }
2989
2990 /* Calculate INSN_TICK of NEXT and add it to either ready or queue list.  */
2991 static int
2992 fix_tick_ready (rtx next)
2993 {
2994   int tick, delay;
2995
2996   if (!deps_list_empty_p (INSN_RESOLVED_BACK_DEPS (next)))
2997     {
2998       int full_p;
2999       dep_link_t link;
3000
3001       tick = INSN_TICK (next);
3002       /* if tick is not equal to INVALID_TICK, then update
3003          INSN_TICK of NEXT with the most recent resolved dependence
3004          cost.  Otherwise, recalculate from scratch.  */
3005       full_p = (tick == INVALID_TICK);
3006
3007       FOR_EACH_DEP_LINK (link, INSN_RESOLVED_BACK_DEPS (next))
3008         {       
3009           dep_t dep = DEP_LINK_DEP (link);
3010           rtx pro = DEP_PRO (dep);
3011           int tick1;
3012               
3013           gcc_assert (INSN_TICK (pro) >= MIN_TICK);
3014
3015           tick1 = INSN_TICK (pro) + dep_cost (dep);
3016           if (tick1 > tick)
3017             tick = tick1;
3018
3019           if (!full_p)
3020             break;
3021         }
3022     }
3023   else
3024     tick = -1;
3025
3026   INSN_TICK (next) = tick;
3027
3028   delay = tick - clock_var;
3029   if (delay <= 0)
3030     delay = QUEUE_READY;
3031
3032   change_queue_index (next, delay);
3033
3034   return delay;
3035 }
3036
3037 /* Move NEXT to the proper queue list with (DELAY >= 1),
3038    or add it to the ready list (DELAY == QUEUE_READY),
3039    or remove it from ready and queue lists at all (DELAY == QUEUE_NOWHERE).  */
3040 static void
3041 change_queue_index (rtx next, int delay)
3042 {
3043   int i = QUEUE_INDEX (next);
3044
3045   gcc_assert (QUEUE_NOWHERE <= delay && delay <= max_insn_queue_index 
3046               && delay != 0);
3047   gcc_assert (i != QUEUE_SCHEDULED);
3048   
3049   if ((delay > 0 && NEXT_Q_AFTER (q_ptr, delay) == i)
3050       || (delay < 0 && delay == i))
3051     /* We have nothing to do.  */
3052     return;
3053
3054   /* Remove NEXT from wherever it is now.  */
3055   if (i == QUEUE_READY)
3056     ready_remove_insn (next);
3057   else if (i >= 0)
3058     queue_remove (next);
3059     
3060   /* Add it to the proper place.  */
3061   if (delay == QUEUE_READY)
3062     ready_add (readyp, next, false);
3063   else if (delay >= 1)
3064     queue_insn (next, delay);
3065     
3066   if (sched_verbose >= 2)
3067     {         
3068       fprintf (sched_dump, ";;\t\ttick updated: insn %s",
3069                (*current_sched_info->print_insn) (next, 0));
3070       
3071       if (delay == QUEUE_READY)
3072         fprintf (sched_dump, " into ready\n");
3073       else if (delay >= 1)
3074         fprintf (sched_dump, " into queue with cost=%d\n", delay);
3075       else
3076         fprintf (sched_dump, " removed from ready or queue lists\n");
3077     }
3078 }
3079
3080 /* Extend H_I_D data.  */
3081 static void
3082 extend_h_i_d (void)
3083 {
3084   /* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
3085      pseudos which do not cross calls.  */
3086   int new_max_uid = get_max_uid () + 1;  
3087
3088   h_i_d = xrecalloc (h_i_d, new_max_uid, old_max_uid, sizeof (*h_i_d));
3089   old_max_uid = new_max_uid;
3090
3091   if (targetm.sched.h_i_d_extended)
3092     targetm.sched.h_i_d_extended ();
3093 }
3094
3095 /* Extend READY, READY_TRY and CHOICE_STACK arrays.
3096    N_NEW_INSNS is the number of additional elements to allocate.  */
3097 static void
3098 extend_ready (int n_new_insns)
3099 {
3100   int i;
3101
3102   readyp->veclen = rgn_n_insns + n_new_insns + 1 + issue_rate;
3103   readyp->vec = XRESIZEVEC (rtx, readyp->vec, readyp->veclen);
3104  
3105   ready_try = xrecalloc (ready_try, rgn_n_insns + n_new_insns + 1,
3106                          rgn_n_insns + 1, sizeof (char));
3107
3108   rgn_n_insns += n_new_insns;
3109
3110   choice_stack = XRESIZEVEC (struct choice_entry, choice_stack,
3111                              rgn_n_insns + 1);
3112
3113   for (i = rgn_n_insns; n_new_insns--; i--)
3114     choice_stack[i].state = xmalloc (dfa_state_size);
3115 }
3116
3117 /* Extend global scheduler structures (those, that live across calls to
3118    schedule_block) to include information about just emitted INSN.  */
3119 static void
3120 extend_global (rtx insn)
3121 {
3122   gcc_assert (INSN_P (insn));
3123   /* These structures have scheduler scope.  */
3124   extend_h_i_d ();
3125   init_h_i_d (insn);
3126
3127   extend_dependency_caches (1, 0);
3128 }
3129
3130 /* Extends global and local scheduler structures to include information
3131    about just emitted INSN.  */
3132 static void
3133 extend_all (rtx insn)
3134
3135   extend_global (insn);
3136
3137   /* These structures have block scope.  */
3138   extend_ready (1);
3139   
3140   (*current_sched_info->add_remove_insn) (insn, 0);
3141 }
3142
3143 /* Initialize h_i_d entry of the new INSN with default values.
3144    Values, that are not explicitly initialized here, hold zero.  */
3145 static void
3146 init_h_i_d (rtx insn)
3147 {
3148   INSN_LUID (insn) = luid++;
3149   INSN_COST (insn) = -1;
3150   TODO_SPEC (insn) = HARD_DEP;
3151   QUEUE_INDEX (insn) = QUEUE_NOWHERE;
3152   INSN_TICK (insn) = INVALID_TICK;
3153   INTER_TICK (insn) = INVALID_TICK;
3154   find_insn_reg_weight1 (insn);
3155
3156   /* These two lists will be freed in schedule_insn ().  */
3157   INSN_BACK_DEPS (insn) = create_deps_list (false);
3158   INSN_RESOLVED_BACK_DEPS (insn) = create_deps_list (false);
3159
3160   /* This one should be allocated on the obstack because it should live till
3161      the scheduling ends.  */
3162   INSN_FORW_DEPS (insn) = create_deps_list (true);
3163 }
3164
3165 /* Generates recovery code for INSN.  */
3166 static void
3167 generate_recovery_code (rtx insn)
3168 {
3169   if (TODO_SPEC (insn) & BEGIN_SPEC)
3170     begin_speculative_block (insn);
3171   
3172   /* Here we have insn with no dependencies to
3173      instructions other then CHECK_SPEC ones.  */
3174   
3175   if (TODO_SPEC (insn) & BE_IN_SPEC)
3176     add_to_speculative_block (insn);
3177 }
3178
3179 /* Helper function.
3180    Tries to add speculative dependencies of type FS between instructions
3181    in deps_list L and TWIN.  */
3182 static void
3183 process_insn_forw_deps_be_in_spec (deps_list_t l, rtx twin, ds_t fs)
3184 {
3185   dep_link_t link;
3186
3187   FOR_EACH_DEP_LINK (link, l)
3188     {
3189       ds_t ds;
3190       rtx consumer;
3191
3192       consumer = DEP_LINK_CON (link);
3193
3194       ds = DEP_LINK_STATUS (link);
3195
3196       if (/* If we want to create speculative dep.  */
3197           fs
3198           /* And we can do that because this is a true dep.  */
3199           && (ds & DEP_TYPES) == DEP_TRUE)
3200         {
3201           gcc_assert (!(ds & BE_IN_SPEC));
3202
3203           if (/* If this dep can be overcome with 'begin speculation'.  */
3204               ds & BEGIN_SPEC)
3205             /* Then we have a choice: keep the dep 'begin speculative'
3206                or transform it into 'be in speculative'.  */
3207             {
3208               if (/* In try_ready we assert that if insn once became ready
3209                      it can be removed from the ready (or queue) list only
3210                      due to backend decision.  Hence we can't let the
3211                      probability of the speculative dep to decrease.  */
3212                   dep_weak (ds) <= dep_weak (fs))
3213                 /* Transform it to be in speculative.  */
3214                 ds = (ds & ~BEGIN_SPEC) | fs;
3215             }
3216           else
3217             /* Mark the dep as 'be in speculative'.  */
3218             ds |= fs;
3219         }
3220
3221       add_back_forw_dep (consumer, twin, DEP_LINK_KIND (link), ds);
3222     }
3223 }
3224
3225 /* Generates recovery code for BEGIN speculative INSN.  */
3226 static void
3227 begin_speculative_block (rtx insn)
3228 {
3229   if (TODO_SPEC (insn) & BEGIN_DATA)
3230     nr_begin_data++;      
3231   if (TODO_SPEC (insn) & BEGIN_CONTROL)
3232     nr_begin_control++;
3233
3234   create_check_block_twin (insn, false);
3235
3236   TODO_SPEC (insn) &= ~BEGIN_SPEC;
3237 }
3238
3239 /* Generates recovery code for BE_IN speculative INSN.  */
3240 static void
3241 add_to_speculative_block (rtx insn)
3242 {
3243   ds_t ts;
3244   dep_link_t link;
3245   rtx twins = NULL;
3246   rtx_vec_t priorities_roots;
3247
3248   ts = TODO_SPEC (insn);
3249   gcc_assert (!(ts & ~BE_IN_SPEC));
3250
3251   if (ts & BE_IN_DATA)
3252     nr_be_in_data++;
3253   if (ts & BE_IN_CONTROL)
3254     nr_be_in_control++;
3255
3256   TODO_SPEC (insn) &= ~BE_IN_SPEC;
3257   gcc_assert (!TODO_SPEC (insn));
3258   
3259   DONE_SPEC (insn) |= ts;
3260
3261   /* First we convert all simple checks to branchy.  */
3262   for (link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn)); link != NULL;)
3263     {
3264       rtx check = DEP_LINK_PRO (link);
3265
3266       if (IS_SPECULATION_SIMPLE_CHECK_P (check))
3267         {
3268           create_check_block_twin (check, true);
3269
3270           /* Restart search.  */
3271           link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn));
3272         }
3273       else
3274         /* Continue search.  */
3275         link = DEP_LINK_NEXT (link);
3276     }
3277
3278   priorities_roots = NULL;
3279   clear_priorities (insn, &priorities_roots);
3280  
3281   do
3282     {
3283       dep_link_t link;
3284       rtx check, twin;
3285       basic_block rec;
3286
3287       link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn));
3288
3289       gcc_assert ((DEP_LINK_STATUS (link) & BEGIN_SPEC) == 0
3290                   && (DEP_LINK_STATUS (link) & BE_IN_SPEC) != 0
3291                   && (DEP_LINK_STATUS (link) & DEP_TYPES) == DEP_TRUE);
3292
3293       check = DEP_LINK_PRO (link);
3294
3295       gcc_assert (!IS_SPECULATION_CHECK_P (check) && !ORIG_PAT (check)
3296                   && QUEUE_INDEX (check) == QUEUE_NOWHERE);
3297       
3298       rec = BLOCK_FOR_INSN (check);
3299       
3300       twin = emit_insn_before (copy_rtx (PATTERN (insn)), BB_END (rec));
3301       extend_global (twin);
3302
3303       copy_deps_list_change_con (INSN_RESOLVED_BACK_DEPS (twin),
3304                                  INSN_RESOLVED_BACK_DEPS (insn),
3305                                  twin);
3306
3307       if (sched_verbose && spec_info->dump)
3308         /* INSN_BB (insn) isn't determined for twin insns yet.
3309            So we can't use current_sched_info->print_insn.  */
3310         fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
3311                  INSN_UID (twin), rec->index);
3312
3313       twins = alloc_INSN_LIST (twin, twins);
3314
3315       /* Add dependences between TWIN and all appropriate
3316          instructions from REC.  */
3317       do
3318         {         
3319           add_back_forw_dep (twin, check, REG_DEP_TRUE, DEP_TRUE);
3320           
3321           do              
3322             {  
3323               link = DEP_LINK_NEXT (link);
3324
3325               if (link != NULL)
3326                 {
3327                   check = DEP_LINK_PRO (link);
3328                   if (BLOCK_FOR_INSN (check) == rec)
3329                     break;
3330                 }
3331               else
3332                 break;
3333             }
3334           while (1);
3335         }
3336       while (link != NULL);
3337
3338       process_insn_forw_deps_be_in_spec (INSN_FORW_DEPS (insn), twin, ts);
3339
3340       /* Remove all dependencies between INSN and insns in REC.  */
3341       for (link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn)); link != NULL;)
3342         {
3343           check = DEP_LINK_PRO (link);
3344
3345           if (BLOCK_FOR_INSN (check) == rec)
3346             {
3347               delete_back_forw_dep (link);
3348
3349               /* Restart search.  */
3350               link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn));
3351             }
3352           else
3353             /* Continue search.  */
3354             link = DEP_LINK_NEXT (link);
3355         }
3356     }
3357   while (!deps_list_empty_p (INSN_BACK_DEPS (insn)));
3358
3359   /* We couldn't have added the dependencies between INSN and TWINS earlier
3360      because that would make TWINS appear in the INSN_BACK_DEPS (INSN).  */
3361   while (twins)
3362     {
3363       rtx twin;
3364
3365       twin = XEXP (twins, 0);
3366       add_back_forw_dep (twin, insn, REG_DEP_OUTPUT, DEP_OUTPUT);
3367
3368       twin = XEXP (twins, 1);
3369       free_INSN_LIST_node (twins);
3370       twins = twin;      
3371     }
3372
3373   calc_priorities (priorities_roots);
3374   VEC_free (rtx, heap, priorities_roots);
3375 }
3376
3377 /* Extends and fills with zeros (only the new part) array pointed to by P.  */
3378 void *
3379 xrecalloc (void *p, size_t new_nmemb, size_t old_nmemb, size_t size)
3380 {
3381   gcc_assert (new_nmemb >= old_nmemb);
3382   p = XRESIZEVAR (void, p, new_nmemb * size);
3383   memset (((char *) p) + old_nmemb * size, 0, (new_nmemb - old_nmemb) * size);
3384   return p;
3385 }
3386
3387 /* Return the probability of speculation success for the speculation
3388    status DS.  */
3389 static dw_t
3390 dep_weak (ds_t ds)
3391 {
3392   ds_t res = 1, dt;
3393   int n = 0;
3394
3395   dt = FIRST_SPEC_TYPE;
3396   do
3397     {
3398       if (ds & dt)
3399         {
3400           res *= (ds_t) get_dep_weak (ds, dt);
3401           n++;
3402         }
3403
3404       if (dt == LAST_SPEC_TYPE)
3405         break;
3406       dt <<= SPEC_TYPE_SHIFT;
3407     }
3408   while (1);
3409
3410   gcc_assert (n);
3411   while (--n)
3412     res /= MAX_DEP_WEAK;
3413
3414   if (res < MIN_DEP_WEAK)
3415     res = MIN_DEP_WEAK;
3416
3417   gcc_assert (res <= MAX_DEP_WEAK);
3418
3419   return (dw_t) res;
3420 }
3421
3422 /* Helper function.
3423    Find fallthru edge from PRED.  */
3424 static edge
3425 find_fallthru_edge (basic_block pred)
3426 {
3427   edge e;
3428   edge_iterator ei;
3429   basic_block succ;
3430
3431   succ = pred->next_bb;
3432   gcc_assert (succ->prev_bb == pred);
3433
3434   if (EDGE_COUNT (pred->succs) <= EDGE_COUNT (succ->preds))
3435     {
3436       FOR_EACH_EDGE (e, ei, pred->succs)
3437         if (e->flags & EDGE_FALLTHRU)
3438           {
3439             gcc_assert (e->dest == succ);
3440             return e;
3441           }
3442     }
3443   else
3444     {
3445       FOR_EACH_EDGE (e, ei, succ->preds)
3446         if (e->flags & EDGE_FALLTHRU)
3447           {
3448             gcc_assert (e->src == pred);
3449             return e;
3450           }
3451     }
3452
3453   return NULL;
3454 }
3455
3456 /* Initialize BEFORE_RECOVERY variable.  */
3457 static void
3458 init_before_recovery (void)
3459 {
3460   basic_block last;
3461   edge e;
3462
3463   last = EXIT_BLOCK_PTR->prev_bb;
3464   e = find_fallthru_edge (last);
3465
3466   if (e)
3467     {
3468       /* We create two basic blocks: 
3469          1. Single instruction block is inserted right after E->SRC
3470          and has jump to 
3471          2. Empty block right before EXIT_BLOCK.
3472          Between these two blocks recovery blocks will be emitted.  */
3473
3474       basic_block single, empty;
3475       rtx x, label;
3476
3477       single = create_empty_bb (last);
3478       empty = create_empty_bb (single);            
3479
3480       single->count = last->count;     
3481       empty->count = last->count;
3482       single->frequency = last->frequency;
3483       empty->frequency = last->frequency;
3484       BB_COPY_PARTITION (single, last);
3485       BB_COPY_PARTITION (empty, last);
3486
3487       redirect_edge_succ (e, single);
3488       make_single_succ_edge (single, empty, 0);
3489       make_single_succ_edge (empty, EXIT_BLOCK_PTR,
3490                              EDGE_FALLTHRU | EDGE_CAN_FALLTHRU);
3491
3492       label = block_label (empty);
3493       x = emit_jump_insn_after (gen_jump (label), BB_END (single));
3494       JUMP_LABEL (x) = label;
3495       LABEL_NUSES (label)++;
3496       extend_global (x);
3497           
3498       emit_barrier_after (x);
3499
3500       add_block (empty, 0);
3501       add_block (single, 0);
3502
3503       before_recovery = single;
3504
3505       if (sched_verbose >= 2 && spec_info->dump)
3506         fprintf (spec_info->dump,
3507                  ";;\t\tFixed fallthru to EXIT : %d->>%d->%d->>EXIT\n", 
3508                  last->index, single->index, empty->index);      
3509     }
3510   else
3511     before_recovery = last;
3512 }
3513
3514 /* Returns new recovery block.  */
3515 static basic_block
3516 create_recovery_block (void)
3517 {
3518   rtx label;
3519   rtx barrier;
3520   basic_block rec;
3521   
3522   added_recovery_block_p = true;
3523
3524   if (!before_recovery)
3525     init_before_recovery ();
3526
3527   barrier = get_last_bb_insn (before_recovery);
3528   gcc_assert (BARRIER_P (barrier));
3529
3530   label = emit_label_after (gen_label_rtx (), barrier);
3531
3532   rec = create_basic_block (label, label, before_recovery);
3533
3534   /* Recovery block always end with an unconditional jump.  */
3535   emit_barrier_after (BB_END (rec));
3536
3537   if (BB_PARTITION (before_recovery) != BB_UNPARTITIONED)
3538     BB_SET_PARTITION (rec, BB_COLD_PARTITION);
3539   
3540   if (sched_verbose && spec_info->dump)    
3541     fprintf (spec_info->dump, ";;\t\tGenerated recovery block rec%d\n",
3542              rec->index);
3543
3544   before_recovery = rec;
3545
3546   return rec;
3547 }
3548
3549 /* This function creates recovery code for INSN.  If MUTATE_P is nonzero,
3550    INSN is a simple check, that should be converted to branchy one.  */
3551 static void
3552 create_check_block_twin (rtx insn, bool mutate_p)
3553 {
3554   basic_block rec;
3555   rtx label, check, twin;
3556   dep_link_t link;
3557   ds_t fs;
3558
3559   gcc_assert (ORIG_PAT (insn)
3560               && (!mutate_p 
3561                   || (IS_SPECULATION_SIMPLE_CHECK_P (insn)
3562                       && !(TODO_SPEC (insn) & SPECULATIVE))));
3563
3564   /* Create recovery block.  */
3565   if (mutate_p || targetm.sched.needs_block_p (insn))
3566     {
3567       rec = create_recovery_block ();
3568       label = BB_HEAD (rec);
3569     }
3570   else
3571     {
3572       rec = EXIT_BLOCK_PTR;
3573       label = 0;
3574     }
3575
3576   /* Emit CHECK.  */
3577   check = targetm.sched.gen_check (insn, label, mutate_p);
3578
3579   if (rec != EXIT_BLOCK_PTR)
3580     {
3581       /* To have mem_reg alive at the beginning of second_bb,
3582          we emit check BEFORE insn, so insn after splitting 
3583          insn will be at the beginning of second_bb, which will
3584          provide us with the correct life information.  */
3585       check = emit_jump_insn_before (check, insn);
3586       JUMP_LABEL (check) = label;
3587       LABEL_NUSES (label)++;
3588     }
3589   else
3590     check = emit_insn_before (check, insn);
3591
3592   /* Extend data structures.  */
3593   extend_all (check);
3594   RECOVERY_BLOCK (check) = rec;
3595
3596   if (sched_verbose && spec_info->dump)
3597     fprintf (spec_info->dump, ";;\t\tGenerated check insn : %s\n",
3598              (*current_sched_info->print_insn) (check, 0));
3599
3600   gcc_assert (ORIG_PAT (insn));
3601
3602   /* Initialize TWIN (twin is a duplicate of original instruction
3603      in the recovery block).  */
3604   if (rec != EXIT_BLOCK_PTR)
3605     {
3606       FOR_EACH_DEP_LINK (link, INSN_RESOLVED_BACK_DEPS (insn))
3607         if ((DEP_LINK_STATUS (link) & DEP_OUTPUT) != 0)
3608           {
3609             struct _dep _dep, *dep = &_dep;
3610
3611             init_dep (dep, DEP_LINK_PRO (link), check, REG_DEP_TRUE);
3612
3613             add_back_dep_to_deps_list (INSN_RESOLVED_BACK_DEPS (check), dep);
3614           }
3615
3616       twin = emit_insn_after (ORIG_PAT (insn), BB_END (rec));
3617       extend_global (twin);
3618
3619       if (sched_verbose && spec_info->dump)
3620         /* INSN_BB (insn) isn't determined for twin insns yet.
3621            So we can't use current_sched_info->print_insn.  */
3622         fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
3623                  INSN_UID (twin), rec->index);
3624     }
3625   else
3626     {
3627       ORIG_PAT (check) = ORIG_PAT (insn);
3628       HAS_INTERNAL_DEP (check) = 1;
3629       twin = check;
3630       /* ??? We probably should change all OUTPUT dependencies to
3631          (TRUE | OUTPUT).  */
3632     }
3633
3634   copy_deps_list_change_con (INSN_RESOLVED_BACK_DEPS (twin),
3635                              INSN_RESOLVED_BACK_DEPS (insn),
3636                              twin);
3637
3638   if (rec != EXIT_BLOCK_PTR)
3639     /* In case of branchy check, fix CFG.  */
3640     {
3641       basic_block first_bb, second_bb;
3642       rtx jump;
3643       edge e;
3644       int edge_flags;
3645
3646       first_bb = BLOCK_FOR_INSN (check);
3647       e = split_block (first_bb, check);
3648       /* split_block emits note if *check == BB_END.  Probably it 
3649          is better to rip that note off.  */
3650       gcc_assert (e->src == first_bb);
3651       second_bb = e->dest;
3652
3653       /* This is fixing of incoming edge.  */
3654       /* ??? Which other flags should be specified?  */      
3655       if (BB_PARTITION (first_bb) != BB_PARTITION (rec))
3656         /* Partition type is the same, if it is "unpartitioned".  */
3657         edge_flags = EDGE_CROSSING;
3658       else
3659         edge_flags = 0;
3660       
3661       e = make_edge (first_bb, rec, edge_flags);
3662
3663       add_block (second_bb, first_bb);
3664       
3665       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (second_bb)));
3666       label = block_label (second_bb);
3667       jump = emit_jump_insn_after (gen_jump (label), BB_END (rec));
3668       JUMP_LABEL (jump) = label;
3669       LABEL_NUSES (label)++;
3670       extend_global (jump);
3671
3672       if (BB_PARTITION (second_bb) != BB_PARTITION (rec))
3673         /* Partition type is the same, if it is "unpartitioned".  */
3674         {
3675           /* Rewritten from cfgrtl.c.  */
3676           if (flag_reorder_blocks_and_partition
3677               && targetm.have_named_sections
3678               /*&& !any_condjump_p (jump)*/)
3679             /* any_condjump_p (jump) == false.
3680                We don't need the same note for the check because
3681                any_condjump_p (check) == true.  */
3682             {
3683               REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP,
3684                                                     NULL_RTX,
3685                                                     REG_NOTES (jump));
3686             }
3687           edge_flags = EDGE_CROSSING;
3688         }
3689       else
3690         edge_flags = 0;  
3691       
3692       make_single_succ_edge (rec, second_bb, edge_flags);  
3693       
3694       add_block (rec, EXIT_BLOCK_PTR);
3695     }
3696
3697   /* Move backward dependences from INSN to CHECK and 
3698      move forward dependences from INSN to TWIN.  */
3699   FOR_EACH_DEP_LINK (link, INSN_BACK_DEPS (insn))
3700     {
3701       rtx pro = DEP_LINK_PRO (link);
3702       enum reg_note dk = DEP_LINK_KIND (link);
3703       ds_t ds;
3704
3705       /* If BEGIN_DATA: [insn ~~TRUE~~> producer]:
3706          check --TRUE--> producer  ??? or ANTI ???
3707          twin  --TRUE--> producer
3708          twin  --ANTI--> check
3709          
3710          If BEGIN_CONTROL: [insn ~~ANTI~~> producer]:
3711          check --ANTI--> producer
3712          twin  --ANTI--> producer
3713          twin  --ANTI--> check
3714
3715          If BE_IN_SPEC: [insn ~~TRUE~~> producer]:
3716          check ~~TRUE~~> producer
3717          twin  ~~TRUE~~> producer
3718          twin  --ANTI--> check  */                
3719
3720       ds = DEP_LINK_STATUS (link);
3721
3722       if (ds & BEGIN_SPEC)
3723         {
3724           gcc_assert (!mutate_p);
3725           ds &= ~BEGIN_SPEC;
3726         }
3727
3728       if (rec != EXIT_BLOCK_PTR)
3729         {
3730           add_back_forw_dep (check, pro, dk, ds);
3731           add_back_forw_dep (twin, pro, dk, ds);
3732         }    
3733       else
3734         add_back_forw_dep (check, pro, dk, ds);
3735     }
3736
3737   for (link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn)); link != NULL;)
3738     if ((DEP_LINK_STATUS (link) & BEGIN_SPEC)
3739         || mutate_p)
3740       /* We can delete this dep only if we totally overcome it with
3741          BEGIN_SPECULATION.  */
3742       {
3743         delete_back_forw_dep (link);
3744
3745         /* Restart search.  */
3746         link = DEPS_LIST_FIRST (INSN_BACK_DEPS (insn));
3747       }
3748     else
3749       /* Continue search.  */
3750       link = DEP_LINK_NEXT (link);    
3751
3752   fs = 0;
3753
3754   /* Fields (DONE_SPEC (x) & BEGIN_SPEC) and CHECK_SPEC (x) are set only
3755      here.  */
3756   
3757   gcc_assert (!DONE_SPEC (insn));
3758   
3759   if (!mutate_p)
3760     { 
3761       ds_t ts = TODO_SPEC (insn);
3762
3763       DONE_SPEC (insn) = ts & BEGIN_SPEC;
3764       CHECK_SPEC (check) = ts & BEGIN_SPEC;
3765
3766       if (ts & BEGIN_DATA)
3767         fs = set_dep_weak (fs, BE_IN_DATA, get_dep_weak (ts, BEGIN_DATA));
3768       if (ts & BEGIN_CONTROL)
3769         fs = set_dep_weak (fs, BE_IN_CONTROL, get_dep_weak (ts, BEGIN_CONTROL));
3770     }
3771   else
3772     CHECK_SPEC (check) = CHECK_SPEC (insn);
3773
3774   /* Future speculations: call the helper.  */
3775   process_insn_forw_deps_be_in_spec (INSN_FORW_DEPS (insn), twin, fs);
3776
3777   if (rec != EXIT_BLOCK_PTR)
3778     {
3779       /* Which types of dependencies should we use here is,
3780          generally, machine-dependent question...  But, for now,
3781          it is not.  */
3782
3783       if (!mutate_p)
3784         {
3785           add_back_forw_dep (check, insn, REG_DEP_TRUE, DEP_TRUE);
3786           add_back_forw_dep (twin, insn, REG_DEP_OUTPUT, DEP_OUTPUT);
3787         }
3788       else
3789         {
3790           dep_link_t link;
3791
3792           if (spec_info->dump)    
3793             fprintf (spec_info->dump, ";;\t\tRemoved simple check : %s\n",
3794                      (*current_sched_info->print_insn) (insn, 0));
3795
3796           /* Remove all forward dependencies of the INSN.  */
3797           link = DEPS_LIST_FIRST (INSN_FORW_DEPS (insn));
3798           while (link != NULL)
3799             {
3800               delete_back_forw_dep (link);
3801               link = DEPS_LIST_FIRST (INSN_FORW_DEPS (insn));
3802             }
3803
3804           if (QUEUE_INDEX (insn) != QUEUE_NOWHERE)
3805             try_ready (check);
3806
3807           sched_remove_insn (insn);
3808         }
3809
3810       add_back_forw_dep (twin, check, REG_DEP_ANTI, DEP_ANTI);
3811     }
3812   else
3813     add_back_forw_dep (check, insn, REG_DEP_TRUE, DEP_TRUE | DEP_OUTPUT);
3814
3815   if (!mutate_p)
3816     /* Fix priorities.  If MUTATE_P is nonzero, this is not necessary,
3817        because it'll be done later in add_to_speculative_block.  */
3818     {
3819       rtx_vec_t priorities_roots = NULL;
3820
3821       clear_priorities (twin, &priorities_roots);
3822       calc_priorities (priorities_roots);
3823       VEC_free (rtx, heap, priorities_roots);
3824     }
3825 }
3826
3827 /* Removes dependency between instructions in the recovery block REC
3828    and usual region instructions.  It keeps inner dependences so it
3829    won't be necessary to recompute them.  */
3830 static void
3831 fix_recovery_deps (basic_block rec)
3832 {
3833   dep_link_t link;
3834   rtx note, insn, jump, ready_list = 0;
3835   bitmap_head in_ready;
3836   rtx link1;
3837
3838   bitmap_initialize (&in_ready, 0);
3839   
3840   /* NOTE - a basic block note.  */
3841   note = NEXT_INSN (BB_HEAD (rec));
3842   gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
3843   insn = BB_END (rec);
3844   gcc_assert (JUMP_P (insn));
3845   insn = PREV_INSN (insn);
3846
3847   do
3848     {    
3849       for (link = DEPS_LIST_FIRST (INSN_FORW_DEPS (insn)); link != NULL;)
3850         {
3851           rtx consumer;
3852
3853           consumer = DEP_LINK_CON (link);
3854
3855           if (BLOCK_FOR_INSN (consumer) != rec)
3856             {
3857               delete_back_forw_dep (link);
3858
3859               if (!bitmap_bit_p (&in_ready, INSN_LUID (consumer)))
3860                 {
3861                   ready_list = alloc_INSN_LIST (consumer, ready_list);
3862                   bitmap_set_bit (&in_ready, INSN_LUID (consumer));
3863                 }
3864
3865               /* Restart search.  */
3866               link = DEPS_LIST_FIRST (INSN_FORW_DEPS (insn));
3867             }
3868           else
3869             {
3870               gcc_assert ((DEP_LINK_STATUS (link) & DEP_TYPES) == DEP_TRUE);
3871
3872               /* Continue search.  */
3873               link = DEP_LINK_NEXT (link);
3874             }
3875         }
3876       
3877       insn = PREV_INSN (insn);
3878     }
3879   while (insn != note);
3880
3881   bitmap_clear (&in_ready);
3882
3883   /* Try to add instructions to the ready or queue list.  */
3884   for (link1 = ready_list; link1; link1 = XEXP (link1, 1))
3885     try_ready (XEXP (link1, 0));
3886   free_INSN_LIST_list (&ready_list);
3887
3888   /* Fixing jump's dependences.  */
3889   insn = BB_HEAD (rec);
3890   jump = BB_END (rec);
3891       
3892   gcc_assert (LABEL_P (insn));
3893   insn = NEXT_INSN (insn);
3894   
3895   gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
3896   add_jump_dependencies (insn, jump);
3897 }
3898
3899 /* Changes pattern of the INSN to NEW_PAT.  */
3900 static void
3901 change_pattern (rtx insn, rtx new_pat)
3902 {
3903   int t;
3904
3905   t = validate_change (insn, &PATTERN (insn), new_pat, 0);
3906   gcc_assert (t);
3907   /* Invalidate INSN_COST, so it'll be recalculated.  */
3908   INSN_COST (insn) = -1;
3909   /* Invalidate INSN_TICK, so it'll be recalculated.  */
3910   INSN_TICK (insn) = INVALID_TICK;
3911   dfa_clear_single_insn_cache (insn);
3912 }
3913
3914
3915 /* -1 - can't speculate,
3916    0 - for speculation with REQUEST mode it is OK to use
3917    current instruction pattern,
3918    1 - need to change pattern for *NEW_PAT to be speculative.  */
3919 static int
3920 speculate_insn (rtx insn, ds_t request, rtx *new_pat)
3921 {
3922   gcc_assert (current_sched_info->flags & DO_SPECULATION
3923               && (request & SPECULATIVE));
3924
3925   if (!NONJUMP_INSN_P (insn)
3926       || HAS_INTERNAL_DEP (insn)
3927       || SCHED_GROUP_P (insn)
3928       || side_effects_p (PATTERN (insn))
3929       || (request & spec_info->mask) != request)    
3930     return -1;
3931   
3932   gcc_assert (!IS_SPECULATION_CHECK_P (insn));
3933
3934   if (request & BE_IN_SPEC)
3935     {            
3936       if (may_trap_p (PATTERN (insn)))
3937         return -1;
3938       
3939       if (!(request & BEGIN_SPEC))
3940         return 0;
3941     }
3942
3943   return targetm.sched.speculate_insn (insn, request & BEGIN_SPEC, new_pat);
3944 }
3945
3946 /* Print some information about block BB, which starts with HEAD and
3947    ends with TAIL, before scheduling it.
3948    I is zero, if scheduler is about to start with the fresh ebb.  */
3949 static void
3950 dump_new_block_header (int i, basic_block bb, rtx head, rtx tail)
3951 {
3952   if (!i)
3953     fprintf (sched_dump,
3954              ";;   ======================================================\n");
3955   else
3956     fprintf (sched_dump,
3957              ";;   =====================ADVANCING TO=====================\n");
3958   fprintf (sched_dump,
3959            ";;   -- basic block %d from %d to %d -- %s reload\n",
3960            bb->index, INSN_UID (head), INSN_UID (tail),
3961            (reload_completed ? "after" : "before"));
3962   fprintf (sched_dump,
3963            ";;   ======================================================\n");
3964   fprintf (sched_dump, "\n");
3965 }
3966
3967 /* Unlink basic block notes and labels and saves them, so they
3968    can be easily restored.  We unlink basic block notes in EBB to
3969    provide back-compatibility with the previous code, as target backends
3970    assume, that there'll be only instructions between
3971    current_sched_info->{head and tail}.  We restore these notes as soon
3972    as we can.
3973    FIRST (LAST) is the first (last) basic block in the ebb.
3974    NB: In usual case (FIRST == LAST) nothing is really done.  */
3975 void
3976 unlink_bb_notes (basic_block first, basic_block last)
3977 {
3978   /* We DON'T unlink basic block notes of the first block in the ebb.  */
3979   if (first == last)
3980     return;
3981
3982   bb_header = xmalloc (last_basic_block * sizeof (*bb_header));
3983
3984   /* Make a sentinel.  */
3985   if (last->next_bb != EXIT_BLOCK_PTR)
3986     bb_header[last->next_bb->index] = 0;
3987
3988   first = first->next_bb;
3989   do
3990     {
3991       rtx prev, label, note, next;
3992
3993       label = BB_HEAD (last);
3994       if (LABEL_P (label))
3995         note = NEXT_INSN (label);
3996       else
3997         note = label;      
3998       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
3999
4000       prev = PREV_INSN (label);
4001       next = NEXT_INSN (note);
4002       gcc_assert (prev && next);
4003
4004       NEXT_INSN (prev) = next;
4005       PREV_INSN (next) = prev;
4006
4007       bb_header[last->index] = label;
4008
4009       if (last == first)
4010         break;
4011       
4012       last = last->prev_bb;
4013     }
4014   while (1);
4015 }
4016
4017 /* Restore basic block notes.
4018    FIRST is the first basic block in the ebb.  */
4019 static void
4020 restore_bb_notes (basic_block first)
4021 {
4022   if (!bb_header)
4023     return;
4024
4025   /* We DON'T unlink basic block notes of the first block in the ebb.  */
4026   first = first->next_bb;  
4027   /* Remember: FIRST is actually a second basic block in the ebb.  */
4028
4029   while (first != EXIT_BLOCK_PTR
4030          && bb_header[first->index])
4031     {
4032       rtx prev, label, note, next;
4033       
4034       label = bb_header[first->index];
4035       prev = PREV_INSN (label);
4036       next = NEXT_INSN (prev);
4037
4038       if (LABEL_P (label))
4039         note = NEXT_INSN (label);
4040       else
4041         note = label;      
4042       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
4043
4044       bb_header[first->index] = 0;
4045
4046       NEXT_INSN (prev) = label;
4047       NEXT_INSN (note) = next;
4048       PREV_INSN (next) = note;
4049       
4050       first = first->next_bb;
4051     }
4052
4053   free (bb_header);
4054   bb_header = 0;
4055 }
4056
4057 /* Extend per basic block data structures of the scheduler.
4058    If BB is NULL, initialize structures for the whole CFG.
4059    Otherwise, initialize them for the just created BB.  */
4060 static void
4061 extend_bb (void)
4062 {
4063   rtx insn;
4064
4065   old_last_basic_block = last_basic_block;
4066
4067   if (current_sched_info->flags & USE_GLAT)
4068     {
4069       glat_start = xrealloc (glat_start,
4070                              last_basic_block * sizeof (*glat_start));
4071       glat_end = xrealloc (glat_end, last_basic_block * sizeof (*glat_end));
4072     }
4073
4074   /* The following is done to keep current_sched_info->next_tail non null.  */
4075
4076   insn = BB_END (EXIT_BLOCK_PTR->prev_bb);
4077   if (NEXT_INSN (insn) == 0
4078       || (!NOTE_P (insn)
4079           && !LABEL_P (insn)
4080           /* Don't emit a NOTE if it would end up before a BARRIER.  */
4081           && !BARRIER_P (NEXT_INSN (insn))))
4082     {
4083       emit_note_after (NOTE_INSN_DELETED, insn);
4084       /* Make insn to appear outside BB.  */
4085       BB_END (EXIT_BLOCK_PTR->prev_bb) = insn;
4086     }
4087 }
4088
4089 /* Add a basic block BB to extended basic block EBB.
4090    If EBB is EXIT_BLOCK_PTR, then BB is recovery block.
4091    If EBB is NULL, then BB should be a new region.  */
4092 void
4093 add_block (basic_block bb, basic_block ebb)
4094 {
4095   gcc_assert (current_sched_info->flags & DETACH_LIFE_INFO
4096               && bb->il.rtl->global_live_at_start == 0
4097               && bb->il.rtl->global_live_at_end == 0);
4098
4099   extend_bb ();
4100
4101   glat_start[bb->index] = 0;
4102   glat_end[bb->index] = 0;
4103
4104   if (current_sched_info->add_block)
4105     /* This changes only data structures of the front-end.  */
4106     current_sched_info->add_block (bb, ebb);
4107 }
4108
4109 /* Helper function.
4110    Fix CFG after both in- and inter-block movement of
4111    control_flow_insn_p JUMP.  */
4112 static void
4113 fix_jump_move (rtx jump)
4114 {
4115   basic_block bb, jump_bb, jump_bb_next;
4116
4117   bb = BLOCK_FOR_INSN (PREV_INSN (jump));
4118   jump_bb = BLOCK_FOR_INSN (jump);
4119   jump_bb_next = jump_bb->next_bb;
4120
4121   gcc_assert (current_sched_info->flags & SCHED_EBB
4122               || IS_SPECULATION_BRANCHY_CHECK_P (jump));
4123   
4124   if (!NOTE_INSN_BASIC_BLOCK_P (BB_END (jump_bb_next)))
4125     /* if jump_bb_next is not empty.  */
4126     BB_END (jump_bb) = BB_END (jump_bb_next);
4127
4128   if (BB_END (bb) != PREV_INSN (jump))
4129     /* Then there are instruction after jump that should be placed
4130        to jump_bb_next.  */
4131     BB_END (jump_bb_next) = BB_END (bb);
4132   else
4133     /* Otherwise jump_bb_next is empty.  */
4134     BB_END (jump_bb_next) = NEXT_INSN (BB_HEAD (jump_bb_next));
4135
4136   /* To make assertion in move_insn happy.  */
4137   BB_END (bb) = PREV_INSN (jump);
4138
4139   update_bb_for_insn (jump_bb_next);
4140 }
4141
4142 /* Fix CFG after interblock movement of control_flow_insn_p JUMP.  */
4143 static void
4144 move_block_after_check (rtx jump)
4145 {
4146   basic_block bb, jump_bb, jump_bb_next;
4147   VEC(edge,gc) *t;
4148
4149   bb = BLOCK_FOR_INSN (PREV_INSN (jump));
4150   jump_bb = BLOCK_FOR_INSN (jump);
4151   jump_bb_next = jump_bb->next_bb;
4152   
4153   update_bb_for_insn (jump_bb);
4154   
4155   gcc_assert (IS_SPECULATION_CHECK_P (jump)
4156               || IS_SPECULATION_CHECK_P (BB_END (jump_bb_next)));
4157
4158   unlink_block (jump_bb_next);
4159   link_block (jump_bb_next, bb);
4160
4161   t = bb->succs;
4162   bb->succs = 0;
4163   move_succs (&(jump_bb->succs), bb);
4164   move_succs (&(jump_bb_next->succs), jump_bb);
4165   move_succs (&t, jump_bb_next);
4166   
4167   if (current_sched_info->fix_recovery_cfg)
4168     current_sched_info->fix_recovery_cfg 
4169       (bb->index, jump_bb->index, jump_bb_next->index);
4170 }
4171
4172 /* Helper function for move_block_after_check.
4173    This functions attaches edge vector pointed to by SUCCSP to
4174    block TO.  */
4175 static void
4176 move_succs (VEC(edge,gc) **succsp, basic_block to)
4177 {
4178   edge e;
4179   edge_iterator ei;
4180
4181   gcc_assert (to->succs == 0);
4182
4183   to->succs = *succsp;
4184
4185   FOR_EACH_EDGE (e, ei, to->succs)
4186     e->src = to;
4187
4188   *succsp = 0;
4189 }
4190
4191 /* Initialize GLAT (global_live_at_{start, end}) structures.
4192    GLAT structures are used to substitute global_live_{start, end}
4193    regsets during scheduling.  This is necessary to use such functions as
4194    split_block (), as they assume consistency of register live information.  */
4195 static void
4196 init_glat (void)
4197 {
4198   basic_block bb;
4199
4200   FOR_ALL_BB (bb)
4201     init_glat1 (bb);
4202 }
4203
4204 /* Helper function for init_glat.  */
4205 static void
4206 init_glat1 (basic_block bb)
4207 {
4208   gcc_assert (bb->il.rtl->global_live_at_start != 0
4209               && bb->il.rtl->global_live_at_end != 0);
4210
4211   glat_start[bb->index] = bb->il.rtl->global_live_at_start;
4212   glat_end[bb->index] = bb->il.rtl->global_live_at_end;
4213   
4214   if (current_sched_info->flags & DETACH_LIFE_INFO)
4215     {
4216       bb->il.rtl->global_live_at_start = 0;
4217       bb->il.rtl->global_live_at_end = 0;
4218     }
4219 }
4220
4221 /* Attach reg_live_info back to basic blocks.
4222    Also save regsets, that should not have been changed during scheduling,
4223    for checking purposes (see check_reg_live).  */
4224 void
4225 attach_life_info (void)
4226 {
4227   basic_block bb;
4228
4229   FOR_ALL_BB (bb)
4230     attach_life_info1 (bb);
4231 }
4232
4233 /* Helper function for attach_life_info.  */
4234 static void
4235 attach_life_info1 (basic_block bb)
4236 {
4237   gcc_assert (bb->il.rtl->global_live_at_start == 0
4238               && bb->il.rtl->global_live_at_end == 0);
4239
4240   if (glat_start[bb->index])
4241     {
4242       gcc_assert (glat_end[bb->index]);    
4243
4244       bb->il.rtl->global_live_at_start = glat_start[bb->index];
4245       bb->il.rtl->global_live_at_end = glat_end[bb->index];
4246
4247       /* Make them NULL, so they won't be freed in free_glat.  */
4248       glat_start[bb->index] = 0;
4249       glat_end[bb->index] = 0;
4250
4251 #ifdef ENABLE_CHECKING
4252       if (bb->index < NUM_FIXED_BLOCKS
4253           || current_sched_info->region_head_or_leaf_p (bb, 0))
4254         {
4255           glat_start[bb->index] = ALLOC_REG_SET (&reg_obstack);
4256           COPY_REG_SET (glat_start[bb->index],
4257                         bb->il.rtl->global_live_at_start);
4258         }
4259
4260       if (bb->index < NUM_FIXED_BLOCKS
4261           || current_sched_info->region_head_or_leaf_p (bb, 1))
4262         {       
4263           glat_end[bb->index] = ALLOC_REG_SET (&reg_obstack);
4264           COPY_REG_SET (glat_end[bb->index], bb->il.rtl->global_live_at_end);
4265         }
4266 #endif
4267     }
4268   else
4269     {
4270       gcc_assert (!glat_end[bb->index]);
4271
4272       bb->il.rtl->global_live_at_start = ALLOC_REG_SET (&reg_obstack);
4273       bb->il.rtl->global_live_at_end = ALLOC_REG_SET (&reg_obstack);
4274     }
4275 }
4276
4277 /* Free GLAT information.  */
4278 static void
4279 free_glat (void)
4280 {
4281 #ifdef ENABLE_CHECKING
4282   if (current_sched_info->flags & DETACH_LIFE_INFO)
4283     {
4284       basic_block bb;
4285
4286       FOR_ALL_BB (bb)
4287         {
4288           if (glat_start[bb->index])
4289             FREE_REG_SET (glat_start[bb->index]);
4290           if (glat_end[bb->index])
4291             FREE_REG_SET (glat_end[bb->index]);
4292         }
4293     }
4294 #endif
4295
4296   free (glat_start);
4297   free (glat_end);
4298 }
4299
4300 /* Remove INSN from the instruction stream.
4301    INSN should have any dependencies.  */
4302 static void
4303 sched_remove_insn (rtx insn)
4304 {
4305   change_queue_index (insn, QUEUE_NOWHERE);
4306   current_sched_info->add_remove_insn (insn, 1);
4307   remove_insn (insn);
4308 }
4309
4310 /* Clear priorities of all instructions, that are forward dependent on INSN.
4311    Store in vector pointed to by ROOTS_PTR insns on which priority () should
4312    be invoked to initialize all cleared priorities.  */
4313 static void
4314 clear_priorities (rtx insn, rtx_vec_t *roots_ptr)
4315 {
4316   dep_link_t link;
4317   bool insn_is_root_p = true;
4318
4319   gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
4320
4321   FOR_EACH_DEP_LINK (link, INSN_BACK_DEPS (insn))
4322     {
4323       dep_t dep = DEP_LINK_DEP (link);
4324       rtx pro = DEP_PRO (dep);
4325
4326       if (INSN_PRIORITY_STATUS (pro) >= 0
4327           && QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
4328         {
4329           /* If DEP doesn't contribute to priority then INSN itself should
4330              be added to priority roots.  */
4331           if (contributes_to_priority_p (dep))
4332             insn_is_root_p = false;
4333
4334           INSN_PRIORITY_STATUS (pro) = -1;
4335           clear_priorities (pro, roots_ptr);
4336         }
4337     }
4338
4339   if (insn_is_root_p)
4340     VEC_safe_push (rtx, heap, *roots_ptr, insn);
4341 }
4342
4343 /* Recompute priorities of instructions, whose priorities might have been
4344    changed.  ROOTS is a vector of instructions whose priority computation will
4345    trigger initialization of all cleared priorities.  */
4346 static void
4347 calc_priorities (rtx_vec_t roots)
4348 {
4349   int i;
4350   rtx insn;
4351
4352   for (i = 0; VEC_iterate (rtx, roots, i, insn); i++)
4353     priority (insn);
4354 }
4355
4356
4357 /* Add dependences between JUMP and other instructions in the recovery
4358    block.  INSN is the first insn the recovery block.  */
4359 static void
4360 add_jump_dependencies (rtx insn, rtx jump)
4361 {
4362   do
4363     {
4364       insn = NEXT_INSN (insn);
4365       if (insn == jump)
4366         break;
4367       
4368       if (deps_list_empty_p (INSN_FORW_DEPS (insn)))
4369         add_back_forw_dep (jump, insn, REG_DEP_ANTI, DEP_ANTI);
4370     }
4371   while (1);
4372
4373   gcc_assert (!deps_list_empty_p (INSN_BACK_DEPS (jump)));
4374 }
4375
4376 /* Return the NOTE_INSN_BASIC_BLOCK of BB.  */
4377 rtx
4378 bb_note (basic_block bb)
4379 {
4380   rtx note;
4381
4382   note = BB_HEAD (bb);
4383   if (LABEL_P (note))
4384     note = NEXT_INSN (note);
4385
4386   gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
4387   return note;
4388 }
4389
4390 #ifdef ENABLE_CHECKING
4391 extern void debug_spec_status (ds_t);
4392
4393 /* Dump information about the dependence status S.  */
4394 void
4395 debug_spec_status (ds_t s)
4396 {
4397   FILE *f = stderr;
4398
4399   if (s & BEGIN_DATA)
4400     fprintf (f, "BEGIN_DATA: %d; ", get_dep_weak (s, BEGIN_DATA));
4401   if (s & BE_IN_DATA)
4402     fprintf (f, "BE_IN_DATA: %d; ", get_dep_weak (s, BE_IN_DATA));
4403   if (s & BEGIN_CONTROL)
4404     fprintf (f, "BEGIN_CONTROL: %d; ", get_dep_weak (s, BEGIN_CONTROL));
4405   if (s & BE_IN_CONTROL)
4406     fprintf (f, "BE_IN_CONTROL: %d; ", get_dep_weak (s, BE_IN_CONTROL));
4407
4408   if (s & HARD_DEP)
4409     fprintf (f, "HARD_DEP; ");
4410
4411   if (s & DEP_TRUE)
4412     fprintf (f, "DEP_TRUE; ");
4413   if (s & DEP_ANTI)
4414     fprintf (f, "DEP_ANTI; ");
4415   if (s & DEP_OUTPUT)
4416     fprintf (f, "DEP_OUTPUT; ");
4417
4418   fprintf (f, "\n");
4419 }
4420
4421 /* Helper function for check_cfg.
4422    Return nonzero, if edge vector pointed to by EL has edge with TYPE in
4423    its flags.  */
4424 static int
4425 has_edge_p (VEC(edge,gc) *el, int type)
4426 {
4427   edge e;
4428   edge_iterator ei;
4429
4430   FOR_EACH_EDGE (e, ei, el)
4431     if (e->flags & type)
4432       return 1;
4433   return 0;
4434 }
4435
4436 /* Check few properties of CFG between HEAD and TAIL.
4437    If HEAD (TAIL) is NULL check from the beginning (till the end) of the
4438    instruction stream.  */
4439 static void
4440 check_cfg (rtx head, rtx tail)
4441 {
4442   rtx next_tail;
4443   basic_block bb = 0;
4444   int not_first = 0, not_last;
4445
4446   if (head == NULL)
4447     head = get_insns ();
4448   if (tail == NULL)
4449     tail = get_last_insn ();
4450   next_tail = NEXT_INSN (tail);
4451
4452   do
4453     {      
4454       not_last = head != tail;        
4455
4456       if (not_first)
4457         gcc_assert (NEXT_INSN (PREV_INSN (head)) == head);
4458       if (not_last)
4459         gcc_assert (PREV_INSN (NEXT_INSN (head)) == head);
4460
4461       if (LABEL_P (head) 
4462           || (NOTE_INSN_BASIC_BLOCK_P (head)
4463               && (!not_first
4464                   || (not_first && !LABEL_P (PREV_INSN (head))))))
4465         {
4466           gcc_assert (bb == 0);   
4467           bb = BLOCK_FOR_INSN (head);
4468           if (bb != 0)
4469             gcc_assert (BB_HEAD (bb) == head);      
4470           else
4471             /* This is the case of jump table.  See inside_basic_block_p ().  */
4472             gcc_assert (LABEL_P (head) && !inside_basic_block_p (head));
4473         }
4474
4475       if (bb == 0)
4476         {
4477           gcc_assert (!inside_basic_block_p (head));
4478           head = NEXT_INSN (head);
4479         }
4480       else
4481         {
4482           gcc_assert (inside_basic_block_p (head)
4483                       || NOTE_P (head));
4484           gcc_assert (BLOCK_FOR_INSN (head) == bb);
4485         
4486           if (LABEL_P (head))
4487             {
4488               head = NEXT_INSN (head);
4489               gcc_assert (NOTE_INSN_BASIC_BLOCK_P (head));
4490             }
4491           else
4492             {
4493               if (control_flow_insn_p (head))
4494                 {
4495                   gcc_assert (BB_END (bb) == head);
4496                   
4497                   if (any_uncondjump_p (head))
4498                     gcc_assert (EDGE_COUNT (bb->succs) == 1
4499                                 && BARRIER_P (NEXT_INSN (head)));
4500                   else if (any_condjump_p (head))
4501                     gcc_assert (/* Usual case.  */
4502                                 (EDGE_COUNT (bb->succs) > 1
4503                                  && !BARRIER_P (NEXT_INSN (head)))
4504                                 /* Or jump to the next instruction.  */
4505                                 || (EDGE_COUNT (bb->succs) == 1
4506                                     && (BB_HEAD (EDGE_I (bb->succs, 0)->dest)
4507                                         == JUMP_LABEL (head))));
4508                 }
4509               if (BB_END (bb) == head)
4510                 {
4511                   if (EDGE_COUNT (bb->succs) > 1)
4512                     gcc_assert (control_flow_insn_p (head)
4513                                 || has_edge_p (bb->succs, EDGE_COMPLEX));
4514                   bb = 0;
4515                 }
4516                               
4517               head = NEXT_INSN (head);
4518             }
4519         }
4520
4521       not_first = 1;
4522     }
4523   while (head != next_tail);
4524
4525   gcc_assert (bb == 0);
4526 }
4527
4528 /* Perform a few consistency checks of flags in different data structures.  */
4529 static void
4530 check_sched_flags (void)
4531 {
4532   unsigned int f = current_sched_info->flags;
4533
4534   if (flag_sched_stalled_insns)
4535     gcc_assert (!(f & DO_SPECULATION));
4536   if (f & DO_SPECULATION)
4537     gcc_assert (!flag_sched_stalled_insns
4538                 && (f & DETACH_LIFE_INFO)
4539                 && spec_info
4540                 && spec_info->mask);
4541   if (f & DETACH_LIFE_INFO)
4542     gcc_assert (f & USE_GLAT);
4543 }
4544
4545 /* Check global_live_at_{start, end} regsets.
4546    If FATAL_P is TRUE, then abort execution at the first failure.
4547    Otherwise, print diagnostics to STDERR (this mode is for calling
4548    from debugger).  */
4549 void
4550 check_reg_live (bool fatal_p)
4551 {
4552   basic_block bb;
4553
4554   FOR_ALL_BB (bb)
4555     {
4556       int i;
4557
4558       i = bb->index;
4559
4560       if (glat_start[i])
4561         {
4562           bool b = bitmap_equal_p (bb->il.rtl->global_live_at_start,
4563                                    glat_start[i]);
4564
4565           if (!b)
4566             {
4567               gcc_assert (!fatal_p);
4568
4569               fprintf (stderr, ";; check_reg_live_at_start (%d) failed.\n", i);
4570             }
4571         }
4572
4573       if (glat_end[i])
4574         {
4575           bool b = bitmap_equal_p (bb->il.rtl->global_live_at_end,
4576                                    glat_end[i]);
4577
4578           if (!b)
4579             {
4580               gcc_assert (!fatal_p);
4581
4582               fprintf (stderr, ";; check_reg_live_at_end (%d) failed.\n", i);
4583             }
4584         }
4585     }
4586 }
4587 #endif /* ENABLE_CHECKING */
4588
4589 #endif /* INSN_SCHEDULING */