1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002 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, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, 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 Function unit conflicts are resolved during forward list scheduling
58 by tracking the time when each insn is committed to the schedule
59 and from that, the time the function units it uses must be free.
60 As insns on the ready list are considered for scheduling, those
61 that would result in a blockage of the already committed insns are
62 queued until no blockage will result.
63
64 The following list shows the order in which we want to break ties
65 among insns in the ready list:
66
67 1. choose insn with the longest path to end of bb, ties
68 broken by
69 2. choose insn with least contribution to register pressure,
70 ties broken by
71 3. prefer in-block upon interblock motion, ties broken by
72 4. prefer useful upon speculative motion, ties broken by
73 5. choose insn with largest control flow probability, ties
74 broken by
75 6. choose insn with the least dependences upon the previously
76 scheduled insn, or finally
77 7 choose the insn which has the most insns dependent on it.
78 8. choose insn with lowest UID.
79
80 Memory references complicate matters. Only if we can be certain
81 that memory references are not part of the data dependency graph
82 (via true, anti, or output dependence), can we move operations past
83 memory references. To first approximation, reads can be done
84 independently, while writes introduce dependencies. Better
85 approximations will yield fewer dependencies.
86
87 Before reload, an extended analysis of interblock data dependences
88 is required for interblock scheduling. This is performed in
89 compute_block_backward_dependences ().
90
91 Dependencies set up by memory references are treated in exactly the
92 same way as other dependencies, by using LOG_LINKS backward
93 dependences. LOG_LINKS are translated into INSN_DEPEND forward
94 dependences for the purpose of forward list scheduling.
95
96 Having optimized the critical path, we may have also unduly
97 extended the lifetimes of some registers. If an operation requires
98 that constants be loaded into registers, it is certainly desirable
99 to load those constants as early as necessary, but no earlier.
100 I.e., it will not do to load up a bunch of registers at the
101 beginning of a basic block only to use them at the end, if they
102 could be loaded later, since this may result in excessive register
103 utilization.
104
105 Note that since branches are never in basic blocks, but only end
106 basic blocks, this pass will not move branches. But that is ok,
107 since we can use GNU's delayed branch scheduling pass to take care
108 of this case.
109
110 Also note that no further optimizations based on algebraic
111 identities are performed, so this pass would be a good one to
112 perform instruction splitting, such as breaking up a multiply
113 instruction into shifts and adds where that is profitable.
114
115 Given the memory aliasing analysis that this pass should perform,
116 it should be possible to remove redundant stores to memory, and to
117 load values from registers instead of hitting memory.
118
119 Before reload, speculative insns are moved only if a 'proof' exists
120 that no exception will be caused by this, and if no live registers
121 exist that inhibit the motion (live registers constraints are not
122 represented by data dependence edges).
123
124 This pass must update information that subsequent passes expect to
125 be correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
126 reg_n_calls_crossed, and reg_live_length. Also, BLOCK_HEAD,
127 BLOCK_END.
128
129 The information in the line number notes is carefully retained by
130 this pass. Notes that refer to the starting and ending of
131 exception regions are also carefully retained by this pass. All
132 other NOTE insns are grouped in their same relative order at the
133 beginning of basic blocks and regions that have been scheduled. */
134
135 #include "config.h"
136 #include "system.h"
137 #include "toplev.h"
138 #include "rtl.h"
139 #include "tm_p.h"
140 #include "hard-reg-set.h"
141 #include "basic-block.h"
142 #include "regs.h"
143 #include "function.h"
144 #include "flags.h"
145 #include "insn-config.h"
146 #include "insn-attr.h"
147 #include "except.h"
148 #include "toplev.h"
149 #include "recog.h"
150 #include "sched-int.h"
151 #include "target.h"
152
153 #ifdef INSN_SCHEDULING
154
155 /* issue_rate is the number of insns that can be scheduled in the same
156 machine cycle. It can be defined in the config/mach/mach.h file,
157 otherwise we set it to 1. */
158
159 static int issue_rate;
160
161 /* If the following variable value is nonzero, the scheduler inserts
162 bubbles (nop insns). The value of variable affects on scheduler
163 behavior only if automaton pipeline interface with multipass
164 scheduling is used and hook dfa_bubble is defined. */
165 int insert_schedule_bubbles_p = 0;
166
167 /* sched-verbose controls the amount of debugging output the
168 scheduler prints. It is controlled by -fsched-verbose=N:
169 N>0 and no -DSR : the output is directed to stderr.
170 N>=10 will direct the printouts to stderr (regardless of -dSR).
171 N=1: same as -dSR.
172 N=2: bb's probabilities, detailed ready list info, unit/insn info.
173 N=3: rtl at abort point, control-flow, regions info.
174 N=5: dependences info. */
175
176 static int sched_verbose_param = 0;
177 int sched_verbose = 0;
178
179 /* Debugging file. All printouts are sent to dump, which is always set,
180 either to stderr, or to the dump listing file (-dRS). */
181 FILE *sched_dump = 0;
182
183 /* Highest uid before scheduling. */
184 static int old_max_uid;
185
186 /* fix_sched_param() is called from toplev.c upon detection
187 of the -fsched-verbose=N option. */
188
189 void
fix_sched_param(param,val)190 fix_sched_param (param, val)
191 const char *param, *val;
192 {
193 if (!strcmp (param, "verbose"))
194 sched_verbose_param = atoi (val);
195 else
196 warning ("fix_sched_param: unknown param: %s", param);
197 }
198
199 struct haifa_insn_data *h_i_d;
200
201 #define LINE_NOTE(INSN) (h_i_d[INSN_UID (INSN)].line_note)
202 #define INSN_TICK(INSN) (h_i_d[INSN_UID (INSN)].tick)
203
204 /* Vector indexed by basic block number giving the starting line-number
205 for each basic block. */
206 static rtx *line_note_head;
207
208 /* List of important notes we must keep around. This is a pointer to the
209 last element in the list. */
210 static rtx note_list;
211
212 /* Queues, etc. */
213
214 /* An instruction is ready to be scheduled when all insns preceding it
215 have already been scheduled. It is important to ensure that all
216 insns which use its result will not be executed until its result
217 has been computed. An insn is maintained in one of four structures:
218
219 (P) the "Pending" set of insns which cannot be scheduled until
220 their dependencies have been satisfied.
221 (Q) the "Queued" set of insns that can be scheduled when sufficient
222 time has passed.
223 (R) the "Ready" list of unscheduled, uncommitted insns.
224 (S) the "Scheduled" list of insns.
225
226 Initially, all insns are either "Pending" or "Ready" depending on
227 whether their dependencies are satisfied.
228
229 Insns move from the "Ready" list to the "Scheduled" list as they
230 are committed to the schedule. As this occurs, the insns in the
231 "Pending" list have their dependencies satisfied and move to either
232 the "Ready" list or the "Queued" set depending on whether
233 sufficient time has passed to make them ready. As time passes,
234 insns move from the "Queued" set to the "Ready" list. Insns may
235 move from the "Ready" list to the "Queued" set if they are blocked
236 due to a function unit conflict.
237
238 The "Pending" list (P) are the insns in the INSN_DEPEND of the unscheduled
239 insns, i.e., those that are ready, queued, and pending.
240 The "Queued" set (Q) is implemented by the variable `insn_queue'.
241 The "Ready" list (R) is implemented by the variables `ready' and
242 `n_ready'.
243 The "Scheduled" list (S) is the new insn chain built by this pass.
244
245 The transition (R->S) is implemented in the scheduling loop in
246 `schedule_block' when the best insn to schedule is chosen.
247 The transition (R->Q) is implemented in `queue_insn' when an
248 insn is found to have a function unit conflict with the already
249 committed insns.
250 The transitions (P->R and P->Q) are implemented in `schedule_insn' as
251 insns move from the ready list to the scheduled list.
252 The transition (Q->R) is implemented in 'queue_to_insn' as time
253 passes or stalls are introduced. */
254
255 /* Implement a circular buffer to delay instructions until sufficient
256 time has passed. For the old pipeline description interface,
257 INSN_QUEUE_SIZE is a power of two larger than MAX_BLOCKAGE and
258 MAX_READY_COST computed by genattr.c. For the new pipeline
259 description interface, MAX_INSN_QUEUE_INDEX is a power of two minus
260 one which is larger than maximal time of instruction execution
261 computed by genattr.c on the base maximal time of functional unit
262 reservations and geting a result. This is the longest time an
263 insn may be queued. */
264
265 #define MAX_INSN_QUEUE_INDEX max_insn_queue_index_macro_value
266
267 static rtx *insn_queue;
268 static int q_ptr = 0;
269 static int q_size = 0;
270 #define NEXT_Q(X) (((X)+1) & MAX_INSN_QUEUE_INDEX)
271 #define NEXT_Q_AFTER(X, C) (((X)+C) & MAX_INSN_QUEUE_INDEX)
272
273 /* The following variable defines value for macro
274 MAX_INSN_QUEUE_INDEX. */
275 static int max_insn_queue_index_macro_value;
276
277 /* The following variable value refers for all current and future
278 reservations of the processor units. */
279 state_t curr_state;
280
281 /* The following variable value is size of memory representing all
282 current and future reservations of the processor units. It is used
283 only by DFA based scheduler. */
284 static size_t dfa_state_size;
285
286 /* The following array is used to find the best insn from ready when
287 the automaton pipeline interface is used. */
288 static char *ready_try;
289
290 /* Describe the ready list of the scheduler.
291 VEC holds space enough for all insns in the current region. VECLEN
292 says how many exactly.
293 FIRST is the index of the element with the highest priority; i.e. the
294 last one in the ready list, since elements are ordered by ascending
295 priority.
296 N_READY determines how many insns are on the ready list. */
297
298 struct ready_list
299 {
300 rtx *vec;
301 int veclen;
302 int first;
303 int n_ready;
304 };
305
306 /* Forward declarations. */
307
308 /* The scheduler using only DFA description should never use the
309 following five functions: */
310 static unsigned int blockage_range PARAMS ((int, rtx));
311 static void clear_units PARAMS ((void));
312 static void schedule_unit PARAMS ((int, rtx, int));
313 static int actual_hazard PARAMS ((int, rtx, int, int));
314 static int potential_hazard PARAMS ((int, rtx, int));
315
316 static int priority PARAMS ((rtx));
317 static int rank_for_schedule PARAMS ((const PTR, const PTR));
318 static void swap_sort PARAMS ((rtx *, int));
319 static void queue_insn PARAMS ((rtx, int));
320 static void schedule_insn PARAMS ((rtx, struct ready_list *, int));
321 static void find_insn_reg_weight PARAMS ((int));
322 static void adjust_priority PARAMS ((rtx));
323 static void advance_one_cycle PARAMS ((void));
324
325 /* Notes handling mechanism:
326 =========================
327 Generally, NOTES are saved before scheduling and restored after scheduling.
328 The scheduler distinguishes between three types of notes:
329
330 (1) LINE_NUMBER notes, generated and used for debugging. Here,
331 before scheduling a region, a pointer to the LINE_NUMBER note is
332 added to the insn following it (in save_line_notes()), and the note
333 is removed (in rm_line_notes() and unlink_line_notes()). After
334 scheduling the region, this pointer is used for regeneration of
335 the LINE_NUMBER note (in restore_line_notes()).
336
337 (2) LOOP_BEGIN, LOOP_END, SETJMP, EHREGION_BEG, EHREGION_END notes:
338 Before scheduling a region, a pointer to the note is added to the insn
339 that follows or precedes it. (This happens as part of the data dependence
340 computation). After scheduling an insn, the pointer contained in it is
341 used for regenerating the corresponding note (in reemit_notes).
342
343 (3) All other notes (e.g. INSN_DELETED): Before scheduling a block,
344 these notes are put in a list (in rm_other_notes() and
345 unlink_other_notes ()). After scheduling the block, these notes are
346 inserted at the beginning of the block (in schedule_block()). */
347
348 static rtx unlink_other_notes PARAMS ((rtx, rtx));
349 static rtx unlink_line_notes PARAMS ((rtx, rtx));
350 static rtx reemit_notes PARAMS ((rtx, rtx));
351
352 static rtx *ready_lastpos PARAMS ((struct ready_list *));
353 static void ready_sort PARAMS ((struct ready_list *));
354 static rtx ready_remove_first PARAMS ((struct ready_list *));
355
356 static void queue_to_ready PARAMS ((struct ready_list *));
357
358 static void debug_ready_list PARAMS ((struct ready_list *));
359
360 static rtx move_insn1 PARAMS ((rtx, rtx));
361 static rtx move_insn PARAMS ((rtx, rtx));
362
363 /* The following functions are used to implement multi-pass scheduling
364 on the first cycle. It is used only for DFA based scheduler. */
365 static rtx ready_element PARAMS ((struct ready_list *, int));
366 static rtx ready_remove PARAMS ((struct ready_list *, int));
367 static int max_issue PARAMS ((struct ready_list *, int *));
368
369 static rtx choose_ready PARAMS ((struct ready_list *));
370
371 #endif /* INSN_SCHEDULING */
372
373 /* Point to state used for the current scheduling pass. */
374 struct sched_info *current_sched_info;
375
376 #ifndef INSN_SCHEDULING
377 void
schedule_insns(dump_file)378 schedule_insns (dump_file)
379 FILE *dump_file ATTRIBUTE_UNUSED;
380 {
381 }
382 #else
383
384 /* Pointer to the last instruction scheduled. Used by rank_for_schedule,
385 so that insns independent of the last scheduled insn will be preferred
386 over dependent instructions. */
387
388 static rtx last_scheduled_insn;
389
390 /* Compute the function units used by INSN. This caches the value
391 returned by function_units_used. A function unit is encoded as the
392 unit number if the value is non-negative and the complement of a
393 mask if the value is negative. A function unit index is the
394 non-negative encoding. The scheduler using only DFA description
395 should never use the following function. */
396
397 HAIFA_INLINE int
insn_unit(insn)398 insn_unit (insn)
399 rtx insn;
400 {
401 int unit = INSN_UNIT (insn);
402
403 if (unit == 0)
404 {
405 recog_memoized (insn);
406
407 /* A USE insn, or something else we don't need to understand.
408 We can't pass these directly to function_units_used because it will
409 trigger a fatal error for unrecognizable insns. */
410 if (INSN_CODE (insn) < 0)
411 unit = -1;
412 else
413 {
414 unit = function_units_used (insn);
415 /* Increment non-negative values so we can cache zero. */
416 if (unit >= 0)
417 unit++;
418 }
419 /* We only cache 16 bits of the result, so if the value is out of
420 range, don't cache it. */
421 if (FUNCTION_UNITS_SIZE < HOST_BITS_PER_SHORT
422 || unit >= 0
423 || (unit & ~((1 << (HOST_BITS_PER_SHORT - 1)) - 1)) == 0)
424 INSN_UNIT (insn) = unit;
425 }
426 return (unit > 0 ? unit - 1 : unit);
427 }
428
429 /* Compute the blockage range for executing INSN on UNIT. This caches
430 the value returned by the blockage_range_function for the unit.
431 These values are encoded in an int where the upper half gives the
432 minimum value and the lower half gives the maximum value. The
433 scheduler using only DFA description should never use the following
434 function. */
435
436 HAIFA_INLINE static unsigned int
blockage_range(unit,insn)437 blockage_range (unit, insn)
438 int unit;
439 rtx insn;
440 {
441 unsigned int blockage = INSN_BLOCKAGE (insn);
442 unsigned int range;
443
444 if ((int) UNIT_BLOCKED (blockage) != unit + 1)
445 {
446 range = function_units[unit].blockage_range_function (insn);
447 /* We only cache the blockage range for one unit and then only if
448 the values fit. */
449 if (HOST_BITS_PER_INT >= UNIT_BITS + 2 * BLOCKAGE_BITS)
450 INSN_BLOCKAGE (insn) = ENCODE_BLOCKAGE (unit + 1, range);
451 }
452 else
453 range = BLOCKAGE_RANGE (blockage);
454
455 return range;
456 }
457
458 /* A vector indexed by function unit instance giving the last insn to
459 use the unit. The value of the function unit instance index for
460 unit U instance I is (U + I * FUNCTION_UNITS_SIZE). The scheduler
461 using only DFA description should never use the following variable. */
462 #if FUNCTION_UNITS_SIZE
463 static rtx unit_last_insn[FUNCTION_UNITS_SIZE * MAX_MULTIPLICITY];
464 #else
465 static rtx unit_last_insn[1];
466 #endif
467
468 /* A vector indexed by function unit instance giving the minimum time
469 when the unit will unblock based on the maximum blockage cost. The
470 scheduler using only DFA description should never use the following
471 variable. */
472 #if FUNCTION_UNITS_SIZE
473 static int unit_tick[FUNCTION_UNITS_SIZE * MAX_MULTIPLICITY];
474 #else
475 static int unit_tick[1];
476 #endif
477
478 /* A vector indexed by function unit number giving the number of insns
479 that remain to use the unit. The scheduler using only DFA
480 description should never use the following variable. */
481 #if FUNCTION_UNITS_SIZE
482 static int unit_n_insns[FUNCTION_UNITS_SIZE];
483 #else
484 static int unit_n_insns[1];
485 #endif
486
487 /* Access the unit_last_insn array. Used by the visualization code.
488 The scheduler using only DFA description should never use the
489 following function. */
490
491 rtx
get_unit_last_insn(instance)492 get_unit_last_insn (instance)
493 int instance;
494 {
495 return unit_last_insn[instance];
496 }
497
498 /* Reset the function unit state to the null state. */
499
500 static void
clear_units()501 clear_units ()
502 {
503 memset ((char *) unit_last_insn, 0, sizeof (unit_last_insn));
504 memset ((char *) unit_tick, 0, sizeof (unit_tick));
505 memset ((char *) unit_n_insns, 0, sizeof (unit_n_insns));
506 }
507
508 /* Return the issue-delay of an insn. The scheduler using only DFA
509 description should never use the following function. */
510
511 HAIFA_INLINE int
insn_issue_delay(insn)512 insn_issue_delay (insn)
513 rtx insn;
514 {
515 int i, delay = 0;
516 int unit = insn_unit (insn);
517
518 /* Efficiency note: in fact, we are working 'hard' to compute a
519 value that was available in md file, and is not available in
520 function_units[] structure. It would be nice to have this
521 value there, too. */
522 if (unit >= 0)
523 {
524 if (function_units[unit].blockage_range_function &&
525 function_units[unit].blockage_function)
526 delay = function_units[unit].blockage_function (insn, insn);
527 }
528 else
529 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
530 if ((unit & 1) != 0 && function_units[i].blockage_range_function
531 && function_units[i].blockage_function)
532 delay = MAX (delay, function_units[i].blockage_function (insn, insn));
533
534 return delay;
535 }
536
537 /* Return the actual hazard cost of executing INSN on the unit UNIT,
538 instance INSTANCE at time CLOCK if the previous actual hazard cost
539 was COST. The scheduler using only DFA description should never
540 use the following function. */
541
542 HAIFA_INLINE int
actual_hazard_this_instance(unit,instance,insn,clock,cost)543 actual_hazard_this_instance (unit, instance, insn, clock, cost)
544 int unit, instance, clock, cost;
545 rtx insn;
546 {
547 int tick = unit_tick[instance]; /* Issue time of the last issued insn. */
548
549 if (tick - clock > cost)
550 {
551 /* The scheduler is operating forward, so unit's last insn is the
552 executing insn and INSN is the candidate insn. We want a
553 more exact measure of the blockage if we execute INSN at CLOCK
554 given when we committed the execution of the unit's last insn.
555
556 The blockage value is given by either the unit's max blockage
557 constant, blockage range function, or blockage function. Use
558 the most exact form for the given unit. */
559
560 if (function_units[unit].blockage_range_function)
561 {
562 if (function_units[unit].blockage_function)
563 tick += (function_units[unit].blockage_function
564 (unit_last_insn[instance], insn)
565 - function_units[unit].max_blockage);
566 else
567 tick += ((int) MAX_BLOCKAGE_COST (blockage_range (unit, insn))
568 - function_units[unit].max_blockage);
569 }
570 if (tick - clock > cost)
571 cost = tick - clock;
572 }
573 return cost;
574 }
575
576 /* Record INSN as having begun execution on the units encoded by UNIT
577 at time CLOCK. The scheduler using only DFA description should
578 never use the following function. */
579
580 HAIFA_INLINE static void
schedule_unit(unit,insn,clock)581 schedule_unit (unit, insn, clock)
582 int unit, clock;
583 rtx insn;
584 {
585 int i;
586
587 if (unit >= 0)
588 {
589 int instance = unit;
590 #if MAX_MULTIPLICITY > 1
591 /* Find the first free instance of the function unit and use that
592 one. We assume that one is free. */
593 for (i = function_units[unit].multiplicity - 1; i > 0; i--)
594 {
595 if (!actual_hazard_this_instance (unit, instance, insn, clock, 0))
596 break;
597 instance += FUNCTION_UNITS_SIZE;
598 }
599 #endif
600 unit_last_insn[instance] = insn;
601 unit_tick[instance] = (clock + function_units[unit].max_blockage);
602 }
603 else
604 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
605 if ((unit & 1) != 0)
606 schedule_unit (i, insn, clock);
607 }
608
609 /* Return the actual hazard cost of executing INSN on the units
610 encoded by UNIT at time CLOCK if the previous actual hazard cost
611 was COST. The scheduler using only DFA description should never
612 use the following function. */
613
614 HAIFA_INLINE static int
actual_hazard(unit,insn,clock,cost)615 actual_hazard (unit, insn, clock, cost)
616 int unit, clock, cost;
617 rtx insn;
618 {
619 int i;
620
621 if (unit >= 0)
622 {
623 /* Find the instance of the function unit with the minimum hazard. */
624 int instance = unit;
625 int best_cost = actual_hazard_this_instance (unit, instance, insn,
626 clock, cost);
627 #if MAX_MULTIPLICITY > 1
628 int this_cost;
629
630 if (best_cost > cost)
631 {
632 for (i = function_units[unit].multiplicity - 1; i > 0; i--)
633 {
634 instance += FUNCTION_UNITS_SIZE;
635 this_cost = actual_hazard_this_instance (unit, instance, insn,
636 clock, cost);
637 if (this_cost < best_cost)
638 {
639 best_cost = this_cost;
640 if (this_cost <= cost)
641 break;
642 }
643 }
644 }
645 #endif
646 cost = MAX (cost, best_cost);
647 }
648 else
649 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
650 if ((unit & 1) != 0)
651 cost = actual_hazard (i, insn, clock, cost);
652
653 return cost;
654 }
655
656 /* Return the potential hazard cost of executing an instruction on the
657 units encoded by UNIT if the previous potential hazard cost was
658 COST. An insn with a large blockage time is chosen in preference
659 to one with a smaller time; an insn that uses a unit that is more
660 likely to be used is chosen in preference to one with a unit that
661 is less used. We are trying to minimize a subsequent actual
662 hazard. The scheduler using only DFA description should never use
663 the following function. */
664
665 HAIFA_INLINE static int
potential_hazard(unit,insn,cost)666 potential_hazard (unit, insn, cost)
667 int unit, cost;
668 rtx insn;
669 {
670 int i, ncost;
671 unsigned int minb, maxb;
672
673 if (unit >= 0)
674 {
675 minb = maxb = function_units[unit].max_blockage;
676 if (maxb > 1)
677 {
678 if (function_units[unit].blockage_range_function)
679 {
680 maxb = minb = blockage_range (unit, insn);
681 maxb = MAX_BLOCKAGE_COST (maxb);
682 minb = MIN_BLOCKAGE_COST (minb);
683 }
684
685 if (maxb > 1)
686 {
687 /* Make the number of instructions left dominate. Make the
688 minimum delay dominate the maximum delay. If all these
689 are the same, use the unit number to add an arbitrary
690 ordering. Other terms can be added. */
691 ncost = minb * 0x40 + maxb;
692 ncost *= (unit_n_insns[unit] - 1) * 0x1000 + unit;
693 if (ncost > cost)
694 cost = ncost;
695 }
696 }
697 }
698 else
699 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
700 if ((unit & 1) != 0)
701 cost = potential_hazard (i, insn, cost);
702
703 return cost;
704 }
705
706 /* Compute cost of executing INSN given the dependence LINK on the insn USED.
707 This is the number of cycles between instruction issue and
708 instruction results. */
709
710 HAIFA_INLINE int
insn_cost(insn,link,used)711 insn_cost (insn, link, used)
712 rtx insn, link, used;
713 {
714 int cost = INSN_COST (insn);
715
716 if (cost < 0)
717 {
718 /* A USE insn, or something else we don't need to
719 understand. We can't pass these directly to
720 result_ready_cost or insn_default_latency because it will
721 trigger a fatal error for unrecognizable insns. */
722 if (recog_memoized (insn) < 0)
723 {
724 INSN_COST (insn) = 0;
725 return 0;
726 }
727 else
728 {
729 if (targetm.sched.use_dfa_pipeline_interface
730 && (*targetm.sched.use_dfa_pipeline_interface) ())
731 cost = insn_default_latency (insn);
732 else
733 cost = result_ready_cost (insn);
734
735 if (cost < 0)
736 cost = 0;
737
738 INSN_COST (insn) = cost;
739 }
740 }
741
742 /* In this case estimate cost without caring how insn is used. */
743 if (link == 0 || used == 0)
744 return cost;
745
746 /* A USE insn should never require the value used to be computed.
747 This allows the computation of a function's result and parameter
748 values to overlap the return and call. */
749 if (recog_memoized (used) < 0)
750 cost = 0;
751 else
752 {
753 if (targetm.sched.use_dfa_pipeline_interface
754 && (*targetm.sched.use_dfa_pipeline_interface) ())
755 {
756 if (INSN_CODE (insn) >= 0)
757 {
758 if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
759 cost = 0;
760 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
761 {
762 cost = (insn_default_latency (insn)
763 - insn_default_latency (used));
764 if (cost <= 0)
765 cost = 1;
766 }
767 else if (bypass_p (insn))
768 cost = insn_latency (insn, used);
769 }
770 }
771
772 if (targetm.sched.adjust_cost)
773 cost = (*targetm.sched.adjust_cost) (used, link, insn, cost);
774
775 if (cost < 0)
776 cost = 0;
777 }
778
779 return cost;
780 }
781
782 /* Compute the priority number for INSN. */
783
784 static int
priority(insn)785 priority (insn)
786 rtx insn;
787 {
788 rtx link;
789
790 if (! INSN_P (insn))
791 return 0;
792
793 if (! INSN_PRIORITY_KNOWN (insn))
794 {
795 int this_priority = 0;
796
797 if (INSN_DEPEND (insn) == 0)
798 this_priority = insn_cost (insn, 0, 0);
799 else
800 {
801 for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
802 {
803 rtx next;
804 int next_priority;
805
806 if (RTX_INTEGRATED_P (link))
807 continue;
808
809 next = XEXP (link, 0);
810
811 /* Critical path is meaningful in block boundaries only. */
812 if (! (*current_sched_info->contributes_to_priority) (next, insn))
813 continue;
814
815 next_priority = insn_cost (insn, link, next) + priority (next);
816 if (next_priority > this_priority)
817 this_priority = next_priority;
818 }
819 }
820 INSN_PRIORITY (insn) = this_priority;
821 INSN_PRIORITY_KNOWN (insn) = 1;
822 }
823
824 return INSN_PRIORITY (insn);
825 }
826
827 /* Macros and functions for keeping the priority queue sorted, and
828 dealing with queueing and dequeueing of instructions. */
829
830 #define SCHED_SORT(READY, N_READY) \
831 do { if ((N_READY) == 2) \
832 swap_sort (READY, N_READY); \
833 else if ((N_READY) > 2) \
834 qsort (READY, N_READY, sizeof (rtx), rank_for_schedule); } \
835 while (0)
836
837 /* Returns a positive value if x is preferred; returns a negative value if
838 y is preferred. Should never return 0, since that will make the sort
839 unstable. */
840
841 static int
rank_for_schedule(x,y)842 rank_for_schedule (x, y)
843 const PTR x;
844 const PTR y;
845 {
846 rtx tmp = *(const rtx *) y;
847 rtx tmp2 = *(const rtx *) x;
848 rtx link;
849 int tmp_class, tmp2_class, depend_count1, depend_count2;
850 int val, priority_val, weight_val, info_val;
851
852 /* Prefer insn with higher priority. */
853 priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
854 if (priority_val)
855 return priority_val;
856
857 /* Prefer an insn with smaller contribution to registers-pressure. */
858 if (!reload_completed &&
859 (weight_val = INSN_REG_WEIGHT (tmp) - INSN_REG_WEIGHT (tmp2)))
860 return (weight_val);
861
862 info_val = (*current_sched_info->rank) (tmp, tmp2);
863 if (info_val)
864 return info_val;
865
866 /* Compare insns based on their relation to the last-scheduled-insn. */
867 if (last_scheduled_insn)
868 {
869 /* Classify the instructions into three classes:
870 1) Data dependent on last schedule insn.
871 2) Anti/Output dependent on last scheduled insn.
872 3) Independent of last scheduled insn, or has latency of one.
873 Choose the insn from the highest numbered class if different. */
874 link = find_insn_list (tmp, INSN_DEPEND (last_scheduled_insn));
875 if (link == 0 || insn_cost (last_scheduled_insn, link, tmp) == 1)
876 tmp_class = 3;
877 else if (REG_NOTE_KIND (link) == 0) /* Data dependence. */
878 tmp_class = 1;
879 else
880 tmp_class = 2;
881
882 link = find_insn_list (tmp2, INSN_DEPEND (last_scheduled_insn));
883 if (link == 0 || insn_cost (last_scheduled_insn, link, tmp2) == 1)
884 tmp2_class = 3;
885 else if (REG_NOTE_KIND (link) == 0) /* Data dependence. */
886 tmp2_class = 1;
887 else
888 tmp2_class = 2;
889
890 if ((val = tmp2_class - tmp_class))
891 return val;
892 }
893
894 /* Prefer the insn which has more later insns that depend on it.
895 This gives the scheduler more freedom when scheduling later
896 instructions at the expense of added register pressure. */
897 depend_count1 = 0;
898 for (link = INSN_DEPEND (tmp); link; link = XEXP (link, 1))
899 depend_count1++;
900
901 depend_count2 = 0;
902 for (link = INSN_DEPEND (tmp2); link; link = XEXP (link, 1))
903 depend_count2++;
904
905 val = depend_count2 - depend_count1;
906 if (val)
907 return val;
908
909 /* If insns are equally good, sort by INSN_LUID (original insn order),
910 so that we make the sort stable. This minimizes instruction movement,
911 thus minimizing sched's effect on debugging and cross-jumping. */
912 return INSN_LUID (tmp) - INSN_LUID (tmp2);
913 }
914
915 /* Resort the array A in which only element at index N may be out of order. */
916
917 HAIFA_INLINE static void
swap_sort(a,n)918 swap_sort (a, n)
919 rtx *a;
920 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
queue_insn(insn,n_cycles)938 queue_insn (insn, n_cycles)
939 rtx insn;
940 int n_cycles;
941 {
942 int next_q = NEXT_Q_AFTER (q_ptr, n_cycles);
943 rtx link = alloc_INSN_LIST (insn, insn_queue[next_q]);
944 insn_queue[next_q] = link;
945 q_size += 1;
946
947 if (sched_verbose >= 2)
948 {
949 fprintf (sched_dump, ";;\t\tReady-->Q: insn %s: ",
950 (*current_sched_info->print_insn) (insn, 0));
951
952 fprintf (sched_dump, "queued for %d cycles.\n", n_cycles);
953 }
954 }
955
956 /* Return a pointer to the bottom of the ready list, i.e. the insn
957 with the lowest priority. */
958
959 HAIFA_INLINE static rtx *
ready_lastpos(ready)960 ready_lastpos (ready)
961 struct ready_list *ready;
962 {
963 if (ready->n_ready == 0)
964 abort ();
965 return ready->vec + ready->first - ready->n_ready + 1;
966 }
967
968 /* Add an element INSN to the ready list so that it ends up with the lowest
969 priority. */
970
971 HAIFA_INLINE void
ready_add(ready,insn)972 ready_add (ready, insn)
973 struct ready_list *ready;
974 rtx insn;
975 {
976 if (ready->first == ready->n_ready)
977 {
978 memmove (ready->vec + ready->veclen - ready->n_ready,
979 ready_lastpos (ready),
980 ready->n_ready * sizeof (rtx));
981 ready->first = ready->veclen - 1;
982 }
983 ready->vec[ready->first - ready->n_ready] = insn;
984 ready->n_ready++;
985 }
986
987 /* Remove the element with the highest priority from the ready list and
988 return it. */
989
990 HAIFA_INLINE static rtx
ready_remove_first(ready)991 ready_remove_first (ready)
992 struct ready_list *ready;
993 {
994 rtx t;
995 if (ready->n_ready == 0)
996 abort ();
997 t = ready->vec[ready->first--];
998 ready->n_ready--;
999 /* If the queue becomes empty, reset it. */
1000 if (ready->n_ready == 0)
1001 ready->first = ready->veclen - 1;
1002 return t;
1003 }
1004
1005 /* The following code implements multi-pass scheduling for the first
1006 cycle. In other words, we will try to choose ready insn which
1007 permits to start maximum number of insns on the same cycle. */
1008
1009 /* Return a pointer to the element INDEX from the ready. INDEX for
1010 insn with the highest priority is 0, and the lowest priority has
1011 N_READY - 1. */
1012
1013 HAIFA_INLINE static rtx
ready_element(ready,index)1014 ready_element (ready, index)
1015 struct ready_list *ready;
1016 int index;
1017 {
1018 if (ready->n_ready == 0 || index >= ready->n_ready)
1019 abort ();
1020 return ready->vec[ready->first - index];
1021 }
1022
1023 /* Remove the element INDEX from the ready list and return it. INDEX
1024 for insn with the highest priority is 0, and the lowest priority
1025 has N_READY - 1. */
1026
1027 HAIFA_INLINE static rtx
ready_remove(ready,index)1028 ready_remove (ready, index)
1029 struct ready_list *ready;
1030 int index;
1031 {
1032 rtx t;
1033 int i;
1034
1035 if (index == 0)
1036 return ready_remove_first (ready);
1037 if (ready->n_ready == 0 || index >= ready->n_ready)
1038 abort ();
1039 t = ready->vec[ready->first - index];
1040 ready->n_ready--;
1041 for (i = index; i < ready->n_ready; i++)
1042 ready->vec[ready->first - i] = ready->vec[ready->first - i - 1];
1043 return t;
1044 }
1045
1046
1047 /* Sort the ready list READY by ascending priority, using the SCHED_SORT
1048 macro. */
1049
1050 HAIFA_INLINE static void
ready_sort(ready)1051 ready_sort (ready)
1052 struct ready_list *ready;
1053 {
1054 rtx *first = ready_lastpos (ready);
1055 SCHED_SORT (first, ready->n_ready);
1056 }
1057
1058 /* PREV is an insn that is ready to execute. Adjust its priority if that
1059 will help shorten or lengthen register lifetimes as appropriate. Also
1060 provide a hook for the target to tweek itself. */
1061
1062 HAIFA_INLINE static void
adjust_priority(prev)1063 adjust_priority (prev)
1064 rtx prev;
1065 {
1066 /* ??? There used to be code here to try and estimate how an insn
1067 affected register lifetimes, but it did it by looking at REG_DEAD
1068 notes, which we removed in schedule_region. Nor did it try to
1069 take into account register pressure or anything useful like that.
1070
1071 Revisit when we have a machine model to work with and not before. */
1072
1073 if (targetm.sched.adjust_priority)
1074 INSN_PRIORITY (prev) =
1075 (*targetm.sched.adjust_priority) (prev, INSN_PRIORITY (prev));
1076 }
1077
1078 /* Advance time on one cycle. */
1079 HAIFA_INLINE static void
advance_one_cycle()1080 advance_one_cycle ()
1081 {
1082 if (targetm.sched.use_dfa_pipeline_interface
1083 && (*targetm.sched.use_dfa_pipeline_interface) ())
1084 {
1085 if (targetm.sched.dfa_pre_cycle_insn)
1086 state_transition (curr_state,
1087 (*targetm.sched.dfa_pre_cycle_insn) ());
1088
1089 state_transition (curr_state, NULL);
1090
1091 if (targetm.sched.dfa_post_cycle_insn)
1092 state_transition (curr_state,
1093 (*targetm.sched.dfa_post_cycle_insn) ());
1094 }
1095 }
1096
1097 /* Clock at which the previous instruction was issued. */
1098 static int last_clock_var;
1099
1100 /* INSN is the "currently executing insn". Launch each insn which was
1101 waiting on INSN. READY is the ready list which contains the insns
1102 that are ready to fire. CLOCK is the current cycle.
1103 */
1104
1105 static void
schedule_insn(insn,ready,clock)1106 schedule_insn (insn, ready, clock)
1107 rtx insn;
1108 struct ready_list *ready;
1109 int clock;
1110 {
1111 rtx link;
1112 int unit = 0;
1113
1114 if (!targetm.sched.use_dfa_pipeline_interface
1115 || !(*targetm.sched.use_dfa_pipeline_interface) ())
1116 unit = insn_unit (insn);
1117
1118 if (targetm.sched.use_dfa_pipeline_interface
1119 && (*targetm.sched.use_dfa_pipeline_interface) ()
1120 && sched_verbose >= 1)
1121 {
1122 char buf[2048];
1123
1124 print_insn (buf, insn, 0);
1125 buf[40]=0;
1126 fprintf (sched_dump, ";;\t%3i--> %-40s:", clock, buf);
1127
1128 if (recog_memoized (insn) < 0)
1129 fprintf (sched_dump, "nothing");
1130 else
1131 print_reservation (sched_dump, insn);
1132 fputc ('\n', sched_dump);
1133 }
1134 else if (sched_verbose >= 2)
1135 {
1136 fprintf (sched_dump, ";;\t\t--> scheduling insn <<<%d>>> on unit ",
1137 INSN_UID (insn));
1138 insn_print_units (insn);
1139 fputc ('\n', sched_dump);
1140 }
1141
1142 if (!targetm.sched.use_dfa_pipeline_interface
1143 || !(*targetm.sched.use_dfa_pipeline_interface) ())
1144 {
1145 if (sched_verbose && unit == -1)
1146 visualize_no_unit (insn);
1147
1148
1149 if (MAX_BLOCKAGE > 1 || issue_rate > 1 || sched_verbose)
1150 schedule_unit (unit, insn, clock);
1151
1152 if (INSN_DEPEND (insn) == 0)
1153 return;
1154 }
1155
1156 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
1157 {
1158 rtx next = XEXP (link, 0);
1159 int cost = insn_cost (insn, link, next);
1160
1161 INSN_TICK (next) = MAX (INSN_TICK (next), clock + cost);
1162
1163 if ((INSN_DEP_COUNT (next) -= 1) == 0)
1164 {
1165 int effective_cost = INSN_TICK (next) - clock;
1166
1167 if (! (*current_sched_info->new_ready) (next))
1168 continue;
1169
1170 if (sched_verbose >= 2)
1171 {
1172 fprintf (sched_dump, ";;\t\tdependences resolved: insn %s ",
1173 (*current_sched_info->print_insn) (next, 0));
1174
1175 if (effective_cost < 1)
1176 fprintf (sched_dump, "into ready\n");
1177 else
1178 fprintf (sched_dump, "into queue with cost=%d\n", effective_cost);
1179 }
1180
1181 /* Adjust the priority of NEXT and either put it on the ready
1182 list or queue it. */
1183 adjust_priority (next);
1184 if (effective_cost < 1)
1185 ready_add (ready, next);
1186 else
1187 queue_insn (next, effective_cost);
1188 }
1189 }
1190
1191 /* Annotate the instruction with issue information -- TImode
1192 indicates that the instruction is expected not to be able
1193 to issue on the same cycle as the previous insn. A machine
1194 may use this information to decide how the instruction should
1195 be aligned. */
1196 if (reload_completed && issue_rate > 1
1197 && GET_CODE (PATTERN (insn)) != USE
1198 && GET_CODE (PATTERN (insn)) != CLOBBER)
1199 {
1200 PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
1201 last_clock_var = clock;
1202 }
1203 }
1204
1205 /* Functions for handling of notes. */
1206
1207 /* Delete notes beginning with INSN and put them in the chain
1208 of notes ended by NOTE_LIST.
1209 Returns the insn following the notes. */
1210
1211 static rtx
unlink_other_notes(insn,tail)1212 unlink_other_notes (insn, tail)
1213 rtx insn, tail;
1214 {
1215 rtx prev = PREV_INSN (insn);
1216
1217 while (insn != tail && GET_CODE (insn) == NOTE)
1218 {
1219 rtx next = NEXT_INSN (insn);
1220 /* Delete the note from its current position. */
1221 if (prev)
1222 NEXT_INSN (prev) = next;
1223 if (next)
1224 PREV_INSN (next) = prev;
1225
1226 /* See sched_analyze to see how these are handled. */
1227 if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG
1228 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END
1229 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
1230 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END)
1231 {
1232 /* Insert the note at the end of the notes list. */
1233 PREV_INSN (insn) = note_list;
1234 if (note_list)
1235 NEXT_INSN (note_list) = insn;
1236 note_list = insn;
1237 }
1238
1239 insn = next;
1240 }
1241 return insn;
1242 }
1243
1244 /* Delete line notes beginning with INSN. Record line-number notes so
1245 they can be reused. Returns the insn following the notes. */
1246
1247 static rtx
unlink_line_notes(insn,tail)1248 unlink_line_notes (insn, tail)
1249 rtx insn, tail;
1250 {
1251 rtx prev = PREV_INSN (insn);
1252
1253 while (insn != tail && GET_CODE (insn) == NOTE)
1254 {
1255 rtx next = NEXT_INSN (insn);
1256
1257 if (write_symbols != NO_DEBUG && NOTE_LINE_NUMBER (insn) > 0)
1258 {
1259 /* Delete the note from its current position. */
1260 if (prev)
1261 NEXT_INSN (prev) = next;
1262 if (next)
1263 PREV_INSN (next) = prev;
1264
1265 /* Record line-number notes so they can be reused. */
1266 LINE_NOTE (insn) = insn;
1267 }
1268 else
1269 prev = insn;
1270
1271 insn = next;
1272 }
1273 return insn;
1274 }
1275
1276 /* Return the head and tail pointers of BB. */
1277
1278 void
get_block_head_tail(b,headp,tailp)1279 get_block_head_tail (b, headp, tailp)
1280 int b;
1281 rtx *headp;
1282 rtx *tailp;
1283 {
1284 /* HEAD and TAIL delimit the basic block being scheduled. */
1285 rtx head = BLOCK_HEAD (b);
1286 rtx tail = BLOCK_END (b);
1287
1288 /* Don't include any notes or labels at the beginning of the
1289 basic block, or notes at the ends of basic blocks. */
1290 while (head != tail)
1291 {
1292 if (GET_CODE (head) == NOTE)
1293 head = NEXT_INSN (head);
1294 else if (GET_CODE (tail) == NOTE)
1295 tail = PREV_INSN (tail);
1296 else if (GET_CODE (head) == CODE_LABEL)
1297 head = NEXT_INSN (head);
1298 else
1299 break;
1300 }
1301
1302 *headp = head;
1303 *tailp = tail;
1304 }
1305
1306 /* Return nonzero if there are no real insns in the range [ HEAD, TAIL ]. */
1307
1308 int
no_real_insns_p(head,tail)1309 no_real_insns_p (head, tail)
1310 rtx head, tail;
1311 {
1312 while (head != NEXT_INSN (tail))
1313 {
1314 if (GET_CODE (head) != NOTE && GET_CODE (head) != CODE_LABEL)
1315 return 0;
1316 head = NEXT_INSN (head);
1317 }
1318 return 1;
1319 }
1320
1321 /* Delete line notes from one block. Save them so they can be later restored
1322 (in restore_line_notes). HEAD and TAIL are the boundaries of the
1323 block in which notes should be processed. */
1324
1325 void
rm_line_notes(head,tail)1326 rm_line_notes (head, tail)
1327 rtx head, tail;
1328 {
1329 rtx next_tail;
1330 rtx insn;
1331
1332 next_tail = NEXT_INSN (tail);
1333 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1334 {
1335 rtx prev;
1336
1337 /* Farm out notes, and maybe save them in NOTE_LIST.
1338 This is needed to keep the debugger from
1339 getting completely deranged. */
1340 if (GET_CODE (insn) == NOTE)
1341 {
1342 prev = insn;
1343 insn = unlink_line_notes (insn, next_tail);
1344
1345 if (prev == tail)
1346 abort ();
1347 if (prev == head)
1348 abort ();
1349 if (insn == next_tail)
1350 abort ();
1351 }
1352 }
1353 }
1354
1355 /* Save line number notes for each insn in block B. HEAD and TAIL are
1356 the boundaries of the block in which notes should be processed. */
1357
1358 void
save_line_notes(b,head,tail)1359 save_line_notes (b, head, tail)
1360 int b;
1361 rtx head, tail;
1362 {
1363 rtx next_tail;
1364
1365 /* We must use the true line number for the first insn in the block
1366 that was computed and saved at the start of this pass. We can't
1367 use the current line number, because scheduling of the previous
1368 block may have changed the current line number. */
1369
1370 rtx line = line_note_head[b];
1371 rtx insn;
1372
1373 next_tail = NEXT_INSN (tail);
1374
1375 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1376 if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1377 line = insn;
1378 else
1379 LINE_NOTE (insn) = line;
1380 }
1381
1382 /* After a block was scheduled, insert line notes into the insns list.
1383 HEAD and TAIL are the boundaries of the block in which notes should
1384 be processed. */
1385
1386 void
restore_line_notes(head,tail)1387 restore_line_notes (head, tail)
1388 rtx head, tail;
1389 {
1390 rtx line, note, prev, new;
1391 int added_notes = 0;
1392 rtx next_tail, insn;
1393
1394 head = head;
1395 next_tail = NEXT_INSN (tail);
1396
1397 /* Determine the current line-number. We want to know the current
1398 line number of the first insn of the block here, in case it is
1399 different from the true line number that was saved earlier. If
1400 different, then we need a line number note before the first insn
1401 of this block. If it happens to be the same, then we don't want to
1402 emit another line number note here. */
1403 for (line = head; line; line = PREV_INSN (line))
1404 if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
1405 break;
1406
1407 /* Walk the insns keeping track of the current line-number and inserting
1408 the line-number notes as needed. */
1409 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1410 if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1411 line = insn;
1412 /* This used to emit line number notes before every non-deleted note.
1413 However, this confuses a debugger, because line notes not separated
1414 by real instructions all end up at the same address. I can find no
1415 use for line number notes before other notes, so none are emitted. */
1416 else if (GET_CODE (insn) != NOTE
1417 && INSN_UID (insn) < old_max_uid
1418 && (note = LINE_NOTE (insn)) != 0
1419 && note != line
1420 && (line == 0
1421 || NOTE_LINE_NUMBER (note) != NOTE_LINE_NUMBER (line)
1422 || NOTE_SOURCE_FILE (note) != NOTE_SOURCE_FILE (line)))
1423 {
1424 line = note;
1425 prev = PREV_INSN (insn);
1426 if (LINE_NOTE (note))
1427 {
1428 /* Re-use the original line-number note. */
1429 LINE_NOTE (note) = 0;
1430 PREV_INSN (note) = prev;
1431 NEXT_INSN (prev) = note;
1432 PREV_INSN (insn) = note;
1433 NEXT_INSN (note) = insn;
1434 }
1435 else
1436 {
1437 added_notes++;
1438 new = emit_note_after (NOTE_LINE_NUMBER (note), prev);
1439 NOTE_SOURCE_FILE (new) = NOTE_SOURCE_FILE (note);
1440 RTX_INTEGRATED_P (new) = RTX_INTEGRATED_P (note);
1441 }
1442 }
1443 if (sched_verbose && added_notes)
1444 fprintf (sched_dump, ";; added %d line-number notes\n", added_notes);
1445 }
1446
1447 /* After scheduling the function, delete redundant line notes from the
1448 insns list. */
1449
1450 void
rm_redundant_line_notes()1451 rm_redundant_line_notes ()
1452 {
1453 rtx line = 0;
1454 rtx insn = get_insns ();
1455 int active_insn = 0;
1456 int notes = 0;
1457
1458 /* Walk the insns deleting redundant line-number notes. Many of these
1459 are already present. The remainder tend to occur at basic
1460 block boundaries. */
1461 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1462 if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1463 {
1464 /* If there are no active insns following, INSN is redundant. */
1465 if (active_insn == 0)
1466 {
1467 notes++;
1468 NOTE_SOURCE_FILE (insn) = 0;
1469 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
1470 }
1471 /* If the line number is unchanged, LINE is redundant. */
1472 else if (line
1473 && NOTE_LINE_NUMBER (line) == NOTE_LINE_NUMBER (insn)
1474 && NOTE_SOURCE_FILE (line) == NOTE_SOURCE_FILE (insn))
1475 {
1476 notes++;
1477 NOTE_SOURCE_FILE (line) = 0;
1478 NOTE_LINE_NUMBER (line) = NOTE_INSN_DELETED;
1479 line = insn;
1480 }
1481 else
1482 line = insn;
1483 active_insn = 0;
1484 }
1485 else if (!((GET_CODE (insn) == NOTE
1486 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
1487 || (GET_CODE (insn) == INSN
1488 && (GET_CODE (PATTERN (insn)) == USE
1489 || GET_CODE (PATTERN (insn)) == CLOBBER))))
1490 active_insn++;
1491
1492 if (sched_verbose && notes)
1493 fprintf (sched_dump, ";; deleted %d line-number notes\n", notes);
1494 }
1495
1496 /* Delete notes between HEAD and TAIL and put them in the chain
1497 of notes ended by NOTE_LIST. */
1498
1499 void
rm_other_notes(head,tail)1500 rm_other_notes (head, tail)
1501 rtx head;
1502 rtx tail;
1503 {
1504 rtx next_tail;
1505 rtx insn;
1506
1507 note_list = 0;
1508 if (head == tail && (! INSN_P (head)))
1509 return;
1510
1511 next_tail = NEXT_INSN (tail);
1512 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1513 {
1514 rtx prev;
1515
1516 /* Farm out notes, and maybe save them in NOTE_LIST.
1517 This is needed to keep the debugger from
1518 getting completely deranged. */
1519 if (GET_CODE (insn) == NOTE)
1520 {
1521 prev = insn;
1522
1523 insn = unlink_other_notes (insn, next_tail);
1524
1525 if (prev == tail)
1526 abort ();
1527 if (prev == head)
1528 abort ();
1529 if (insn == next_tail)
1530 abort ();
1531 }
1532 }
1533 }
1534
1535 /* Functions for computation of registers live/usage info. */
1536
1537 /* Calculate INSN_REG_WEIGHT for all insns of a block. */
1538
1539 static void
find_insn_reg_weight(b)1540 find_insn_reg_weight (b)
1541 int b;
1542 {
1543 rtx insn, next_tail, head, tail;
1544
1545 get_block_head_tail (b, &head, &tail);
1546 next_tail = NEXT_INSN (tail);
1547
1548 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
1549 {
1550 int reg_weight = 0;
1551 rtx x;
1552
1553 /* Handle register life information. */
1554 if (! INSN_P (insn))
1555 continue;
1556
1557 /* Increment weight for each register born here. */
1558 x = PATTERN (insn);
1559 if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
1560 && register_operand (SET_DEST (x), VOIDmode))
1561 reg_weight++;
1562 else if (GET_CODE (x) == PARALLEL)
1563 {
1564 int j;
1565 for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
1566 {
1567 x = XVECEXP (PATTERN (insn), 0, j);
1568 if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
1569 && register_operand (SET_DEST (x), VOIDmode))
1570 reg_weight++;
1571 }
1572 }
1573
1574 /* Decrement weight for each register that dies here. */
1575 for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
1576 {
1577 if (REG_NOTE_KIND (x) == REG_DEAD
1578 || REG_NOTE_KIND (x) == REG_UNUSED)
1579 reg_weight--;
1580 }
1581
1582 INSN_REG_WEIGHT (insn) = reg_weight;
1583 }
1584 }
1585
1586 /* Scheduling clock, modified in schedule_block() and queue_to_ready (). */
1587 static int clock_var;
1588
1589 /* Move insns that became ready to fire from queue to ready list. */
1590
1591 static void
queue_to_ready(ready)1592 queue_to_ready (ready)
1593 struct ready_list *ready;
1594 {
1595 rtx insn;
1596 rtx link;
1597
1598 q_ptr = NEXT_Q (q_ptr);
1599
1600 /* Add all pending insns that can be scheduled without stalls to the
1601 ready list. */
1602 for (link = insn_queue[q_ptr]; link; link = XEXP (link, 1))
1603 {
1604 insn = XEXP (link, 0);
1605 q_size -= 1;
1606
1607 if (sched_verbose >= 2)
1608 fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
1609 (*current_sched_info->print_insn) (insn, 0));
1610
1611 ready_add (ready, insn);
1612 if (sched_verbose >= 2)
1613 fprintf (sched_dump, "moving to ready without stalls\n");
1614 }
1615 insn_queue[q_ptr] = 0;
1616
1617 /* If there are no ready insns, stall until one is ready and add all
1618 of the pending insns at that point to the ready list. */
1619 if (ready->n_ready == 0)
1620 {
1621 int stalls;
1622
1623 for (stalls = 1; stalls <= MAX_INSN_QUEUE_INDEX; stalls++)
1624 {
1625 if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
1626 {
1627 for (; link; link = XEXP (link, 1))
1628 {
1629 insn = XEXP (link, 0);
1630 q_size -= 1;
1631
1632 if (sched_verbose >= 2)
1633 fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
1634 (*current_sched_info->print_insn) (insn, 0));
1635
1636 ready_add (ready, insn);
1637 if (sched_verbose >= 2)
1638 fprintf (sched_dump, "moving to ready with %d stalls\n", stalls);
1639 }
1640 insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
1641
1642 advance_one_cycle ();
1643
1644 break;
1645 }
1646
1647 advance_one_cycle ();
1648 }
1649
1650 if ((!targetm.sched.use_dfa_pipeline_interface
1651 || !(*targetm.sched.use_dfa_pipeline_interface) ())
1652 && sched_verbose && stalls)
1653 visualize_stall_cycles (stalls);
1654
1655 q_ptr = NEXT_Q_AFTER (q_ptr, stalls);
1656 clock_var += stalls;
1657 }
1658 }
1659
1660 /* Print the ready list for debugging purposes. Callable from debugger. */
1661
1662 static void
debug_ready_list(ready)1663 debug_ready_list (ready)
1664 struct ready_list *ready;
1665 {
1666 rtx *p;
1667 int i;
1668
1669 if (ready->n_ready == 0)
1670 {
1671 fprintf (sched_dump, "\n");
1672 return;
1673 }
1674
1675 p = ready_lastpos (ready);
1676 for (i = 0; i < ready->n_ready; i++)
1677 fprintf (sched_dump, " %s", (*current_sched_info->print_insn) (p[i], 0));
1678 fprintf (sched_dump, "\n");
1679 }
1680
1681 /* move_insn1: Remove INSN from insn chain, and link it after LAST insn. */
1682
1683 static rtx
move_insn1(insn,last)1684 move_insn1 (insn, last)
1685 rtx insn, last;
1686 {
1687 NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
1688 PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
1689
1690 NEXT_INSN (insn) = NEXT_INSN (last);
1691 PREV_INSN (NEXT_INSN (last)) = insn;
1692
1693 NEXT_INSN (last) = insn;
1694 PREV_INSN (insn) = last;
1695
1696 return insn;
1697 }
1698
1699 /* Search INSN for REG_SAVE_NOTE note pairs for
1700 NOTE_INSN_{LOOP,EHREGION}_{BEG,END}; and convert them back into
1701 NOTEs. The REG_SAVE_NOTE note following first one is contains the
1702 saved value for NOTE_BLOCK_NUMBER which is useful for
1703 NOTE_INSN_EH_REGION_{BEG,END} NOTEs. LAST is the last instruction
1704 output by the instruction scheduler. Return the new value of LAST. */
1705
1706 static rtx
reemit_notes(insn,last)1707 reemit_notes (insn, last)
1708 rtx insn;
1709 rtx last;
1710 {
1711 rtx note, retval;
1712
1713 retval = last;
1714 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1715 {
1716 if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
1717 {
1718 enum insn_note note_type = INTVAL (XEXP (note, 0));
1719
1720 last = emit_note_before (note_type, last);
1721 remove_note (insn, note);
1722 note = XEXP (note, 1);
1723 if (note_type == NOTE_INSN_EH_REGION_BEG
1724 || note_type == NOTE_INSN_EH_REGION_END)
1725 NOTE_EH_HANDLER (last) = INTVAL (XEXP (note, 0));
1726 remove_note (insn, note);
1727 }
1728 }
1729 return retval;
1730 }
1731
1732 /* Move INSN, and all insns which should be issued before it,
1733 due to SCHED_GROUP_P flag. Reemit notes if needed.
1734
1735 Return the last insn emitted by the scheduler, which is the
1736 return value from the first call to reemit_notes. */
1737
1738 static rtx
move_insn(insn,last)1739 move_insn (insn, last)
1740 rtx insn, last;
1741 {
1742 rtx retval = NULL;
1743
1744 /* If INSN has SCHED_GROUP_P set, then issue it and any other
1745 insns with SCHED_GROUP_P set first. */
1746 while (SCHED_GROUP_P (insn))
1747 {
1748 rtx prev = PREV_INSN (insn);
1749
1750 /* Move a SCHED_GROUP_P insn. */
1751 move_insn1 (insn, last);
1752 /* If this is the first call to reemit_notes, then record
1753 its return value. */
1754 if (retval == NULL_RTX)
1755 retval = reemit_notes (insn, insn);
1756 else
1757 reemit_notes (insn, insn);
1758 /* Consume SCHED_GROUP_P flag. */
1759 SCHED_GROUP_P (insn) = 0;
1760 insn = prev;
1761 }
1762
1763 /* Now move the first non SCHED_GROUP_P insn. */
1764 move_insn1 (insn, last);
1765
1766 /* If this is the first call to reemit_notes, then record
1767 its return value. */
1768 if (retval == NULL_RTX)
1769 retval = reemit_notes (insn, insn);
1770 else
1771 reemit_notes (insn, insn);
1772
1773 return retval;
1774 }
1775
1776 /* The following structure describe an entry of the stack of choices. */
1777 struct choice_entry
1778 {
1779 /* Ordinal number of the issued insn in the ready queue. */
1780 int index;
1781 /* The number of the rest insns whose issues we should try. */
1782 int rest;
1783 /* The number of issued essential insns. */
1784 int n;
1785 /* State after issuing the insn. */
1786 state_t state;
1787 };
1788
1789 /* The following array is used to implement a stack of choices used in
1790 function max_issue. */
1791 static struct choice_entry *choice_stack;
1792
1793 /* The following variable value is number of essential insns issued on
1794 the current cycle. An insn is essential one if it changes the
1795 processors state. */
1796 static int cycle_issued_insns;
1797
1798 /* The following variable value is maximal number of tries of issuing
1799 insns for the first cycle multipass insn scheduling. We define
1800 this value as constant*(DFA_LOOKAHEAD**ISSUE_RATE). We would not
1801 need this constraint if all real insns (with non-negative codes)
1802 had reservations because in this case the algorithm complexity is
1803 O(DFA_LOOKAHEAD**ISSUE_RATE). Unfortunately, the dfa descriptions
1804 might be incomplete and such insn might occur. For such
1805 descriptions, the complexity of algorithm (without the constraint)
1806 could achieve DFA_LOOKAHEAD ** N , where N is the queue length. */
1807 static int max_lookahead_tries;
1808
1809 /* The following value is value of hook
1810 `first_cycle_multipass_dfa_lookahead' at the last call of
1811 `max_issue'. */
1812 static int cached_first_cycle_multipass_dfa_lookahead = 0;
1813
1814 /* The following value is value of `issue_rate' at the last call of
1815 `sched_init'. */
1816 static int cached_issue_rate = 0;
1817
1818 /* The following function returns maximal (or close to maximal) number
1819 of insns which can be issued on the same cycle and one of which
1820 insns is insns with the best rank (the first insn in READY). To
1821 make this function tries different samples of ready insns. READY
1822 is current queue `ready'. Global array READY_TRY reflects what
1823 insns are already issued in this try. INDEX will contain index
1824 of the best insn in READY. The following function is used only for
1825 first cycle multipass scheduling. */
1826 static int
max_issue(ready,index)1827 max_issue (ready, index)
1828 struct ready_list *ready;
1829 int *index;
1830 {
1831 int n, i, all, n_ready, best, delay, tries_num;
1832 struct choice_entry *top;
1833 rtx insn;
1834
1835 best = 0;
1836 memcpy (choice_stack->state, curr_state, dfa_state_size);
1837 top = choice_stack;
1838 top->rest = cached_first_cycle_multipass_dfa_lookahead;
1839 top->n = 0;
1840 n_ready = ready->n_ready;
1841 for (all = i = 0; i < n_ready; i++)
1842 if (!ready_try [i])
1843 all++;
1844 i = 0;
1845 tries_num = 0;
1846 for (;;)
1847 {
1848 if (top->rest == 0 || i >= n_ready)
1849 {
1850 if (top == choice_stack)
1851 break;
1852 if (best < top - choice_stack && ready_try [0])
1853 {
1854 best = top - choice_stack;
1855 *index = choice_stack [1].index;
1856 if (top->n == issue_rate - cycle_issued_insns || best == all)
1857 break;
1858 }
1859 i = top->index;
1860 ready_try [i] = 0;
1861 top--;
1862 memcpy (curr_state, top->state, dfa_state_size);
1863 }
1864 else if (!ready_try [i])
1865 {
1866 tries_num++;
1867 if (tries_num > max_lookahead_tries)
1868 break;
1869 insn = ready_element (ready, i);
1870 delay = state_transition (curr_state, insn);
1871 if (delay < 0)
1872 {
1873 if (state_dead_lock_p (curr_state))
1874 top->rest = 0;
1875 else
1876 top->rest--;
1877 n = top->n;
1878 if (memcmp (top->state, curr_state, dfa_state_size) != 0)
1879 n++;
1880 top++;
1881 top->rest = cached_first_cycle_multipass_dfa_lookahead;
1882 top->index = i;
1883 top->n = n;
1884 memcpy (top->state, curr_state, dfa_state_size);
1885 ready_try [i] = 1;
1886 i = -1;
1887 }
1888 }
1889 i++;
1890 }
1891 while (top != choice_stack)
1892 {
1893 ready_try [top->index] = 0;
1894 top--;
1895 }
1896 memcpy (curr_state, choice_stack->state, dfa_state_size);
1897 return best;
1898 }
1899
1900 /* The following function chooses insn from READY and modifies
1901 *N_READY and READY. The following function is used only for first
1902 cycle multipass scheduling. */
1903
1904 static rtx
choose_ready(ready)1905 choose_ready (ready)
1906 struct ready_list *ready;
1907 {
1908 int lookahead = 0;
1909
1910 if (targetm.sched.first_cycle_multipass_dfa_lookahead)
1911 lookahead = (*targetm.sched.first_cycle_multipass_dfa_lookahead) ();
1912 if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)))
1913 return ready_remove_first (ready);
1914 else
1915 {
1916 /* Try to choose the better insn. */
1917 int index, i;
1918 rtx insn;
1919
1920 if (cached_first_cycle_multipass_dfa_lookahead != lookahead)
1921 {
1922 cached_first_cycle_multipass_dfa_lookahead = lookahead;
1923 max_lookahead_tries = 100;
1924 for (i = 0; i < issue_rate; i++)
1925 max_lookahead_tries *= lookahead;
1926 }
1927 insn = ready_element (ready, 0);
1928 if (INSN_CODE (insn) < 0)
1929 return ready_remove_first (ready);
1930 for (i = 1; i < ready->n_ready; i++)
1931 {
1932 insn = ready_element (ready, i);
1933 ready_try [i] = INSN_CODE (insn) < 0;
1934 }
1935 if (max_issue (ready, &index) == 0)
1936 return ready_remove_first (ready);
1937 else
1938 return ready_remove (ready, index);
1939 }
1940 }
1941
1942 /* Called from backends from targetm.sched.reorder to emit stuff into
1943 the instruction stream. */
1944
1945 rtx
sched_emit_insn(pat)1946 sched_emit_insn (pat)
1947 rtx pat;
1948 {
1949 rtx insn = emit_insn_after (pat, last_scheduled_insn);
1950 last_scheduled_insn = insn;
1951 return insn;
1952 }
1953
1954 /* Use forward list scheduling to rearrange insns of block B in region RGN,
1955 possibly bringing insns from subsequent blocks in the same region. */
1956
1957 void
schedule_block(b,rgn_n_insns)1958 schedule_block (b, rgn_n_insns)
1959 int b;
1960 int rgn_n_insns;
1961 {
1962 struct ready_list ready;
1963 int i;
1964 int first_cycle_insn_p;
1965 int can_issue_more;
1966 state_t temp_state = NULL; /* It is used for multipass scheduling. */
1967
1968 /* Head/tail info for this block. */
1969 rtx prev_head = current_sched_info->prev_head;
1970 rtx next_tail = current_sched_info->next_tail;
1971 rtx head = NEXT_INSN (prev_head);
1972 rtx tail = PREV_INSN (next_tail);
1973
1974 /* We used to have code to avoid getting parameters moved from hard
1975 argument registers into pseudos.
1976
1977 However, it was removed when it proved to be of marginal benefit
1978 and caused problems because schedule_block and compute_forward_dependences
1979 had different notions of what the "head" insn was. */
1980
1981 if (head == tail && (! INSN_P (head)))
1982 abort ();
1983
1984 /* Debug info. */
1985 if (sched_verbose)
1986 {
1987 fprintf (sched_dump, ";; ======================================================\n");
1988 fprintf (sched_dump,
1989 ";; -- basic block %d from %d to %d -- %s reload\n",
1990 b, INSN_UID (head), INSN_UID (tail),
1991 (reload_completed ? "after" : "before"));
1992 fprintf (sched_dump, ";; ======================================================\n");
1993 fprintf (sched_dump, "\n");
1994
1995 visualize_alloc ();
1996 init_block_visualization ();
1997 }
1998
1999 if (targetm.sched.use_dfa_pipeline_interface
2000 && (*targetm.sched.use_dfa_pipeline_interface) ())
2001 state_reset (curr_state);
2002 else
2003 clear_units ();
2004
2005 /* Allocate the ready list. */
2006 ready.veclen = rgn_n_insns + 1 + issue_rate;
2007 ready.first = ready.veclen - 1;
2008 ready.vec = (rtx *) xmalloc (ready.veclen * sizeof (rtx));
2009 ready.n_ready = 0;
2010
2011 if (targetm.sched.use_dfa_pipeline_interface
2012 && (*targetm.sched.use_dfa_pipeline_interface) ())
2013 {
2014 /* It is used for first cycle multipass scheduling. */
2015 temp_state = alloca (dfa_state_size);
2016 ready_try = (char *) xmalloc ((rgn_n_insns + 1) * sizeof (char));
2017 memset (ready_try, 0, (rgn_n_insns + 1) * sizeof (char));
2018 choice_stack
2019 = (struct choice_entry *) xmalloc ((rgn_n_insns + 1)
2020 * sizeof (struct choice_entry));
2021 for (i = 0; i <= rgn_n_insns; i++)
2022 choice_stack[i].state = (state_t) xmalloc (dfa_state_size);
2023 }
2024
2025 (*current_sched_info->init_ready_list) (&ready);
2026
2027 if (targetm.sched.md_init)
2028 (*targetm.sched.md_init) (sched_dump, sched_verbose, ready.veclen);
2029
2030 /* We start inserting insns after PREV_HEAD. */
2031 last_scheduled_insn = prev_head;
2032
2033 /* Initialize INSN_QUEUE. Q_SIZE is the total number of insns in the
2034 queue. */
2035 q_ptr = 0;
2036 q_size = 0;
2037
2038 if (!targetm.sched.use_dfa_pipeline_interface
2039 || !(*targetm.sched.use_dfa_pipeline_interface) ())
2040 max_insn_queue_index_macro_value = INSN_QUEUE_SIZE - 1;
2041 else
2042 max_insn_queue_index_macro_value = max_insn_queue_index;
2043
2044 insn_queue = (rtx *) alloca ((MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
2045 memset ((char *) insn_queue, 0, (MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
2046 last_clock_var = -1;
2047
2048 /* Start just before the beginning of time. */
2049 clock_var = -1;
2050
2051 /* Loop until all the insns in BB are scheduled. */
2052 while ((*current_sched_info->schedule_more_p) ())
2053 {
2054 clock_var++;
2055
2056 advance_one_cycle ();
2057
2058 /* Add to the ready list all pending insns that can be issued now.
2059 If there are no ready insns, increment clock until one
2060 is ready and add all pending insns at that point to the ready
2061 list. */
2062 queue_to_ready (&ready);
2063
2064 if (ready.n_ready == 0)
2065 abort ();
2066
2067 if (sched_verbose >= 2)
2068 {
2069 fprintf (sched_dump, ";;\t\tReady list after queue_to_ready: ");
2070 debug_ready_list (&ready);
2071 }
2072
2073 /* Sort the ready list based on priority. */
2074 ready_sort (&ready);
2075
2076 /* Allow the target to reorder the list, typically for
2077 better instruction bundling. */
2078 if (targetm.sched.reorder)
2079 can_issue_more =
2080 (*targetm.sched.reorder) (sched_dump, sched_verbose,
2081 ready_lastpos (&ready),
2082 &ready.n_ready, clock_var);
2083 else
2084 can_issue_more = issue_rate;
2085
2086 first_cycle_insn_p = 1;
2087 cycle_issued_insns = 0;
2088 for (;;)
2089 {
2090 rtx insn;
2091 int cost;
2092
2093 if (sched_verbose >= 2)
2094 {
2095 fprintf (sched_dump, ";;\tReady list (t =%3d): ",
2096 clock_var);
2097 debug_ready_list (&ready);
2098 }
2099
2100 if (!targetm.sched.use_dfa_pipeline_interface
2101 || !(*targetm.sched.use_dfa_pipeline_interface) ())
2102 {
2103 if (ready.n_ready == 0 || !can_issue_more
2104 || !(*current_sched_info->schedule_more_p) ())
2105 break;
2106 insn = choose_ready (&ready);
2107 cost = actual_hazard (insn_unit (insn), insn, clock_var, 0);
2108 }
2109 else
2110 {
2111 if (ready.n_ready == 0 || !can_issue_more
2112 || state_dead_lock_p (curr_state)
2113 || !(*current_sched_info->schedule_more_p) ())
2114 break;
2115
2116 /* Select and remove the insn from the ready list. */
2117 insn = choose_ready (&ready);
2118
2119 memcpy (temp_state, curr_state, dfa_state_size);
2120 if (recog_memoized (insn) < 0)
2121 {
2122 if (!first_cycle_insn_p
2123 && (GET_CODE (PATTERN (insn)) == ASM_INPUT
2124 || asm_noperands (PATTERN (insn)) >= 0))
2125 /* This is asm insn which is tryed to be issued on the
2126 cycle not first. Issue it on the next cycle. */
2127 cost = 1;
2128 else
2129 /* A USE insn, or something else we don't need to
2130 understand. We can't pass these directly to
2131 state_transition because it will trigger a
2132 fatal error for unrecognizable insns. */
2133 cost = 0;
2134 }
2135 else
2136 {
2137 cost = state_transition (temp_state, insn);
2138
2139 if (targetm.sched.first_cycle_multipass_dfa_lookahead
2140 && targetm.sched.dfa_bubble)
2141 {
2142 if (cost == 0)
2143 {
2144 int j;
2145 rtx bubble;
2146
2147 for (j = 0;
2148 (bubble = (*targetm.sched.dfa_bubble) (j))
2149 != NULL_RTX;
2150 j++)
2151 {
2152 memcpy (temp_state, curr_state, dfa_state_size);
2153
2154 if (state_transition (temp_state, bubble) < 0
2155 && state_transition (temp_state, insn) < 0)
2156 break;
2157 }
2158
2159 if (bubble != NULL_RTX)
2160 {
2161 if (insert_schedule_bubbles_p)
2162 {
2163 rtx copy;
2164
2165 copy = copy_rtx (PATTERN (bubble));
2166 emit_insn_after (copy, last_scheduled_insn);
2167 last_scheduled_insn
2168 = NEXT_INSN (last_scheduled_insn);
2169 INSN_CODE (last_scheduled_insn)
2170 = INSN_CODE (bubble);
2171
2172 /* Annotate the same for the first insns
2173 scheduling by using mode. */
2174 PUT_MODE (last_scheduled_insn,
2175 (clock_var > last_clock_var
2176 ? clock_var - last_clock_var
2177 : VOIDmode));
2178 last_clock_var = clock_var;
2179
2180 if (sched_verbose >= 2)
2181 {
2182 fprintf (sched_dump,
2183 ";;\t\t--> scheduling bubble insn <<<%d>>>:reservation ",
2184 INSN_UID (last_scheduled_insn));
2185
2186 if (recog_memoized (last_scheduled_insn)
2187 < 0)
2188 fprintf (sched_dump, "nothing");
2189 else
2190 print_reservation
2191 (sched_dump, last_scheduled_insn);
2192
2193 fprintf (sched_dump, "\n");
2194 }
2195 }
2196 cost = -1;
2197 }
2198 }
2199 }
2200
2201 if (cost < 0)
2202 cost = 0;
2203 else if (cost == 0)
2204 cost = 1;
2205 }
2206 }
2207
2208
2209 if (cost >= 1)
2210 {
2211 queue_insn (insn, cost);
2212 continue;
2213 }
2214
2215 if (! (*current_sched_info->can_schedule_ready_p) (insn))
2216 goto next;
2217
2218 last_scheduled_insn = move_insn (insn, last_scheduled_insn);
2219
2220 if (targetm.sched.use_dfa_pipeline_interface
2221 && (*targetm.sched.use_dfa_pipeline_interface) ())
2222 {
2223 if (memcmp (curr_state, temp_state, dfa_state_size) != 0)
2224 cycle_issued_insns++;
2225 memcpy (curr_state, temp_state, dfa_state_size);
2226 }
2227
2228 if (targetm.sched.variable_issue)
2229 can_issue_more =
2230 (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
2231 insn, can_issue_more);
2232 /* A naked CLOBBER or USE generates no instruction, so do
2233 not count them against the issue rate. */
2234 else if (GET_CODE (PATTERN (insn)) != USE
2235 && GET_CODE (PATTERN (insn)) != CLOBBER)
2236 can_issue_more--;
2237
2238 schedule_insn (insn, &ready, clock_var);
2239
2240 next:
2241 first_cycle_insn_p = 0;
2242
2243 if (targetm.sched.reorder2)
2244 {
2245 /* Sort the ready list based on priority. */
2246 if (ready.n_ready > 0)
2247 ready_sort (&ready);
2248 can_issue_more =
2249 (*targetm.sched.reorder2) (sched_dump,sched_verbose,
2250 ready.n_ready
2251 ? ready_lastpos (&ready) : NULL,
2252 &ready.n_ready, clock_var);
2253 }
2254 }
2255
2256 if ((!targetm.sched.use_dfa_pipeline_interface
2257 || !(*targetm.sched.use_dfa_pipeline_interface) ())
2258 && sched_verbose)
2259 /* Debug info. */
2260 visualize_scheduled_insns (clock_var);
2261 }
2262
2263 if (targetm.sched.md_finish)
2264 (*targetm.sched.md_finish) (sched_dump, sched_verbose);
2265
2266 /* Debug info. */
2267 if (sched_verbose)
2268 {
2269 fprintf (sched_dump, ";;\tReady list (final): ");
2270 debug_ready_list (&ready);
2271 if (!targetm.sched.use_dfa_pipeline_interface
2272 || !(*targetm.sched.use_dfa_pipeline_interface) ())
2273 print_block_visualization ("");
2274 }
2275
2276 /* Sanity check -- queue must be empty now. Meaningless if region has
2277 multiple bbs. */
2278 if (current_sched_info->queue_must_finish_empty && q_size != 0)
2279 abort ();
2280
2281 /* Update head/tail boundaries. */
2282 head = NEXT_INSN (prev_head);
2283 tail = last_scheduled_insn;
2284
2285 /* Restore-other-notes: NOTE_LIST is the end of a chain of notes
2286 previously found among the insns. Insert them at the beginning
2287 of the insns. */
2288 if (note_list != 0)
2289 {
2290 rtx note_head = note_list;
2291
2292 while (PREV_INSN (note_head))
2293 {
2294 note_head = PREV_INSN (note_head);
2295 }
2296
2297 PREV_INSN (note_head) = PREV_INSN (head);
2298 NEXT_INSN (PREV_INSN (head)) = note_head;
2299 PREV_INSN (head) = note_list;
2300 NEXT_INSN (note_list) = head;
2301 head = note_head;
2302 }
2303
2304 /* Debugging. */
2305 if (sched_verbose)
2306 {
2307 fprintf (sched_dump, ";; total time = %d\n;; new head = %d\n",
2308 clock_var, INSN_UID (head));
2309 fprintf (sched_dump, ";; new tail = %d\n\n",
2310 INSN_UID (tail));
2311 visualize_free ();
2312 }
2313
2314 current_sched_info->head = head;
2315 current_sched_info->tail = tail;
2316
2317 free (ready.vec);
2318
2319 if (targetm.sched.use_dfa_pipeline_interface
2320 && (*targetm.sched.use_dfa_pipeline_interface) ())
2321 {
2322 free (ready_try);
2323 for (i = 0; i <= rgn_n_insns; i++)
2324 free (choice_stack [i].state);
2325 free (choice_stack);
2326 }
2327 }
2328
2329 /* Set_priorities: compute priority of each insn in the block. */
2330
2331 int
set_priorities(head,tail)2332 set_priorities (head, tail)
2333 rtx head, tail;
2334 {
2335 rtx insn;
2336 int n_insn;
2337
2338 rtx prev_head;
2339
2340 prev_head = PREV_INSN (head);
2341
2342 if (head == tail && (! INSN_P (head)))
2343 return 0;
2344
2345 n_insn = 0;
2346 for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
2347 {
2348 if (GET_CODE (insn) == NOTE)
2349 continue;
2350
2351 if (!(SCHED_GROUP_P (insn)))
2352 n_insn++;
2353 (void) priority (insn);
2354 }
2355
2356 return n_insn;
2357 }
2358
2359 /* Initialize some global state for the scheduler. DUMP_FILE is to be used
2360 for debugging output. */
2361
2362 void
sched_init(dump_file)2363 sched_init (dump_file)
2364 FILE *dump_file;
2365 {
2366 int luid;
2367 basic_block b;
2368 rtx insn;
2369 int i;
2370
2371 /* Disable speculative loads in their presence if cc0 defined. */
2372 #ifdef HAVE_cc0
2373 flag_schedule_speculative_load = 0;
2374 #endif
2375
2376 /* Set dump and sched_verbose for the desired debugging output. If no
2377 dump-file was specified, but -fsched-verbose=N (any N), print to stderr.
2378 For -fsched-verbose=N, N>=10, print everything to stderr. */
2379 sched_verbose = sched_verbose_param;
2380 if (sched_verbose_param == 0 && dump_file)
2381 sched_verbose = 1;
2382 sched_dump = ((sched_verbose_param >= 10 || !dump_file)
2383 ? stderr : dump_file);
2384
2385 /* Initialize issue_rate. */
2386 if (targetm.sched.issue_rate)
2387 issue_rate = (*targetm.sched.issue_rate) ();
2388 else
2389 issue_rate = 1;
2390
2391 if (cached_issue_rate != issue_rate)
2392 {
2393 cached_issue_rate = issue_rate;
2394 /* To invalidate max_lookahead_tries: */
2395 cached_first_cycle_multipass_dfa_lookahead = 0;
2396 }
2397
2398 /* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
2399 pseudos which do not cross calls. */
2400 old_max_uid = get_max_uid () + 1;
2401
2402 h_i_d = (struct haifa_insn_data *) xcalloc (old_max_uid, sizeof (*h_i_d));
2403
2404 for (i = 0; i < old_max_uid; i++)
2405 h_i_d [i].cost = -1;
2406
2407 if (targetm.sched.use_dfa_pipeline_interface
2408 && (*targetm.sched.use_dfa_pipeline_interface) ())
2409 {
2410 if (targetm.sched.init_dfa_pre_cycle_insn)
2411 (*targetm.sched.init_dfa_pre_cycle_insn) ();
2412
2413 if (targetm.sched.init_dfa_post_cycle_insn)
2414 (*targetm.sched.init_dfa_post_cycle_insn) ();
2415
2416 if (targetm.sched.first_cycle_multipass_dfa_lookahead
2417 && targetm.sched.init_dfa_bubbles)
2418 (*targetm.sched.init_dfa_bubbles) ();
2419
2420 dfa_start ();
2421 dfa_state_size = state_size ();
2422 curr_state = xmalloc (dfa_state_size);
2423 }
2424
2425 h_i_d[0].luid = 0;
2426 luid = 1;
2427 FOR_EACH_BB (b)
2428 for (insn = b->head;; insn = NEXT_INSN (insn))
2429 {
2430 INSN_LUID (insn) = luid;
2431
2432 /* Increment the next luid, unless this is a note. We don't
2433 really need separate IDs for notes and we don't want to
2434 schedule differently depending on whether or not there are
2435 line-number notes, i.e., depending on whether or not we're
2436 generating debugging information. */
2437 if (GET_CODE (insn) != NOTE)
2438 ++luid;
2439
2440 if (insn == b->end)
2441 break;
2442 }
2443
2444 init_dependency_caches (luid);
2445
2446 init_alias_analysis ();
2447
2448 if (write_symbols != NO_DEBUG)
2449 {
2450 rtx line;
2451
2452 line_note_head = (rtx *) xcalloc (last_basic_block, sizeof (rtx));
2453
2454 /* Save-line-note-head:
2455 Determine the line-number at the start of each basic block.
2456 This must be computed and saved now, because after a basic block's
2457 predecessor has been scheduled, it is impossible to accurately
2458 determine the correct line number for the first insn of the block. */
2459
2460 FOR_EACH_BB (b)
2461 {
2462 for (line = b->head; line; line = PREV_INSN (line))
2463 if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
2464 {
2465 line_note_head[b->index] = line;
2466 break;
2467 }
2468 /* Do a forward search as well, since we won't get to see the first
2469 notes in a basic block. */
2470 for (line = b->head; line; line = NEXT_INSN (line))
2471 {
2472 if (INSN_P (line))
2473 break;
2474 if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
2475 line_note_head[b->index] = line;
2476 }
2477 }
2478 }
2479
2480 if ((!targetm.sched.use_dfa_pipeline_interface
2481 || !(*targetm.sched.use_dfa_pipeline_interface) ())
2482 && sched_verbose)
2483 /* Find units used in this function, for visualization. */
2484 init_target_units ();
2485
2486 /* ??? Add a NOTE after the last insn of the last basic block. It is not
2487 known why this is done. */
2488
2489 insn = EXIT_BLOCK_PTR->prev_bb->end;
2490 if (NEXT_INSN (insn) == 0
2491 || (GET_CODE (insn) != NOTE
2492 && GET_CODE (insn) != CODE_LABEL
2493 /* Don't emit a NOTE if it would end up before a BARRIER. */
2494 && GET_CODE (NEXT_INSN (insn)) != BARRIER))
2495 {
2496 emit_note_after (NOTE_INSN_DELETED, EXIT_BLOCK_PTR->prev_bb->end);
2497 /* Make insn to appear outside BB. */
2498 EXIT_BLOCK_PTR->prev_bb->end = PREV_INSN (EXIT_BLOCK_PTR->prev_bb->end);
2499 }
2500
2501 /* Compute INSN_REG_WEIGHT for all blocks. We must do this before
2502 removing death notes. */
2503 FOR_EACH_BB_REVERSE (b)
2504 find_insn_reg_weight (b->index);
2505 }
2506
2507 /* Free global data used during insn scheduling. */
2508
2509 void
sched_finish()2510 sched_finish ()
2511 {
2512 free (h_i_d);
2513
2514 if (targetm.sched.use_dfa_pipeline_interface
2515 && (*targetm.sched.use_dfa_pipeline_interface) ())
2516 {
2517 free (curr_state);
2518 dfa_finish ();
2519 }
2520 free_dependency_caches ();
2521 end_alias_analysis ();
2522 if (write_symbols != NO_DEBUG)
2523 free (line_note_head);
2524 }
2525 #endif /* INSN_SCHEDULING */
2526