OSDN Git Service

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