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