Line data Source code
1 : /* Instruction scheduling pass.
2 : Copyright (C) 1992-2026 Free Software Foundation, Inc.
3 : Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
4 : and currently maintained by, Jim Wilson (wilson@cygnus.com)
5 :
6 : This file is part of GCC.
7 :
8 : GCC is free software; you can redistribute it and/or modify it under
9 : the terms of the GNU General Public License as published by the Free
10 : Software Foundation; either version 3, or (at your option) any later
11 : version.
12 :
13 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 : for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with GCC; see the file COPYING3. If not see
20 : <http://www.gnu.org/licenses/>. */
21 :
22 : /* Instruction scheduling pass. This file, along with sched-deps.cc,
23 : contains the generic parts. The actual entry point for
24 : the normal instruction scheduling pass is found in sched-rgn.cc.
25 :
26 : We compute insn priorities based on data dependencies. Flow
27 : analysis only creates a fraction of the data-dependencies we must
28 : observe: namely, only those dependencies which the combiner can be
29 : expected to use. For this pass, we must therefore create the
30 : remaining dependencies we need to observe: register dependencies,
31 : memory dependencies, dependencies to keep function calls in order,
32 : and the dependence between a conditional branch and the setting of
33 : condition codes are all dealt with here.
34 :
35 : The scheduler first traverses the data flow graph, starting with
36 : the last instruction, and proceeding to the first, assigning values
37 : to insn_priority as it goes. This sorts the instructions
38 : topologically by data dependence.
39 :
40 : Once priorities have been established, we order the insns using
41 : list scheduling. This works as follows: starting with a list of
42 : all the ready insns, and sorted according to priority number, we
43 : schedule the insn from the end of the list by placing its
44 : predecessors in the list according to their priority order. We
45 : consider this insn scheduled by setting the pointer to the "end" of
46 : the list to point to the previous insn. When an insn has no
47 : predecessors, we either queue it until sufficient time has elapsed
48 : or add it to the ready list. As the instructions are scheduled or
49 : when stalls are introduced, the queue advances and dumps insns into
50 : the ready list. When all insns down to the lowest priority have
51 : been scheduled, the critical path of the basic block has been made
52 : as short as possible. The remaining insns are then scheduled in
53 : remaining slots.
54 :
55 : The following list shows the order in which we want to break ties
56 : among insns in the ready list:
57 :
58 : 1. choose insn with the longest path to end of bb, ties
59 : broken by
60 : 2. choose insn with least contribution to register pressure,
61 : ties broken by
62 : 3. prefer in-block upon interblock motion, ties broken by
63 : 4. prefer useful upon speculative motion, ties broken by
64 : 5. choose insn with largest control flow probability, ties
65 : broken by
66 : 6. choose insn with the least dependences upon the previously
67 : scheduled insn, or finally
68 : 7 choose the insn which has the most insns dependent on it.
69 : 8. choose insn with lowest UID.
70 :
71 : Memory references complicate matters. Only if we can be certain
72 : that memory references are not part of the data dependency graph
73 : (via true, anti, or output dependence), can we move operations past
74 : memory references. To first approximation, reads can be done
75 : independently, while writes introduce dependencies. Better
76 : approximations will yield fewer dependencies.
77 :
78 : Before reload, an extended analysis of interblock data dependences
79 : is required for interblock scheduling. This is performed in
80 : compute_block_dependences ().
81 :
82 : Dependencies set up by memory references are treated in exactly the
83 : same way as other dependencies, by using insn backward dependences
84 : INSN_BACK_DEPS. INSN_BACK_DEPS are translated into forward dependences
85 : INSN_FORW_DEPS for the purpose of forward list scheduling.
86 :
87 : Having optimized the critical path, we may have also unduly
88 : extended the lifetimes of some registers. If an operation requires
89 : that constants be loaded into registers, it is certainly desirable
90 : to load those constants as early as necessary, but no earlier.
91 : I.e., it will not do to load up a bunch of registers at the
92 : beginning of a basic block only to use them at the end, if they
93 : could be loaded later, since this may result in excessive register
94 : utilization.
95 :
96 : Note that since branches are never in basic blocks, but only end
97 : basic blocks, this pass will not move branches. But that is ok,
98 : since we can use GNU's delayed branch scheduling pass to take care
99 : of this case.
100 :
101 : Also note that no further optimizations based on algebraic
102 : identities are performed, so this pass would be a good one to
103 : perform instruction splitting, such as breaking up a multiply
104 : instruction into shifts and adds where that is profitable.
105 :
106 : Given the memory aliasing analysis that this pass should perform,
107 : it should be possible to remove redundant stores to memory, and to
108 : load values from registers instead of hitting memory.
109 :
110 : Before reload, speculative insns are moved only if a 'proof' exists
111 : that no exception will be caused by this, and if no live registers
112 : exist that inhibit the motion (live registers constraints are not
113 : represented by data dependence edges).
114 :
115 : This pass must update information that subsequent passes expect to
116 : be correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
117 : reg_n_calls_crossed, and reg_live_length. Also, BB_HEAD, BB_END.
118 :
119 : The information in the line number notes is carefully retained by
120 : this pass. Notes that refer to the starting and ending of
121 : exception regions are also carefully retained by this pass. All
122 : other NOTE insns are grouped in their same relative order at the
123 : beginning of basic blocks and regions that have been scheduled. */
124 :
125 : #include "config.h"
126 : #include "system.h"
127 : #include "coretypes.h"
128 : #include "backend.h"
129 : #include "target.h"
130 : #include "rtl.h"
131 : #include "cfghooks.h"
132 : #include "df.h"
133 : #include "memmodel.h"
134 : #include "tm_p.h"
135 : #include "insn-config.h"
136 : #include "regs.h"
137 : #include "ira.h"
138 : #include "recog.h"
139 : #include "insn-attr.h"
140 : #include "cfgrtl.h"
141 : #include "cfgbuild.h"
142 : #include "sched-int.h"
143 : #include "common/common-target.h"
144 : #include "dbgcnt.h"
145 : #include "cfgloop.h"
146 : #include "dumpfile.h"
147 : #include "print-rtl.h"
148 : #include "function-abi.h"
149 :
150 : #ifdef INSN_SCHEDULING
151 :
152 : /* True if we do register pressure relief through live-range
153 : shrinkage. */
154 : static bool live_range_shrinkage_p;
155 :
156 : /* Switch on live range shrinkage. */
157 : void
158 35 : initialize_live_range_shrinkage (void)
159 : {
160 35 : live_range_shrinkage_p = true;
161 35 : }
162 :
163 : /* Switch off live range shrinkage. */
164 : void
165 35 : finish_live_range_shrinkage (void)
166 : {
167 35 : live_range_shrinkage_p = false;
168 35 : }
169 :
170 : /* issue_rate is the number of insns that can be scheduled in the same
171 : machine cycle. It can be defined in the config/mach/mach.h file,
172 : otherwise we set it to 1. */
173 :
174 : int issue_rate;
175 :
176 : /* This can be set to true by a backend if the scheduler should not
177 : enable a DCE pass. */
178 : bool sched_no_dce;
179 :
180 : /* The current initiation interval used when modulo scheduling. */
181 : static int modulo_ii;
182 :
183 : /* The maximum number of stages we are prepared to handle. */
184 : static int modulo_max_stages;
185 :
186 : /* The number of insns that exist in each iteration of the loop. We use this
187 : to detect when we've scheduled all insns from the first iteration. */
188 : static int modulo_n_insns;
189 :
190 : /* The current count of insns in the first iteration of the loop that have
191 : already been scheduled. */
192 : static int modulo_insns_scheduled;
193 :
194 : /* The maximum uid of insns from the first iteration of the loop. */
195 : static int modulo_iter0_max_uid;
196 :
197 : /* The number of times we should attempt to backtrack when modulo scheduling.
198 : Decreased each time we have to backtrack. */
199 : static int modulo_backtracks_left;
200 :
201 : /* The stage in which the last insn from the original loop was
202 : scheduled. */
203 : static int modulo_last_stage;
204 :
205 : /* sched-verbose controls the amount of debugging output the
206 : scheduler prints. It is controlled by -fsched-verbose=N:
207 : N=0: no debugging output.
208 : N=1: default value.
209 : N=2: bb's probabilities, detailed ready list info, unit/insn info.
210 : N=3: rtl at abort point, control-flow, regions info.
211 : N=5: dependences info. */
212 : int sched_verbose = 0;
213 :
214 : /* Debugging file. All printouts are sent to dump. */
215 : FILE *sched_dump = 0;
216 :
217 : /* This is a placeholder for the scheduler parameters common
218 : to all schedulers. */
219 : struct common_sched_info_def *common_sched_info;
220 :
221 : #define INSN_TICK(INSN) (HID (INSN)->tick)
222 : #define INSN_EXACT_TICK(INSN) (HID (INSN)->exact_tick)
223 : #define INSN_TICK_ESTIMATE(INSN) (HID (INSN)->tick_estimate)
224 : #define INTER_TICK(INSN) (HID (INSN)->inter_tick)
225 : #define FEEDS_BACKTRACK_INSN(INSN) (HID (INSN)->feeds_backtrack_insn)
226 : #define SHADOW_P(INSN) (HID (INSN)->shadow_p)
227 : #define MUST_RECOMPUTE_SPEC_P(INSN) (HID (INSN)->must_recompute_spec)
228 : /* Cached cost of the instruction. Use insn_sched_cost to get cost of the
229 : insn. -1 here means that the field is not initialized. */
230 : #define INSN_COST(INSN) (HID (INSN)->cost)
231 :
232 : /* If INSN_TICK of an instruction is equal to INVALID_TICK,
233 : then it should be recalculated from scratch. */
234 : #define INVALID_TICK (-(max_insn_queue_index + 1))
235 : /* The minimal value of the INSN_TICK of an instruction. */
236 : #define MIN_TICK (-max_insn_queue_index)
237 :
238 : /* Original order of insns in the ready list.
239 : Used to keep order of normal insns while separating DEBUG_INSNs. */
240 : #define INSN_RFS_DEBUG_ORIG_ORDER(INSN) (HID (INSN)->rfs_debug_orig_order)
241 :
242 : /* The deciding reason for INSN's place in the ready list. */
243 : #define INSN_LAST_RFS_WIN(INSN) (HID (INSN)->last_rfs_win)
244 :
245 : /* List of important notes we must keep around. This is a pointer to the
246 : last element in the list. */
247 : rtx_insn *note_list;
248 :
249 : static struct spec_info_def spec_info_var;
250 : /* Description of the speculative part of the scheduling.
251 : If NULL - no speculation. */
252 : spec_info_t spec_info = NULL;
253 :
254 : /* True, if recovery block was added during scheduling of current block.
255 : Used to determine, if we need to fix INSN_TICKs. */
256 : static bool haifa_recovery_bb_recently_added_p;
257 :
258 : /* True, if recovery block was added during this scheduling pass.
259 : Used to determine if we should have empty memory pools of dependencies
260 : after finishing current region. */
261 : bool haifa_recovery_bb_ever_added_p;
262 :
263 : /* Counters of different types of speculative instructions. */
264 : static int nr_begin_data, nr_be_in_data, nr_begin_control, nr_be_in_control;
265 :
266 : /* Array used in {unlink, restore}_bb_notes. */
267 : static rtx_insn **bb_header = 0;
268 :
269 : /* Basic block after which recovery blocks will be created. */
270 : static basic_block before_recovery;
271 :
272 : /* Basic block just before the EXIT_BLOCK and after recovery, if we have
273 : created it. */
274 : basic_block after_recovery;
275 :
276 : /* FALSE if we add bb to another region, so we don't need to initialize it. */
277 : bool adding_bb_to_current_region_p = true;
278 :
279 : /* Queues, etc. */
280 :
281 : /* An instruction is ready to be scheduled when all insns preceding it
282 : have already been scheduled. It is important to ensure that all
283 : insns which use its result will not be executed until its result
284 : has been computed. An insn is maintained in one of four structures:
285 :
286 : (P) the "Pending" set of insns which cannot be scheduled until
287 : their dependencies have been satisfied.
288 : (Q) the "Queued" set of insns that can be scheduled when sufficient
289 : time has passed.
290 : (R) the "Ready" list of unscheduled, uncommitted insns.
291 : (S) the "Scheduled" list of insns.
292 :
293 : Initially, all insns are either "Pending" or "Ready" depending on
294 : whether their dependencies are satisfied.
295 :
296 : Insns move from the "Ready" list to the "Scheduled" list as they
297 : are committed to the schedule. As this occurs, the insns in the
298 : "Pending" list have their dependencies satisfied and move to either
299 : the "Ready" list or the "Queued" set depending on whether
300 : sufficient time has passed to make them ready. As time passes,
301 : insns move from the "Queued" set to the "Ready" list.
302 :
303 : The "Pending" list (P) are the insns in the INSN_FORW_DEPS of the
304 : unscheduled insns, i.e., those that are ready, queued, and pending.
305 : The "Queued" set (Q) is implemented by the variable `insn_queue'.
306 : The "Ready" list (R) is implemented by the variables `ready' and
307 : `n_ready'.
308 : The "Scheduled" list (S) is the new insn chain built by this pass.
309 :
310 : The transition (R->S) is implemented in the scheduling loop in
311 : `schedule_block' when the best insn to schedule is chosen.
312 : The transitions (P->R and P->Q) are implemented in `schedule_insn' as
313 : insns move from the ready list to the scheduled list.
314 : The transition (Q->R) is implemented in 'queue_to_insn' as time
315 : passes or stalls are introduced. */
316 :
317 : /* Implement a circular buffer to delay instructions until sufficient
318 : time has passed. For the new pipeline description interface,
319 : MAX_INSN_QUEUE_INDEX is a power of two minus one which is not less
320 : than maximal time of instruction execution computed by genattr.cc on
321 : the base maximal time of functional unit reservations and getting a
322 : result. This is the longest time an insn may be queued. */
323 :
324 : static rtx_insn_list **insn_queue;
325 : static int q_ptr = 0;
326 : static int q_size = 0;
327 : #define NEXT_Q(X) (((X)+1) & max_insn_queue_index)
328 : #define NEXT_Q_AFTER(X, C) (((X)+C) & max_insn_queue_index)
329 :
330 : #define QUEUE_SCHEDULED (-3)
331 : #define QUEUE_NOWHERE (-2)
332 : #define QUEUE_READY (-1)
333 : /* QUEUE_SCHEDULED - INSN is scheduled.
334 : QUEUE_NOWHERE - INSN isn't scheduled yet and is neither in
335 : queue or ready list.
336 : QUEUE_READY - INSN is in ready list.
337 : N >= 0 - INSN queued for X [where NEXT_Q_AFTER (q_ptr, X) == N] cycles. */
338 :
339 : #define QUEUE_INDEX(INSN) (HID (INSN)->queue_index)
340 :
341 : /* The following variable value refers for all current and future
342 : reservations of the processor units. */
343 : state_t curr_state;
344 :
345 : /* The following variable value is size of memory representing all
346 : current and future reservations of the processor units. */
347 : size_t dfa_state_size;
348 :
349 : /* The following array is used to find the best insn from ready when
350 : the automaton pipeline interface is used. */
351 : signed char *ready_try = NULL;
352 :
353 : /* The ready list. */
354 : struct ready_list ready = {NULL, 0, 0, 0, 0};
355 :
356 : /* The pointer to the ready list (to be removed). */
357 : static struct ready_list *readyp = &ready;
358 :
359 : /* Scheduling clock. */
360 : static int clock_var;
361 :
362 : /* Clock at which the previous instruction was issued. */
363 : static int last_clock_var;
364 :
365 : /* Set to true if, when queuing a shadow insn, we discover that it would be
366 : scheduled too late. */
367 : static bool must_backtrack;
368 :
369 : /* The following variable value is number of essential insns issued on
370 : the current cycle. An insn is essential one if it changes the
371 : processors state. */
372 : int cycle_issued_insns;
373 :
374 : /* This records the actual schedule. It is built up during the main phase
375 : of schedule_block, and afterwards used to reorder the insns in the RTL. */
376 : static vec<rtx_insn *> scheduled_insns;
377 :
378 : static int may_trap_exp (const_rtx, int);
379 :
380 : /* Nonzero iff the address is comprised from at most 1 register. */
381 : #define CONST_BASED_ADDRESS_P(x) \
382 : (REG_P (x) \
383 : || ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS \
384 : || (GET_CODE (x) == LO_SUM)) \
385 : && (CONSTANT_P (XEXP (x, 0)) \
386 : || CONSTANT_P (XEXP (x, 1)))))
387 :
388 : /* Returns a class that insn with GET_DEST(insn)=x may belong to,
389 : as found by analyzing insn's expression. */
390 :
391 :
392 : static int haifa_luid_for_non_insn (rtx x);
393 :
394 : /* Haifa version of sched_info hooks common to all headers. */
395 : const struct common_sched_info_def haifa_common_sched_info =
396 : {
397 : NULL, /* fix_recovery_cfg */
398 : NULL, /* add_block */
399 : NULL, /* estimate_number_of_insns */
400 : haifa_luid_for_non_insn, /* luid_for_non_insn */
401 : SCHED_PASS_UNKNOWN /* sched_pass_id */
402 : };
403 :
404 : /* Mapping from instruction UID to its Logical UID. */
405 : vec<int> sched_luids;
406 :
407 : /* Next LUID to assign to an instruction. */
408 : int sched_max_luid = 1;
409 :
410 : /* Haifa Instruction Data. */
411 : vec<haifa_insn_data_def> h_i_d;
412 :
413 : void (* sched_init_only_bb) (basic_block, basic_block);
414 :
415 : /* Split block function. Different schedulers might use different functions
416 : to handle their internal data consistent. */
417 : basic_block (* sched_split_block) (basic_block, rtx);
418 :
419 : /* Create empty basic block after the specified block. */
420 : basic_block (* sched_create_empty_bb) (basic_block);
421 :
422 : /* Return the number of cycles until INSN is expected to be ready.
423 : Return zero if it already is. */
424 : static int
425 27322 : insn_delay (rtx_insn *insn)
426 : {
427 27322 : return MAX (INSN_TICK (insn) - clock_var, 0);
428 : }
429 :
430 : static int
431 28052 : may_trap_exp (const_rtx x, int is_store)
432 : {
433 28052 : enum rtx_code code;
434 :
435 28052 : if (x == 0)
436 : return TRAP_FREE;
437 28052 : code = GET_CODE (x);
438 28052 : if (is_store)
439 : {
440 5744 : if (code == MEM && may_trap_p (x))
441 : return TRAP_RISKY;
442 : else
443 5492 : return TRAP_FREE;
444 : }
445 22308 : if (code == MEM)
446 : {
447 : /* The insn uses memory: a volatile load. */
448 1662 : if (MEM_VOLATILE_P (x))
449 : return IRISKY;
450 : /* An exception-free load. */
451 1640 : if (!may_trap_p (x))
452 : return IFREE;
453 : /* A load with 1 base register, to be further checked. */
454 402 : if (CONST_BASED_ADDRESS_P (XEXP (x, 0)))
455 : return PFREE_CANDIDATE;
456 : /* No info on the load, to be further checked. */
457 26 : return PRISKY_CANDIDATE;
458 : }
459 : else
460 : {
461 20646 : const char *fmt;
462 20646 : int i, insn_class = TRAP_FREE;
463 :
464 : /* Neither store nor load, check if it may cause a trap. */
465 20646 : if (may_trap_p (x))
466 : return TRAP_RISKY;
467 : /* Recursive step: walk the insn... */
468 20048 : fmt = GET_RTX_FORMAT (code);
469 45802 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
470 : {
471 25758 : if (fmt[i] == 'e')
472 : {
473 12374 : int tmp_class = may_trap_exp (XEXP (x, i), is_store);
474 12374 : insn_class = WORST_CLASS (insn_class, tmp_class);
475 : }
476 13384 : else if (fmt[i] == 'E')
477 : {
478 : int j;
479 308 : for (j = 0; j < XVECLEN (x, i); j++)
480 : {
481 266 : int tmp_class = may_trap_exp (XVECEXP (x, i, j), is_store);
482 266 : insn_class = WORST_CLASS (insn_class, tmp_class);
483 266 : if (insn_class == TRAP_RISKY || insn_class == IRISKY)
484 : break;
485 : }
486 : }
487 25758 : if (insn_class == TRAP_RISKY || insn_class == IRISKY)
488 : break;
489 : }
490 20048 : return insn_class;
491 : }
492 : }
493 :
494 : /* Classifies rtx X of an insn for the purpose of verifying that X can be
495 : executed speculatively (and consequently the insn can be moved
496 : speculatively), by examining X, returning:
497 : TRAP_RISKY: store, or risky non-load insn (e.g. division by variable).
498 : TRAP_FREE: non-load insn.
499 : IFREE: load from a globally safe location.
500 : IRISKY: volatile load.
501 : PFREE_CANDIDATE, PRISKY_CANDIDATE: load that need to be checked for
502 : being either PFREE or PRISKY. */
503 :
504 : static int
505 6874 : haifa_classify_rtx (const_rtx x)
506 : {
507 6874 : int tmp_class = TRAP_FREE;
508 6874 : int insn_class = TRAP_FREE;
509 6874 : enum rtx_code code;
510 :
511 6874 : if (GET_CODE (x) == PARALLEL)
512 : {
513 800 : int i, len = XVECLEN (x, 0);
514 :
515 2176 : for (i = len - 1; i >= 0; i--)
516 : {
517 1547 : tmp_class = haifa_classify_rtx (XVECEXP (x, 0, i));
518 1547 : insn_class = WORST_CLASS (insn_class, tmp_class);
519 1547 : if (insn_class == TRAP_RISKY || insn_class == IRISKY)
520 : break;
521 : }
522 : }
523 : else
524 : {
525 6074 : code = GET_CODE (x);
526 6074 : switch (code)
527 : {
528 752 : case CLOBBER:
529 : /* Test if it is a 'store'. */
530 752 : tmp_class = may_trap_exp (XEXP (x, 0), 1);
531 752 : break;
532 4992 : case SET:
533 : /* Test if it is a store. */
534 4992 : tmp_class = may_trap_exp (SET_DEST (x), 1);
535 4992 : if (tmp_class == TRAP_RISKY)
536 : break;
537 : /* Test if it is a load. */
538 4834 : tmp_class =
539 4834 : WORST_CLASS (tmp_class,
540 : may_trap_exp (SET_SRC (x), 0));
541 : break;
542 0 : case COND_EXEC:
543 0 : tmp_class = haifa_classify_rtx (COND_EXEC_CODE (x));
544 0 : if (tmp_class == TRAP_RISKY)
545 : break;
546 0 : tmp_class = WORST_CLASS (tmp_class,
547 : may_trap_exp (COND_EXEC_TEST (x), 0));
548 : break;
549 : case TRAP_IF:
550 169 : tmp_class = TRAP_RISKY;
551 : break;
552 158 : default:;
553 : }
554 : insn_class = tmp_class;
555 : }
556 :
557 6874 : return insn_class;
558 : }
559 :
560 : int
561 5327 : haifa_classify_insn (const_rtx insn)
562 : {
563 5327 : return haifa_classify_rtx (PATTERN (insn));
564 : }
565 :
566 : /* After the scheduler initialization function has been called, this function
567 : can be called to enable modulo scheduling. II is the initiation interval
568 : we should use, it affects the delays for delay_pairs that were recorded as
569 : separated by a given number of stages.
570 :
571 : MAX_STAGES provides us with a limit
572 : after which we give up scheduling; the caller must have unrolled at least
573 : as many copies of the loop body and recorded delay_pairs for them.
574 :
575 : INSNS is the number of real (non-debug) insns in one iteration of
576 : the loop. MAX_UID can be used to test whether an insn belongs to
577 : the first iteration of the loop; all of them have a uid lower than
578 : MAX_UID. */
579 : void
580 0 : set_modulo_params (int ii, int max_stages, int insns, int max_uid)
581 : {
582 0 : modulo_ii = ii;
583 0 : modulo_max_stages = max_stages;
584 0 : modulo_n_insns = insns;
585 0 : modulo_iter0_max_uid = max_uid;
586 0 : modulo_backtracks_left = param_max_modulo_backtrack_attempts;
587 0 : }
588 :
589 : /* A structure to record a pair of insns where the first one is a real
590 : insn that has delay slots, and the second is its delayed shadow.
591 : I1 is scheduled normally and will emit an assembly instruction,
592 : while I2 describes the side effect that takes place at the
593 : transition between cycles CYCLES and (CYCLES + 1) after I1. */
594 : struct delay_pair
595 : {
596 : struct delay_pair *next_same_i1;
597 : rtx_insn *i1, *i2;
598 : int cycles;
599 : /* When doing modulo scheduling, we a delay_pair can also be used to
600 : show that I1 and I2 are the same insn in a different stage. If that
601 : is the case, STAGES will be nonzero. */
602 : int stages;
603 : };
604 :
605 : /* Helpers for delay hashing. */
606 :
607 : struct delay_i1_hasher : nofree_ptr_hash <delay_pair>
608 : {
609 : typedef void *compare_type;
610 : static inline hashval_t hash (const delay_pair *);
611 : static inline bool equal (const delay_pair *, const void *);
612 : };
613 :
614 : /* Returns a hash value for X, based on hashing just I1. */
615 :
616 : inline hashval_t
617 0 : delay_i1_hasher::hash (const delay_pair *x)
618 : {
619 0 : return htab_hash_pointer (x->i1);
620 : }
621 :
622 : /* Return true if I1 of pair X is the same as that of pair Y. */
623 :
624 : inline bool
625 0 : delay_i1_hasher::equal (const delay_pair *x, const void *y)
626 : {
627 0 : return x->i1 == y;
628 : }
629 :
630 : struct delay_i2_hasher : free_ptr_hash <delay_pair>
631 : {
632 : typedef void *compare_type;
633 : static inline hashval_t hash (const delay_pair *);
634 : static inline bool equal (const delay_pair *, const void *);
635 : };
636 :
637 : /* Returns a hash value for X, based on hashing just I2. */
638 :
639 : inline hashval_t
640 0 : delay_i2_hasher::hash (const delay_pair *x)
641 : {
642 0 : return htab_hash_pointer (x->i2);
643 : }
644 :
645 : /* Return true if I2 of pair X is the same as that of pair Y. */
646 :
647 : inline bool
648 0 : delay_i2_hasher::equal (const delay_pair *x, const void *y)
649 : {
650 0 : return x->i2 == y;
651 : }
652 :
653 : /* Two hash tables to record delay_pairs, one indexed by I1 and the other
654 : indexed by I2. */
655 : static hash_table<delay_i1_hasher> *delay_htab;
656 : static hash_table<delay_i2_hasher> *delay_htab_i2;
657 :
658 : /* Called through htab_traverse. Walk the hashtable using I2 as
659 : index, and delete all elements involving an UID higher than
660 : that pointed to by *DATA. */
661 : int
662 0 : haifa_htab_i2_traverse (delay_pair **slot, int *data)
663 : {
664 0 : int maxuid = *data;
665 0 : struct delay_pair *p = *slot;
666 0 : if (INSN_UID (p->i2) >= maxuid || INSN_UID (p->i1) >= maxuid)
667 : {
668 0 : delay_htab_i2->clear_slot (slot);
669 : }
670 0 : return 1;
671 : }
672 :
673 : /* Called through htab_traverse. Walk the hashtable using I2 as
674 : index, and delete all elements involving an UID higher than
675 : that pointed to by *DATA. */
676 : int
677 0 : haifa_htab_i1_traverse (delay_pair **pslot, int *data)
678 : {
679 0 : int maxuid = *data;
680 0 : struct delay_pair *p, *first, **pprev;
681 :
682 0 : if (INSN_UID ((*pslot)->i1) >= maxuid)
683 : {
684 0 : delay_htab->clear_slot (pslot);
685 0 : return 1;
686 : }
687 : pprev = &first;
688 0 : for (p = *pslot; p; p = p->next_same_i1)
689 : {
690 0 : if (INSN_UID (p->i2) < maxuid)
691 : {
692 0 : *pprev = p;
693 0 : pprev = &p->next_same_i1;
694 : }
695 : }
696 0 : *pprev = NULL;
697 0 : if (first == NULL)
698 0 : delay_htab->clear_slot (pslot);
699 : else
700 0 : *pslot = first;
701 : return 1;
702 : }
703 :
704 : /* Discard all delay pairs which involve an insn with an UID higher
705 : than MAX_UID. */
706 : void
707 0 : discard_delay_pairs_above (int max_uid)
708 : {
709 0 : delay_htab->traverse <int *, haifa_htab_i1_traverse> (&max_uid);
710 0 : delay_htab_i2->traverse <int *, haifa_htab_i2_traverse> (&max_uid);
711 0 : }
712 :
713 : /* This function can be called by a port just before it starts the final
714 : scheduling pass. It records the fact that an instruction with delay
715 : slots has been split into two insns, I1 and I2. The first one will be
716 : scheduled normally and initiates the operation. The second one is a
717 : shadow which must follow a specific number of cycles after I1; its only
718 : purpose is to show the side effect that occurs at that cycle in the RTL.
719 : If a JUMP_INSN or a CALL_INSN has been split, I1 should be a normal INSN,
720 : while I2 retains the original insn type.
721 :
722 : There are two ways in which the number of cycles can be specified,
723 : involving the CYCLES and STAGES arguments to this function. If STAGES
724 : is zero, we just use the value of CYCLES. Otherwise, STAGES is a factor
725 : which is multiplied by MODULO_II to give the number of cycles. This is
726 : only useful if the caller also calls set_modulo_params to enable modulo
727 : scheduling. */
728 :
729 : void
730 0 : record_delay_slot_pair (rtx_insn *i1, rtx_insn *i2, int cycles, int stages)
731 : {
732 0 : struct delay_pair *p = XNEW (struct delay_pair);
733 0 : struct delay_pair **slot;
734 :
735 0 : p->i1 = i1;
736 0 : p->i2 = i2;
737 0 : p->cycles = cycles;
738 0 : p->stages = stages;
739 :
740 0 : if (!delay_htab)
741 : {
742 0 : delay_htab = new hash_table<delay_i1_hasher> (10);
743 0 : delay_htab_i2 = new hash_table<delay_i2_hasher> (10);
744 : }
745 0 : slot = delay_htab->find_slot_with_hash (i1, htab_hash_pointer (i1), INSERT);
746 0 : p->next_same_i1 = *slot;
747 0 : *slot = p;
748 0 : slot = delay_htab_i2->find_slot (p, INSERT);
749 0 : *slot = p;
750 0 : }
751 :
752 : /* Examine the delay pair hashtable to see if INSN is a shadow for another,
753 : and return the other insn if so. Return NULL otherwise. */
754 : rtx_insn *
755 0 : real_insn_for_shadow (rtx_insn *insn)
756 : {
757 0 : struct delay_pair *pair;
758 :
759 0 : if (!delay_htab)
760 : return NULL;
761 :
762 0 : pair = delay_htab_i2->find_with_hash (insn, htab_hash_pointer (insn));
763 0 : if (!pair || pair->stages > 0)
764 : return NULL;
765 0 : return pair->i1;
766 : }
767 :
768 : /* For a pair P of insns, return the fixed distance in cycles from the first
769 : insn after which the second must be scheduled. */
770 : static int
771 0 : pair_delay (struct delay_pair *p)
772 : {
773 0 : if (p->stages == 0)
774 0 : return p->cycles;
775 : else
776 0 : return p->stages * modulo_ii;
777 : }
778 :
779 : /* Given an insn INSN, add a dependence on its delayed shadow if it
780 : has one. Also try to find situations where shadows depend on each other
781 : and add dependencies to the real insns to limit the amount of backtracking
782 : needed. */
783 : void
784 1532 : add_delay_dependencies (rtx_insn *insn)
785 : {
786 1532 : struct delay_pair *pair;
787 1532 : sd_iterator_def sd_it;
788 1532 : dep_t dep;
789 :
790 1532 : if (!delay_htab)
791 1532 : return;
792 :
793 0 : pair = delay_htab_i2->find_with_hash (insn, htab_hash_pointer (insn));
794 0 : if (!pair)
795 : return;
796 0 : add_dependence (insn, pair->i1, REG_DEP_ANTI);
797 0 : if (pair->stages)
798 : return;
799 :
800 0 : FOR_EACH_DEP (pair->i2, SD_LIST_BACK, sd_it, dep)
801 : {
802 0 : rtx_insn *pro = DEP_PRO (dep);
803 0 : struct delay_pair *other_pair
804 0 : = delay_htab_i2->find_with_hash (pro, htab_hash_pointer (pro));
805 0 : if (!other_pair || other_pair->stages)
806 0 : continue;
807 0 : if (pair_delay (other_pair) >= pair_delay (pair))
808 : {
809 0 : if (sched_verbose >= 4)
810 : {
811 0 : fprintf (sched_dump, ";;\tadding dependence %d <- %d\n",
812 0 : INSN_UID (other_pair->i1),
813 0 : INSN_UID (pair->i1));
814 0 : fprintf (sched_dump, ";;\tpair1 %d <- %d, cost %d\n",
815 0 : INSN_UID (pair->i1),
816 0 : INSN_UID (pair->i2),
817 : pair_delay (pair));
818 0 : fprintf (sched_dump, ";;\tpair2 %d <- %d, cost %d\n",
819 0 : INSN_UID (other_pair->i1),
820 0 : INSN_UID (other_pair->i2),
821 : pair_delay (other_pair));
822 : }
823 0 : add_dependence (pair->i1, other_pair->i1, REG_DEP_ANTI);
824 : }
825 : }
826 : }
827 :
828 : /* Forward declarations. */
829 :
830 : static int priority (rtx_insn *, bool force_recompute = false);
831 : static int autopref_rank_for_schedule (const rtx_insn *, const rtx_insn *);
832 : static int rank_for_schedule (const void *, const void *);
833 : static void swap_sort (rtx_insn **, int);
834 : static void queue_insn (rtx_insn *, int, const char *);
835 : static int schedule_insn (rtx_insn *);
836 : static void adjust_priority (rtx_insn *);
837 : static void advance_one_cycle (void);
838 : static void extend_h_i_d (void);
839 :
840 :
841 : /* Notes handling mechanism:
842 : =========================
843 : Generally, NOTES are saved before scheduling and restored after scheduling.
844 : The scheduler distinguishes between two types of notes:
845 :
846 : (1) LOOP_BEGIN, LOOP_END, SETJMP, EHREGION_BEG, EHREGION_END notes:
847 : Before scheduling a region, a pointer to the note is added to the insn
848 : that follows or precedes it. (This happens as part of the data dependence
849 : computation). After scheduling an insn, the pointer contained in it is
850 : used for regenerating the corresponding note (in reemit_notes).
851 :
852 : (2) All other notes (e.g. INSN_DELETED): Before scheduling a block,
853 : these notes are put in a list (in rm_other_notes() and
854 : unlink_other_notes ()). After scheduling the block, these notes are
855 : inserted at the beginning of the block (in schedule_block()). */
856 :
857 : static void ready_add (struct ready_list *, rtx_insn *, bool);
858 : static rtx_insn *ready_remove_first (struct ready_list *);
859 : static rtx_insn *ready_remove_first_dispatch (struct ready_list *ready);
860 :
861 : static void queue_to_ready (struct ready_list *);
862 : static int early_queue_to_ready (state_t, struct ready_list *);
863 :
864 : /* The following functions are used to implement multi-pass scheduling
865 : on the first cycle. */
866 : static rtx_insn *ready_remove (struct ready_list *, int);
867 : static void ready_remove_insn (rtx_insn *);
868 :
869 : static void fix_inter_tick (rtx_insn *, rtx_insn *);
870 : static int fix_tick_ready (rtx_insn *);
871 : static void change_queue_index (rtx_insn *, int);
872 :
873 : /* The following functions are used to implement scheduling of data/control
874 : speculative instructions. */
875 :
876 : static void extend_h_i_d (void);
877 : static void init_h_i_d (rtx_insn *);
878 : static int haifa_speculate_insn (rtx_insn *, ds_t, rtx *);
879 : static void generate_recovery_code (rtx_insn *);
880 : static void process_insn_forw_deps_be_in_spec (rtx_insn *, rtx_insn *, ds_t);
881 : static void begin_speculative_block (rtx_insn *);
882 : static void add_to_speculative_block (rtx_insn *);
883 : static void init_before_recovery (basic_block *);
884 : static void create_check_block_twin (rtx_insn *, bool);
885 : static void fix_recovery_deps (basic_block);
886 : static bool haifa_change_pattern (rtx_insn *, rtx);
887 : static void dump_new_block_header (int, basic_block, rtx_insn *, rtx_insn *);
888 : static void restore_bb_notes (basic_block);
889 : static void fix_jump_move (rtx_insn *);
890 : static void move_block_after_check (rtx_insn *);
891 : static void move_succs (vec<edge, va_gc> **, basic_block);
892 : static void sched_remove_insn (rtx_insn *);
893 : static void clear_priorities (rtx_insn *, rtx_vec_t *);
894 : static void calc_priorities (const rtx_vec_t &);
895 : static void add_jump_dependencies (rtx_insn *, rtx_insn *);
896 :
897 : #endif /* INSN_SCHEDULING */
898 :
899 : /* Point to state used for the current scheduling pass. */
900 : struct haifa_sched_info *current_sched_info;
901 :
902 : #ifndef INSN_SCHEDULING
903 : void
904 : schedule_insns (void)
905 : {
906 : }
907 : #else
908 :
909 : /* Do register pressure sensitive insn scheduling if the flag is set
910 : up. */
911 : enum sched_pressure_algorithm sched_pressure;
912 :
913 : /* Map regno -> its pressure class. The map defined only when
914 : SCHED_PRESSURE != SCHED_PRESSURE_NONE. */
915 : enum reg_class *sched_regno_pressure_class;
916 :
917 : /* The current register pressure. Only elements corresponding pressure
918 : classes are defined. */
919 : static int curr_reg_pressure[N_REG_CLASSES];
920 :
921 : /* Saved value of the previous array. */
922 : static int saved_reg_pressure[N_REG_CLASSES];
923 :
924 : /* Register living at given scheduling point. */
925 : static bitmap curr_reg_live;
926 :
927 : /* Saved value of the previous array. */
928 : static bitmap saved_reg_live;
929 :
930 : /* Registers mentioned in the current region. */
931 : static bitmap region_ref_regs;
932 :
933 : /* Temporary bitmap used for SCHED_PRESSURE_MODEL. */
934 : static bitmap tmp_bitmap;
935 :
936 : /* Effective number of available registers of a given class (see comment
937 : in sched_pressure_start_bb). */
938 : static int sched_class_regs_num[N_REG_CLASSES];
939 : /* The number of registers that the function would need to save before it
940 : uses them, and the number of fixed_regs. Helpers for calculating of
941 : sched_class_regs_num. */
942 : static int call_saved_regs_num[N_REG_CLASSES];
943 : static int fixed_regs_num[N_REG_CLASSES];
944 :
945 : /* Initiate register pressure relative info for scheduling the current
946 : region. Currently it is only clearing register mentioned in the
947 : current region. */
948 : void
949 415 : sched_init_region_reg_pressure_info (void)
950 : {
951 415 : bitmap_clear (region_ref_regs);
952 415 : }
953 :
954 : /* PRESSURE[CL] describes the pressure on register class CL. Update it
955 : for the birth (if BIRTH_P) or death (if !BIRTH_P) of register REGNO.
956 : LIVE tracks the set of live registers; if it is null, assume that
957 : every birth or death is genuine. */
958 : static inline void
959 49429 : mark_regno_birth_or_death (bitmap live, int *pressure, int regno, bool birth_p)
960 : {
961 49429 : enum reg_class pressure_class;
962 :
963 49429 : pressure_class = sched_regno_pressure_class[regno];
964 49429 : if (regno >= FIRST_PSEUDO_REGISTER)
965 : {
966 41989 : if (pressure_class != NO_REGS)
967 : {
968 41945 : if (birth_p)
969 : {
970 25566 : if (!live || bitmap_set_bit (live, regno))
971 24976 : pressure[pressure_class]
972 24976 : += (ira_reg_class_max_nregs
973 24976 : [pressure_class][PSEUDO_REGNO_MODE (regno)]);
974 : }
975 : else
976 : {
977 16379 : if (!live || bitmap_clear_bit (live, regno))
978 15471 : pressure[pressure_class]
979 15471 : -= (ira_reg_class_max_nregs
980 15471 : [pressure_class][PSEUDO_REGNO_MODE (regno)]);
981 : }
982 : }
983 : }
984 7440 : else if (pressure_class != NO_REGS
985 7440 : && ! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
986 : {
987 6211 : if (birth_p)
988 : {
989 4243 : if (!live || bitmap_set_bit (live, regno))
990 4242 : pressure[pressure_class]++;
991 : }
992 : else
993 : {
994 1968 : if (!live || bitmap_clear_bit (live, regno))
995 1968 : pressure[pressure_class]--;
996 : }
997 : }
998 49429 : }
999 :
1000 : /* Initiate current register pressure related info from living
1001 : registers given by LIVE. */
1002 : static void
1003 430 : initiate_reg_pressure_info (bitmap live)
1004 : {
1005 430 : int i;
1006 430 : unsigned int j;
1007 430 : bitmap_iterator bi;
1008 :
1009 2154 : for (i = 0; i < ira_pressure_classes_num; i++)
1010 1724 : curr_reg_pressure[ira_pressure_classes[i]] = 0;
1011 430 : bitmap_clear (curr_reg_live);
1012 4628 : EXECUTE_IF_SET_IN_BITMAP (live, 0, j, bi)
1013 4198 : if (sched_pressure == SCHED_PRESSURE_MODEL
1014 4198 : || current_nr_blocks == 1
1015 4738 : || bitmap_bit_p (region_ref_regs, j))
1016 3970 : mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure, j, true);
1017 430 : }
1018 :
1019 : /* Mark registers in X as mentioned in the current region. */
1020 : static void
1021 2580 : setup_ref_regs (rtx x)
1022 : {
1023 2580 : int i, j;
1024 2580 : const RTX_CODE code = GET_CODE (x);
1025 2580 : const char *fmt;
1026 :
1027 2580 : if (REG_P (x))
1028 : {
1029 924 : bitmap_set_range (region_ref_regs, REGNO (x), REG_NREGS (x));
1030 924 : return;
1031 : }
1032 1656 : fmt = GET_RTX_FORMAT (code);
1033 4428 : for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1034 2772 : if (fmt[i] == 'e')
1035 1956 : setup_ref_regs (XEXP (x, i));
1036 816 : else if (fmt[i] == 'E')
1037 : {
1038 84 : for (j = 0; j < XVECLEN (x, i); j++)
1039 48 : setup_ref_regs (XVECEXP (x, i, j));
1040 : }
1041 : }
1042 :
1043 : /* Initiate current register pressure related info at the start of
1044 : basic block BB. */
1045 : static void
1046 430 : initiate_bb_reg_pressure_info (basic_block bb)
1047 : {
1048 430 : unsigned int i ATTRIBUTE_UNUSED;
1049 430 : rtx_insn *insn;
1050 :
1051 430 : if (current_nr_blocks > 1)
1052 816 : FOR_BB_INSNS (bb, insn)
1053 780 : if (NONDEBUG_INSN_P (insn))
1054 576 : setup_ref_regs (PATTERN (insn));
1055 430 : initiate_reg_pressure_info (df_get_live_in (bb));
1056 430 : if (bb_has_eh_pred (bb))
1057 0 : for (i = 0; ; ++i)
1058 : {
1059 0 : unsigned int regno = EH_RETURN_DATA_REGNO (i);
1060 :
1061 0 : if (regno == INVALID_REGNUM)
1062 : break;
1063 0 : if (! bitmap_bit_p (df_get_live_in (bb), regno))
1064 0 : mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
1065 : regno, true);
1066 0 : }
1067 430 : }
1068 :
1069 : /* Save current register pressure related info. */
1070 : static void
1071 2579 : save_reg_pressure (void)
1072 : {
1073 2579 : int i;
1074 :
1075 13084 : for (i = 0; i < ira_pressure_classes_num; i++)
1076 10505 : saved_reg_pressure[ira_pressure_classes[i]]
1077 10505 : = curr_reg_pressure[ira_pressure_classes[i]];
1078 2579 : bitmap_copy (saved_reg_live, curr_reg_live);
1079 2579 : }
1080 :
1081 : /* Restore saved register pressure related info. */
1082 : static void
1083 2579 : restore_reg_pressure (void)
1084 : {
1085 2579 : int i;
1086 :
1087 13084 : for (i = 0; i < ira_pressure_classes_num; i++)
1088 10505 : curr_reg_pressure[ira_pressure_classes[i]]
1089 10505 : = saved_reg_pressure[ira_pressure_classes[i]];
1090 2579 : bitmap_copy (curr_reg_live, saved_reg_live);
1091 2579 : }
1092 :
1093 : /* Return TRUE if the register is dying after its USE. */
1094 : static bool
1095 38804 : dying_use_p (struct reg_use_data *use)
1096 : {
1097 38804 : struct reg_use_data *next;
1098 :
1099 46037 : for (next = use->next_regno_use; next != use; next = next->next_regno_use)
1100 17812 : if (NONDEBUG_INSN_P (next->insn)
1101 17812 : && QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
1102 : return false;
1103 : return true;
1104 : }
1105 :
1106 : /* Print info about the current register pressure and its excess for
1107 : each pressure class. */
1108 : static void
1109 0 : print_curr_reg_pressure (void)
1110 : {
1111 0 : int i;
1112 0 : enum reg_class cl;
1113 :
1114 0 : fprintf (sched_dump, ";;\t");
1115 0 : for (i = 0; i < ira_pressure_classes_num; i++)
1116 : {
1117 0 : cl = ira_pressure_classes[i];
1118 0 : gcc_assert (curr_reg_pressure[cl] >= 0);
1119 0 : fprintf (sched_dump, " %s:%d(%d)", reg_class_names[cl],
1120 : curr_reg_pressure[cl],
1121 0 : curr_reg_pressure[cl] - sched_class_regs_num[cl]);
1122 : }
1123 0 : fprintf (sched_dump, "\n");
1124 0 : }
1125 :
1126 : /* Determine if INSN has a condition that is clobbered if a register
1127 : in SET_REGS is modified. */
1128 : static bool
1129 0 : cond_clobbered_p (rtx_insn *insn, HARD_REG_SET set_regs)
1130 : {
1131 0 : rtx pat = PATTERN (insn);
1132 0 : gcc_assert (GET_CODE (pat) == COND_EXEC);
1133 0 : if (TEST_HARD_REG_BIT (set_regs, REGNO (XEXP (COND_EXEC_TEST (pat), 0))))
1134 : {
1135 0 : sd_iterator_def sd_it;
1136 0 : dep_t dep;
1137 0 : haifa_change_pattern (insn, ORIG_PAT (insn));
1138 0 : FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
1139 0 : DEP_STATUS (dep) &= ~DEP_CANCELLED;
1140 0 : TODO_SPEC (insn) = HARD_DEP;
1141 0 : if (sched_verbose >= 2)
1142 0 : fprintf (sched_dump,
1143 : ";;\t\tdequeue insn %s because of clobbered condition\n",
1144 0 : (*current_sched_info->print_insn) (insn, 0));
1145 0 : return true;
1146 : }
1147 :
1148 : return false;
1149 : }
1150 :
1151 : /* This function should be called after modifying the pattern of INSN,
1152 : to update scheduler data structures as needed. */
1153 : static void
1154 665849 : update_insn_after_change (rtx_insn *insn)
1155 : {
1156 665849 : sd_iterator_def sd_it;
1157 665849 : dep_t dep;
1158 :
1159 665849 : dfa_clear_single_insn_cache (insn);
1160 :
1161 665849 : sd_it = sd_iterator_start (insn,
1162 : SD_LIST_FORW | SD_LIST_BACK | SD_LIST_RES_BACK);
1163 7367769 : while (sd_iterator_cond (&sd_it, &dep))
1164 : {
1165 6701920 : DEP_COST (dep) = UNKNOWN_DEP_COST;
1166 6701920 : sd_iterator_next (&sd_it);
1167 : }
1168 :
1169 : /* Invalidate INSN_COST, so it'll be recalculated. */
1170 665849 : INSN_COST (insn) = -1;
1171 : /* Invalidate INSN_TICK, so it'll be recalculated. */
1172 665849 : INSN_TICK (insn) = INVALID_TICK;
1173 :
1174 : /* Invalidate autoprefetch data entry. */
1175 665849 : INSN_AUTOPREF_MULTIPASS_DATA (insn)[0].status
1176 665849 : = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
1177 665849 : INSN_AUTOPREF_MULTIPASS_DATA (insn)[1].status
1178 665849 : = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
1179 665849 : }
1180 :
1181 :
1182 : /* Two VECs, one to hold dependencies for which pattern replacements
1183 : need to be applied or restored at the start of the next cycle, and
1184 : another to hold an integer that is either one, to apply the
1185 : corresponding replacement, or zero to restore it. */
1186 : static vec<dep_t> next_cycle_replace_deps;
1187 : static vec<int> next_cycle_apply;
1188 :
1189 : static void apply_replacement (dep_t, bool);
1190 : static void restore_pattern (dep_t, bool);
1191 :
1192 : /* Look at the remaining dependencies for insn NEXT, and compute and return
1193 : the TODO_SPEC value we should use for it. This is called after one of
1194 : NEXT's dependencies has been resolved.
1195 : We also perform pattern replacements for predication, and for broken
1196 : replacement dependencies. The latter is only done if FOR_BACKTRACK is
1197 : false. */
1198 :
1199 : static ds_t
1200 311309911 : recompute_todo_spec (rtx_insn *next, bool for_backtrack)
1201 : {
1202 311309911 : ds_t new_ds;
1203 311309911 : sd_iterator_def sd_it;
1204 311309911 : dep_t dep, modify_dep = NULL;
1205 311309911 : int n_spec = 0;
1206 311309911 : int n_control = 0;
1207 311309911 : int n_replace = 0;
1208 311309911 : bool first_p = true;
1209 :
1210 311309911 : if (sd_lists_empty_p (next, SD_LIST_BACK))
1211 : /* NEXT has all its dependencies resolved. */
1212 : return 0;
1213 :
1214 203082601 : if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
1215 : return HARD_DEP;
1216 :
1217 : /* If NEXT is intended to sit adjacent to this instruction, we don't
1218 : want to try to break any dependencies. Treat it as a HARD_DEP. */
1219 393858 : if (SCHED_GROUP_P (next))
1220 : return HARD_DEP;
1221 :
1222 : /* Now we've got NEXT with speculative deps only.
1223 : 1. Look at the deps to see what we have to do.
1224 : 2. Check if we can do 'todo'. */
1225 393858 : new_ds = 0;
1226 :
1227 1371208 : FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep)
1228 : {
1229 977350 : rtx_insn *pro = DEP_PRO (dep);
1230 977350 : ds_t ds = DEP_STATUS (dep) & SPECULATIVE;
1231 :
1232 977350 : if (DEBUG_INSN_P (pro) && !DEBUG_INSN_P (next))
1233 134272 : continue;
1234 :
1235 843078 : if (ds)
1236 : {
1237 0 : n_spec++;
1238 0 : if (first_p)
1239 : {
1240 : first_p = false;
1241 :
1242 : new_ds = ds;
1243 : }
1244 : else
1245 0 : new_ds = ds_merge (new_ds, ds);
1246 : }
1247 843078 : else if (DEP_TYPE (dep) == REG_DEP_CONTROL)
1248 : {
1249 0 : if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED)
1250 : {
1251 0 : n_control++;
1252 0 : modify_dep = dep;
1253 : }
1254 0 : DEP_STATUS (dep) &= ~DEP_CANCELLED;
1255 : }
1256 843078 : else if (DEP_REPLACE (dep) != NULL)
1257 : {
1258 843078 : if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED)
1259 : {
1260 843078 : n_replace++;
1261 843078 : modify_dep = dep;
1262 : }
1263 843078 : DEP_STATUS (dep) &= ~DEP_CANCELLED;
1264 : }
1265 : }
1266 :
1267 393858 : if (n_replace > 0 && n_control == 0 && n_spec == 0)
1268 : {
1269 393858 : if (!dbg_cnt (sched_breakdep))
1270 : return HARD_DEP;
1271 1371208 : FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep)
1272 : {
1273 977350 : struct dep_replacement *desc = DEP_REPLACE (dep);
1274 977350 : if (desc != NULL)
1275 : {
1276 843078 : if (desc->insn == next && !for_backtrack)
1277 : {
1278 90957 : gcc_assert (n_replace == 1);
1279 90957 : apply_replacement (dep, true);
1280 : }
1281 843078 : DEP_STATUS (dep) |= DEP_CANCELLED;
1282 : }
1283 : }
1284 : return 0;
1285 : }
1286 :
1287 0 : else if (n_control == 1 && n_replace == 0 && n_spec == 0)
1288 : {
1289 0 : rtx_insn *pro, *other;
1290 0 : rtx new_pat;
1291 0 : rtx cond = NULL_RTX;
1292 0 : bool success;
1293 0 : rtx_insn *prev = NULL;
1294 0 : int i;
1295 0 : unsigned regno;
1296 :
1297 0 : if ((current_sched_info->flags & DO_PREDICATION) == 0
1298 0 : || (ORIG_PAT (next) != NULL_RTX
1299 0 : && PREDICATED_PAT (next) == NULL_RTX))
1300 : return HARD_DEP;
1301 :
1302 0 : pro = DEP_PRO (modify_dep);
1303 0 : other = real_insn_for_shadow (pro);
1304 0 : if (other != NULL_RTX)
1305 0 : pro = other;
1306 :
1307 0 : cond = sched_get_reverse_condition_uncached (pro);
1308 0 : regno = REGNO (XEXP (cond, 0));
1309 :
1310 : /* Find the last scheduled insn that modifies the condition register.
1311 : We can stop looking once we find the insn we depend on through the
1312 : REG_DEP_CONTROL; if the condition register isn't modified after it,
1313 : we know that it still has the right value. */
1314 0 : if (QUEUE_INDEX (pro) == QUEUE_SCHEDULED)
1315 0 : FOR_EACH_VEC_ELT_REVERSE (scheduled_insns, i, prev)
1316 : {
1317 0 : HARD_REG_SET t;
1318 :
1319 0 : find_all_hard_reg_sets (prev, &t, true);
1320 0 : if (TEST_HARD_REG_BIT (t, regno))
1321 0 : return HARD_DEP;
1322 0 : if (prev == pro)
1323 : break;
1324 : }
1325 0 : if (ORIG_PAT (next) == NULL_RTX)
1326 : {
1327 0 : ORIG_PAT (next) = PATTERN (next);
1328 :
1329 0 : new_pat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (next));
1330 0 : success = haifa_change_pattern (next, new_pat);
1331 0 : if (!success)
1332 : return HARD_DEP;
1333 0 : PREDICATED_PAT (next) = new_pat;
1334 : }
1335 0 : else if (PATTERN (next) != PREDICATED_PAT (next))
1336 : {
1337 0 : bool success = haifa_change_pattern (next,
1338 0 : PREDICATED_PAT (next));
1339 0 : gcc_assert (success);
1340 : }
1341 0 : DEP_STATUS (modify_dep) |= DEP_CANCELLED;
1342 0 : return DEP_CONTROL;
1343 : }
1344 :
1345 0 : if (PREDICATED_PAT (next) != NULL_RTX)
1346 : {
1347 0 : int tick = INSN_TICK (next);
1348 0 : bool success = haifa_change_pattern (next,
1349 0 : ORIG_PAT (next));
1350 0 : INSN_TICK (next) = tick;
1351 0 : gcc_assert (success);
1352 : }
1353 :
1354 : /* We can't handle the case where there are both speculative and control
1355 : dependencies, so we return HARD_DEP in such a case. Also fail if
1356 : we have speculative dependencies with not enough points, or more than
1357 : one control dependency. */
1358 0 : if ((n_spec > 0 && (n_control > 0 || n_replace > 0))
1359 0 : || (n_spec > 0
1360 : /* Too few points? */
1361 0 : && ds_weak (new_ds) < spec_info->data_weakness_cutoff)
1362 0 : || n_control > 0
1363 0 : || n_replace > 0)
1364 0 : return HARD_DEP;
1365 :
1366 : return new_ds;
1367 : }
1368 :
1369 : /* Pointer to the last instruction scheduled. */
1370 : static rtx_insn *last_scheduled_insn;
1371 :
1372 : /* Pointer to the last nondebug instruction scheduled within the
1373 : block, or the prev_head of the scheduling block. Used by
1374 : rank_for_schedule, so that insns independent of the last scheduled
1375 : insn will be preferred over dependent instructions. */
1376 : static rtx_insn *last_nondebug_scheduled_insn;
1377 :
1378 : /* Pointer that iterates through the list of unscheduled insns if we
1379 : have a dbg_cnt enabled. It always points at an insn prior to the
1380 : first unscheduled one. */
1381 : static rtx_insn *nonscheduled_insns_begin;
1382 :
1383 : /* Compute cost of executing INSN.
1384 : This is the number of cycles between instruction issue and
1385 : instruction results. */
1386 : int
1387 211578817 : insn_sched_cost (rtx_insn *insn)
1388 : {
1389 211578817 : int cost;
1390 :
1391 211578817 : if (sched_fusion)
1392 : return 0;
1393 :
1394 211578817 : if (sel_sched_p ())
1395 : {
1396 36236 : if (recog_memoized (insn) < 0)
1397 : return 0;
1398 :
1399 35640 : cost = insn_default_latency (insn);
1400 35640 : if (cost < 0)
1401 : cost = 0;
1402 :
1403 35640 : return cost;
1404 : }
1405 :
1406 211542581 : cost = INSN_COST (insn);
1407 :
1408 211542581 : if (cost < 0)
1409 : {
1410 : /* A USE insn, or something else we don't need to
1411 : understand. We can't pass these directly to
1412 : result_ready_cost or insn_default_latency because it will
1413 : trigger a fatal error for unrecognizable insns. */
1414 109204766 : if (recog_memoized (insn) < 0)
1415 : {
1416 49340910 : INSN_COST (insn) = 0;
1417 49340910 : return 0;
1418 : }
1419 : else
1420 : {
1421 59863856 : cost = insn_default_latency (insn);
1422 59863856 : if (cost < 0)
1423 : cost = 0;
1424 :
1425 59863856 : INSN_COST (insn) = cost;
1426 : }
1427 : }
1428 :
1429 : return cost;
1430 : }
1431 :
1432 : /* Compute cost of dependence LINK.
1433 : This is the number of cycles between instruction issue and
1434 : instruction results.
1435 : ??? We also use this function to call recog_memoized on all insns. */
1436 : int
1437 328620314 : dep_cost_1 (dep_t link, dw_t dw)
1438 : {
1439 328620314 : rtx_insn *insn = DEP_PRO (link);
1440 328620314 : rtx_insn *used = DEP_CON (link);
1441 328620314 : int cost;
1442 :
1443 328620314 : if (DEP_COST (link) != UNKNOWN_DEP_COST)
1444 175554171 : return DEP_COST (link);
1445 :
1446 153066143 : if (delay_htab)
1447 : {
1448 0 : struct delay_pair *delay_entry;
1449 0 : delay_entry
1450 0 : = delay_htab_i2->find_with_hash (used, htab_hash_pointer (used));
1451 0 : if (delay_entry)
1452 : {
1453 0 : if (delay_entry->i1 == insn)
1454 : {
1455 0 : DEP_COST (link) = pair_delay (delay_entry);
1456 0 : return DEP_COST (link);
1457 : }
1458 : }
1459 : }
1460 :
1461 : /* A USE insn should never require the value used to be computed.
1462 : This allows the computation of a function's result and parameter
1463 : values to overlap the return and call. We don't care about the
1464 : dependence cost when only decreasing register pressure. */
1465 153066143 : if (recog_memoized (used) < 0)
1466 : {
1467 1416789 : cost = 0;
1468 1416789 : recog_memoized (insn);
1469 : }
1470 : else
1471 : {
1472 151649354 : enum reg_note dep_type = DEP_TYPE (link);
1473 :
1474 151649354 : cost = insn_sched_cost (insn);
1475 :
1476 151649354 : if (INSN_CODE (insn) >= 0)
1477 : {
1478 146579542 : if (dep_type == REG_DEP_ANTI)
1479 : cost = 0;
1480 77543477 : else if (dep_type == REG_DEP_OUTPUT)
1481 : {
1482 23871782 : cost = (insn_default_latency (insn)
1483 23871782 : - insn_default_latency (used));
1484 23871782 : if (cost <= 0)
1485 : cost = 1;
1486 : }
1487 53671695 : else if (bypass_p (insn))
1488 1639 : cost = insn_latency (insn, used);
1489 : }
1490 :
1491 :
1492 151649354 : if (targetm.sched.adjust_cost)
1493 151649354 : cost = targetm.sched.adjust_cost (used, (int) dep_type, insn, cost,
1494 : dw);
1495 :
1496 151649354 : if (cost < 0)
1497 1416789 : cost = 0;
1498 : }
1499 :
1500 153066143 : DEP_COST (link) = cost;
1501 153066143 : return cost;
1502 : }
1503 :
1504 : /* Compute cost of dependence LINK.
1505 : This is the number of cycles between instruction issue and
1506 : instruction results. */
1507 : int
1508 328591449 : dep_cost (dep_t link)
1509 : {
1510 328591449 : return dep_cost_1 (link, 0);
1511 : }
1512 :
1513 : /* Use this sel-sched.cc friendly function in reorder2 instead of increasing
1514 : INSN_PRIORITY explicitly. */
1515 : void
1516 0 : increase_insn_priority (rtx_insn *insn, int amount)
1517 : {
1518 0 : if (!sel_sched_p ())
1519 : {
1520 : /* We're dealing with haifa-sched.cc INSN_PRIORITY. */
1521 0 : if (INSN_PRIORITY_KNOWN (insn))
1522 0 : INSN_PRIORITY (insn) += amount;
1523 : }
1524 : else
1525 : {
1526 : /* In sel-sched.cc INSN_PRIORITY is not kept up to date.
1527 : Use EXPR_PRIORITY instead. */
1528 0 : sel_add_to_insn_priority (insn, amount);
1529 : }
1530 0 : }
1531 :
1532 : /* Return 'true' if DEP should be included in priority calculations. */
1533 : static bool
1534 156107211 : contributes_to_priority_p (dep_t dep)
1535 : {
1536 156107211 : if (DEBUG_INSN_P (DEP_CON (dep))
1537 143205864 : || DEBUG_INSN_P (DEP_PRO (dep)))
1538 : return false;
1539 :
1540 : /* Critical path is meaningful in block boundaries only. */
1541 143205864 : if (!current_sched_info->contributes_to_priority (DEP_CON (dep),
1542 : DEP_PRO (dep)))
1543 : return false;
1544 :
1545 143202189 : if (DEP_REPLACE (dep) != NULL)
1546 : return false;
1547 :
1548 : /* If flag COUNT_SPEC_IN_CRITICAL_PATH is set,
1549 : then speculative instructions will less likely be
1550 : scheduled. That is because the priority of
1551 : their producers will increase, and, thus, the
1552 : producers will more likely be scheduled, thus,
1553 : resolving the dependence. */
1554 142548620 : if (sched_deps_info->generate_spec_deps
1555 0 : && !(spec_info->flags & COUNT_SPEC_IN_CRITICAL_PATH)
1556 0 : && (DEP_STATUS (dep) & SPECULATIVE))
1557 : return false;
1558 :
1559 : return true;
1560 : }
1561 :
1562 : /* Compute the number of nondebug deps in list LIST for INSN. */
1563 : int
1564 655969062 : dep_list_size (rtx_insn *insn, sd_list_types_def list)
1565 : {
1566 655969062 : sd_iterator_def sd_it;
1567 655969062 : dep_t dep;
1568 655969062 : int dbgcount = 0, nodbgcount = 0;
1569 :
1570 655969062 : if (!MAY_HAVE_DEBUG_INSNS)
1571 276572669 : return sd_lists_size (insn, list);
1572 :
1573 : /* TODO: We should split normal and debug insns into separate SD_LIST_*
1574 : sub-lists, and then we'll be able to use something like
1575 : sd_lists_size(insn, list & SD_LIST_NON_DEBUG)
1576 : instead of walking dependencies below. */
1577 :
1578 1334459039 : FOR_EACH_DEP (insn, list, sd_it, dep)
1579 : {
1580 955062646 : if (DEBUG_INSN_P (DEP_CON (dep)))
1581 102663754 : dbgcount++;
1582 852398892 : else if (!DEBUG_INSN_P (DEP_PRO (dep)))
1583 845118247 : nodbgcount++;
1584 : }
1585 :
1586 379396393 : gcc_assert (dbgcount + nodbgcount == sd_lists_size (insn, list));
1587 :
1588 : return nodbgcount;
1589 : }
1590 :
1591 : bool sched_fusion;
1592 :
1593 : /* Compute the priority number for INSN. */
1594 : static int
1595 251776975 : priority (rtx_insn *insn, bool force_recompute)
1596 : {
1597 251776975 : if (! INSN_P (insn))
1598 : return 0;
1599 :
1600 : /* We should not be interested in priority of an already scheduled insn. */
1601 251776975 : gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
1602 :
1603 251776975 : if (force_recompute || !INSN_PRIORITY_KNOWN (insn))
1604 : {
1605 109228234 : int this_priority = -1;
1606 :
1607 109228234 : if (sched_fusion)
1608 : {
1609 0 : int this_fusion_priority;
1610 :
1611 0 : targetm.sched.fusion_priority (insn, FUSION_MAX_PRIORITY,
1612 : &this_fusion_priority, &this_priority);
1613 0 : INSN_FUSION_PRIORITY (insn) = this_fusion_priority;
1614 : }
1615 109228234 : else if (dep_list_size (insn, SD_LIST_FORW) == 0)
1616 : /* ??? We should set INSN_PRIORITY to insn_sched_cost when and insn
1617 : has some forward deps but all of them are ignored by
1618 : contributes_to_priority hook. At the moment we set priority of
1619 : such insn to 0. */
1620 59920002 : this_priority = insn_sched_cost (insn);
1621 : else
1622 : {
1623 49308232 : rtx_insn *prev_first, *twin;
1624 49308232 : basic_block rec;
1625 :
1626 : /* For recovery check instructions we calculate priority slightly
1627 : different than that of normal instructions. Instead of walking
1628 : through INSN_FORW_DEPS (check) list, we walk through
1629 : INSN_FORW_DEPS list of each instruction in the corresponding
1630 : recovery block. */
1631 :
1632 : /* Selective scheduling does not define RECOVERY_BLOCK macro. */
1633 49308232 : rec = sel_sched_p () ? NULL : RECOVERY_BLOCK (insn);
1634 49304875 : if (!rec || rec == EXIT_BLOCK_PTR_FOR_FN (cfun))
1635 : {
1636 49308232 : prev_first = PREV_INSN (insn);
1637 49308232 : twin = insn;
1638 : }
1639 : else
1640 : {
1641 0 : prev_first = NEXT_INSN (BB_HEAD (rec));
1642 0 : twin = PREV_INSN (BB_END (rec));
1643 : }
1644 :
1645 49308232 : do
1646 : {
1647 49308232 : sd_iterator_def sd_it;
1648 49308232 : dep_t dep;
1649 :
1650 205415443 : FOR_EACH_DEP (twin, SD_LIST_FORW, sd_it, dep)
1651 : {
1652 156107211 : rtx_insn *next;
1653 156107211 : int next_priority;
1654 :
1655 156107211 : next = DEP_CON (dep);
1656 :
1657 156107211 : if (BLOCK_FOR_INSN (next) != rec)
1658 : {
1659 156107211 : int cost;
1660 :
1661 156107211 : if (!contributes_to_priority_p (dep))
1662 13558591 : continue;
1663 :
1664 142548620 : if (twin == insn)
1665 142548620 : cost = dep_cost (dep);
1666 : else
1667 : {
1668 0 : struct _dep _dep1, *dep1 = &_dep1;
1669 :
1670 0 : init_dep (dep1, insn, next, REG_DEP_ANTI);
1671 :
1672 0 : cost = dep_cost (dep1);
1673 : }
1674 :
1675 142548620 : next_priority = cost + priority (next);
1676 :
1677 142548620 : if (next_priority > this_priority)
1678 101677104 : this_priority = next_priority;
1679 : }
1680 : }
1681 :
1682 49308232 : twin = PREV_INSN (twin);
1683 : }
1684 49308232 : while (twin != prev_first);
1685 : }
1686 :
1687 109228234 : if (this_priority < 0)
1688 : {
1689 9461 : gcc_assert (this_priority == -1);
1690 :
1691 9461 : this_priority = insn_sched_cost (insn);
1692 : }
1693 :
1694 109228234 : INSN_PRIORITY (insn) = this_priority;
1695 109228234 : INSN_PRIORITY_STATUS (insn) = 1;
1696 : }
1697 :
1698 251776975 : return INSN_PRIORITY (insn);
1699 : }
1700 :
1701 : /* Macros and functions for keeping the priority queue sorted, and
1702 : dealing with queuing and dequeuing of instructions. */
1703 :
1704 : /* For each pressure class CL, set DEATH[CL] to the number of registers
1705 : in that class that die in INSN. */
1706 :
1707 : static void
1708 23095 : calculate_reg_deaths (rtx_insn *insn, int *death)
1709 : {
1710 23095 : int i;
1711 23095 : struct reg_use_data *use;
1712 :
1713 126029 : for (i = 0; i < ira_pressure_classes_num; i++)
1714 102934 : death[ira_pressure_classes[i]] = 0;
1715 40369 : for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
1716 17274 : if (dying_use_p (use))
1717 9842 : mark_regno_birth_or_death (0, death, use->regno, true);
1718 23095 : }
1719 :
1720 : /* Setup info about the current register pressure impact of scheduling
1721 : INSN at the current scheduling point. */
1722 : static void
1723 23095 : setup_insn_reg_pressure_info (rtx_insn *insn)
1724 : {
1725 23095 : int i, change, before, after, hard_regno;
1726 23095 : int excess_cost_change;
1727 23095 : machine_mode mode;
1728 23095 : enum reg_class cl;
1729 23095 : struct reg_pressure_data *pressure_info;
1730 23095 : int *max_reg_pressure;
1731 23095 : static int death[N_REG_CLASSES];
1732 :
1733 23095 : gcc_checking_assert (!DEBUG_INSN_P (insn));
1734 :
1735 23095 : excess_cost_change = 0;
1736 23095 : calculate_reg_deaths (insn, death);
1737 23095 : pressure_info = INSN_REG_PRESSURE (insn);
1738 23095 : max_reg_pressure = INSN_MAX_REG_PRESSURE (insn);
1739 23095 : gcc_assert (pressure_info != NULL && max_reg_pressure != NULL);
1740 126029 : for (i = 0; i < ira_pressure_classes_num; i++)
1741 : {
1742 102934 : cl = ira_pressure_classes[i];
1743 102934 : gcc_assert (curr_reg_pressure[cl] >= 0);
1744 102934 : change = (int) pressure_info[i].set_increase - death[cl];
1745 102934 : before = MAX (0, max_reg_pressure[i] - sched_class_regs_num[cl]);
1746 102934 : after = MAX (0, max_reg_pressure[i] + change
1747 : - sched_class_regs_num[cl]);
1748 102934 : hard_regno = ira_class_hard_regs[cl][0];
1749 102934 : gcc_assert (hard_regno >= 0);
1750 102934 : mode = reg_raw_mode[hard_regno];
1751 102934 : excess_cost_change += ((after - before)
1752 102934 : * (ira_memory_move_cost[mode][cl][0]
1753 102934 : + ira_memory_move_cost[mode][cl][1]));
1754 : }
1755 23095 : INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insn) = excess_cost_change;
1756 23095 : }
1757 :
1758 : /* This is the first page of code related to SCHED_PRESSURE_MODEL.
1759 : It tries to make the scheduler take register pressure into account
1760 : without introducing too many unnecessary stalls. It hooks into the
1761 : main scheduling algorithm at several points:
1762 :
1763 : - Before scheduling starts, model_start_schedule constructs a
1764 : "model schedule" for the current block. This model schedule is
1765 : chosen solely to keep register pressure down. It does not take the
1766 : target's pipeline or the original instruction order into account,
1767 : except as a tie-breaker. It also doesn't work to a particular
1768 : pressure limit.
1769 :
1770 : This model schedule gives us an idea of what pressure can be
1771 : achieved for the block and gives us an example of a schedule that
1772 : keeps to that pressure. It also makes the final schedule less
1773 : dependent on the original instruction order. This is important
1774 : because the original order can either be "wide" (many values live
1775 : at once, such as in user-scheduled code) or "narrow" (few values
1776 : live at once, such as after loop unrolling, where several
1777 : iterations are executed sequentially).
1778 :
1779 : We do not apply this model schedule to the rtx stream. We simply
1780 : record it in model_schedule. We also compute the maximum pressure,
1781 : MP, that was seen during this schedule.
1782 :
1783 : - Instructions are added to the ready queue even if they require
1784 : a stall. The length of the stall is instead computed as:
1785 :
1786 : MAX (INSN_TICK (INSN) - clock_var, 0)
1787 :
1788 : (= insn_delay). This allows rank_for_schedule to choose between
1789 : introducing a deliberate stall or increasing pressure.
1790 :
1791 : - Before sorting the ready queue, model_set_excess_costs assigns
1792 : a pressure-based cost to each ready instruction in the queue.
1793 : This is the instruction's INSN_REG_PRESSURE_EXCESS_COST_CHANGE
1794 : (ECC for short) and is effectively measured in cycles.
1795 :
1796 : - rank_for_schedule ranks instructions based on:
1797 :
1798 : ECC (insn) + insn_delay (insn)
1799 :
1800 : then as:
1801 :
1802 : insn_delay (insn)
1803 :
1804 : So, for example, an instruction X1 with an ECC of 1 that can issue
1805 : now will win over an instruction X0 with an ECC of zero that would
1806 : introduce a stall of one cycle. However, an instruction X2 with an
1807 : ECC of 2 that can issue now will lose to both X0 and X1.
1808 :
1809 : - When an instruction is scheduled, model_recompute updates the model
1810 : schedule with the new pressures (some of which might now exceed the
1811 : original maximum pressure MP). model_update_limit_points then searches
1812 : for the new point of maximum pressure, if not already known. */
1813 :
1814 : /* Used to separate high-verbosity debug information for SCHED_PRESSURE_MODEL
1815 : from surrounding debug information. */
1816 : #define MODEL_BAR \
1817 : ";;\t\t+------------------------------------------------------\n"
1818 :
1819 : /* Information about the pressure on a particular register class at a
1820 : particular point of the model schedule. */
1821 : struct model_pressure_data {
1822 : /* The pressure at this point of the model schedule, or -1 if the
1823 : point is associated with an instruction that has already been
1824 : scheduled. */
1825 : int ref_pressure;
1826 :
1827 : /* The maximum pressure during or after this point of the model schedule. */
1828 : int max_pressure;
1829 : };
1830 :
1831 : /* Per-instruction information that is used while building the model
1832 : schedule. Here, "schedule" refers to the model schedule rather
1833 : than the main schedule. */
1834 : struct model_insn_info {
1835 : /* The instruction itself. */
1836 : rtx_insn *insn;
1837 :
1838 : /* If this instruction is in model_worklist, these fields link to the
1839 : previous (higher-priority) and next (lower-priority) instructions
1840 : in the list. */
1841 : struct model_insn_info *prev;
1842 : struct model_insn_info *next;
1843 :
1844 : /* While constructing the schedule, QUEUE_INDEX describes whether an
1845 : instruction has already been added to the schedule (QUEUE_SCHEDULED),
1846 : is in model_worklist (QUEUE_READY), or neither (QUEUE_NOWHERE).
1847 : old_queue records the value that QUEUE_INDEX had before scheduling
1848 : started, so that we can restore it once the schedule is complete. */
1849 : int old_queue;
1850 :
1851 : /* The relative importance of an unscheduled instruction. Higher
1852 : values indicate greater importance. */
1853 : unsigned int model_priority;
1854 :
1855 : /* The length of the longest path of satisfied true dependencies
1856 : that leads to this instruction. */
1857 : unsigned int depth;
1858 :
1859 : /* The length of the longest path of dependencies of any kind
1860 : that leads from this instruction. */
1861 : unsigned int alap;
1862 :
1863 : /* The number of predecessor nodes that must still be scheduled. */
1864 : int unscheduled_preds;
1865 : };
1866 :
1867 : /* Information about the pressure limit for a particular register class.
1868 : This structure is used when applying a model schedule to the main
1869 : schedule. */
1870 : struct model_pressure_limit {
1871 : /* The maximum register pressure seen in the original model schedule. */
1872 : int orig_pressure;
1873 :
1874 : /* The maximum register pressure seen in the current model schedule
1875 : (which excludes instructions that have already been scheduled). */
1876 : int pressure;
1877 :
1878 : /* The point of the current model schedule at which PRESSURE is first
1879 : reached. It is set to -1 if the value needs to be recomputed. */
1880 : int point;
1881 : };
1882 :
1883 : /* Describes a particular way of measuring register pressure. */
1884 : struct model_pressure_group {
1885 : /* Index PCI describes the maximum pressure on ira_pressure_classes[PCI]. */
1886 : struct model_pressure_limit limits[N_REG_CLASSES];
1887 :
1888 : /* Index (POINT * ira_num_pressure_classes + PCI) describes the pressure
1889 : on register class ira_pressure_classes[PCI] at point POINT of the
1890 : current model schedule. A POINT of model_num_insns describes the
1891 : pressure at the end of the schedule. */
1892 : struct model_pressure_data *model;
1893 : };
1894 :
1895 : /* Index POINT gives the instruction at point POINT of the model schedule.
1896 : This array doesn't change during main scheduling. */
1897 : static vec<rtx_insn *> model_schedule;
1898 :
1899 : /* The list of instructions in the model worklist, sorted in order of
1900 : decreasing priority. */
1901 : static struct model_insn_info *model_worklist;
1902 :
1903 : /* Index I describes the instruction with INSN_LUID I. */
1904 : static struct model_insn_info *model_insns;
1905 :
1906 : /* The number of instructions in the model schedule. */
1907 : static int model_num_insns;
1908 :
1909 : /* The index of the first instruction in model_schedule that hasn't yet been
1910 : added to the main schedule, or model_num_insns if all of them have. */
1911 : static int model_curr_point;
1912 :
1913 : /* Describes the pressure before each instruction in the model schedule. */
1914 : static struct model_pressure_group model_before_pressure;
1915 :
1916 : /* The first unused model_priority value (as used in model_insn_info). */
1917 : static unsigned int model_next_priority;
1918 :
1919 :
1920 : /* The model_pressure_data for ira_pressure_classes[PCI] in GROUP
1921 : at point POINT of the model schedule. */
1922 : #define MODEL_PRESSURE_DATA(GROUP, POINT, PCI) \
1923 : (&(GROUP)->model[(POINT) * ira_pressure_classes_num + (PCI)])
1924 :
1925 : /* The maximum pressure on ira_pressure_classes[PCI] in GROUP at or
1926 : after point POINT of the model schedule. */
1927 : #define MODEL_MAX_PRESSURE(GROUP, POINT, PCI) \
1928 : (MODEL_PRESSURE_DATA (GROUP, POINT, PCI)->max_pressure)
1929 :
1930 : /* The pressure on ira_pressure_classes[PCI] in GROUP at point POINT
1931 : of the model schedule. */
1932 : #define MODEL_REF_PRESSURE(GROUP, POINT, PCI) \
1933 : (MODEL_PRESSURE_DATA (GROUP, POINT, PCI)->ref_pressure)
1934 :
1935 : /* Information about INSN that is used when creating the model schedule. */
1936 : #define MODEL_INSN_INFO(INSN) \
1937 : (&model_insns[INSN_LUID (INSN)])
1938 :
1939 : /* The instruction at point POINT of the model schedule. */
1940 : #define MODEL_INSN(POINT) \
1941 : (model_schedule[POINT])
1942 :
1943 :
1944 : /* Return INSN's index in the model schedule, or model_num_insns if it
1945 : doesn't belong to that schedule. */
1946 :
1947 : static int
1948 0 : model_index (rtx_insn *insn)
1949 : {
1950 0 : if (INSN_MODEL_INDEX (insn) == 0)
1951 0 : return model_num_insns;
1952 0 : return INSN_MODEL_INDEX (insn) - 1;
1953 : }
1954 :
1955 : /* Make sure that GROUP->limits is up-to-date for the current point
1956 : of the model schedule. */
1957 :
1958 : static void
1959 0 : model_update_limit_points_in_group (struct model_pressure_group *group)
1960 : {
1961 0 : int pci, max_pressure, point;
1962 :
1963 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
1964 : {
1965 : /* We may have passed the final point at which the pressure in
1966 : group->limits[pci].pressure was reached. Update the limit if so. */
1967 0 : max_pressure = MODEL_MAX_PRESSURE (group, model_curr_point, pci);
1968 0 : group->limits[pci].pressure = max_pressure;
1969 :
1970 : /* Find the point at which MAX_PRESSURE is first reached. We need
1971 : to search in three cases:
1972 :
1973 : - We've already moved past the previous pressure point.
1974 : In this case we search forward from model_curr_point.
1975 :
1976 : - We scheduled the previous point of maximum pressure ahead of
1977 : its position in the model schedule, but doing so didn't bring
1978 : the pressure point earlier. In this case we search forward
1979 : from that previous pressure point.
1980 :
1981 : - Scheduling an instruction early caused the maximum pressure
1982 : to decrease. In this case we will have set the pressure
1983 : point to -1, and we search forward from model_curr_point. */
1984 0 : point = MAX (group->limits[pci].point, model_curr_point);
1985 0 : while (point < model_num_insns
1986 0 : && MODEL_REF_PRESSURE (group, point, pci) < max_pressure)
1987 0 : point++;
1988 0 : group->limits[pci].point = point;
1989 :
1990 0 : gcc_assert (MODEL_REF_PRESSURE (group, point, pci) == max_pressure);
1991 0 : gcc_assert (MODEL_MAX_PRESSURE (group, point, pci) == max_pressure);
1992 : }
1993 0 : }
1994 :
1995 : /* Make sure that all register-pressure limits are up-to-date for the
1996 : current position in the model schedule. */
1997 :
1998 : static void
1999 0 : model_update_limit_points (void)
2000 : {
2001 0 : model_update_limit_points_in_group (&model_before_pressure);
2002 0 : }
2003 :
2004 : /* Return the model_index of the last unscheduled use in chain USE
2005 : outside of USE's instruction. Return -1 if there are no other uses,
2006 : or model_num_insns if the register is live at the end of the block. */
2007 :
2008 : static int
2009 0 : model_last_use_except (struct reg_use_data *use)
2010 : {
2011 0 : struct reg_use_data *next;
2012 0 : int last, index;
2013 :
2014 0 : last = -1;
2015 0 : for (next = use->next_regno_use; next != use; next = next->next_regno_use)
2016 0 : if (NONDEBUG_INSN_P (next->insn)
2017 0 : && QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
2018 : {
2019 0 : index = model_index (next->insn);
2020 0 : if (index == model_num_insns)
2021 : return model_num_insns;
2022 0 : if (last < index)
2023 0 : last = index;
2024 : }
2025 : return last;
2026 : }
2027 :
2028 : /* An instruction with model_index POINT has just been scheduled, and it
2029 : adds DELTA to the pressure on ira_pressure_classes[PCI] after POINT - 1.
2030 : Update MODEL_REF_PRESSURE (GROUP, POINT, PCI) and
2031 : MODEL_MAX_PRESSURE (GROUP, POINT, PCI) accordingly. */
2032 :
2033 : static void
2034 0 : model_start_update_pressure (struct model_pressure_group *group,
2035 : int point, int pci, int delta)
2036 : {
2037 0 : int next_max_pressure;
2038 :
2039 0 : if (point == model_num_insns)
2040 : {
2041 : /* The instruction wasn't part of the model schedule; it was moved
2042 : from a different block. Update the pressure for the end of
2043 : the model schedule. */
2044 0 : MODEL_REF_PRESSURE (group, point, pci) += delta;
2045 0 : MODEL_MAX_PRESSURE (group, point, pci) += delta;
2046 : }
2047 : else
2048 : {
2049 : /* Record that this instruction has been scheduled. Nothing now
2050 : changes between POINT and POINT + 1, so get the maximum pressure
2051 : from the latter. If the maximum pressure decreases, the new
2052 : pressure point may be before POINT. */
2053 0 : MODEL_REF_PRESSURE (group, point, pci) = -1;
2054 0 : next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, pci);
2055 0 : if (MODEL_MAX_PRESSURE (group, point, pci) > next_max_pressure)
2056 : {
2057 0 : MODEL_MAX_PRESSURE (group, point, pci) = next_max_pressure;
2058 0 : if (group->limits[pci].point == point)
2059 0 : group->limits[pci].point = -1;
2060 : }
2061 : }
2062 0 : }
2063 :
2064 : /* Record that scheduling a later instruction has changed the pressure
2065 : at point POINT of the model schedule by DELTA (which might be 0).
2066 : Update GROUP accordingly. Return nonzero if these changes might
2067 : trigger changes to previous points as well. */
2068 :
2069 : static int
2070 0 : model_update_pressure (struct model_pressure_group *group,
2071 : int point, int pci, int delta)
2072 : {
2073 0 : int ref_pressure, max_pressure, next_max_pressure;
2074 :
2075 : /* If POINT hasn't yet been scheduled, update its pressure. */
2076 0 : ref_pressure = MODEL_REF_PRESSURE (group, point, pci);
2077 0 : if (ref_pressure >= 0 && delta != 0)
2078 : {
2079 0 : ref_pressure += delta;
2080 0 : MODEL_REF_PRESSURE (group, point, pci) = ref_pressure;
2081 :
2082 : /* Check whether the maximum pressure in the overall schedule
2083 : has increased. (This means that the MODEL_MAX_PRESSURE of
2084 : every point <= POINT will need to increase too; see below.) */
2085 0 : if (group->limits[pci].pressure < ref_pressure)
2086 0 : group->limits[pci].pressure = ref_pressure;
2087 :
2088 : /* If we are at maximum pressure, and the maximum pressure
2089 : point was previously unknown or later than POINT,
2090 : bring it forward. */
2091 0 : if (group->limits[pci].pressure == ref_pressure
2092 0 : && !IN_RANGE (group->limits[pci].point, 0, point))
2093 0 : group->limits[pci].point = point;
2094 :
2095 : /* If POINT used to be the point of maximum pressure, but isn't
2096 : any longer, we need to recalculate it using a forward walk. */
2097 0 : if (group->limits[pci].pressure > ref_pressure
2098 0 : && group->limits[pci].point == point)
2099 0 : group->limits[pci].point = -1;
2100 : }
2101 :
2102 : /* Update the maximum pressure at POINT. Changes here might also
2103 : affect the maximum pressure at POINT - 1. */
2104 0 : next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, pci);
2105 0 : max_pressure = MAX (ref_pressure, next_max_pressure);
2106 0 : if (MODEL_MAX_PRESSURE (group, point, pci) != max_pressure)
2107 : {
2108 0 : MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
2109 0 : return 1;
2110 : }
2111 : return 0;
2112 : }
2113 :
2114 : /* INSN has just been scheduled. Update the model schedule accordingly. */
2115 :
2116 : static void
2117 0 : model_recompute (rtx_insn *insn)
2118 : {
2119 0 : struct {
2120 : int last_use;
2121 : int regno;
2122 : } uses[FIRST_PSEUDO_REGISTER + MAX_RECOG_OPERANDS];
2123 0 : struct reg_use_data *use;
2124 0 : struct reg_pressure_data *reg_pressure;
2125 0 : int delta[N_REG_CLASSES];
2126 0 : int pci, point, mix, new_last, cl, ref_pressure, queue;
2127 0 : unsigned int i, num_uses, num_pending_births;
2128 0 : bool print_p;
2129 :
2130 : /* The destinations of INSN were previously live from POINT onwards, but are
2131 : now live from model_curr_point onwards. Set up DELTA accordingly. */
2132 0 : point = model_index (insn);
2133 0 : reg_pressure = INSN_REG_PRESSURE (insn);
2134 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2135 : {
2136 0 : cl = ira_pressure_classes[pci];
2137 0 : delta[cl] = reg_pressure[pci].set_increase;
2138 : }
2139 :
2140 : /* Record which registers previously died at POINT, but which now die
2141 : before POINT. Adjust DELTA so that it represents the effect of
2142 : this change after POINT - 1. Set NUM_PENDING_BIRTHS to the number of
2143 : registers that will be born in the range [model_curr_point, POINT). */
2144 0 : num_uses = 0;
2145 0 : num_pending_births = 0;
2146 0 : bitmap_clear (tmp_bitmap);
2147 0 : for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
2148 : {
2149 0 : new_last = model_last_use_except (use);
2150 0 : if (new_last < point
2151 0 : && bitmap_set_bit (tmp_bitmap, use->regno)
2152 : /* df_get_live_in has not necessarily been updated to reflect the
2153 : effect of inter-block movement performed by earlier schedules.
2154 : Cope with stale live-in sets by ignoring registers that are not
2155 : currently assumed to be live. */
2156 0 : && bitmap_bit_p (curr_reg_live, use->regno))
2157 : {
2158 0 : gcc_assert (num_uses < ARRAY_SIZE (uses));
2159 0 : uses[num_uses].last_use = new_last;
2160 0 : uses[num_uses].regno = use->regno;
2161 : /* This register is no longer live after POINT - 1. */
2162 0 : mark_regno_birth_or_death (NULL, delta, use->regno, false);
2163 0 : num_uses++;
2164 0 : if (new_last >= 0)
2165 0 : num_pending_births++;
2166 : }
2167 : }
2168 :
2169 : /* Update the MODEL_REF_PRESSURE and MODEL_MAX_PRESSURE for POINT.
2170 : Also set each group pressure limit for POINT. */
2171 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2172 : {
2173 0 : cl = ira_pressure_classes[pci];
2174 0 : model_start_update_pressure (&model_before_pressure,
2175 : point, pci, delta[cl]);
2176 : }
2177 :
2178 : /* Walk the model schedule backwards, starting immediately before POINT. */
2179 0 : print_p = false;
2180 0 : if (point != model_curr_point)
2181 0 : do
2182 : {
2183 0 : point--;
2184 0 : insn = MODEL_INSN (point);
2185 0 : queue = QUEUE_INDEX (insn);
2186 :
2187 0 : if (queue != QUEUE_SCHEDULED)
2188 : {
2189 : /* DELTA describes the effect of the move on the register pressure
2190 : after POINT. Make it describe the effect on the pressure
2191 : before POINT. */
2192 : i = 0;
2193 0 : while (i < num_uses)
2194 : {
2195 0 : if (uses[i].last_use == point)
2196 : {
2197 : /* This register is now live again. */
2198 0 : mark_regno_birth_or_death (NULL, delta,
2199 : uses[i].regno, true);
2200 :
2201 : /* Remove this use from the array. */
2202 0 : uses[i] = uses[num_uses - 1];
2203 0 : num_uses--;
2204 0 : num_pending_births--;
2205 : }
2206 : else
2207 0 : i++;
2208 : }
2209 :
2210 0 : if (sched_verbose >= 5)
2211 : {
2212 0 : if (!print_p)
2213 : {
2214 0 : fprintf (sched_dump, MODEL_BAR);
2215 0 : fprintf (sched_dump, ";;\t\t| New pressure for model"
2216 : " schedule\n");
2217 0 : fprintf (sched_dump, MODEL_BAR);
2218 0 : print_p = true;
2219 : }
2220 :
2221 0 : fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ",
2222 0 : point, INSN_UID (insn),
2223 0 : str_pattern_slim (PATTERN (insn)));
2224 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2225 : {
2226 0 : cl = ira_pressure_classes[pci];
2227 0 : ref_pressure = MODEL_REF_PRESSURE (&model_before_pressure,
2228 : point, pci);
2229 0 : fprintf (sched_dump, " %s:[%d->%d]",
2230 : reg_class_names[ira_pressure_classes[pci]],
2231 0 : ref_pressure, ref_pressure + delta[cl]);
2232 : }
2233 0 : fprintf (sched_dump, "\n");
2234 : }
2235 : }
2236 :
2237 : /* Adjust the pressure at POINT. Set MIX to nonzero if POINT - 1
2238 : might have changed as well. */
2239 0 : mix = num_pending_births;
2240 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2241 : {
2242 0 : cl = ira_pressure_classes[pci];
2243 0 : mix |= delta[cl];
2244 0 : mix |= model_update_pressure (&model_before_pressure,
2245 : point, pci, delta[cl]);
2246 : }
2247 : }
2248 0 : while (mix && point > model_curr_point);
2249 :
2250 0 : if (print_p)
2251 0 : fprintf (sched_dump, MODEL_BAR);
2252 0 : }
2253 :
2254 : /* After DEP, which was cancelled, has been resolved for insn NEXT,
2255 : check whether the insn's pattern needs restoring. */
2256 : static bool
2257 843078 : must_restore_pattern_p (rtx_insn *next, dep_t dep)
2258 : {
2259 843078 : if (QUEUE_INDEX (next) == QUEUE_SCHEDULED)
2260 : return false;
2261 :
2262 303439 : if (DEP_TYPE (dep) == REG_DEP_CONTROL)
2263 : {
2264 0 : gcc_assert (ORIG_PAT (next) != NULL_RTX);
2265 0 : gcc_assert (next == DEP_CON (dep));
2266 : }
2267 : else
2268 : {
2269 303439 : struct dep_replacement *desc = DEP_REPLACE (dep);
2270 303439 : if (desc->insn != next)
2271 : {
2272 240334 : gcc_assert (*desc->loc == desc->orig);
2273 : return false;
2274 : }
2275 : }
2276 : return true;
2277 : }
2278 :
2279 : /* model_spill_cost (CL, P, P') returns the cost of increasing the
2280 : pressure on CL from P to P'. We use this to calculate a "base ECC",
2281 : baseECC (CL, X), for each pressure class CL and each instruction X.
2282 : Supposing X changes the pressure on CL from P to P', and that the
2283 : maximum pressure on CL in the current model schedule is MP', then:
2284 :
2285 : * if X occurs before or at the next point of maximum pressure in
2286 : the model schedule and P' > MP', then:
2287 :
2288 : baseECC (CL, X) = model_spill_cost (CL, MP, P')
2289 :
2290 : The idea is that the pressure after scheduling a fixed set of
2291 : instructions -- in this case, the set up to and including the
2292 : next maximum pressure point -- is going to be the same regardless
2293 : of the order; we simply want to keep the intermediate pressure
2294 : under control. Thus X has a cost of zero unless scheduling it
2295 : now would exceed MP'.
2296 :
2297 : If all increases in the set are by the same amount, no zero-cost
2298 : instruction will ever cause the pressure to exceed MP'. However,
2299 : if X is instead moved past an instruction X' with pressure in the
2300 : range (MP' - (P' - P), MP'), the pressure at X' will increase
2301 : beyond MP'. Since baseECC is very much a heuristic anyway,
2302 : it doesn't seem worth the overhead of tracking cases like these.
2303 :
2304 : The cost of exceeding MP' is always based on the original maximum
2305 : pressure MP. This is so that going 2 registers over the original
2306 : limit has the same cost regardless of whether it comes from two
2307 : separate +1 deltas or from a single +2 delta.
2308 :
2309 : * if X occurs after the next point of maximum pressure in the model
2310 : schedule and P' > P, then:
2311 :
2312 : baseECC (CL, X) = model_spill_cost (CL, MP, MP' + (P' - P))
2313 :
2314 : That is, if we move X forward across a point of maximum pressure,
2315 : and if X increases the pressure by P' - P, then we conservatively
2316 : assume that scheduling X next would increase the maximum pressure
2317 : by P' - P. Again, the cost of doing this is based on the original
2318 : maximum pressure MP, for the same reason as above.
2319 :
2320 : * if P' < P, P > MP, and X occurs at or after the next point of
2321 : maximum pressure, then:
2322 :
2323 : baseECC (CL, X) = -model_spill_cost (CL, MAX (MP, P'), P)
2324 :
2325 : That is, if we have already exceeded the original maximum pressure MP,
2326 : and if X might reduce the maximum pressure again -- or at least push
2327 : it further back, and thus allow more scheduling freedom -- it is given
2328 : a negative cost to reflect the improvement.
2329 :
2330 : * otherwise,
2331 :
2332 : baseECC (CL, X) = 0
2333 :
2334 : In this case, X is not expected to affect the maximum pressure MP',
2335 : so it has zero cost.
2336 :
2337 : We then create a combined value baseECC (X) that is the sum of
2338 : baseECC (CL, X) for each pressure class CL.
2339 :
2340 : baseECC (X) could itself be used as the ECC value described above.
2341 : However, this is often too conservative, in the sense that it
2342 : tends to make high-priority instructions that increase pressure
2343 : wait too long in cases where introducing a spill would be better.
2344 : For this reason the final ECC is a priority-adjusted form of
2345 : baseECC (X). Specifically, we calculate:
2346 :
2347 : P (X) = INSN_PRIORITY (X) - insn_delay (X) - baseECC (X)
2348 : baseP = MAX { P (X) | baseECC (X) <= 0 }
2349 :
2350 : Then:
2351 :
2352 : ECC (X) = MAX (MIN (baseP - P (X), baseECC (X)), 0)
2353 :
2354 : Thus an instruction's effect on pressure is ignored if it has a high
2355 : enough priority relative to the ones that don't increase pressure.
2356 : Negative values of baseECC (X) do not increase the priority of X
2357 : itself, but they do make it harder for other instructions to
2358 : increase the pressure further.
2359 :
2360 : This pressure cost is deliberately timid. The intention has been
2361 : to choose a heuristic that rarely interferes with the normal list
2362 : scheduler in cases where that scheduler would produce good code.
2363 : We simply want to curb some of its worst excesses. */
2364 :
2365 : /* Return the cost of increasing the pressure in class CL from FROM to TO.
2366 :
2367 : Here we use the very simplistic cost model that every register above
2368 : sched_class_regs_num[CL] has a spill cost of 1. We could use other
2369 : measures instead, such as one based on MEMORY_MOVE_COST. However:
2370 :
2371 : (1) In order for an instruction to be scheduled, the higher cost
2372 : would need to be justified in a single saving of that many stalls.
2373 : This is overly pessimistic, because the benefit of spilling is
2374 : often to avoid a sequence of several short stalls rather than
2375 : a single long one.
2376 :
2377 : (2) The cost is still arbitrary. Because we are not allocating
2378 : registers during scheduling, we have no way of knowing for
2379 : sure how many memory accesses will be required by each spill,
2380 : where the spills will be placed within the block, or even
2381 : which block(s) will contain the spills.
2382 :
2383 : So a higher cost than 1 is often too conservative in practice,
2384 : forcing blocks to contain unnecessary stalls instead of spill code.
2385 : The simple cost below seems to be the best compromise. It reduces
2386 : the interference with the normal list scheduler, which helps make
2387 : it more suitable for a default-on option. */
2388 :
2389 : static int
2390 0 : model_spill_cost (int cl, int from, int to)
2391 : {
2392 0 : from = MAX (from, sched_class_regs_num[cl]);
2393 0 : return MAX (to, from) - from;
2394 : }
2395 :
2396 : /* Return baseECC (ira_pressure_classes[PCI], POINT), given that
2397 : P = curr_reg_pressure[ira_pressure_classes[PCI]] and that
2398 : P' = P + DELTA. */
2399 :
2400 : static int
2401 0 : model_excess_group_cost (struct model_pressure_group *group,
2402 : int point, int pci, int delta)
2403 : {
2404 0 : int pressure, cl;
2405 :
2406 0 : cl = ira_pressure_classes[pci];
2407 0 : if (delta < 0)
2408 : {
2409 0 : if (point >= group->limits[pci].point)
2410 : {
2411 0 : pressure = MAX (group->limits[pci].orig_pressure,
2412 : curr_reg_pressure[cl] + delta);
2413 0 : return -model_spill_cost (cl, pressure, curr_reg_pressure[cl]);
2414 : }
2415 : /* if target prefers fewer spills, return the -ve delta indicating
2416 : pressure reduction. */
2417 0 : else if (!param_cycle_accurate_model)
2418 : return delta;
2419 : }
2420 :
2421 0 : if (delta > 0)
2422 : {
2423 0 : if (point > group->limits[pci].point)
2424 0 : pressure = group->limits[pci].pressure + delta;
2425 : else
2426 0 : pressure = curr_reg_pressure[cl] + delta;
2427 :
2428 0 : if (pressure > group->limits[pci].pressure)
2429 0 : return model_spill_cost (cl, group->limits[pci].orig_pressure,
2430 : pressure);
2431 : }
2432 :
2433 : return 0;
2434 : }
2435 :
2436 : /* Return baseECC (MODEL_INSN (INSN)). Dump the costs to sched_dump
2437 : if PRINT_P. */
2438 :
2439 : static int
2440 0 : model_excess_cost (rtx_insn *insn, bool print_p)
2441 : {
2442 0 : int point, pci, cl, cost, this_cost, delta;
2443 0 : struct reg_pressure_data *insn_reg_pressure;
2444 0 : int insn_death[N_REG_CLASSES];
2445 :
2446 0 : calculate_reg_deaths (insn, insn_death);
2447 0 : point = model_index (insn);
2448 0 : insn_reg_pressure = INSN_REG_PRESSURE (insn);
2449 0 : cost = 0;
2450 :
2451 0 : if (print_p)
2452 0 : fprintf (sched_dump, ";;\t\t| %3d %4d | %4d %+3d |", point,
2453 0 : INSN_UID (insn), INSN_PRIORITY (insn), insn_delay (insn));
2454 :
2455 : /* Sum up the individual costs for each register class. */
2456 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2457 : {
2458 0 : cl = ira_pressure_classes[pci];
2459 0 : delta = insn_reg_pressure[pci].set_increase - insn_death[cl];
2460 0 : this_cost = model_excess_group_cost (&model_before_pressure,
2461 : point, pci, delta);
2462 0 : cost += this_cost;
2463 0 : if (print_p)
2464 0 : fprintf (sched_dump, " %s:[%d base cost %d]",
2465 : reg_class_names[cl], delta, this_cost);
2466 : }
2467 :
2468 0 : if (print_p)
2469 0 : fprintf (sched_dump, " ECC %d\n", cost);
2470 :
2471 0 : return cost;
2472 : }
2473 :
2474 : /* Dump the next points of maximum pressure for GROUP. */
2475 :
2476 : static void
2477 0 : model_dump_pressure_points (struct model_pressure_group *group)
2478 : {
2479 0 : int pci, cl;
2480 :
2481 0 : fprintf (sched_dump, ";;\t\t| pressure points");
2482 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
2483 : {
2484 0 : cl = ira_pressure_classes[pci];
2485 0 : fprintf (sched_dump, " %s:[%d->%d at ", reg_class_names[cl],
2486 : curr_reg_pressure[cl], group->limits[pci].pressure);
2487 0 : if (group->limits[pci].point < model_num_insns)
2488 0 : fprintf (sched_dump, "%d:%d]", group->limits[pci].point,
2489 0 : INSN_UID (MODEL_INSN (group->limits[pci].point)));
2490 : else
2491 0 : fprintf (sched_dump, "end]");
2492 : }
2493 0 : fprintf (sched_dump, "\n");
2494 0 : }
2495 :
2496 : /* Set INSN_REG_PRESSURE_EXCESS_COST_CHANGE for INSNS[0...COUNT-1]. */
2497 :
2498 : static void
2499 0 : model_set_excess_costs (rtx_insn **insns, int count)
2500 : {
2501 0 : int i, cost, priority_base, priority;
2502 0 : bool print_p;
2503 :
2504 : /* Record the baseECC value for each instruction in the model schedule,
2505 : except that for targets which prefer wider schedules (more spills)
2506 : negative costs are converted to zero ones now rather than later.
2507 : Do not assign a cost to debug instructions, since they must
2508 : not change code-generation decisions. Experiments suggest we also
2509 : get better results by not assigning a cost to instructions from
2510 : a different block.
2511 :
2512 : Set PRIORITY_BASE to baseP in the block comment above. This is the
2513 : maximum priority of the "cheap" instructions, which should always
2514 : include the next model instruction. */
2515 0 : priority_base = 0;
2516 0 : print_p = false;
2517 0 : for (i = 0; i < count; i++)
2518 0 : if (INSN_MODEL_INDEX (insns[i]))
2519 : {
2520 0 : if (sched_verbose >= 6 && !print_p)
2521 : {
2522 0 : fprintf (sched_dump, MODEL_BAR);
2523 0 : fprintf (sched_dump, ";;\t\t| Pressure costs for ready queue\n");
2524 0 : model_dump_pressure_points (&model_before_pressure);
2525 0 : fprintf (sched_dump, MODEL_BAR);
2526 0 : print_p = true;
2527 : }
2528 0 : cost = model_excess_cost (insns[i], print_p);
2529 0 : if (param_cycle_accurate_model && cost <= 0)
2530 : {
2531 0 : priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]) - cost;
2532 0 : priority_base = MAX (priority_base, priority);
2533 : cost = 0;
2534 : }
2535 0 : INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = cost;
2536 : }
2537 0 : if (print_p)
2538 0 : fprintf (sched_dump, MODEL_BAR);
2539 :
2540 : /* Typically in-order cores have a good pipeline scheduling model and the
2541 : algorithm would try to use that to minimize bubbles, favoring spills.
2542 : MAX (baseECC, 0) below changes negative baseECC (pressure reduction)
2543 : to 0 (pressure neutral) thus tending to more spills.
2544 : Otherwise return. */
2545 0 : if (!param_cycle_accurate_model)
2546 : return;
2547 :
2548 : /* Use MAX (baseECC, 0) and baseP to calculcate ECC for each
2549 : instruction. */
2550 0 : for (i = 0; i < count; i++)
2551 : {
2552 0 : cost = INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]);
2553 0 : priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]);
2554 0 : if (cost > 0 && priority > priority_base)
2555 : {
2556 0 : cost += priority_base - priority;
2557 0 : INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = MAX (cost, 0);
2558 : }
2559 : }
2560 : }
2561 :
2562 :
2563 : /* Enum of rank_for_schedule heuristic decisions. */
2564 : enum rfs_decision {
2565 : RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2,
2566 : RFS_SCHED_GROUP, RFS_PRESSURE_DELAY, RFS_PRESSURE_TICK,
2567 : RFS_FEEDS_BACKTRACK_INSN, RFS_PRIORITY, RFS_AUTOPREF, RFS_SPECULATION,
2568 : RFS_SCHED_RANK, RFS_LAST_INSN, RFS_PRESSURE_INDEX,
2569 : RFS_DEP_COUNT, RFS_TIE, RFS_FUSION, RFS_COST, RFS_N };
2570 :
2571 : /* Corresponding strings for print outs. */
2572 : static const char *rfs_str[RFS_N] = {
2573 : "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2",
2574 : "RFS_SCHED_GROUP", "RFS_PRESSURE_DELAY", "RFS_PRESSURE_TICK",
2575 : "RFS_FEEDS_BACKTRACK_INSN", "RFS_PRIORITY", "RFS_AUTOPREF", "RFS_SPECULATION",
2576 : "RFS_SCHED_RANK", "RFS_LAST_INSN", "RFS_PRESSURE_INDEX",
2577 : "RFS_DEP_COUNT", "RFS_TIE", "RFS_FUSION", "RFS_COST" };
2578 :
2579 : /* Statistical breakdown of rank_for_schedule decisions. */
2580 : struct rank_for_schedule_stats_t { unsigned stats[RFS_N]; };
2581 : static rank_for_schedule_stats_t rank_for_schedule_stats;
2582 :
2583 : /* Return the result of comparing insns TMP and TMP2 and update
2584 : Rank_For_Schedule statistics. */
2585 : static int
2586 332525761 : rfs_result (enum rfs_decision decision, int result, rtx tmp, rtx tmp2)
2587 : {
2588 332525761 : ++rank_for_schedule_stats.stats[decision];
2589 332525761 : if (result < 0)
2590 182517124 : INSN_LAST_RFS_WIN (tmp) = decision;
2591 150008637 : else if (result > 0)
2592 150008637 : INSN_LAST_RFS_WIN (tmp2) = decision;
2593 : else
2594 0 : gcc_unreachable ();
2595 332525761 : return result;
2596 : }
2597 :
2598 : /* Sorting predicate to move DEBUG_INSNs to the top of ready list, while
2599 : keeping normal insns in original order. */
2600 :
2601 : static int
2602 387387286 : rank_for_schedule_debug (const void *x, const void *y)
2603 : {
2604 387387286 : rtx_insn *tmp = *(rtx_insn * const *) y;
2605 387387286 : rtx_insn *tmp2 = *(rtx_insn * const *) x;
2606 :
2607 : /* Schedule debug insns as early as possible. */
2608 387387286 : if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2))
2609 : return -1;
2610 242533067 : else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
2611 : return 1;
2612 180262378 : else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
2613 0 : return INSN_LUID (tmp) - INSN_LUID (tmp2);
2614 : else
2615 180262378 : return INSN_RFS_DEBUG_ORIG_ORDER (tmp2) - INSN_RFS_DEBUG_ORIG_ORDER (tmp);
2616 : }
2617 :
2618 : /* Returns a positive value if x is preferred; returns a negative value if
2619 : y is preferred. Should never return 0, since that will make the sort
2620 : unstable. */
2621 :
2622 : static int
2623 332525761 : rank_for_schedule (const void *x, const void *y)
2624 : {
2625 332525761 : rtx_insn *tmp = *(rtx_insn * const *) y;
2626 332525761 : rtx_insn *tmp2 = *(rtx_insn * const *) x;
2627 332525761 : int tmp_class, tmp2_class;
2628 332525761 : int val, priority_val, info_val, diff;
2629 :
2630 332525761 : if (live_range_shrinkage_p)
2631 : {
2632 : /* Don't use SCHED_PRESSURE_MODEL -- it results in much worse
2633 : code. */
2634 257525 : gcc_assert (sched_pressure == SCHED_PRESSURE_WEIGHTED);
2635 257525 : if ((INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp) < 0
2636 252167 : || INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2) < 0)
2637 257525 : && (diff = (INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp)
2638 9318 : - INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2))) != 0)
2639 9210 : return rfs_result (RFS_LIVE_RANGE_SHRINK1, diff, tmp, tmp2);
2640 : /* Sort by INSN_LUID (original insn order), so that we make the
2641 : sort stable. This minimizes instruction movement, thus
2642 : minimizing sched's effect on debugging and cross-jumping. */
2643 744945 : return rfs_result (RFS_LIVE_RANGE_SHRINK2,
2644 248315 : INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
2645 : }
2646 :
2647 : /* The insn in a schedule group should be issued the first. */
2648 332268236 : if (flag_sched_group_heuristic &&
2649 332268236 : SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
2650 225 : return rfs_result (RFS_SCHED_GROUP, SCHED_GROUP_P (tmp2) ? 1 : -1,
2651 158 : tmp, tmp2);
2652 :
2653 : /* Make sure that priority of TMP and TMP2 are initialized. */
2654 332268078 : gcc_assert (INSN_PRIORITY_KNOWN (tmp) && INSN_PRIORITY_KNOWN (tmp2));
2655 :
2656 332268078 : if (sched_fusion)
2657 : {
2658 : /* The instruction that has the same fusion priority as the last
2659 : instruction is the instruction we picked next. If that is not
2660 : the case, we sort ready list firstly by fusion priority, then
2661 : by priority, and at last by INSN_LUID. */
2662 0 : int a = INSN_FUSION_PRIORITY (tmp);
2663 0 : int b = INSN_FUSION_PRIORITY (tmp2);
2664 0 : int last = -1;
2665 :
2666 0 : if (last_nondebug_scheduled_insn
2667 0 : && !NOTE_P (last_nondebug_scheduled_insn)
2668 0 : && BLOCK_FOR_INSN (tmp)
2669 0 : == BLOCK_FOR_INSN (last_nondebug_scheduled_insn))
2670 0 : last = INSN_FUSION_PRIORITY (last_nondebug_scheduled_insn);
2671 :
2672 0 : if (a != last && b != last)
2673 : {
2674 0 : if (a == b)
2675 : {
2676 0 : a = INSN_PRIORITY (tmp);
2677 0 : b = INSN_PRIORITY (tmp2);
2678 : }
2679 0 : if (a != b)
2680 0 : return rfs_result (RFS_FUSION, b - a, tmp, tmp2);
2681 : else
2682 0 : return rfs_result (RFS_FUSION,
2683 0 : INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
2684 : }
2685 0 : else if (a == b)
2686 : {
2687 0 : gcc_assert (last_nondebug_scheduled_insn
2688 : && !NOTE_P (last_nondebug_scheduled_insn));
2689 0 : last = INSN_PRIORITY (last_nondebug_scheduled_insn);
2690 :
2691 0 : a = abs (INSN_PRIORITY (tmp) - last);
2692 0 : b = abs (INSN_PRIORITY (tmp2) - last);
2693 0 : if (a != b)
2694 0 : return rfs_result (RFS_FUSION, a - b, tmp, tmp2);
2695 : else
2696 0 : return rfs_result (RFS_FUSION,
2697 0 : INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
2698 : }
2699 0 : else if (a == last)
2700 0 : return rfs_result (RFS_FUSION, -1, tmp, tmp2);
2701 : else
2702 0 : return rfs_result (RFS_FUSION, 1, tmp, tmp2);
2703 : }
2704 :
2705 332268078 : if (sched_pressure != SCHED_PRESSURE_NONE)
2706 : {
2707 : /* Prefer insn whose scheduling results in the smallest register
2708 : pressure excess. */
2709 13661 : if ((diff = (INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp)
2710 13661 : + insn_delay (tmp)
2711 13661 : - INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2)
2712 13661 : - insn_delay (tmp2))))
2713 5021 : return rfs_result (RFS_PRESSURE_DELAY, diff, tmp, tmp2);
2714 : }
2715 :
2716 332263057 : if (sched_pressure != SCHED_PRESSURE_NONE
2717 8640 : && (INSN_TICK (tmp2) > clock_var || INSN_TICK (tmp) > clock_var)
2718 332264002 : && INSN_TICK (tmp2) != INSN_TICK (tmp))
2719 : {
2720 0 : diff = INSN_TICK (tmp) - INSN_TICK (tmp2);
2721 0 : return rfs_result (RFS_PRESSURE_TICK, diff, tmp, tmp2);
2722 : }
2723 :
2724 : /* If we are doing backtracking in this schedule, prefer insns that
2725 : have forward dependencies with negative cost against an insn that
2726 : was already scheduled. */
2727 332263057 : if (current_sched_info->flags & DO_BACKTRACKING)
2728 : {
2729 0 : priority_val = FEEDS_BACKTRACK_INSN (tmp2) - FEEDS_BACKTRACK_INSN (tmp);
2730 0 : if (priority_val)
2731 0 : return rfs_result (RFS_FEEDS_BACKTRACK_INSN, priority_val, tmp, tmp2);
2732 : }
2733 :
2734 : /* Prefer insn with higher priority. */
2735 332263057 : priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
2736 :
2737 332263057 : if (flag_sched_critical_path_heuristic && priority_val)
2738 88269008 : return rfs_result (RFS_PRIORITY, priority_val, tmp, tmp2);
2739 :
2740 243994049 : if (param_sched_autopref_queue_depth >= 0)
2741 : {
2742 12 : int autopref = autopref_rank_for_schedule (tmp, tmp2);
2743 12 : if (autopref != 0)
2744 12 : return rfs_result (RFS_AUTOPREF, autopref, tmp, tmp2);
2745 : }
2746 :
2747 : /* Prefer speculative insn with greater dependencies weakness. */
2748 243994037 : if (flag_sched_spec_insn_heuristic && spec_info)
2749 : {
2750 0 : ds_t ds1, ds2;
2751 0 : dw_t dw1, dw2;
2752 0 : int dw;
2753 :
2754 0 : ds1 = TODO_SPEC (tmp) & SPECULATIVE;
2755 0 : if (ds1)
2756 0 : dw1 = ds_weak (ds1);
2757 : else
2758 : dw1 = NO_DEP_WEAK;
2759 :
2760 0 : ds2 = TODO_SPEC (tmp2) & SPECULATIVE;
2761 0 : if (ds2)
2762 0 : dw2 = ds_weak (ds2);
2763 : else
2764 : dw2 = NO_DEP_WEAK;
2765 :
2766 0 : dw = dw2 - dw1;
2767 0 : if (dw > (NO_DEP_WEAK / 8) || dw < -(NO_DEP_WEAK / 8))
2768 0 : return rfs_result (RFS_SPECULATION, dw, tmp, tmp2);
2769 : }
2770 :
2771 243994037 : info_val = (*current_sched_info->rank) (tmp, tmp2);
2772 243994037 : if (flag_sched_rank_heuristic && info_val)
2773 0 : return rfs_result (RFS_SCHED_RANK, info_val, tmp, tmp2);
2774 :
2775 : /* Compare insns based on their relation to the last scheduled
2776 : non-debug insn. */
2777 243994037 : if (flag_sched_last_insn_heuristic && last_nondebug_scheduled_insn)
2778 : {
2779 217421101 : dep_t dep1;
2780 217421101 : dep_t dep2;
2781 217421101 : rtx_insn *last = last_nondebug_scheduled_insn;
2782 :
2783 : /* Classify the instructions into three classes:
2784 : 1) Data dependent on last schedule insn.
2785 : 2) Anti/Output dependent on last scheduled insn.
2786 : 3) Independent of last scheduled insn, or has latency of one.
2787 : Choose the insn from the highest numbered class if different. */
2788 217421101 : dep1 = sd_find_dep_between (last, tmp, true);
2789 :
2790 217421101 : if (dep1 == NULL || dep_cost (dep1) == 1)
2791 : tmp_class = 3;
2792 16284216 : else if (/* Data dependence. */
2793 16284216 : DEP_TYPE (dep1) == REG_DEP_TRUE)
2794 : tmp_class = 1;
2795 : else
2796 14769906 : tmp_class = 2;
2797 :
2798 217421101 : dep2 = sd_find_dep_between (last, tmp2, true);
2799 :
2800 217421101 : if (dep2 == NULL || dep_cost (dep2) == 1)
2801 : tmp2_class = 3;
2802 16636433 : else if (/* Data dependence. */
2803 16636433 : DEP_TYPE (dep2) == REG_DEP_TRUE)
2804 : tmp2_class = 1;
2805 : else
2806 14905129 : tmp2_class = 2;
2807 :
2808 217421101 : if ((val = tmp2_class - tmp_class))
2809 3329685 : return rfs_result (RFS_LAST_INSN, val, tmp, tmp2);
2810 : }
2811 :
2812 : /* Prefer instructions that occur earlier in the model schedule. */
2813 240664352 : if (sched_pressure == SCHED_PRESSURE_MODEL)
2814 : {
2815 0 : diff = model_index (tmp) - model_index (tmp2);
2816 0 : if (diff != 0)
2817 0 : return rfs_result (RFS_PRESSURE_INDEX, diff, tmp, tmp2);
2818 : }
2819 :
2820 : /* Prefer the insn which has more later insns that depend on it.
2821 : This gives the scheduler more freedom when scheduling later
2822 : instructions at the expense of added register pressure. */
2823 :
2824 240664352 : val = (dep_list_size (tmp2, SD_LIST_FORW)
2825 240664352 : - dep_list_size (tmp, SD_LIST_FORW));
2826 :
2827 240664352 : if (flag_sched_dep_count_heuristic && val != 0)
2828 28655100 : return rfs_result (RFS_DEP_COUNT, val, tmp, tmp2);
2829 :
2830 : /* Sort by INSN_COST rather than INSN_LUID. This means that instructions
2831 : which take longer to execute are prioritised and it leads to more
2832 : dual-issue opportunities on in-order cores which have this feature. */
2833 :
2834 212009252 : if (INSN_COST (tmp) != INSN_COST (tmp2))
2835 13078880 : return rfs_result (RFS_COST, INSN_COST (tmp2) - INSN_COST (tmp),
2836 13078880 : tmp, tmp2);
2837 :
2838 : /* If insns are equally good, sort by INSN_LUID (original insn order),
2839 : so that we make the sort stable. This minimizes instruction movement,
2840 : thus minimizing sched's effect on debugging and cross-jumping. */
2841 198930372 : return rfs_result (RFS_TIE, INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
2842 : }
2843 :
2844 : /* Resort the array A in which only element at index N may be out of order. */
2845 :
2846 : HAIFA_INLINE static void
2847 7903426 : swap_sort (rtx_insn **a, int n)
2848 : {
2849 7903426 : rtx_insn *insn = a[n - 1];
2850 7903426 : int i = n - 2;
2851 :
2852 10622981 : while (i >= 0 && rank_for_schedule (a + i, &insn) >= 0)
2853 : {
2854 2719555 : a[i + 1] = a[i];
2855 2719555 : i -= 1;
2856 : }
2857 7903426 : a[i + 1] = insn;
2858 7903426 : }
2859 :
2860 : /* Add INSN to the insn queue so that it can be executed at least
2861 : N_CYCLES after the currently executing insn. Preserve insns
2862 : chain for debugging purposes. REASON will be printed in debugging
2863 : output. */
2864 :
2865 : HAIFA_INLINE static void
2866 38783621 : queue_insn (rtx_insn *insn, int n_cycles, const char *reason)
2867 : {
2868 38783621 : int next_q = NEXT_Q_AFTER (q_ptr, n_cycles);
2869 38783621 : rtx_insn_list *link = alloc_INSN_LIST (insn, insn_queue[next_q]);
2870 38783621 : int new_tick;
2871 :
2872 38783621 : gcc_assert (n_cycles <= max_insn_queue_index);
2873 38783621 : gcc_assert (!DEBUG_INSN_P (insn));
2874 :
2875 38783621 : insn_queue[next_q] = link;
2876 38783621 : q_size += 1;
2877 :
2878 38783621 : if (sched_verbose >= 2)
2879 : {
2880 0 : fprintf (sched_dump, ";;\t\tReady-->Q: insn %s: ",
2881 0 : (*current_sched_info->print_insn) (insn, 0));
2882 :
2883 0 : fprintf (sched_dump, "queued for %d cycles (%s).\n", n_cycles, reason);
2884 : }
2885 :
2886 38783621 : QUEUE_INDEX (insn) = next_q;
2887 :
2888 38783621 : if (current_sched_info->flags & DO_BACKTRACKING)
2889 : {
2890 0 : new_tick = clock_var + n_cycles;
2891 0 : if (INSN_TICK (insn) == INVALID_TICK || INSN_TICK (insn) < new_tick)
2892 0 : INSN_TICK (insn) = new_tick;
2893 :
2894 0 : if (INSN_EXACT_TICK (insn) != INVALID_TICK
2895 0 : && INSN_EXACT_TICK (insn) < clock_var + n_cycles)
2896 : {
2897 0 : must_backtrack = true;
2898 0 : if (sched_verbose >= 2)
2899 0 : fprintf (sched_dump, ";;\t\tcausing a backtrack.\n");
2900 : }
2901 : }
2902 38783621 : }
2903 :
2904 : /* Remove INSN from queue. */
2905 : static void
2906 138267 : queue_remove (rtx_insn *insn)
2907 : {
2908 138267 : gcc_assert (QUEUE_INDEX (insn) >= 0);
2909 138267 : remove_free_INSN_LIST_elem (insn, &insn_queue[QUEUE_INDEX (insn)]);
2910 138267 : q_size--;
2911 138267 : QUEUE_INDEX (insn) = QUEUE_NOWHERE;
2912 138267 : }
2913 :
2914 : /* Return a pointer to the bottom of the ready list, i.e. the insn
2915 : with the lowest priority. */
2916 :
2917 : rtx_insn **
2918 143633490 : ready_lastpos (struct ready_list *ready)
2919 : {
2920 143633490 : gcc_assert (ready->n_ready >= 1);
2921 143633490 : return ready->vec + ready->first - ready->n_ready + 1;
2922 : }
2923 :
2924 : /* Add an element INSN to the ready list so that it ends up with the
2925 : lowest/highest priority depending on FIRST_P. */
2926 :
2927 : HAIFA_INLINE static void
2928 128130352 : ready_add (struct ready_list *ready, rtx_insn *insn, bool first_p)
2929 : {
2930 128130352 : if (!first_p)
2931 : {
2932 128128114 : if (ready->first == ready->n_ready)
2933 : {
2934 122 : memmove (ready->vec + ready->veclen - ready->n_ready,
2935 61 : ready_lastpos (ready),
2936 61 : ready->n_ready * sizeof (rtx));
2937 61 : ready->first = ready->veclen - 1;
2938 : }
2939 128128114 : ready->vec[ready->first - ready->n_ready] = insn;
2940 : }
2941 : else
2942 : {
2943 2238 : if (ready->first == ready->veclen - 1)
2944 : {
2945 950 : if (ready->n_ready)
2946 : /* ready_lastpos() fails when called with (ready->n_ready == 0). */
2947 0 : memmove (ready->vec + ready->veclen - ready->n_ready - 1,
2948 0 : ready_lastpos (ready),
2949 0 : ready->n_ready * sizeof (rtx));
2950 950 : ready->first = ready->veclen - 2;
2951 : }
2952 2238 : ready->vec[++(ready->first)] = insn;
2953 : }
2954 :
2955 128130352 : ready->n_ready++;
2956 128130352 : if (DEBUG_INSN_P (insn))
2957 48493730 : ready->n_debug++;
2958 :
2959 128130352 : gcc_assert (QUEUE_INDEX (insn) != QUEUE_READY);
2960 128130352 : QUEUE_INDEX (insn) = QUEUE_READY;
2961 :
2962 128130352 : if (INSN_EXACT_TICK (insn) != INVALID_TICK
2963 128130352 : && INSN_EXACT_TICK (insn) < clock_var)
2964 : {
2965 0 : must_backtrack = true;
2966 : }
2967 128130352 : }
2968 :
2969 : /* Remove the element with the highest priority from the ready list and
2970 : return it. */
2971 :
2972 : HAIFA_INLINE static rtx_insn *
2973 125930798 : ready_remove_first (struct ready_list *ready)
2974 : {
2975 125930798 : rtx_insn *t;
2976 :
2977 125930798 : gcc_assert (ready->n_ready);
2978 125930798 : t = ready->vec[ready->first--];
2979 125930798 : ready->n_ready--;
2980 125930798 : if (DEBUG_INSN_P (t))
2981 48493730 : ready->n_debug--;
2982 : /* If the queue becomes empty, reset it. */
2983 125930798 : if (ready->n_ready == 0)
2984 66060212 : ready->first = ready->veclen - 1;
2985 :
2986 125930798 : gcc_assert (QUEUE_INDEX (t) == QUEUE_READY);
2987 125930798 : QUEUE_INDEX (t) = QUEUE_NOWHERE;
2988 :
2989 125930798 : return t;
2990 : }
2991 :
2992 : /* The following code implements multi-pass scheduling for the first
2993 : cycle. In other words, we will try to choose ready insn which
2994 : permits to start maximum number of insns on the same cycle. */
2995 :
2996 : /* Return a pointer to the element INDEX from the ready. INDEX for
2997 : insn with the highest priority is 0, and the lowest priority has
2998 : N_READY - 1. */
2999 :
3000 : rtx_insn *
3001 1103979428 : ready_element (struct ready_list *ready, int index)
3002 : {
3003 1103979428 : gcc_assert (ready->n_ready && index < ready->n_ready);
3004 :
3005 1103979428 : return ready->vec[ready->first - index];
3006 : }
3007 :
3008 : /* Remove the element INDEX from the ready list and return it. INDEX
3009 : for insn with the highest priority is 0, and the lowest priority
3010 : has N_READY - 1. */
3011 :
3012 : HAIFA_INLINE static rtx_insn *
3013 72437967 : ready_remove (struct ready_list *ready, int index)
3014 : {
3015 72437967 : rtx_insn *t;
3016 72437967 : int i;
3017 :
3018 72437967 : if (index == 0)
3019 70238425 : return ready_remove_first (ready);
3020 2199542 : gcc_assert (ready->n_ready && index < ready->n_ready);
3021 2199542 : t = ready->vec[ready->first - index];
3022 2199542 : ready->n_ready--;
3023 2199542 : if (DEBUG_INSN_P (t))
3024 0 : ready->n_debug--;
3025 7271703 : for (i = index; i < ready->n_ready; i++)
3026 5072161 : ready->vec[ready->first - i] = ready->vec[ready->first - i - 1];
3027 2199542 : QUEUE_INDEX (t) = QUEUE_NOWHERE;
3028 2199542 : return t;
3029 : }
3030 :
3031 : /* Remove INSN from the ready list. */
3032 : static void
3033 0 : ready_remove_insn (rtx_insn *insn)
3034 : {
3035 0 : int i;
3036 :
3037 0 : for (i = 0; i < readyp->n_ready; i++)
3038 0 : if (ready_element (readyp, i) == insn)
3039 : {
3040 0 : ready_remove (readyp, i);
3041 0 : return;
3042 : }
3043 0 : gcc_unreachable ();
3044 : }
3045 :
3046 : /* Calculate difference of two statistics set WAS and NOW.
3047 : Result returned in WAS. */
3048 : static void
3049 0 : rank_for_schedule_stats_diff (rank_for_schedule_stats_t *was,
3050 : const rank_for_schedule_stats_t *now)
3051 : {
3052 0 : for (int i = 0; i < RFS_N; ++i)
3053 0 : was->stats[i] = now->stats[i] - was->stats[i];
3054 0 : }
3055 :
3056 : /* Print rank_for_schedule statistics. */
3057 : static void
3058 0 : print_rank_for_schedule_stats (const char *prefix,
3059 : const rank_for_schedule_stats_t *stats,
3060 : struct ready_list *ready)
3061 : {
3062 0 : for (int i = 0; i < RFS_N; ++i)
3063 0 : if (stats->stats[i])
3064 : {
3065 0 : fprintf (sched_dump, "%s%20s: %u", prefix, rfs_str[i], stats->stats[i]);
3066 :
3067 0 : if (ready != NULL)
3068 : /* Print out insns that won due to RFS_<I>. */
3069 : {
3070 0 : rtx_insn **p = ready_lastpos (ready);
3071 :
3072 0 : fprintf (sched_dump, ":");
3073 : /* Start with 1 since least-priority insn didn't have any wins. */
3074 0 : for (int j = 1; j < ready->n_ready; ++j)
3075 0 : if (INSN_LAST_RFS_WIN (p[j]) == i)
3076 0 : fprintf (sched_dump, " %s",
3077 0 : (*current_sched_info->print_insn) (p[j], 0));
3078 : }
3079 0 : fprintf (sched_dump, "\n");
3080 : }
3081 0 : }
3082 :
3083 : /* Separate DEBUG_INSNS from normal insns. DEBUG_INSNs go to the end
3084 : of array. */
3085 : static void
3086 48493734 : ready_sort_debug (struct ready_list *ready)
3087 : {
3088 48493734 : int i;
3089 48493734 : rtx_insn **first = ready_lastpos (ready);
3090 :
3091 204758389 : for (i = 0; i < ready->n_ready; ++i)
3092 107770921 : if (!DEBUG_INSN_P (first[i]))
3093 59277190 : INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i;
3094 :
3095 48493734 : qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug);
3096 48493734 : }
3097 :
3098 : /* Sort non-debug insns in the ready list READY by ascending priority.
3099 : Assumes that all debug insns are separated from the real insns. */
3100 : static void
3101 60206721 : ready_sort_real (struct ready_list *ready)
3102 : {
3103 60206721 : int i;
3104 60206721 : rtx_insn **first = ready_lastpos (ready);
3105 60206721 : int n_ready_real = ready->n_ready - ready->n_debug;
3106 :
3107 60206721 : if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
3108 28787 : for (i = 0; i < n_ready_real; ++i)
3109 23095 : setup_insn_reg_pressure_info (first[i]);
3110 60201029 : else if (sched_pressure == SCHED_PRESSURE_MODEL
3111 0 : && model_curr_point < model_num_insns)
3112 0 : model_set_excess_costs (first, n_ready_real);
3113 :
3114 60206721 : rank_for_schedule_stats_t stats1;
3115 60206721 : if (sched_verbose >= 4)
3116 0 : stats1 = rank_for_schedule_stats;
3117 :
3118 60206721 : if (n_ready_real == 2)
3119 7903426 : swap_sort (first, n_ready_real);
3120 52303295 : else if (n_ready_real > 2)
3121 7471245 : qsort (first, n_ready_real, sizeof (rtx), rank_for_schedule);
3122 :
3123 60206721 : if (sched_verbose >= 4)
3124 : {
3125 0 : rank_for_schedule_stats_diff (&stats1, &rank_for_schedule_stats);
3126 0 : print_rank_for_schedule_stats (";;\t\t", &stats1, ready);
3127 : }
3128 60206721 : }
3129 :
3130 : /* Sort the ready list READY by ascending priority. */
3131 : static void
3132 108700447 : ready_sort (struct ready_list *ready)
3133 : {
3134 108700447 : if (ready->n_debug > 0)
3135 48493730 : ready_sort_debug (ready);
3136 : else
3137 60206717 : ready_sort_real (ready);
3138 108700447 : }
3139 :
3140 : /* PREV is an insn that is ready to execute. Adjust its priority if that
3141 : will help shorten or lengthen register lifetimes as appropriate. Also
3142 : provide a hook for the target to tweak itself. */
3143 :
3144 : HAIFA_INLINE static void
3145 108621144 : adjust_priority (rtx_insn *prev)
3146 : {
3147 : /* ??? There used to be code here to try and estimate how an insn
3148 : affected register lifetimes, but it did it by looking at REG_DEAD
3149 : notes, which we removed in schedule_region. Nor did it try to
3150 : take into account register pressure or anything useful like that.
3151 :
3152 : Revisit when we have a machine model to work with and not before. */
3153 :
3154 108621144 : if (targetm.sched.adjust_priority)
3155 108621144 : INSN_PRIORITY (prev) =
3156 108621144 : targetm.sched.adjust_priority (prev, INSN_PRIORITY (prev));
3157 108621144 : }
3158 :
3159 : /* Advance DFA state STATE on one cycle. */
3160 : void
3161 45949227 : advance_state (state_t state)
3162 : {
3163 45949227 : if (targetm.sched.dfa_pre_advance_cycle)
3164 0 : targetm.sched.dfa_pre_advance_cycle ();
3165 :
3166 45949227 : if (targetm.sched.dfa_pre_cycle_insn)
3167 0 : state_transition (state,
3168 : targetm.sched.dfa_pre_cycle_insn ());
3169 :
3170 45949227 : state_transition (state, NULL);
3171 :
3172 45949227 : if (targetm.sched.dfa_post_cycle_insn)
3173 0 : state_transition (state,
3174 0 : targetm.sched.dfa_post_cycle_insn ());
3175 :
3176 45949227 : if (targetm.sched.dfa_post_advance_cycle)
3177 45774424 : targetm.sched.dfa_post_advance_cycle ();
3178 45949227 : }
3179 :
3180 : /* Advance time on one cycle. */
3181 : HAIFA_INLINE static void
3182 45944067 : advance_one_cycle (void)
3183 : {
3184 45944067 : int i;
3185 :
3186 45944067 : advance_state (curr_state);
3187 91888134 : for (i = 4; i <= sched_verbose; ++i)
3188 0 : fprintf (sched_dump, ";;\tAdvance the current state: %d.\n", clock_var);
3189 45944067 : }
3190 :
3191 : /* Update register pressure after scheduling INSN. */
3192 : static void
3193 22232 : update_register_pressure (rtx_insn *insn)
3194 : {
3195 22232 : struct reg_use_data *use;
3196 22232 : struct reg_set_data *set;
3197 :
3198 22232 : gcc_checking_assert (!DEBUG_INSN_P (insn));
3199 :
3200 43762 : for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
3201 21530 : if (dying_use_p (use))
3202 18383 : mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
3203 : use->regno, false);
3204 39466 : for (set = INSN_REG_SET_LIST (insn); set != NULL; set = set->next_insn_set)
3205 17234 : mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
3206 : set->regno, true);
3207 22232 : }
3208 :
3209 : /* Set up or update (if UPDATE_P) max register pressure (see its
3210 : meaning in sched-int.h::_haifa_insn_data) for all current BB insns
3211 : after insn AFTER. */
3212 : static void
3213 2579 : setup_insn_max_reg_pressure (rtx_insn *after, bool update_p)
3214 : {
3215 2579 : int i, p;
3216 2579 : bool eq_p;
3217 2579 : rtx_insn *insn;
3218 2579 : static int max_reg_pressure[N_REG_CLASSES];
3219 :
3220 2579 : save_reg_pressure ();
3221 15663 : for (i = 0; i < ira_pressure_classes_num; i++)
3222 10505 : max_reg_pressure[ira_pressure_classes[i]]
3223 10505 : = curr_reg_pressure[ira_pressure_classes[i]];
3224 24861 : for (insn = NEXT_INSN (after);
3225 24861 : insn != NULL_RTX && ! BARRIER_P (insn)
3226 49561 : && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (after);
3227 22282 : insn = NEXT_INSN (insn))
3228 23812 : if (NONDEBUG_INSN_P (insn))
3229 : {
3230 : eq_p = true;
3231 109172 : for (i = 0; i < ira_pressure_classes_num; i++)
3232 : {
3233 88718 : p = max_reg_pressure[ira_pressure_classes[i]];
3234 88718 : if (INSN_MAX_REG_PRESSURE (insn)[i] != p)
3235 : {
3236 21898 : eq_p = false;
3237 21898 : INSN_MAX_REG_PRESSURE (insn)[i]
3238 21898 : = max_reg_pressure[ira_pressure_classes[i]];
3239 : }
3240 : }
3241 20454 : if (update_p && eq_p)
3242 : break;
3243 18924 : update_register_pressure (insn);
3244 120341 : for (i = 0; i < ira_pressure_classes_num; i++)
3245 82493 : if (max_reg_pressure[ira_pressure_classes[i]]
3246 82493 : < curr_reg_pressure[ira_pressure_classes[i]])
3247 2883 : max_reg_pressure[ira_pressure_classes[i]]
3248 2883 : = curr_reg_pressure[ira_pressure_classes[i]];
3249 : }
3250 2579 : restore_reg_pressure ();
3251 2579 : }
3252 :
3253 : /* Update the current register pressure after scheduling INSN. Update
3254 : also max register pressure for unscheduled insns of the current
3255 : BB. */
3256 : static void
3257 3308 : update_reg_and_insn_max_reg_pressure (rtx_insn *insn)
3258 : {
3259 3308 : int i;
3260 3308 : int before[N_REG_CLASSES];
3261 :
3262 16829 : for (i = 0; i < ira_pressure_classes_num; i++)
3263 13521 : before[i] = curr_reg_pressure[ira_pressure_classes[i]];
3264 3308 : update_register_pressure (insn);
3265 11679 : for (i = 0; i < ira_pressure_classes_num; i++)
3266 7212 : if (curr_reg_pressure[ira_pressure_classes[i]] != before[i])
3267 : break;
3268 3308 : if (i < ira_pressure_classes_num)
3269 2149 : setup_insn_max_reg_pressure (insn, true);
3270 3308 : }
3271 :
3272 : /* Set up register pressure at the beginning of basic block BB whose
3273 : insns starting after insn AFTER. Set up also max register pressure
3274 : for all insns of the basic block. */
3275 : void
3276 430 : sched_setup_bb_reg_pressure_info (basic_block bb, rtx_insn *after)
3277 : {
3278 430 : gcc_assert (sched_pressure == SCHED_PRESSURE_WEIGHTED);
3279 430 : initiate_bb_reg_pressure_info (bb);
3280 430 : setup_insn_max_reg_pressure (after, false);
3281 430 : }
3282 :
3283 : /* If doing predication while scheduling, verify whether INSN, which
3284 : has just been scheduled, clobbers the conditions of any
3285 : instructions that must be predicated in order to break their
3286 : dependencies. If so, remove them from the queues so that they will
3287 : only be scheduled once their control dependency is resolved. */
3288 :
3289 : static void
3290 108621132 : check_clobbered_conditions (rtx_insn *insn)
3291 : {
3292 108621132 : HARD_REG_SET t;
3293 108621132 : int i;
3294 :
3295 108621132 : if ((current_sched_info->flags & DO_PREDICATION) == 0)
3296 108621132 : return;
3297 :
3298 0 : find_all_hard_reg_sets (insn, &t, true);
3299 :
3300 0 : restart:
3301 0 : for (i = 0; i < ready.n_ready; i++)
3302 : {
3303 0 : rtx_insn *x = ready_element (&ready, i);
3304 0 : if (TODO_SPEC (x) == DEP_CONTROL && cond_clobbered_p (x, t))
3305 : {
3306 0 : ready_remove_insn (x);
3307 0 : goto restart;
3308 : }
3309 : }
3310 0 : for (i = 0; i <= max_insn_queue_index; i++)
3311 : {
3312 0 : rtx_insn_list *link;
3313 0 : int q = NEXT_Q_AFTER (q_ptr, i);
3314 :
3315 0 : restart_queue:
3316 0 : for (link = insn_queue[q]; link; link = link->next ())
3317 : {
3318 0 : rtx_insn *x = link->insn ();
3319 0 : if (TODO_SPEC (x) == DEP_CONTROL && cond_clobbered_p (x, t))
3320 : {
3321 0 : queue_remove (x);
3322 0 : goto restart_queue;
3323 : }
3324 : }
3325 : }
3326 : }
3327 :
3328 : /* Return (in order):
3329 :
3330 : - positive if INSN adversely affects the pressure on one
3331 : register class
3332 :
3333 : - negative if INSN reduces the pressure on one register class
3334 :
3335 : - 0 if INSN doesn't affect the pressure on any register class. */
3336 :
3337 : static int
3338 0 : model_classify_pressure (struct model_insn_info *insn)
3339 : {
3340 0 : struct reg_pressure_data *reg_pressure;
3341 0 : int death[N_REG_CLASSES];
3342 0 : int pci, cl, sum;
3343 :
3344 0 : calculate_reg_deaths (insn->insn, death);
3345 0 : reg_pressure = INSN_REG_PRESSURE (insn->insn);
3346 0 : sum = 0;
3347 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
3348 : {
3349 0 : cl = ira_pressure_classes[pci];
3350 0 : if (death[cl] < reg_pressure[pci].set_increase)
3351 : return 1;
3352 0 : sum += reg_pressure[pci].set_increase - death[cl];
3353 : }
3354 : return sum;
3355 : }
3356 :
3357 : /* Return true if INSN1 should come before INSN2 in the model schedule. */
3358 :
3359 : static int
3360 0 : model_order_p (struct model_insn_info *insn1, struct model_insn_info *insn2)
3361 : {
3362 0 : unsigned int height1, height2;
3363 0 : unsigned int priority1, priority2;
3364 :
3365 : /* Prefer instructions with a higher model priority. */
3366 0 : if (insn1->model_priority != insn2->model_priority)
3367 0 : return insn1->model_priority > insn2->model_priority;
3368 :
3369 : /* Combine the length of the longest path of satisfied true dependencies
3370 : that leads to each instruction (depth) with the length of the longest
3371 : path of any dependencies that leads from the instruction (alap).
3372 : Prefer instructions with the greatest combined length. If the combined
3373 : lengths are equal, prefer instructions with the greatest depth.
3374 :
3375 : The idea is that, if we have a set S of "equal" instructions that each
3376 : have ALAP value X, and we pick one such instruction I, any true-dependent
3377 : successors of I that have ALAP value X - 1 should be preferred over S.
3378 : This encourages the schedule to be "narrow" rather than "wide".
3379 : However, if I is a low-priority instruction that we decided to
3380 : schedule because of its model_classify_pressure, and if there
3381 : is a set of higher-priority instructions T, the aforementioned
3382 : successors of I should not have the edge over T. */
3383 0 : height1 = insn1->depth + insn1->alap;
3384 0 : height2 = insn2->depth + insn2->alap;
3385 0 : if (height1 != height2)
3386 0 : return height1 > height2;
3387 0 : if (insn1->depth != insn2->depth)
3388 0 : return insn1->depth > insn2->depth;
3389 :
3390 : /* We have no real preference between INSN1 an INSN2 as far as attempts
3391 : to reduce pressure go. Prefer instructions with higher priorities. */
3392 0 : priority1 = INSN_PRIORITY (insn1->insn);
3393 0 : priority2 = INSN_PRIORITY (insn2->insn);
3394 0 : if (priority1 != priority2)
3395 0 : return priority1 > priority2;
3396 :
3397 : /* Use the original rtl sequence as a tie-breaker. */
3398 0 : return insn1 < insn2;
3399 : }
3400 :
3401 : /* Add INSN to the model worklist immediately after PREV. Add it to the
3402 : beginning of the list if PREV is null. */
3403 :
3404 : static void
3405 0 : model_add_to_worklist_at (struct model_insn_info *insn,
3406 : struct model_insn_info *prev)
3407 : {
3408 0 : gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_NOWHERE);
3409 0 : QUEUE_INDEX (insn->insn) = QUEUE_READY;
3410 :
3411 0 : insn->prev = prev;
3412 0 : if (prev)
3413 : {
3414 0 : insn->next = prev->next;
3415 0 : prev->next = insn;
3416 : }
3417 : else
3418 : {
3419 0 : insn->next = model_worklist;
3420 0 : model_worklist = insn;
3421 : }
3422 0 : if (insn->next)
3423 0 : insn->next->prev = insn;
3424 0 : }
3425 :
3426 : /* Remove INSN from the model worklist. */
3427 :
3428 : static void
3429 0 : model_remove_from_worklist (struct model_insn_info *insn)
3430 : {
3431 0 : gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_READY);
3432 0 : QUEUE_INDEX (insn->insn) = QUEUE_NOWHERE;
3433 :
3434 0 : if (insn->prev)
3435 0 : insn->prev->next = insn->next;
3436 : else
3437 0 : model_worklist = insn->next;
3438 0 : if (insn->next)
3439 0 : insn->next->prev = insn->prev;
3440 0 : }
3441 :
3442 : /* Add INSN to the model worklist. Start looking for a suitable position
3443 : between neighbors PREV and NEXT, testing at most param_max_sched_ready_insns
3444 : insns either side. A null PREV indicates the beginning of the list and
3445 : a null NEXT indicates the end. */
3446 :
3447 : static void
3448 0 : model_add_to_worklist (struct model_insn_info *insn,
3449 : struct model_insn_info *prev,
3450 : struct model_insn_info *next)
3451 : {
3452 0 : int count;
3453 :
3454 0 : count = param_max_sched_ready_insns;
3455 0 : if (count > 0 && prev && model_order_p (insn, prev))
3456 0 : do
3457 : {
3458 0 : count--;
3459 0 : prev = prev->prev;
3460 : }
3461 0 : while (count > 0 && prev && model_order_p (insn, prev));
3462 : else
3463 0 : while (count > 0 && next && model_order_p (next, insn))
3464 : {
3465 0 : count--;
3466 0 : prev = next;
3467 0 : next = next->next;
3468 : }
3469 0 : model_add_to_worklist_at (insn, prev);
3470 0 : }
3471 :
3472 : /* INSN may now have a higher priority (in the model_order_p sense)
3473 : than before. Move it up the worklist if necessary. */
3474 :
3475 : static void
3476 0 : model_promote_insn (struct model_insn_info *insn)
3477 : {
3478 0 : struct model_insn_info *prev;
3479 0 : int count;
3480 :
3481 0 : prev = insn->prev;
3482 0 : count = param_max_sched_ready_insns;
3483 0 : while (count > 0 && prev && model_order_p (insn, prev))
3484 : {
3485 0 : count--;
3486 0 : prev = prev->prev;
3487 : }
3488 0 : if (prev != insn->prev)
3489 : {
3490 0 : model_remove_from_worklist (insn);
3491 0 : model_add_to_worklist_at (insn, prev);
3492 : }
3493 0 : }
3494 :
3495 : /* Add INSN to the end of the model schedule. */
3496 :
3497 : static void
3498 0 : model_add_to_schedule (rtx_insn *insn)
3499 : {
3500 0 : unsigned int point;
3501 :
3502 0 : gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
3503 0 : QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
3504 :
3505 0 : point = model_schedule.length ();
3506 0 : model_schedule.quick_push (insn);
3507 0 : INSN_MODEL_INDEX (insn) = point + 1;
3508 0 : }
3509 :
3510 : /* Analyze the instructions that are to be scheduled, setting up
3511 : MODEL_INSN_INFO (...) and model_num_insns accordingly. Add ready
3512 : instructions to model_worklist. */
3513 :
3514 : static void
3515 0 : model_analyze_insns (void)
3516 : {
3517 0 : rtx_insn *start, *end, *iter;
3518 0 : sd_iterator_def sd_it;
3519 0 : dep_t dep;
3520 0 : struct model_insn_info *insn, *con;
3521 :
3522 0 : model_num_insns = 0;
3523 0 : start = PREV_INSN (current_sched_info->next_tail);
3524 0 : end = current_sched_info->prev_head;
3525 0 : for (iter = start; iter != end; iter = PREV_INSN (iter))
3526 0 : if (NONDEBUG_INSN_P (iter))
3527 : {
3528 0 : insn = MODEL_INSN_INFO (iter);
3529 0 : insn->insn = iter;
3530 0 : FOR_EACH_DEP (iter, SD_LIST_FORW, sd_it, dep)
3531 : {
3532 0 : con = MODEL_INSN_INFO (DEP_CON (dep));
3533 0 : if (con->insn && insn->alap < con->alap + 1)
3534 0 : insn->alap = con->alap + 1;
3535 : }
3536 :
3537 0 : insn->old_queue = QUEUE_INDEX (iter);
3538 0 : QUEUE_INDEX (iter) = QUEUE_NOWHERE;
3539 :
3540 0 : insn->unscheduled_preds = dep_list_size (iter, SD_LIST_HARD_BACK);
3541 0 : if (insn->unscheduled_preds == 0)
3542 0 : model_add_to_worklist (insn, NULL, model_worklist);
3543 :
3544 0 : model_num_insns++;
3545 : }
3546 0 : }
3547 :
3548 : /* The global state describes the register pressure at the start of the
3549 : model schedule. Initialize GROUP accordingly. */
3550 :
3551 : static void
3552 0 : model_init_pressure_group (struct model_pressure_group *group)
3553 : {
3554 0 : int pci, cl;
3555 :
3556 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
3557 : {
3558 0 : cl = ira_pressure_classes[pci];
3559 0 : group->limits[pci].pressure = curr_reg_pressure[cl];
3560 0 : group->limits[pci].point = 0;
3561 : }
3562 : /* Use index model_num_insns to record the state after the last
3563 : instruction in the model schedule. */
3564 0 : group->model = XNEWVEC (struct model_pressure_data,
3565 : (model_num_insns + 1) * ira_pressure_classes_num);
3566 0 : }
3567 :
3568 : /* Record that MODEL_REF_PRESSURE (GROUP, POINT, PCI) is PRESSURE.
3569 : Update the maximum pressure for the whole schedule. */
3570 :
3571 : static void
3572 0 : model_record_pressure (struct model_pressure_group *group,
3573 : int point, int pci, int pressure)
3574 : {
3575 0 : MODEL_REF_PRESSURE (group, point, pci) = pressure;
3576 0 : if (group->limits[pci].pressure < pressure)
3577 : {
3578 0 : group->limits[pci].pressure = pressure;
3579 0 : group->limits[pci].point = point;
3580 : }
3581 0 : }
3582 :
3583 : /* INSN has just been added to the end of the model schedule. Record its
3584 : register-pressure information. */
3585 :
3586 : static void
3587 0 : model_record_pressures (struct model_insn_info *insn)
3588 : {
3589 0 : struct reg_pressure_data *reg_pressure;
3590 0 : int point, pci, cl, delta;
3591 0 : int death[N_REG_CLASSES];
3592 :
3593 0 : point = model_index (insn->insn);
3594 0 : if (sched_verbose >= 2)
3595 : {
3596 0 : if (point == 0)
3597 : {
3598 0 : fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n");
3599 0 : fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n");
3600 : }
3601 0 : fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ",
3602 : point, INSN_UID (insn->insn), insn->model_priority,
3603 0 : insn->depth + insn->alap, insn->depth,
3604 0 : INSN_PRIORITY (insn->insn),
3605 0 : str_pattern_slim (PATTERN (insn->insn)));
3606 : }
3607 0 : calculate_reg_deaths (insn->insn, death);
3608 0 : reg_pressure = INSN_REG_PRESSURE (insn->insn);
3609 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
3610 : {
3611 0 : cl = ira_pressure_classes[pci];
3612 0 : delta = reg_pressure[pci].set_increase - death[cl];
3613 0 : if (sched_verbose >= 2)
3614 0 : fprintf (sched_dump, " %s:[%d,%+d]", reg_class_names[cl],
3615 : curr_reg_pressure[cl], delta);
3616 0 : model_record_pressure (&model_before_pressure, point, pci,
3617 : curr_reg_pressure[cl]);
3618 : }
3619 0 : if (sched_verbose >= 2)
3620 0 : fprintf (sched_dump, "\n");
3621 0 : }
3622 :
3623 : /* All instructions have been added to the model schedule. Record the
3624 : final register pressure in GROUP and set up all MODEL_MAX_PRESSUREs. */
3625 :
3626 : static void
3627 0 : model_record_final_pressures (struct model_pressure_group *group)
3628 : {
3629 0 : int point, pci, max_pressure, ref_pressure, cl;
3630 :
3631 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
3632 : {
3633 : /* Record the final pressure for this class. */
3634 0 : cl = ira_pressure_classes[pci];
3635 0 : point = model_num_insns;
3636 0 : ref_pressure = curr_reg_pressure[cl];
3637 0 : model_record_pressure (group, point, pci, ref_pressure);
3638 :
3639 : /* Record the original maximum pressure. */
3640 0 : group->limits[pci].orig_pressure = group->limits[pci].pressure;
3641 :
3642 : /* Update the MODEL_MAX_PRESSURE for every point of the schedule. */
3643 0 : max_pressure = ref_pressure;
3644 0 : MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
3645 0 : while (point > 0)
3646 : {
3647 0 : point--;
3648 0 : ref_pressure = MODEL_REF_PRESSURE (group, point, pci);
3649 0 : max_pressure = MAX (max_pressure, ref_pressure);
3650 0 : MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
3651 : }
3652 : }
3653 0 : }
3654 :
3655 : /* Update all successors of INSN, given that INSN has just been scheduled. */
3656 :
3657 : static void
3658 0 : model_add_successors_to_worklist (struct model_insn_info *insn)
3659 : {
3660 0 : sd_iterator_def sd_it;
3661 0 : struct model_insn_info *con;
3662 0 : dep_t dep;
3663 :
3664 0 : FOR_EACH_DEP (insn->insn, SD_LIST_FORW, sd_it, dep)
3665 : {
3666 0 : con = MODEL_INSN_INFO (DEP_CON (dep));
3667 : /* Ignore debug instructions, and instructions from other blocks. */
3668 0 : if (con->insn)
3669 : {
3670 0 : con->unscheduled_preds--;
3671 :
3672 : /* Update the depth field of each true-dependent successor.
3673 : Increasing the depth gives them a higher priority than
3674 : before. */
3675 0 : if (DEP_TYPE (dep) == REG_DEP_TRUE && con->depth < insn->depth + 1)
3676 : {
3677 0 : con->depth = insn->depth + 1;
3678 0 : if (QUEUE_INDEX (con->insn) == QUEUE_READY)
3679 0 : model_promote_insn (con);
3680 : }
3681 :
3682 : /* If this is a true dependency, or if there are no remaining
3683 : dependencies for CON (meaning that CON only had non-true
3684 : dependencies), make sure that CON is on the worklist.
3685 : We don't bother otherwise because it would tend to fill the
3686 : worklist with a lot of low-priority instructions that are not
3687 : yet ready to issue. */
3688 0 : if ((con->depth > 0 || con->unscheduled_preds == 0)
3689 0 : && QUEUE_INDEX (con->insn) == QUEUE_NOWHERE)
3690 0 : model_add_to_worklist (con, insn, insn->next);
3691 : }
3692 : }
3693 0 : }
3694 :
3695 : /* Give INSN a higher priority than any current instruction, then give
3696 : unscheduled predecessors of INSN a higher priority still. If any of
3697 : those predecessors are not on the model worklist, do the same for its
3698 : predecessors, and so on. */
3699 :
3700 : static void
3701 0 : model_promote_predecessors (struct model_insn_info *insn)
3702 : {
3703 0 : struct model_insn_info *pro, *first;
3704 0 : sd_iterator_def sd_it;
3705 0 : dep_t dep;
3706 :
3707 0 : if (sched_verbose >= 7)
3708 0 : fprintf (sched_dump, ";;\t+--- priority of %d = %d, priority of",
3709 0 : INSN_UID (insn->insn), model_next_priority);
3710 0 : insn->model_priority = model_next_priority++;
3711 0 : model_remove_from_worklist (insn);
3712 0 : model_add_to_worklist_at (insn, NULL);
3713 :
3714 0 : first = NULL;
3715 0 : for (;;)
3716 : {
3717 0 : FOR_EACH_DEP (insn->insn, SD_LIST_HARD_BACK, sd_it, dep)
3718 : {
3719 0 : pro = MODEL_INSN_INFO (DEP_PRO (dep));
3720 : /* The first test is to ignore debug instructions, and instructions
3721 : from other blocks. */
3722 0 : if (pro->insn
3723 0 : && pro->model_priority != model_next_priority
3724 0 : && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
3725 : {
3726 0 : pro->model_priority = model_next_priority;
3727 0 : if (sched_verbose >= 7)
3728 0 : fprintf (sched_dump, " %d", INSN_UID (pro->insn));
3729 0 : if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
3730 : {
3731 : /* PRO is already in the worklist, but it now has
3732 : a higher priority than before. Move it at the
3733 : appropriate place. */
3734 0 : model_remove_from_worklist (pro);
3735 0 : model_add_to_worklist (pro, NULL, model_worklist);
3736 : }
3737 : else
3738 : {
3739 : /* PRO isn't in the worklist. Recursively process
3740 : its predecessors until we find one that is. */
3741 0 : pro->next = first;
3742 0 : first = pro;
3743 : }
3744 : }
3745 : }
3746 0 : if (!first)
3747 : break;
3748 0 : insn = first;
3749 0 : first = insn->next;
3750 : }
3751 0 : if (sched_verbose >= 7)
3752 0 : fprintf (sched_dump, " = %d\n", model_next_priority);
3753 0 : model_next_priority++;
3754 0 : }
3755 :
3756 : /* Pick one instruction from model_worklist and process it. */
3757 :
3758 : static void
3759 0 : model_choose_insn (void)
3760 : {
3761 0 : struct model_insn_info *insn, *fallback;
3762 0 : int count;
3763 :
3764 0 : if (sched_verbose >= 7)
3765 : {
3766 0 : fprintf (sched_dump, ";;\t+--- worklist:\n");
3767 0 : insn = model_worklist;
3768 0 : count = param_max_sched_ready_insns;
3769 0 : while (count > 0 && insn)
3770 : {
3771 0 : fprintf (sched_dump, ";;\t+--- %d [%d, %d, %d, %d][%d]\n",
3772 : INSN_UID (insn->insn), insn->model_priority,
3773 0 : insn->depth + insn->alap, insn->depth,
3774 0 : INSN_PRIORITY (insn->insn), insn->unscheduled_preds);
3775 0 : count--;
3776 0 : insn = insn->next;
3777 : }
3778 : }
3779 :
3780 : /* Look for a ready instruction whose model_classify_priority is zero
3781 : or negative, picking the highest-priority one. Adding such an
3782 : instruction to the schedule now should do no harm, and may actually
3783 : do some good.
3784 :
3785 : Failing that, see whether there is an instruction with the highest
3786 : extant model_priority that is not yet ready, but which would reduce
3787 : pressure if it became ready. This is designed to catch cases like:
3788 :
3789 : (set (mem (reg R1)) (reg R2))
3790 :
3791 : where the instruction is the last remaining use of R1 and where the
3792 : value of R2 is not yet available (or vice versa). The death of R1
3793 : means that this instruction already reduces pressure. It is of
3794 : course possible that the computation of R2 involves other registers
3795 : that are hard to kill, but such cases are rare enough for this
3796 : heuristic to be a win in general.
3797 :
3798 : Failing that, just pick the highest-priority instruction in the
3799 : worklist. */
3800 0 : count = param_max_sched_ready_insns;
3801 0 : insn = model_worklist;
3802 0 : fallback = 0;
3803 0 : for (;;)
3804 : {
3805 0 : if (count == 0 || !insn)
3806 : {
3807 0 : insn = fallback ? fallback : model_worklist;
3808 : break;
3809 : }
3810 0 : if (insn->unscheduled_preds)
3811 : {
3812 0 : if (model_worklist->model_priority == insn->model_priority
3813 0 : && !fallback
3814 0 : && model_classify_pressure (insn) < 0)
3815 : fallback = insn;
3816 : }
3817 : else
3818 : {
3819 0 : if (model_classify_pressure (insn) <= 0)
3820 : break;
3821 : }
3822 0 : count--;
3823 0 : insn = insn->next;
3824 : }
3825 :
3826 0 : if (sched_verbose >= 7 && insn != model_worklist)
3827 : {
3828 0 : if (insn->unscheduled_preds)
3829 0 : fprintf (sched_dump, ";;\t+--- promoting insn %d, with dependencies\n",
3830 0 : INSN_UID (insn->insn));
3831 : else
3832 0 : fprintf (sched_dump, ";;\t+--- promoting insn %d, which is ready\n",
3833 0 : INSN_UID (insn->insn));
3834 : }
3835 0 : if (insn->unscheduled_preds)
3836 : /* INSN isn't yet ready to issue. Give all its predecessors the
3837 : highest priority. */
3838 0 : model_promote_predecessors (insn);
3839 : else
3840 : {
3841 : /* INSN is ready. Add it to the end of model_schedule and
3842 : process its successors. */
3843 0 : model_add_successors_to_worklist (insn);
3844 0 : model_remove_from_worklist (insn);
3845 0 : model_add_to_schedule (insn->insn);
3846 0 : model_record_pressures (insn);
3847 0 : update_register_pressure (insn->insn);
3848 : }
3849 0 : }
3850 :
3851 : /* Restore all QUEUE_INDEXs to the values that they had before
3852 : model_start_schedule was called. */
3853 :
3854 : static void
3855 0 : model_reset_queue_indices (void)
3856 : {
3857 0 : unsigned int i;
3858 0 : rtx_insn *insn;
3859 :
3860 0 : FOR_EACH_VEC_ELT (model_schedule, i, insn)
3861 0 : QUEUE_INDEX (insn) = MODEL_INSN_INFO (insn)->old_queue;
3862 0 : }
3863 :
3864 : /* We have calculated the model schedule and spill costs. Print a summary
3865 : to sched_dump. */
3866 :
3867 : static void
3868 0 : model_dump_pressure_summary (basic_block bb)
3869 : {
3870 0 : int pci, cl;
3871 :
3872 0 : fprintf (sched_dump, ";; Pressure summary (bb %d):", bb->index);
3873 0 : for (pci = 0; pci < ira_pressure_classes_num; pci++)
3874 : {
3875 0 : cl = ira_pressure_classes[pci];
3876 0 : fprintf (sched_dump, " %s:%d", reg_class_names[cl],
3877 : model_before_pressure.limits[pci].pressure);
3878 : }
3879 0 : fprintf (sched_dump, "\n\n");
3880 0 : }
3881 :
3882 : /* Initialize the SCHED_PRESSURE_MODEL information for the current
3883 : scheduling region. */
3884 :
3885 : static void
3886 0 : model_start_schedule (basic_block bb)
3887 : {
3888 0 : model_next_priority = 1;
3889 0 : model_schedule.create (sched_max_luid);
3890 0 : model_insns = XCNEWVEC (struct model_insn_info, sched_max_luid);
3891 :
3892 0 : gcc_assert (bb == BLOCK_FOR_INSN (NEXT_INSN (current_sched_info->prev_head)));
3893 0 : initiate_reg_pressure_info (df_get_live_in (bb));
3894 :
3895 0 : model_analyze_insns ();
3896 0 : model_init_pressure_group (&model_before_pressure);
3897 0 : while (model_worklist)
3898 0 : model_choose_insn ();
3899 0 : gcc_assert (model_num_insns == (int) model_schedule.length ());
3900 0 : if (sched_verbose >= 2)
3901 0 : fprintf (sched_dump, "\n");
3902 :
3903 0 : model_record_final_pressures (&model_before_pressure);
3904 0 : model_reset_queue_indices ();
3905 :
3906 0 : XDELETEVEC (model_insns);
3907 :
3908 0 : model_curr_point = 0;
3909 0 : initiate_reg_pressure_info (df_get_live_in (bb));
3910 0 : if (sched_verbose >= 1)
3911 0 : model_dump_pressure_summary (bb);
3912 0 : }
3913 :
3914 : /* Free the information associated with GROUP. */
3915 :
3916 : static void
3917 0 : model_finalize_pressure_group (struct model_pressure_group *group)
3918 : {
3919 0 : XDELETEVEC (group->model);
3920 0 : }
3921 :
3922 : /* Free the information created by model_start_schedule. */
3923 :
3924 : static void
3925 0 : model_end_schedule (void)
3926 : {
3927 0 : model_finalize_pressure_group (&model_before_pressure);
3928 0 : model_schedule.release ();
3929 0 : }
3930 :
3931 : /* Prepare reg pressure scheduling for basic block BB. */
3932 : static void
3933 430 : sched_pressure_start_bb (basic_block bb)
3934 : {
3935 : /* Set the number of available registers for each class taking into account
3936 : relative probability of current basic block versus function prologue and
3937 : epilogue.
3938 : * If the basic block executes much more often than the prologue/epilogue
3939 : (e.g., inside a hot loop), then cost of spill in the prologue is close to
3940 : nil, so the effective number of available registers is
3941 : (ira_class_hard_regs_num[cl] - fixed_regs_num[cl] - 0).
3942 : * If the basic block executes as often as the prologue/epilogue,
3943 : then spill in the block is as costly as in the prologue, so the effective
3944 : number of available registers is
3945 : (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
3946 : - call_saved_regs_num[cl]).
3947 : Note that all-else-equal, we prefer to spill in the prologue, since that
3948 : allows "extra" registers for other basic blocks of the function.
3949 : * If the basic block is on the cold path of the function and executes
3950 : rarely, then we should always prefer to spill in the block, rather than
3951 : in the prologue/epilogue. The effective number of available register is
3952 : (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
3953 : - call_saved_regs_num[cl]). */
3954 430 : {
3955 430 : int i;
3956 430 : int entry_freq = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun);
3957 430 : int bb_freq = bb->count.to_frequency (cfun);
3958 :
3959 430 : if (bb_freq == 0)
3960 : {
3961 8 : if (entry_freq == 0)
3962 : entry_freq = bb_freq = 1;
3963 : }
3964 430 : if (bb_freq < entry_freq)
3965 : bb_freq = entry_freq;
3966 :
3967 2154 : for (i = 0; i < ira_pressure_classes_num; ++i)
3968 : {
3969 1724 : enum reg_class cl = ira_pressure_classes[i];
3970 1724 : sched_class_regs_num[cl] = ira_class_hard_regs_num[cl]
3971 1724 : - fixed_regs_num[cl];
3972 1724 : sched_class_regs_num[cl]
3973 1724 : -= (call_saved_regs_num[cl] * entry_freq) / bb_freq;
3974 : }
3975 : }
3976 :
3977 430 : if (sched_pressure == SCHED_PRESSURE_MODEL)
3978 0 : model_start_schedule (bb);
3979 430 : }
3980 :
3981 : /* A structure that holds local state for the loop in schedule_block. */
3982 : struct sched_block_state
3983 : {
3984 : /* True if no real insns have been scheduled in the current cycle. */
3985 : bool first_cycle_insn_p;
3986 : /* True if a shadow insn has been scheduled in the current cycle, which
3987 : means that no more normal insns can be issued. */
3988 : bool shadows_only_p;
3989 : /* True if we're winding down a modulo schedule, which means that we only
3990 : issue insns with INSN_EXACT_TICK set. */
3991 : bool modulo_epilogue;
3992 : /* Initialized with the machine's issue rate every cycle, and updated
3993 : by calls to the variable_issue hook. */
3994 : int can_issue_more;
3995 : };
3996 :
3997 : /* INSN is the "currently executing insn". Launch each insn which was
3998 : waiting on INSN. READY is the ready list which contains the insns
3999 : that are ready to fire. CLOCK is the current cycle. The function
4000 : returns necessary cycle advance after issuing the insn (it is not
4001 : zero for insns in a schedule group). */
4002 :
4003 : static int
4004 108621132 : schedule_insn (rtx_insn *insn)
4005 : {
4006 108621132 : sd_iterator_def sd_it;
4007 108621132 : dep_t dep;
4008 108621132 : int i;
4009 108621132 : int advance = 0;
4010 :
4011 108621132 : if (sched_verbose >= 1)
4012 : {
4013 1004 : struct reg_pressure_data *pressure_info;
4014 1004 : fprintf (sched_dump, ";;\t%3i--> %s %-40s:",
4015 1004 : clock_var, (*current_sched_info->print_insn) (insn, 1),
4016 1004 : str_pattern_slim (PATTERN (insn)));
4017 :
4018 1004 : if (recog_memoized (insn) < 0)
4019 134 : fprintf (sched_dump, "nothing");
4020 : else
4021 870 : print_reservation (sched_dump, insn);
4022 1004 : pressure_info = INSN_REG_PRESSURE (insn);
4023 1004 : if (pressure_info != NULL)
4024 : {
4025 0 : fputc (':', sched_dump);
4026 0 : for (i = 0; i < ira_pressure_classes_num; i++)
4027 0 : fprintf (sched_dump, "%s%s%+d(%d)",
4028 0 : scheduled_insns.length () > 1
4029 0 : && INSN_LUID (insn)
4030 0 : < INSN_LUID (scheduled_insns[scheduled_insns.length () - 2]) ? "@" : "",
4031 0 : reg_class_names[ira_pressure_classes[i]],
4032 0 : pressure_info[i].set_increase, pressure_info[i].change);
4033 : }
4034 1004 : if (sched_pressure == SCHED_PRESSURE_MODEL
4035 0 : && model_curr_point < model_num_insns
4036 1004 : && model_index (insn) == model_curr_point)
4037 0 : fprintf (sched_dump, ":model %d", model_curr_point);
4038 1004 : fputc ('\n', sched_dump);
4039 : }
4040 :
4041 108621132 : if (sched_pressure == SCHED_PRESSURE_WEIGHTED && !DEBUG_INSN_P (insn))
4042 3308 : update_reg_and_insn_max_reg_pressure (insn);
4043 :
4044 : /* Scheduling instruction should have all its dependencies resolved and
4045 : should have been removed from the ready list. */
4046 108621132 : gcc_assert (sd_lists_empty_p (insn, SD_LIST_HARD_BACK));
4047 :
4048 : /* Reset debug insns invalidated by moving this insn. */
4049 108621132 : if (MAY_HAVE_DEBUG_BIND_INSNS && !DEBUG_INSN_P (insn))
4050 41356263 : for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
4051 41857645 : sd_iterator_cond (&sd_it, &dep);)
4052 : {
4053 501382 : rtx_insn *dbg = DEP_PRO (dep);
4054 501382 : struct reg_use_data *use, *next;
4055 :
4056 501382 : if (DEP_STATUS (dep) & DEP_CANCELLED)
4057 : {
4058 381457 : sd_iterator_next (&sd_it);
4059 381457 : continue;
4060 : }
4061 :
4062 119925 : gcc_assert (DEBUG_BIND_INSN_P (dbg));
4063 :
4064 119925 : if (sched_verbose >= 6)
4065 0 : fprintf (sched_dump, ";;\t\tresetting: debug insn %d\n",
4066 0 : INSN_UID (dbg));
4067 :
4068 : /* ??? Rather than resetting the debug insn, we might be able
4069 : to emit a debug temp before the just-scheduled insn, but
4070 : this would involve checking that the expression at the
4071 : point of the debug insn is equivalent to the expression
4072 : before the just-scheduled insn. They might not be: the
4073 : expression in the debug insn may depend on other insns not
4074 : yet scheduled that set MEMs, REGs or even other debug
4075 : insns. It's not clear that attempting to preserve debug
4076 : information in these cases is worth the effort, given how
4077 : uncommon these resets are and the likelihood that the debug
4078 : temps introduced won't survive the schedule change. */
4079 119925 : INSN_VAR_LOCATION_LOC (dbg) = gen_rtx_UNKNOWN_VAR_LOC ();
4080 119925 : df_insn_rescan (dbg);
4081 :
4082 : /* Unknown location doesn't use any registers. */
4083 119925 : for (use = INSN_REG_USE_LIST (dbg); use != NULL; use = next)
4084 : {
4085 : struct reg_use_data *prev = use;
4086 :
4087 : /* Remove use from the cyclic next_regno_use chain first. */
4088 0 : while (prev->next_regno_use != use)
4089 : prev = prev->next_regno_use;
4090 0 : prev->next_regno_use = use->next_regno_use;
4091 0 : next = use->next_insn_use;
4092 0 : free (use);
4093 : }
4094 119925 : INSN_REG_USE_LIST (dbg) = NULL;
4095 :
4096 : /* We delete rather than resolve these deps, otherwise we
4097 : crash in sched_free_deps(), because forward deps are
4098 : expected to be released before backward deps. */
4099 119925 : sd_delete_dep (sd_it);
4100 : }
4101 :
4102 108621132 : gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
4103 108621132 : QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
4104 :
4105 108621132 : if (sched_pressure == SCHED_PRESSURE_MODEL
4106 0 : && model_curr_point < model_num_insns
4107 0 : && NONDEBUG_INSN_P (insn))
4108 : {
4109 0 : if (model_index (insn) == model_curr_point)
4110 0 : do
4111 0 : model_curr_point++;
4112 : while (model_curr_point < model_num_insns
4113 0 : && (QUEUE_INDEX (MODEL_INSN (model_curr_point))
4114 : == QUEUE_SCHEDULED));
4115 : else
4116 0 : model_recompute (insn);
4117 0 : model_update_limit_points ();
4118 0 : update_register_pressure (insn);
4119 0 : if (sched_verbose >= 2)
4120 0 : print_curr_reg_pressure ();
4121 : }
4122 :
4123 108621132 : gcc_assert (INSN_TICK (insn) >= MIN_TICK);
4124 108621132 : if (INSN_TICK (insn) > clock_var)
4125 : /* INSN has been prematurely moved from the queue to the ready list.
4126 : This is possible only if following flags are set. */
4127 5 : gcc_assert (flag_sched_stalled_insns || sched_fusion);
4128 :
4129 : /* ??? Probably, if INSN is scheduled prematurely, we should leave
4130 : INSN_TICK untouched. This is a machine-dependent issue, actually. */
4131 108621132 : INSN_TICK (insn) = clock_var;
4132 :
4133 108621132 : check_clobbered_conditions (insn);
4134 :
4135 : /* Update dependent instructions. First, see if by scheduling this insn
4136 : now we broke a dependence in a way that requires us to change another
4137 : insn. */
4138 108621132 : for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
4139 109160771 : sd_iterator_cond (&sd_it, &dep); sd_iterator_next (&sd_it))
4140 : {
4141 539639 : struct dep_replacement *desc = DEP_REPLACE (dep);
4142 539639 : rtx_insn *pro = DEP_PRO (dep);
4143 539639 : if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED
4144 539639 : && desc != NULL && desc->insn == pro)
4145 511787 : apply_replacement (dep, false);
4146 : }
4147 :
4148 : /* Go through and resolve forward dependencies. */
4149 108621132 : for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
4150 316932759 : sd_iterator_cond (&sd_it, &dep);)
4151 : {
4152 208311627 : rtx_insn *next = DEP_CON (dep);
4153 208311627 : bool cancelled = (DEP_STATUS (dep) & DEP_CANCELLED) != 0;
4154 :
4155 : /* Resolve the dependence between INSN and NEXT.
4156 : sd_resolve_dep () moves current dep to another list thus
4157 : advancing the iterator. */
4158 208311627 : sd_resolve_dep (sd_it);
4159 :
4160 208311627 : if (cancelled)
4161 : {
4162 843078 : if (must_restore_pattern_p (next, dep))
4163 63105 : restore_pattern (dep, false);
4164 843078 : continue;
4165 : }
4166 :
4167 : /* Don't bother trying to mark next as ready if insn is a debug
4168 : insn. If insn is the last hard dependency, it will have
4169 : already been discounted. */
4170 207468549 : if (DEBUG_INSN_P (insn) && !DEBUG_INSN_P (next))
4171 4780399 : continue;
4172 :
4173 202688150 : if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
4174 : {
4175 202688150 : int effective_cost;
4176 :
4177 202688150 : effective_cost = try_ready (next);
4178 :
4179 202688150 : if (effective_cost >= 0
4180 19276473 : && SCHED_GROUP_P (next)
4181 202688150 : && advance < effective_cost)
4182 208311627 : advance = effective_cost;
4183 : }
4184 : else
4185 : /* Check always has only one forward dependence (to the first insn in
4186 : the recovery block), therefore, this will be executed only once. */
4187 : {
4188 0 : gcc_assert (sd_lists_empty_p (insn, SD_LIST_FORW));
4189 0 : fix_recovery_deps (RECOVERY_BLOCK (insn));
4190 : }
4191 : }
4192 :
4193 : /* Annotate the instruction with issue information -- TImode
4194 : indicates that the instruction is expected not to be able
4195 : to issue on the same cycle as the previous insn. A machine
4196 : may use this information to decide how the instruction should
4197 : be aligned. */
4198 108621132 : if (issue_rate > 1
4199 108620269 : && GET_CODE (PATTERN (insn)) != USE
4200 107911527 : && GET_CODE (PATTERN (insn)) != CLOBBER
4201 216450927 : && !DEBUG_INSN_P (insn))
4202 : {
4203 59336290 : if (reload_completed)
4204 94274672 : PUT_MODE (insn, clock_var > last_clock_var ? TImode : VOIDmode);
4205 59336290 : last_clock_var = clock_var;
4206 : }
4207 :
4208 108621132 : if (nonscheduled_insns_begin != NULL_RTX)
4209 : /* Indicate to debug counters that INSN is scheduled. */
4210 0 : nonscheduled_insns_begin = insn;
4211 :
4212 108621132 : return advance;
4213 : }
4214 :
4215 : /* Functions for handling of notes. */
4216 :
4217 : /* Add note list that ends on FROM_END to the end of TO_ENDP. */
4218 : void
4219 62 : concat_note_lists (rtx_insn *from_end, rtx_insn **to_endp)
4220 : {
4221 62 : rtx_insn *from_start;
4222 :
4223 : /* It's easy when have nothing to concat. */
4224 62 : if (from_end == NULL)
4225 : return;
4226 :
4227 : /* It's also easy when destination is empty. */
4228 0 : if (*to_endp == NULL)
4229 : {
4230 0 : *to_endp = from_end;
4231 0 : return;
4232 : }
4233 :
4234 : from_start = from_end;
4235 0 : while (PREV_INSN (from_start) != NULL)
4236 : from_start = PREV_INSN (from_start);
4237 :
4238 0 : SET_PREV_INSN (from_start) = *to_endp;
4239 0 : SET_NEXT_INSN (*to_endp) = from_start;
4240 0 : *to_endp = from_end;
4241 : }
4242 :
4243 : /* Delete notes between HEAD and TAIL and put them in the chain
4244 : of notes ended by NOTE_LIST. */
4245 : void
4246 10314455 : remove_notes (rtx_insn *head, rtx_insn *tail)
4247 : {
4248 10314455 : rtx_insn *next_tail, *insn, *next;
4249 :
4250 10314455 : note_list = 0;
4251 10314455 : if (head == tail && !INSN_P (head))
4252 : return;
4253 :
4254 10314424 : next_tail = NEXT_INSN (tail);
4255 135080221 : for (insn = head; insn != next_tail; insn = next)
4256 : {
4257 114451373 : next = NEXT_INSN (insn);
4258 114451373 : if (!NOTE_P (insn))
4259 108625968 : continue;
4260 :
4261 5825405 : switch (NOTE_KIND (insn))
4262 : {
4263 1134 : case NOTE_INSN_BASIC_BLOCK:
4264 1134 : continue;
4265 :
4266 911031 : case NOTE_INSN_EPILOGUE_BEG:
4267 911031 : if (insn != tail)
4268 : {
4269 911031 : remove_insn (insn);
4270 : /* If an insn was split just before the EPILOGUE_BEG note and
4271 : that split created new basic blocks, we could have a
4272 : BASIC_BLOCK note here. Safely advance over it in that case
4273 : and assert that we land on a real insn. */
4274 911031 : if (NOTE_P (next)
4275 0 : && NOTE_KIND (next) == NOTE_INSN_BASIC_BLOCK
4276 0 : && next != next_tail)
4277 0 : next = NEXT_INSN (next);
4278 911031 : gcc_assert (INSN_P (next));
4279 911031 : add_reg_note (next, REG_SAVE_NOTE,
4280 : GEN_INT (NOTE_INSN_EPILOGUE_BEG));
4281 911031 : break;
4282 : }
4283 : /* FALLTHRU */
4284 :
4285 4913240 : default:
4286 4913240 : remove_insn (insn);
4287 :
4288 : /* Add the note to list that ends at NOTE_LIST. */
4289 4913240 : SET_PREV_INSN (insn) = note_list;
4290 4913240 : SET_NEXT_INSN (insn) = NULL_RTX;
4291 4913240 : if (note_list)
4292 2830983 : SET_NEXT_INSN (note_list) = insn;
4293 4913240 : note_list = insn;
4294 4913240 : break;
4295 : }
4296 :
4297 5824271 : gcc_assert ((sel_sched_p () || insn != tail) && insn != head);
4298 : }
4299 : }
4300 :
4301 : /* A structure to record enough data to allow us to backtrack the scheduler to
4302 : a previous state. */
4303 : struct haifa_saved_data
4304 : {
4305 : /* Next entry on the list. */
4306 : struct haifa_saved_data *next;
4307 :
4308 : /* Backtracking is associated with scheduling insns that have delay slots.
4309 : DELAY_PAIR points to the structure that contains the insns involved, and
4310 : the number of cycles between them. */
4311 : struct delay_pair *delay_pair;
4312 :
4313 : /* Data used by the frontend (e.g. sched-ebb or sched-rgn). */
4314 : void *fe_saved_data;
4315 : /* Data used by the backend. */
4316 : void *be_saved_data;
4317 :
4318 : /* Copies of global state. */
4319 : int clock_var, last_clock_var;
4320 : struct ready_list ready;
4321 : state_t curr_state;
4322 :
4323 : rtx_insn *last_scheduled_insn;
4324 : rtx_insn *last_nondebug_scheduled_insn;
4325 : rtx_insn *nonscheduled_insns_begin;
4326 : int cycle_issued_insns;
4327 :
4328 : /* Copies of state used in the inner loop of schedule_block. */
4329 : struct sched_block_state sched_block;
4330 :
4331 : /* We don't need to save q_ptr, as its value is arbitrary and we can set it
4332 : to 0 when restoring. */
4333 : int q_size;
4334 : rtx_insn_list **insn_queue;
4335 :
4336 : /* Describe pattern replacements that occurred since this backtrack point
4337 : was queued. */
4338 : vec<dep_t> replacement_deps;
4339 : vec<int> replace_apply;
4340 :
4341 : /* A copy of the next-cycle replacement vectors at the time of the backtrack
4342 : point. */
4343 : vec<dep_t> next_cycle_deps;
4344 : vec<int> next_cycle_apply;
4345 : };
4346 :
4347 : /* A record, in reverse order, of all scheduled insns which have delay slots
4348 : and may require backtracking. */
4349 : static struct haifa_saved_data *backtrack_queue;
4350 :
4351 : /* For every dependency of INSN, set the FEEDS_BACKTRACK_INSN bit according
4352 : to SET_P. */
4353 : static void
4354 0 : mark_backtrack_feeds (rtx_insn *insn, int set_p)
4355 : {
4356 0 : sd_iterator_def sd_it;
4357 0 : dep_t dep;
4358 0 : FOR_EACH_DEP (insn, SD_LIST_HARD_BACK, sd_it, dep)
4359 : {
4360 0 : FEEDS_BACKTRACK_INSN (DEP_PRO (dep)) = set_p;
4361 : }
4362 0 : }
4363 :
4364 : /* Save the current scheduler state so that we can backtrack to it
4365 : later if necessary. PAIR gives the insns that make it necessary to
4366 : save this point. SCHED_BLOCK is the local state of schedule_block
4367 : that need to be saved. */
4368 : static void
4369 0 : save_backtrack_point (struct delay_pair *pair,
4370 : struct sched_block_state sched_block)
4371 : {
4372 0 : int i;
4373 0 : struct haifa_saved_data *save = XNEW (struct haifa_saved_data);
4374 :
4375 0 : save->curr_state = xmalloc (dfa_state_size);
4376 0 : memcpy (save->curr_state, curr_state, dfa_state_size);
4377 :
4378 0 : save->ready.first = ready.first;
4379 0 : save->ready.n_ready = ready.n_ready;
4380 0 : save->ready.n_debug = ready.n_debug;
4381 0 : save->ready.veclen = ready.veclen;
4382 0 : save->ready.vec = XNEWVEC (rtx_insn *, ready.veclen);
4383 0 : memcpy (save->ready.vec, ready.vec, ready.veclen * sizeof (rtx));
4384 :
4385 0 : save->insn_queue = XNEWVEC (rtx_insn_list *, max_insn_queue_index + 1);
4386 0 : save->q_size = q_size;
4387 0 : for (i = 0; i <= max_insn_queue_index; i++)
4388 : {
4389 0 : int q = NEXT_Q_AFTER (q_ptr, i);
4390 0 : save->insn_queue[i] = copy_INSN_LIST (insn_queue[q]);
4391 : }
4392 :
4393 0 : save->clock_var = clock_var;
4394 0 : save->last_clock_var = last_clock_var;
4395 0 : save->cycle_issued_insns = cycle_issued_insns;
4396 0 : save->last_scheduled_insn = last_scheduled_insn;
4397 0 : save->last_nondebug_scheduled_insn = last_nondebug_scheduled_insn;
4398 0 : save->nonscheduled_insns_begin = nonscheduled_insns_begin;
4399 :
4400 0 : save->sched_block = sched_block;
4401 :
4402 0 : save->replacement_deps.create (0);
4403 0 : save->replace_apply.create (0);
4404 0 : save->next_cycle_deps = next_cycle_replace_deps.copy ();
4405 0 : save->next_cycle_apply = next_cycle_apply.copy ();
4406 :
4407 0 : if (current_sched_info->save_state)
4408 0 : save->fe_saved_data = (*current_sched_info->save_state) ();
4409 :
4410 0 : if (targetm.sched.alloc_sched_context)
4411 : {
4412 0 : save->be_saved_data = targetm.sched.alloc_sched_context ();
4413 0 : targetm.sched.init_sched_context (save->be_saved_data, false);
4414 : }
4415 : else
4416 0 : save->be_saved_data = NULL;
4417 :
4418 0 : save->delay_pair = pair;
4419 :
4420 0 : save->next = backtrack_queue;
4421 0 : backtrack_queue = save;
4422 :
4423 0 : while (pair)
4424 : {
4425 0 : mark_backtrack_feeds (pair->i2, 1);
4426 0 : INSN_TICK (pair->i2) = INVALID_TICK;
4427 0 : INSN_EXACT_TICK (pair->i2) = clock_var + pair_delay (pair);
4428 0 : SHADOW_P (pair->i2) = pair->stages == 0;
4429 0 : pair = pair->next_same_i1;
4430 : }
4431 0 : }
4432 :
4433 : /* Walk the ready list and all queues. If any insns have unresolved backwards
4434 : dependencies, these must be cancelled deps, broken by predication. Set or
4435 : clear (depending on SET) the DEP_CANCELLED bit in DEP_STATUS. */
4436 :
4437 : static void
4438 0 : toggle_cancelled_flags (bool set)
4439 : {
4440 0 : int i;
4441 0 : sd_iterator_def sd_it;
4442 0 : dep_t dep;
4443 :
4444 0 : if (ready.n_ready > 0)
4445 : {
4446 0 : rtx_insn **first = ready_lastpos (&ready);
4447 0 : for (i = 0; i < ready.n_ready; i++)
4448 0 : FOR_EACH_DEP (first[i], SD_LIST_BACK, sd_it, dep)
4449 0 : if (!DEBUG_INSN_P (DEP_PRO (dep)))
4450 : {
4451 0 : if (set)
4452 0 : DEP_STATUS (dep) |= DEP_CANCELLED;
4453 : else
4454 0 : DEP_STATUS (dep) &= ~DEP_CANCELLED;
4455 : }
4456 : }
4457 0 : for (i = 0; i <= max_insn_queue_index; i++)
4458 : {
4459 0 : int q = NEXT_Q_AFTER (q_ptr, i);
4460 0 : rtx_insn_list *link;
4461 0 : for (link = insn_queue[q]; link; link = link->next ())
4462 : {
4463 0 : rtx_insn *insn = link->insn ();
4464 0 : FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
4465 0 : if (!DEBUG_INSN_P (DEP_PRO (dep)))
4466 : {
4467 0 : if (set)
4468 0 : DEP_STATUS (dep) |= DEP_CANCELLED;
4469 : else
4470 0 : DEP_STATUS (dep) &= ~DEP_CANCELLED;
4471 : }
4472 : }
4473 : }
4474 0 : }
4475 :
4476 : /* Undo the replacements that have occurred after backtrack point SAVE
4477 : was placed. */
4478 : static void
4479 0 : undo_replacements_for_backtrack (struct haifa_saved_data *save)
4480 : {
4481 0 : while (!save->replacement_deps.is_empty ())
4482 : {
4483 0 : dep_t dep = save->replacement_deps.pop ();
4484 0 : int apply_p = save->replace_apply.pop ();
4485 :
4486 0 : if (apply_p)
4487 0 : restore_pattern (dep, true);
4488 : else
4489 0 : apply_replacement (dep, true);
4490 : }
4491 0 : save->replacement_deps.release ();
4492 0 : save->replace_apply.release ();
4493 0 : }
4494 :
4495 : /* Pop entries from the SCHEDULED_INSNS vector up to and including INSN.
4496 : Restore their dependencies to an unresolved state, and mark them as
4497 : queued nowhere. */
4498 :
4499 : static void
4500 0 : unschedule_insns_until (rtx_insn *insn)
4501 : {
4502 0 : auto_vec<rtx_insn *> recompute_vec;
4503 :
4504 : /* Make two passes over the insns to be unscheduled. First, we clear out
4505 : dependencies and other trivial bookkeeping. */
4506 0 : for (;;)
4507 : {
4508 0 : rtx_insn *last;
4509 0 : sd_iterator_def sd_it;
4510 0 : dep_t dep;
4511 :
4512 0 : last = scheduled_insns.pop ();
4513 :
4514 : /* This will be changed by restore_backtrack_point if the insn is in
4515 : any queue. */
4516 0 : QUEUE_INDEX (last) = QUEUE_NOWHERE;
4517 0 : if (last != insn)
4518 0 : INSN_TICK (last) = INVALID_TICK;
4519 :
4520 0 : if (modulo_ii > 0 && INSN_UID (last) < modulo_iter0_max_uid)
4521 0 : modulo_insns_scheduled--;
4522 :
4523 0 : for (sd_it = sd_iterator_start (last, SD_LIST_RES_FORW);
4524 0 : sd_iterator_cond (&sd_it, &dep);)
4525 : {
4526 0 : rtx_insn *con = DEP_CON (dep);
4527 0 : sd_unresolve_dep (sd_it);
4528 0 : if (!MUST_RECOMPUTE_SPEC_P (con))
4529 : {
4530 0 : MUST_RECOMPUTE_SPEC_P (con) = 1;
4531 0 : recompute_vec.safe_push (con);
4532 : }
4533 : }
4534 :
4535 0 : if (last == insn)
4536 : break;
4537 0 : }
4538 :
4539 : /* A second pass, to update ready and speculation status for insns
4540 : depending on the unscheduled ones. The first pass must have
4541 : popped the scheduled_insns vector up to the point where we
4542 : restart scheduling, as recompute_todo_spec requires it to be
4543 : up-to-date. */
4544 0 : while (!recompute_vec.is_empty ())
4545 : {
4546 0 : rtx_insn *con;
4547 :
4548 0 : con = recompute_vec.pop ();
4549 0 : MUST_RECOMPUTE_SPEC_P (con) = 0;
4550 0 : if (!sd_lists_empty_p (con, SD_LIST_HARD_BACK))
4551 : {
4552 0 : TODO_SPEC (con) = HARD_DEP;
4553 0 : INSN_TICK (con) = INVALID_TICK;
4554 0 : if (PREDICATED_PAT (con) != NULL_RTX)
4555 0 : haifa_change_pattern (con, ORIG_PAT (con));
4556 : }
4557 0 : else if (QUEUE_INDEX (con) != QUEUE_SCHEDULED)
4558 0 : TODO_SPEC (con) = recompute_todo_spec (con, true);
4559 : }
4560 0 : }
4561 :
4562 : /* Restore scheduler state from the topmost entry on the backtracking queue.
4563 : PSCHED_BLOCK_P points to the local data of schedule_block that we must
4564 : overwrite with the saved data.
4565 : The caller must already have called unschedule_insns_until. */
4566 :
4567 : static void
4568 0 : restore_last_backtrack_point (struct sched_block_state *psched_block)
4569 : {
4570 0 : int i;
4571 0 : struct haifa_saved_data *save = backtrack_queue;
4572 :
4573 0 : backtrack_queue = save->next;
4574 :
4575 0 : if (current_sched_info->restore_state)
4576 0 : (*current_sched_info->restore_state) (save->fe_saved_data);
4577 :
4578 0 : if (targetm.sched.alloc_sched_context)
4579 : {
4580 0 : targetm.sched.set_sched_context (save->be_saved_data);
4581 0 : targetm.sched.free_sched_context (save->be_saved_data);
4582 : }
4583 :
4584 : /* Do this first since it clobbers INSN_TICK of the involved
4585 : instructions. */
4586 0 : undo_replacements_for_backtrack (save);
4587 :
4588 : /* Clear the QUEUE_INDEX of everything in the ready list or one
4589 : of the queues. */
4590 0 : if (ready.n_ready > 0)
4591 : {
4592 0 : rtx_insn **first = ready_lastpos (&ready);
4593 0 : for (i = 0; i < ready.n_ready; i++)
4594 : {
4595 0 : rtx_insn *insn = first[i];
4596 0 : QUEUE_INDEX (insn) = QUEUE_NOWHERE;
4597 0 : INSN_TICK (insn) = INVALID_TICK;
4598 : }
4599 : }
4600 0 : for (i = 0; i <= max_insn_queue_index; i++)
4601 : {
4602 0 : int q = NEXT_Q_AFTER (q_ptr, i);
4603 :
4604 0 : for (rtx_insn_list *link = insn_queue[q]; link; link = link->next ())
4605 : {
4606 0 : rtx_insn *x = link->insn ();
4607 0 : QUEUE_INDEX (x) = QUEUE_NOWHERE;
4608 0 : INSN_TICK (x) = INVALID_TICK;
4609 : }
4610 0 : free_INSN_LIST_list (&insn_queue[q]);
4611 : }
4612 :
4613 0 : free (ready.vec);
4614 0 : ready = save->ready;
4615 :
4616 0 : if (ready.n_ready > 0)
4617 : {
4618 0 : rtx_insn **first = ready_lastpos (&ready);
4619 0 : for (i = 0; i < ready.n_ready; i++)
4620 : {
4621 0 : rtx_insn *insn = first[i];
4622 0 : QUEUE_INDEX (insn) = QUEUE_READY;
4623 0 : TODO_SPEC (insn) = recompute_todo_spec (insn, true);
4624 0 : INSN_TICK (insn) = save->clock_var;
4625 : }
4626 : }
4627 :
4628 0 : q_ptr = 0;
4629 0 : q_size = save->q_size;
4630 0 : for (i = 0; i <= max_insn_queue_index; i++)
4631 : {
4632 0 : int q = NEXT_Q_AFTER (q_ptr, i);
4633 :
4634 0 : insn_queue[q] = save->insn_queue[q];
4635 :
4636 0 : for (rtx_insn_list *link = insn_queue[q]; link; link = link->next ())
4637 : {
4638 0 : rtx_insn *x = link->insn ();
4639 0 : QUEUE_INDEX (x) = i;
4640 0 : TODO_SPEC (x) = recompute_todo_spec (x, true);
4641 0 : INSN_TICK (x) = save->clock_var + i;
4642 : }
4643 : }
4644 0 : free (save->insn_queue);
4645 :
4646 0 : toggle_cancelled_flags (true);
4647 :
4648 0 : clock_var = save->clock_var;
4649 0 : last_clock_var = save->last_clock_var;
4650 0 : cycle_issued_insns = save->cycle_issued_insns;
4651 0 : last_scheduled_insn = save->last_scheduled_insn;
4652 0 : last_nondebug_scheduled_insn = save->last_nondebug_scheduled_insn;
4653 0 : nonscheduled_insns_begin = save->nonscheduled_insns_begin;
4654 :
4655 0 : *psched_block = save->sched_block;
4656 :
4657 0 : memcpy (curr_state, save->curr_state, dfa_state_size);
4658 0 : free (save->curr_state);
4659 :
4660 0 : mark_backtrack_feeds (save->delay_pair->i2, 0);
4661 :
4662 0 : gcc_assert (next_cycle_replace_deps.is_empty ());
4663 0 : next_cycle_replace_deps = save->next_cycle_deps.copy ();
4664 0 : next_cycle_apply = save->next_cycle_apply.copy ();
4665 :
4666 0 : free (save);
4667 :
4668 0 : for (save = backtrack_queue; save; save = save->next)
4669 : {
4670 0 : mark_backtrack_feeds (save->delay_pair->i2, 1);
4671 : }
4672 0 : }
4673 :
4674 : /* Discard all data associated with the topmost entry in the backtrack
4675 : queue. If RESET_TICK is false, we just want to free the data. If true,
4676 : we are doing this because we discovered a reason to backtrack. In the
4677 : latter case, also reset the INSN_TICK for the shadow insn. */
4678 : static void
4679 0 : free_topmost_backtrack_point (bool reset_tick)
4680 : {
4681 0 : struct haifa_saved_data *save = backtrack_queue;
4682 0 : int i;
4683 :
4684 0 : backtrack_queue = save->next;
4685 :
4686 0 : if (reset_tick)
4687 : {
4688 0 : struct delay_pair *pair = save->delay_pair;
4689 0 : while (pair)
4690 : {
4691 0 : INSN_TICK (pair->i2) = INVALID_TICK;
4692 0 : INSN_EXACT_TICK (pair->i2) = INVALID_TICK;
4693 0 : pair = pair->next_same_i1;
4694 : }
4695 0 : undo_replacements_for_backtrack (save);
4696 : }
4697 : else
4698 : {
4699 0 : save->replacement_deps.release ();
4700 0 : save->replace_apply.release ();
4701 : }
4702 :
4703 0 : if (targetm.sched.free_sched_context)
4704 0 : targetm.sched.free_sched_context (save->be_saved_data);
4705 0 : if (current_sched_info->restore_state)
4706 0 : free (save->fe_saved_data);
4707 0 : for (i = 0; i <= max_insn_queue_index; i++)
4708 0 : free_INSN_LIST_list (&save->insn_queue[i]);
4709 0 : free (save->insn_queue);
4710 0 : free (save->curr_state);
4711 0 : free (save->ready.vec);
4712 0 : free (save);
4713 0 : }
4714 :
4715 : /* Free the entire backtrack queue. */
4716 : static void
4717 10313337 : free_backtrack_queue (void)
4718 : {
4719 10313337 : while (backtrack_queue)
4720 0 : free_topmost_backtrack_point (false);
4721 10313337 : }
4722 :
4723 : /* Apply a replacement described by DESC. If IMMEDIATELY is false, we
4724 : may have to postpone the replacement until the start of the next cycle,
4725 : at which point we will be called again with IMMEDIATELY true. This is
4726 : only done for machines which have instruction packets with explicit
4727 : parallelism however. */
4728 : static void
4729 602744 : apply_replacement (dep_t dep, bool immediately)
4730 : {
4731 602744 : struct dep_replacement *desc = DEP_REPLACE (dep);
4732 602744 : if (!immediately && targetm.sched.exposed_pipeline && reload_completed)
4733 : {
4734 0 : next_cycle_replace_deps.safe_push (dep);
4735 0 : next_cycle_apply.safe_push (1);
4736 : }
4737 : else
4738 : {
4739 602744 : bool success;
4740 :
4741 602744 : if (QUEUE_INDEX (desc->insn) == QUEUE_SCHEDULED)
4742 : return;
4743 :
4744 602744 : if (sched_verbose >= 5)
4745 0 : fprintf (sched_dump, "applying replacement for insn %d\n",
4746 : INSN_UID (desc->insn));
4747 :
4748 602744 : success = validate_change (desc->insn, desc->loc, desc->newval, 0);
4749 602744 : gcc_assert (success);
4750 :
4751 602744 : rtx_insn *insn = DEP_PRO (dep);
4752 :
4753 : /* Recompute priority since dependent priorities may have changed. */
4754 602744 : priority (insn, true);
4755 602744 : update_insn_after_change (desc->insn);
4756 :
4757 602744 : if ((TODO_SPEC (desc->insn) & (HARD_DEP | DEP_POSTPONED)) == 0)
4758 311240 : fix_tick_ready (desc->insn);
4759 :
4760 602744 : if (backtrack_queue != NULL)
4761 : {
4762 0 : backtrack_queue->replacement_deps.safe_push (dep);
4763 0 : backtrack_queue->replace_apply.safe_push (1);
4764 : }
4765 : }
4766 : }
4767 :
4768 : /* We have determined that a pattern involved in DEP must be restored.
4769 : If IMMEDIATELY is false, we may have to postpone the replacement
4770 : until the start of the next cycle, at which point we will be called
4771 : again with IMMEDIATELY true. */
4772 : static void
4773 63105 : restore_pattern (dep_t dep, bool immediately)
4774 : {
4775 63105 : rtx_insn *next = DEP_CON (dep);
4776 63105 : int tick = INSN_TICK (next);
4777 :
4778 : /* If we already scheduled the insn, the modified version is
4779 : correct. */
4780 63105 : if (QUEUE_INDEX (next) == QUEUE_SCHEDULED)
4781 : return;
4782 :
4783 63105 : if (!immediately && targetm.sched.exposed_pipeline && reload_completed)
4784 : {
4785 0 : next_cycle_replace_deps.safe_push (dep);
4786 0 : next_cycle_apply.safe_push (0);
4787 0 : return;
4788 : }
4789 :
4790 :
4791 63105 : if (DEP_TYPE (dep) == REG_DEP_CONTROL)
4792 : {
4793 0 : if (sched_verbose >= 5)
4794 0 : fprintf (sched_dump, "restoring pattern for insn %d\n",
4795 : INSN_UID (next));
4796 0 : haifa_change_pattern (next, ORIG_PAT (next));
4797 : }
4798 : else
4799 : {
4800 63105 : struct dep_replacement *desc = DEP_REPLACE (dep);
4801 63105 : bool success;
4802 :
4803 63105 : if (sched_verbose >= 5)
4804 0 : fprintf (sched_dump, "restoring pattern for insn %d\n",
4805 0 : INSN_UID (desc->insn));
4806 63105 : tick = INSN_TICK (desc->insn);
4807 :
4808 63105 : success = validate_change (desc->insn, desc->loc, desc->orig, 0);
4809 63105 : gcc_assert (success);
4810 :
4811 63105 : rtx_insn *insn = DEP_PRO (dep);
4812 :
4813 63105 : if (QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
4814 : {
4815 : /* Recompute priority since dependent priorities may have changed. */
4816 0 : priority (insn, true);
4817 : }
4818 :
4819 63105 : update_insn_after_change (desc->insn);
4820 :
4821 63105 : if (backtrack_queue != NULL)
4822 : {
4823 0 : backtrack_queue->replacement_deps.safe_push (dep);
4824 0 : backtrack_queue->replace_apply.safe_push (0);
4825 : }
4826 : }
4827 63105 : INSN_TICK (next) = tick;
4828 63105 : if (TODO_SPEC (next) == DEP_POSTPONED)
4829 : return;
4830 :
4831 63105 : if (sd_lists_empty_p (next, SD_LIST_BACK))
4832 63105 : TODO_SPEC (next) = 0;
4833 0 : else if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
4834 0 : TODO_SPEC (next) = HARD_DEP;
4835 : }
4836 :
4837 : /* Perform pattern replacements that were queued up until the next
4838 : cycle. */
4839 : static void
4840 45271138 : perform_replacements_new_cycle (void)
4841 : {
4842 45271138 : int i;
4843 45271138 : dep_t dep;
4844 45271138 : FOR_EACH_VEC_ELT (next_cycle_replace_deps, i, dep)
4845 : {
4846 0 : int apply_p = next_cycle_apply[i];
4847 0 : if (apply_p)
4848 0 : apply_replacement (dep, true);
4849 : else
4850 0 : restore_pattern (dep, true);
4851 : }
4852 45271138 : next_cycle_replace_deps.truncate (0);
4853 45271138 : next_cycle_apply.truncate (0);
4854 45271138 : }
4855 :
4856 : /* Compute INSN_TICK_ESTIMATE for INSN. PROCESSED is a bitmap of
4857 : instructions we've previously encountered, a set bit prevents
4858 : recursion. BUDGET is a limit on how far ahead we look, it is
4859 : reduced on recursive calls. Return true if we produced a good
4860 : estimate, or false if we exceeded the budget. */
4861 : static bool
4862 0 : estimate_insn_tick (bitmap processed, rtx_insn *insn, int budget)
4863 : {
4864 0 : sd_iterator_def sd_it;
4865 0 : dep_t dep;
4866 0 : int earliest = INSN_TICK (insn);
4867 :
4868 0 : FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
4869 : {
4870 0 : rtx_insn *pro = DEP_PRO (dep);
4871 0 : int t;
4872 :
4873 0 : if (DEP_STATUS (dep) & DEP_CANCELLED)
4874 0 : continue;
4875 :
4876 0 : if (QUEUE_INDEX (pro) == QUEUE_SCHEDULED)
4877 0 : gcc_assert (INSN_TICK (pro) + dep_cost (dep) <= INSN_TICK (insn));
4878 : else
4879 : {
4880 0 : int cost = dep_cost (dep);
4881 0 : if (cost >= budget)
4882 : return false;
4883 0 : if (!bitmap_bit_p (processed, INSN_LUID (pro)))
4884 : {
4885 0 : if (!estimate_insn_tick (processed, pro, budget - cost))
4886 : return false;
4887 : }
4888 0 : gcc_assert (INSN_TICK_ESTIMATE (pro) != INVALID_TICK);
4889 0 : t = INSN_TICK_ESTIMATE (pro) + cost;
4890 0 : if (earliest == INVALID_TICK || t > earliest)
4891 0 : earliest = t;
4892 : }
4893 : }
4894 0 : bitmap_set_bit (processed, INSN_LUID (insn));
4895 0 : INSN_TICK_ESTIMATE (insn) = earliest;
4896 0 : return true;
4897 : }
4898 :
4899 : /* Examine the pair of insns in P, and estimate (optimistically, assuming
4900 : infinite resources) the cycle in which the delayed shadow can be issued.
4901 : Return the number of cycles that must pass before the real insn can be
4902 : issued in order to meet this constraint. */
4903 : static int
4904 0 : estimate_shadow_tick (struct delay_pair *p)
4905 : {
4906 0 : auto_bitmap processed;
4907 0 : int t;
4908 0 : bool cutoff;
4909 :
4910 0 : cutoff = !estimate_insn_tick (processed, p->i2,
4911 0 : max_insn_queue_index + pair_delay (p));
4912 0 : if (cutoff)
4913 : return max_insn_queue_index;
4914 0 : t = INSN_TICK_ESTIMATE (p->i2) - (clock_var + pair_delay (p) + 1);
4915 0 : if (t > 0)
4916 : return t;
4917 : return 0;
4918 0 : }
4919 :
4920 : /* If INSN has no unresolved backwards dependencies, add it to the schedule and
4921 : recursively resolve all its forward dependencies. */
4922 : static void
4923 0 : resolve_dependencies (rtx_insn *insn)
4924 : {
4925 0 : sd_iterator_def sd_it;
4926 0 : dep_t dep;
4927 :
4928 : /* Don't use sd_lists_empty_p; it ignores debug insns. */
4929 0 : if (DEPS_LIST_FIRST (INSN_HARD_BACK_DEPS (insn)) != NULL
4930 0 : || DEPS_LIST_FIRST (INSN_SPEC_BACK_DEPS (insn)) != NULL)
4931 0 : return;
4932 :
4933 0 : if (sched_verbose >= 4)
4934 0 : fprintf (sched_dump, ";;\tquickly resolving %d\n", INSN_UID (insn));
4935 :
4936 0 : if (QUEUE_INDEX (insn) >= 0)
4937 0 : queue_remove (insn);
4938 :
4939 0 : scheduled_insns.safe_push (insn);
4940 :
4941 : /* Update dependent instructions. */
4942 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
4943 0 : sd_iterator_cond (&sd_it, &dep);)
4944 : {
4945 0 : rtx_insn *next = DEP_CON (dep);
4946 :
4947 0 : if (sched_verbose >= 4)
4948 0 : fprintf (sched_dump, ";;\t\tdep %d against %d\n", INSN_UID (insn),
4949 0 : INSN_UID (next));
4950 :
4951 : /* Resolve the dependence between INSN and NEXT.
4952 : sd_resolve_dep () moves current dep to another list thus
4953 : advancing the iterator. */
4954 0 : sd_resolve_dep (sd_it);
4955 :
4956 0 : if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
4957 : {
4958 0 : resolve_dependencies (next);
4959 : }
4960 : else
4961 : /* Check always has only one forward dependence (to the first insn in
4962 : the recovery block), therefore, this will be executed only once. */
4963 : {
4964 0 : gcc_assert (sd_lists_empty_p (insn, SD_LIST_FORW));
4965 : }
4966 : }
4967 : }
4968 :
4969 :
4970 : /* Return the head and tail pointers of ebb starting at BEG and ending
4971 : at END. */
4972 : void
4973 41326222 : get_ebb_head_tail (basic_block beg, basic_block end,
4974 : rtx_insn **headp, rtx_insn **tailp)
4975 : {
4976 41326222 : rtx_insn *beg_head = BB_HEAD (beg);
4977 41326222 : rtx_insn * beg_tail = BB_END (beg);
4978 41326222 : rtx_insn * end_head = BB_HEAD (end);
4979 41326222 : rtx_insn * end_tail = BB_END (end);
4980 :
4981 : /* Don't include any notes or labels at the beginning of the BEG
4982 : basic block, or notes at the end of the END basic blocks. */
4983 :
4984 41326222 : if (LABEL_P (beg_head))
4985 20211474 : beg_head = NEXT_INSN (beg_head);
4986 :
4987 96941276 : while (beg_head != beg_tail)
4988 93025593 : if (NOTE_P (beg_head))
4989 55615054 : beg_head = NEXT_INSN (beg_head);
4990 37410539 : else if (DEBUG_INSN_P (beg_head))
4991 : {
4992 10234674 : rtx_insn * note, *next;
4993 :
4994 10234674 : for (note = NEXT_INSN (beg_head);
4995 82667992 : note != beg_tail;
4996 : note = next)
4997 : {
4998 82365022 : next = NEXT_INSN (note);
4999 82365022 : if (NOTE_P (note))
5000 : {
5001 429788 : if (sched_verbose >= 9)
5002 0 : fprintf (sched_dump, "reorder %i\n", INSN_UID (note));
5003 :
5004 429788 : reorder_insns_nobb (note, note, PREV_INSN (beg_head));
5005 :
5006 429788 : if (BLOCK_FOR_INSN (note) != beg)
5007 0 : df_insn_change_bb (note, beg);
5008 : }
5009 81935234 : else if (!DEBUG_INSN_P (note))
5010 : break;
5011 : }
5012 :
5013 : break;
5014 : }
5015 : else
5016 : break;
5017 :
5018 41326222 : *headp = beg_head;
5019 :
5020 41326222 : if (beg == end)
5021 41326222 : end_head = beg_head;
5022 67 : else if (LABEL_P (end_head))
5023 3 : end_head = NEXT_INSN (end_head);
5024 :
5025 41485048 : while (end_head != end_tail)
5026 37554787 : if (NOTE_P (end_tail))
5027 158826 : end_tail = PREV_INSN (end_tail);
5028 37395961 : else if (DEBUG_INSN_P (end_tail))
5029 : {
5030 817144 : rtx_insn * note, *prev;
5031 :
5032 817144 : for (note = PREV_INSN (end_tail);
5033 6898983 : note != end_head;
5034 : note = prev)
5035 : {
5036 6865458 : prev = PREV_INSN (note);
5037 6865458 : if (NOTE_P (note))
5038 : {
5039 1642 : if (sched_verbose >= 9)
5040 0 : fprintf (sched_dump, "reorder %i\n", INSN_UID (note));
5041 :
5042 1642 : reorder_insns_nobb (note, note, end_tail);
5043 :
5044 1642 : if (end_tail == BB_END (end))
5045 937 : BB_END (end) = note;
5046 :
5047 1642 : if (BLOCK_FOR_INSN (note) != end)
5048 0 : df_insn_change_bb (note, end);
5049 : }
5050 6863816 : else if (!DEBUG_INSN_P (note))
5051 : break;
5052 : }
5053 :
5054 : break;
5055 : }
5056 : else
5057 : break;
5058 :
5059 41326222 : *tailp = end_tail;
5060 41326222 : }
5061 :
5062 : /* Return true if there are no real insns in the range [ HEAD, TAIL ]. */
5063 :
5064 : bool
5065 30993539 : no_real_insns_p (const rtx_insn *head, const rtx_insn *tail)
5066 : {
5067 31045356 : while (head != NEXT_INSN (tail))
5068 : {
5069 30993539 : if (!NOTE_P (head) && !LABEL_P (head))
5070 : return false;
5071 51817 : head = NEXT_INSN (head);
5072 : }
5073 : return true;
5074 : }
5075 :
5076 : /* Restore-other-notes: NOTE_LIST is the end of a chain of notes
5077 : previously found among the insns. Insert them just before HEAD. */
5078 : rtx_insn *
5079 10314393 : restore_other_notes (rtx_insn *head, basic_block head_bb)
5080 : {
5081 10314393 : if (note_list != 0)
5082 : {
5083 2082257 : rtx_insn *note_head = note_list;
5084 :
5085 2082257 : if (head)
5086 2081883 : head_bb = BLOCK_FOR_INSN (head);
5087 : else
5088 374 : head = NEXT_INSN (bb_note (head_bb));
5089 :
5090 4913240 : while (PREV_INSN (note_head))
5091 : {
5092 2830983 : set_block_for_insn (note_head, head_bb);
5093 2830983 : note_head = PREV_INSN (note_head);
5094 : }
5095 : /* In the above cycle we've missed this note. */
5096 2082257 : set_block_for_insn (note_head, head_bb);
5097 :
5098 2082257 : SET_PREV_INSN (note_head) = PREV_INSN (head);
5099 2082257 : SET_NEXT_INSN (PREV_INSN (head)) = note_head;
5100 2082257 : SET_PREV_INSN (head) = note_list;
5101 2082257 : SET_NEXT_INSN (note_list) = head;
5102 :
5103 2082257 : if (BLOCK_FOR_INSN (head) != head_bb)
5104 0 : BB_END (head_bb) = note_list;
5105 :
5106 : head = note_head;
5107 : }
5108 :
5109 10314393 : return head;
5110 : }
5111 :
5112 : /* When we know we are going to discard the schedule due to a failed attempt
5113 : at modulo scheduling, undo all replacements. */
5114 : static void
5115 0 : undo_all_replacements (void)
5116 : {
5117 0 : rtx_insn *insn;
5118 0 : int i;
5119 :
5120 0 : FOR_EACH_VEC_ELT (scheduled_insns, i, insn)
5121 : {
5122 0 : sd_iterator_def sd_it;
5123 0 : dep_t dep;
5124 :
5125 : /* See if we must undo a replacement. */
5126 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_RES_FORW);
5127 0 : sd_iterator_cond (&sd_it, &dep); sd_iterator_next (&sd_it))
5128 : {
5129 0 : struct dep_replacement *desc = DEP_REPLACE (dep);
5130 0 : if (desc != NULL)
5131 0 : validate_change (desc->insn, desc->loc, desc->orig, 0);
5132 : }
5133 : }
5134 0 : }
5135 :
5136 : /* Return first non-scheduled insn in the current scheduling block.
5137 : This is mostly used for debug-counter purposes. */
5138 : static rtx_insn *
5139 0 : first_nonscheduled_insn (void)
5140 : {
5141 0 : rtx_insn *insn = (nonscheduled_insns_begin != NULL_RTX
5142 0 : ? nonscheduled_insns_begin
5143 0 : : current_sched_info->prev_head);
5144 :
5145 0 : do
5146 : {
5147 0 : insn = next_nonnote_nondebug_insn (insn);
5148 : }
5149 0 : while (QUEUE_INDEX (insn) == QUEUE_SCHEDULED);
5150 :
5151 0 : return insn;
5152 : }
5153 :
5154 : /* Move insns that became ready to fire from queue to ready list. */
5155 :
5156 : static void
5157 34957801 : queue_to_ready (struct ready_list *ready)
5158 : {
5159 34957801 : rtx_insn *insn;
5160 34957801 : rtx_insn_list *link;
5161 34957801 : rtx_insn *skip_insn;
5162 :
5163 34957801 : q_ptr = NEXT_Q (q_ptr);
5164 :
5165 34957801 : if (dbg_cnt (sched_insn) == false)
5166 : /* If debug counter is activated do not requeue the first
5167 : nonscheduled insn. */
5168 0 : skip_insn = first_nonscheduled_insn ();
5169 : else
5170 : skip_insn = NULL;
5171 :
5172 : /* Add all pending insns that can be scheduled without stalls to the
5173 : ready list. */
5174 67082073 : for (link = insn_queue[q_ptr]; link; link = link->next ())
5175 : {
5176 32124272 : insn = link->insn ();
5177 32124272 : q_size -= 1;
5178 :
5179 32124272 : if (sched_verbose >= 2)
5180 0 : fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
5181 0 : (*current_sched_info->print_insn) (insn, 0));
5182 :
5183 : /* If the ready list is full, delay the insn for 1 cycle.
5184 : See the comment in schedule_block for the rationale. */
5185 32124272 : if (!reload_completed
5186 5296 : && (ready->n_ready - ready->n_debug > param_max_sched_ready_insns
5187 5119 : || (sched_pressure == SCHED_PRESSURE_MODEL
5188 : /* Limit pressure recalculations to
5189 : param_max_sched_ready_insns instructions too. */
5190 0 : && model_index (insn) > (model_curr_point
5191 0 : + param_max_sched_ready_insns)))
5192 177 : && !(sched_pressure == SCHED_PRESSURE_MODEL
5193 0 : && model_curr_point < model_num_insns
5194 : /* Always allow the next model instruction to issue. */
5195 0 : && model_index (insn) == model_curr_point)
5196 177 : && !SCHED_GROUP_P (insn)
5197 32124449 : && insn != skip_insn)
5198 : {
5199 177 : if (sched_verbose >= 2)
5200 0 : fprintf (sched_dump, "keeping in queue, ready full\n");
5201 177 : queue_insn (insn, 1, "ready full");
5202 : }
5203 : else
5204 : {
5205 32124095 : ready_add (ready, insn, false);
5206 32124095 : if (sched_verbose >= 2)
5207 0 : fprintf (sched_dump, "moving to ready without stalls\n");
5208 : }
5209 : }
5210 34957801 : free_INSN_LIST_list (&insn_queue[q_ptr]);
5211 :
5212 : /* If there are no ready insns, stall until one is ready and add all
5213 : of the pending insns at that point to the ready list. */
5214 34957801 : if (ready->n_ready == 0)
5215 : {
5216 : int stalls;
5217 :
5218 10985388 : for (stalls = 1; stalls <= max_insn_queue_index; stalls++)
5219 : {
5220 10985388 : if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
5221 : {
5222 12595942 : for (; link; link = link->next ())
5223 : {
5224 6521077 : insn = link->insn ();
5225 6521077 : q_size -= 1;
5226 :
5227 6521077 : if (sched_verbose >= 2)
5228 0 : fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
5229 0 : (*current_sched_info->print_insn) (insn, 0));
5230 :
5231 6521077 : ready_add (ready, insn, false);
5232 6521077 : if (sched_verbose >= 2)
5233 0 : fprintf (sched_dump, "moving to ready with %d stalls\n", stalls);
5234 : }
5235 6074865 : free_INSN_LIST_list (&insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]);
5236 :
5237 6074865 : advance_one_cycle ();
5238 :
5239 6074865 : break;
5240 : }
5241 :
5242 4910523 : advance_one_cycle ();
5243 : }
5244 :
5245 6074865 : q_ptr = NEXT_Q_AFTER (q_ptr, stalls);
5246 6074865 : clock_var += stalls;
5247 6074865 : if (sched_verbose >= 2)
5248 0 : fprintf (sched_dump, ";;\tAdvancing clock by %d cycle[s] to %d\n",
5249 : stalls, clock_var);
5250 : }
5251 34957801 : }
5252 :
5253 : /* Used by early_queue_to_ready. Determines whether it is "ok" to
5254 : prematurely move INSN from the queue to the ready list. Currently,
5255 : if a target defines the hook 'is_costly_dependence', this function
5256 : uses the hook to check whether there exist any dependences which are
5257 : considered costly by the target, between INSN and other insns that
5258 : have already been scheduled. Dependences are checked up to Y cycles
5259 : back, with default Y=1; The flag -fsched-stalled-insns-dep=Y allows
5260 : controlling this value.
5261 : (Other considerations could be taken into account instead (or in
5262 : addition) depending on user flags and target hooks. */
5263 :
5264 : static bool
5265 5 : ok_for_early_queue_removal (rtx_insn *insn)
5266 : {
5267 5 : if (targetm.sched.is_costly_dependence)
5268 : {
5269 0 : int n_cycles;
5270 0 : int i = scheduled_insns.length ();
5271 0 : for (n_cycles = flag_sched_stalled_insns_dep; n_cycles; n_cycles--)
5272 : {
5273 0 : while (i-- > 0)
5274 : {
5275 0 : int cost;
5276 :
5277 0 : rtx_insn *prev_insn = scheduled_insns[i];
5278 :
5279 0 : if (!NOTE_P (prev_insn))
5280 : {
5281 0 : dep_t dep;
5282 :
5283 0 : dep = sd_find_dep_between (prev_insn, insn, true);
5284 :
5285 0 : if (dep != NULL)
5286 : {
5287 0 : cost = dep_cost (dep);
5288 :
5289 0 : if (targetm.sched.is_costly_dependence (dep, cost,
5290 0 : flag_sched_stalled_insns_dep - n_cycles))
5291 : return false;
5292 : }
5293 : }
5294 :
5295 0 : if (GET_MODE (prev_insn) == TImode) /* end of dispatch group */
5296 : break;
5297 : }
5298 :
5299 0 : if (i == 0)
5300 : break;
5301 : }
5302 : }
5303 :
5304 : return true;
5305 : }
5306 :
5307 :
5308 : /* Remove insns from the queue, before they become "ready" with respect
5309 : to FU latency considerations. */
5310 :
5311 : static int
5312 33057763 : early_queue_to_ready (state_t state, struct ready_list *ready)
5313 : {
5314 33057763 : rtx_insn *insn;
5315 33057763 : rtx_insn_list *link;
5316 33057763 : rtx_insn_list *next_link;
5317 33057763 : rtx_insn_list *prev_link;
5318 33057763 : bool move_to_ready;
5319 33057763 : int cost;
5320 33057763 : state_t temp_state = alloca (dfa_state_size);
5321 33057763 : int stalls;
5322 33057763 : int insns_removed = 0;
5323 :
5324 : /*
5325 : Flag '-fsched-stalled-insns=X' determines the aggressiveness of this
5326 : function:
5327 :
5328 : X == 0: There is no limit on how many queued insns can be removed
5329 : prematurely. (flag_sched_stalled_insns = -1).
5330 :
5331 : X >= 1: Only X queued insns can be removed prematurely in each
5332 : invocation. (flag_sched_stalled_insns = X).
5333 :
5334 : Otherwise: Early queue removal is disabled.
5335 : (flag_sched_stalled_insns = 0)
5336 : */
5337 :
5338 33057763 : if (! flag_sched_stalled_insns)
5339 : return 0;
5340 :
5341 1799 : for (stalls = 0; stalls <= max_insn_queue_index; stalls++)
5342 : {
5343 1792 : if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
5344 : {
5345 4 : if (sched_verbose > 6)
5346 0 : fprintf (sched_dump, ";; look at index %d + %d\n", q_ptr, stalls);
5347 :
5348 : prev_link = 0;
5349 9 : while (link)
5350 : {
5351 5 : next_link = link->next ();
5352 5 : insn = link->insn ();
5353 5 : if (insn && sched_verbose > 6)
5354 0 : print_rtl_single (sched_dump, insn);
5355 :
5356 5 : memcpy (temp_state, state, dfa_state_size);
5357 5 : if (recog_memoized (insn) < 0)
5358 : /* non-negative to indicate that it's not ready
5359 : to avoid infinite Q->R->Q->R... */
5360 : cost = 0;
5361 : else
5362 5 : cost = state_transition (temp_state, insn);
5363 :
5364 5 : if (sched_verbose >= 6)
5365 0 : fprintf (sched_dump, "transition cost = %d\n", cost);
5366 :
5367 5 : move_to_ready = false;
5368 5 : if (cost < 0)
5369 : {
5370 5 : move_to_ready = ok_for_early_queue_removal (insn);
5371 5 : if (move_to_ready == true)
5372 : {
5373 : /* move from Q to R */
5374 5 : q_size -= 1;
5375 5 : ready_add (ready, insn, false);
5376 :
5377 5 : if (prev_link)
5378 0 : XEXP (prev_link, 1) = next_link;
5379 : else
5380 5 : insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = next_link;
5381 :
5382 5 : free_INSN_LIST_node (link);
5383 :
5384 5 : if (sched_verbose >= 2)
5385 0 : fprintf (sched_dump, ";;\t\tEarly Q-->Ready: insn %s\n",
5386 0 : (*current_sched_info->print_insn) (insn, 0));
5387 :
5388 5 : insns_removed++;
5389 5 : if (insns_removed == flag_sched_stalled_insns)
5390 : /* Remove no more than flag_sched_stalled_insns insns
5391 : from Q at a time. */
5392 : return insns_removed;
5393 : }
5394 : }
5395 :
5396 : if (move_to_ready == false)
5397 : prev_link = link;
5398 :
5399 : link = next_link;
5400 : } /* while link */
5401 : } /* if link */
5402 :
5403 : } /* for stalls.. */
5404 :
5405 : return insns_removed;
5406 : }
5407 :
5408 :
5409 : /* Print the ready list for debugging purposes.
5410 : If READY_TRY is non-zero then only print insns that max_issue
5411 : will consider. */
5412 : static void
5413 190 : debug_ready_list_1 (struct ready_list *ready, signed char *ready_try)
5414 : {
5415 190 : rtx_insn **p;
5416 190 : int i;
5417 :
5418 190 : if (ready->n_ready == 0)
5419 : {
5420 190 : fprintf (sched_dump, "\n");
5421 190 : return;
5422 : }
5423 :
5424 0 : p = ready_lastpos (ready);
5425 0 : for (i = 0; i < ready->n_ready; i++)
5426 : {
5427 0 : if (ready_try != NULL && ready_try[ready->n_ready - i - 1])
5428 0 : continue;
5429 :
5430 0 : fprintf (sched_dump, " %s:%d",
5431 0 : (*current_sched_info->print_insn) (p[i], 0),
5432 0 : INSN_LUID (p[i]));
5433 0 : if (sched_pressure != SCHED_PRESSURE_NONE)
5434 0 : fprintf (sched_dump, "(cost=%d",
5435 0 : INSN_REG_PRESSURE_EXCESS_COST_CHANGE (p[i]));
5436 0 : fprintf (sched_dump, ":prio=%d", INSN_PRIORITY (p[i]));
5437 0 : if (INSN_TICK (p[i]) > clock_var)
5438 0 : fprintf (sched_dump, ":delay=%d", INSN_TICK (p[i]) - clock_var);
5439 0 : if (sched_pressure == SCHED_PRESSURE_MODEL)
5440 0 : fprintf (sched_dump, ":idx=%d",
5441 : model_index (p[i]));
5442 0 : if (sched_pressure != SCHED_PRESSURE_NONE)
5443 0 : fprintf (sched_dump, ")");
5444 : }
5445 0 : fprintf (sched_dump, "\n");
5446 : }
5447 :
5448 : /* Print the ready list. Callable from debugger. */
5449 : static void
5450 190 : debug_ready_list (struct ready_list *ready)
5451 : {
5452 0 : debug_ready_list_1 (ready, NULL);
5453 190 : }
5454 :
5455 : /* Search INSN for REG_SAVE_NOTE notes and convert them back into insn
5456 : NOTEs. This is used for NOTE_INSN_EPILOGUE_BEG, so that sched-ebb
5457 : replaces the epilogue note in the correct basic block. */
5458 : void
5459 60132003 : reemit_notes (rtx_insn *insn)
5460 : {
5461 60132003 : rtx note;
5462 60132003 : rtx_insn *last = insn;
5463 :
5464 119199256 : for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
5465 : {
5466 59067253 : if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
5467 : {
5468 911031 : enum insn_note note_type = (enum insn_note) INTVAL (XEXP (note, 0));
5469 :
5470 911031 : last = emit_note_before (note_type, last);
5471 911031 : remove_note (insn, note);
5472 911031 : df_insn_create_insn_record (last);
5473 : }
5474 : }
5475 60132003 : }
5476 :
5477 : /* Move INSN. Reemit notes if needed. Update CFG, if needed. */
5478 : static void
5479 108621132 : move_insn (rtx_insn *insn, rtx_insn *last, rtx nt)
5480 : {
5481 108621132 : if (PREV_INSN (insn) != last)
5482 : {
5483 13122891 : basic_block bb;
5484 13122891 : rtx_insn *note;
5485 13122891 : int jump_p = 0;
5486 :
5487 13122891 : bb = BLOCK_FOR_INSN (insn);
5488 :
5489 : /* BB_HEAD is either LABEL or NOTE. */
5490 13122891 : gcc_assert (BB_HEAD (bb) != insn);
5491 :
5492 13122891 : if (BB_END (bb) == insn)
5493 : /* If this is last instruction in BB, move end marker one
5494 : instruction up. */
5495 : {
5496 : /* Jumps are always placed at the end of basic block. */
5497 236129 : jump_p = control_flow_insn_p (insn);
5498 :
5499 236129 : gcc_assert (!jump_p
5500 : || ((common_sched_info->sched_pass_id == SCHED_RGN_PASS)
5501 : && IS_SPECULATION_BRANCHY_CHECK_P (insn))
5502 : || (common_sched_info->sched_pass_id
5503 : == SCHED_EBB_PASS));
5504 :
5505 236129 : gcc_assert (BLOCK_FOR_INSN (PREV_INSN (insn)) == bb);
5506 :
5507 236129 : BB_END (bb) = PREV_INSN (insn);
5508 : }
5509 :
5510 13122891 : gcc_assert (BB_END (bb) != last);
5511 :
5512 13122891 : if (jump_p)
5513 : /* We move the block note along with jump. */
5514 : {
5515 1 : gcc_assert (nt);
5516 :
5517 1 : note = NEXT_INSN (insn);
5518 2 : while (NOTE_NOT_BB_P (note) && note != nt)
5519 0 : note = NEXT_INSN (note);
5520 :
5521 1 : if (note != nt
5522 1 : && (LABEL_P (note)
5523 1 : || BARRIER_P (note)))
5524 0 : note = NEXT_INSN (note);
5525 :
5526 1 : gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
5527 : }
5528 : else
5529 : note = insn;
5530 :
5531 13122891 : SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (note);
5532 13122891 : SET_PREV_INSN (NEXT_INSN (note)) = PREV_INSN (insn);
5533 :
5534 13122891 : SET_NEXT_INSN (note) = NEXT_INSN (last);
5535 13122891 : SET_PREV_INSN (NEXT_INSN (last)) = note;
5536 :
5537 13122891 : SET_NEXT_INSN (last) = insn;
5538 13122891 : SET_PREV_INSN (insn) = last;
5539 :
5540 13122891 : bb = BLOCK_FOR_INSN (last);
5541 :
5542 13122891 : if (jump_p)
5543 : {
5544 1 : fix_jump_move (insn);
5545 :
5546 1 : if (BLOCK_FOR_INSN (insn) != bb)
5547 0 : move_block_after_check (insn);
5548 :
5549 1 : gcc_assert (BB_END (bb) == last);
5550 : }
5551 :
5552 13122891 : df_insn_change_bb (insn, bb);
5553 :
5554 : /* Update BB_END, if needed. */
5555 13122891 : if (BB_END (bb) == last)
5556 1 : BB_END (bb) = insn;
5557 : }
5558 :
5559 108621132 : SCHED_GROUP_P (insn) = 0;
5560 108621132 : }
5561 :
5562 : /* Return true if scheduling INSN will finish current clock cycle. */
5563 : static bool
5564 111256674 : insn_finishes_cycle_p (rtx_insn *insn)
5565 : {
5566 111256674 : if (SCHED_GROUP_P (insn))
5567 : /* After issuing INSN, rest of the sched_group will be forced to issue
5568 : in order. Don't make any plans for the rest of cycle. */
5569 : return true;
5570 :
5571 : /* Finishing the block will, apparently, finish the cycle. */
5572 111256416 : if (current_sched_info->insn_finishes_block_p
5573 111256416 : && current_sched_info->insn_finishes_block_p (insn))
5574 : return true;
5575 :
5576 : return false;
5577 : }
5578 :
5579 : /* Helper for autopref_multipass_init. Given a SET in PAT and whether
5580 : we're expecting a memory WRITE or not, check that the insn is relevant to
5581 : the autoprefetcher modelling code. Return true iff that is the case.
5582 : If it is relevant, record the base register of the memory op in BASE and
5583 : the offset in OFFSET. */
5584 :
5585 : static bool
5586 3 : analyze_set_insn_for_autopref (rtx pat, bool write, rtx *base, int *offset)
5587 : {
5588 3 : if (GET_CODE (pat) != SET)
5589 : return false;
5590 :
5591 3 : rtx mem = write ? SET_DEST (pat) : SET_SRC (pat);
5592 3 : if (!MEM_P (mem))
5593 : return false;
5594 :
5595 3 : struct address_info info;
5596 3 : decompose_mem_address (&info, mem);
5597 :
5598 : /* TODO: Currently only (base+const) addressing is supported. */
5599 3 : if (info.base == NULL || !REG_P (*info.base)
5600 3 : || (info.disp != NULL && !CONST_INT_P (*info.disp)))
5601 : return false;
5602 :
5603 3 : *base = *info.base;
5604 3 : *offset = info.disp ? INTVAL (*info.disp) : 0;
5605 3 : return true;
5606 : }
5607 :
5608 : /* Functions to model cache auto-prefetcher.
5609 :
5610 : Some of the CPUs have cache auto-prefetcher, which /seems/ to initiate
5611 : memory prefetches if it sees instructions with consequitive memory accesses
5612 : in the instruction stream. Details of such hardware units are not published,
5613 : so we can only guess what exactly is going on there.
5614 : In the scheduler, we model abstract auto-prefetcher. If there are memory
5615 : insns in the ready list (or the queue) that have same memory base, but
5616 : different offsets, then we delay the insns with larger offsets until insns
5617 : with smaller offsets get scheduled. If PARAM_SCHED_AUTOPREF_QUEUE_DEPTH
5618 : is "1", then we look at the ready list; if it is N>1, then we also look
5619 : through N-1 queue entries.
5620 : If the param is N>=0, then rank_for_schedule will consider auto-prefetching
5621 : among its heuristics.
5622 : Param value of "-1" disables modelling of the auto-prefetcher. */
5623 :
5624 : /* Initialize autoprefetcher model data for INSN. */
5625 : static void
5626 3 : autopref_multipass_init (const rtx_insn *insn, int write)
5627 : {
5628 3 : autopref_multipass_data_t data = &INSN_AUTOPREF_MULTIPASS_DATA (insn)[write];
5629 :
5630 3 : gcc_assert (data->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED);
5631 3 : data->base = NULL_RTX;
5632 3 : data->offset = 0;
5633 : /* Set insn entry initialized, but not relevant for auto-prefetcher. */
5634 3 : data->status = AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
5635 :
5636 3 : rtx pat = PATTERN (insn);
5637 :
5638 : /* We have a multi-set insn like a load-multiple or store-multiple.
5639 : We care about these as long as all the memory ops inside the PARALLEL
5640 : have the same base register. We care about the minimum and maximum
5641 : offsets from that base but don't check for the order of those offsets
5642 : within the PARALLEL insn itself. */
5643 3 : if (GET_CODE (pat) == PARALLEL)
5644 : {
5645 0 : int n_elems = XVECLEN (pat, 0);
5646 :
5647 0 : int i, offset;
5648 0 : rtx base, prev_base = NULL_RTX;
5649 0 : int min_offset = INT_MAX;
5650 :
5651 0 : for (i = 0; i < n_elems; i++)
5652 : {
5653 0 : rtx set = XVECEXP (pat, 0, i);
5654 0 : if (GET_CODE (set) != SET)
5655 : return;
5656 :
5657 0 : if (!analyze_set_insn_for_autopref (set, write, &base, &offset))
5658 : return;
5659 :
5660 : /* Ensure that all memory operations in the PARALLEL use the same
5661 : base register. */
5662 0 : if (i > 0 && REGNO (base) != REGNO (prev_base))
5663 : return;
5664 0 : prev_base = base;
5665 0 : min_offset = MIN (min_offset, offset);
5666 : }
5667 :
5668 : /* If we reached here then we have a valid PARALLEL of multiple memory ops
5669 : with prev_base as the base and min_offset containing the offset. */
5670 0 : gcc_assert (prev_base);
5671 0 : data->base = prev_base;
5672 0 : data->offset = min_offset;
5673 0 : data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
5674 0 : return;
5675 : }
5676 :
5677 : /* Otherwise this is a single set memory operation. */
5678 3 : rtx set = single_set (insn);
5679 3 : if (set == NULL_RTX)
5680 : return;
5681 :
5682 3 : if (!analyze_set_insn_for_autopref (set, write, &data->base,
5683 : &data->offset))
5684 : return;
5685 :
5686 : /* This insn is relevant for the auto-prefetcher.
5687 : The base and offset fields will have been filled in the
5688 : analyze_set_insn_for_autopref call above. */
5689 3 : data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
5690 : }
5691 :
5692 : /* Helper function for rank_for_schedule sorting. */
5693 : static int
5694 12 : autopref_rank_for_schedule (const rtx_insn *insn1, const rtx_insn *insn2)
5695 : {
5696 12 : int r = 0;
5697 24 : for (int write = 0; write < 2 && !r; ++write)
5698 : {
5699 12 : autopref_multipass_data_t data1
5700 12 : = &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];
5701 12 : autopref_multipass_data_t data2
5702 12 : = &INSN_AUTOPREF_MULTIPASS_DATA (insn2)[write];
5703 :
5704 12 : if (data1->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
5705 1 : autopref_multipass_init (insn1, write);
5706 :
5707 12 : if (data2->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
5708 2 : autopref_multipass_init (insn2, write);
5709 :
5710 12 : int irrel1 = data1->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
5711 12 : int irrel2 = data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
5712 :
5713 12 : if (!irrel1 && !irrel2)
5714 : /* Sort memory references from lowest offset to the largest. */
5715 12 : r = (data1->offset > data2->offset) - (data1->offset < data2->offset);
5716 0 : else if (write)
5717 : /* Schedule "irrelevant" insns before memory stores to resolve
5718 : as many producer dependencies of stores as possible. */
5719 0 : r = irrel2 - irrel1;
5720 : else
5721 : /* Schedule "irrelevant" insns after memory reads to avoid breaking
5722 : memory read sequences. */
5723 0 : r = irrel1 - irrel2;
5724 : }
5725 :
5726 12 : return r;
5727 : }
5728 :
5729 : /* True if header of debug dump was printed. */
5730 : static bool autopref_multipass_dfa_lookahead_guard_started_dump_p;
5731 :
5732 : /* Helper for autopref_multipass_dfa_lookahead_guard.
5733 : Return "1" if INSN1 should be delayed in favor of INSN2. */
5734 : static int
5735 0 : autopref_multipass_dfa_lookahead_guard_1 (const rtx_insn *insn1,
5736 : const rtx_insn *insn2, int write)
5737 : {
5738 0 : autopref_multipass_data_t data1
5739 0 : = &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];
5740 0 : autopref_multipass_data_t data2
5741 0 : = &INSN_AUTOPREF_MULTIPASS_DATA (insn2)[write];
5742 :
5743 0 : if (data2->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
5744 0 : autopref_multipass_init (insn2, write);
5745 0 : if (data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT)
5746 : return 0;
5747 :
5748 0 : if (rtx_equal_p (data1->base, data2->base)
5749 0 : && data1->offset > data2->offset)
5750 : {
5751 0 : if (sched_verbose >= 2)
5752 : {
5753 0 : if (!autopref_multipass_dfa_lookahead_guard_started_dump_p)
5754 : {
5755 0 : fprintf (sched_dump,
5756 : ";;\t\tnot trying in max_issue due to autoprefetch "
5757 : "model: ");
5758 0 : autopref_multipass_dfa_lookahead_guard_started_dump_p = true;
5759 : }
5760 :
5761 0 : fprintf (sched_dump, " %d(%d)", INSN_UID (insn1), INSN_UID (insn2));
5762 : }
5763 :
5764 0 : return 1;
5765 : }
5766 :
5767 : return 0;
5768 : }
5769 :
5770 : /* General note:
5771 :
5772 : We could have also hooked autoprefetcher model into
5773 : first_cycle_multipass_backtrack / first_cycle_multipass_issue hooks
5774 : to enable intelligent selection of "[r1+0]=r2; [r1+4]=r3" on the same cycle
5775 : (e.g., once "[r1+0]=r2" is issued in max_issue(), "[r1+4]=r3" gets
5776 : unblocked). We don't bother about this yet because target of interest
5777 : (ARM Cortex-A15) can issue only 1 memory operation per cycle. */
5778 :
5779 : /* Implementation of first_cycle_multipass_dfa_lookahead_guard hook.
5780 : Return "1" if INSN1 should not be considered in max_issue due to
5781 : auto-prefetcher considerations. */
5782 : int
5783 0 : autopref_multipass_dfa_lookahead_guard (rtx_insn *insn1, int ready_index)
5784 : {
5785 0 : int r = 0;
5786 :
5787 : /* Exit early if the param forbids this or if we're not entering here through
5788 : normal haifa scheduling. This can happen if selective scheduling is
5789 : explicitly enabled. */
5790 0 : if (!insn_queue || param_sched_autopref_queue_depth <= 0)
5791 : return 0;
5792 :
5793 0 : if (sched_verbose >= 2 && ready_index == 0)
5794 0 : autopref_multipass_dfa_lookahead_guard_started_dump_p = false;
5795 :
5796 0 : for (int write = 0; write < 2; ++write)
5797 : {
5798 0 : autopref_multipass_data_t data1
5799 0 : = &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];
5800 :
5801 0 : if (data1->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
5802 0 : autopref_multipass_init (insn1, write);
5803 0 : if (data1->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT)
5804 0 : continue;
5805 :
5806 0 : if (ready_index == 0
5807 0 : && data1->status == AUTOPREF_MULTIPASS_DATA_DONT_DELAY)
5808 : /* We allow only a single delay on priviledged instructions.
5809 : Doing otherwise would cause infinite loop. */
5810 : {
5811 0 : if (sched_verbose >= 2)
5812 : {
5813 0 : if (!autopref_multipass_dfa_lookahead_guard_started_dump_p)
5814 : {
5815 0 : fprintf (sched_dump,
5816 : ";;\t\tnot trying in max_issue due to autoprefetch "
5817 : "model: ");
5818 0 : autopref_multipass_dfa_lookahead_guard_started_dump_p = true;
5819 : }
5820 :
5821 0 : fprintf (sched_dump, " *%d*", INSN_UID (insn1));
5822 : }
5823 0 : continue;
5824 : }
5825 :
5826 0 : for (int i2 = 0; i2 < ready.n_ready; ++i2)
5827 : {
5828 0 : rtx_insn *insn2 = get_ready_element (i2);
5829 0 : if (insn1 == insn2)
5830 0 : continue;
5831 0 : r = autopref_multipass_dfa_lookahead_guard_1 (insn1, insn2, write);
5832 0 : if (r)
5833 : {
5834 0 : if (ready_index == 0)
5835 : {
5836 0 : r = -1;
5837 0 : data1->status = AUTOPREF_MULTIPASS_DATA_DONT_DELAY;
5838 : }
5839 0 : goto finish;
5840 : }
5841 : }
5842 :
5843 0 : if (param_sched_autopref_queue_depth == 1)
5844 0 : continue;
5845 :
5846 : /* Everything from the current queue slot should have been moved to
5847 : the ready list. */
5848 0 : gcc_assert (insn_queue[NEXT_Q_AFTER (q_ptr, 0)] == NULL_RTX);
5849 :
5850 0 : int n_stalls = param_sched_autopref_queue_depth - 1;
5851 0 : if (n_stalls > max_insn_queue_index)
5852 : n_stalls = max_insn_queue_index;
5853 :
5854 0 : for (int stalls = 1; stalls <= n_stalls; ++stalls)
5855 : {
5856 0 : for (rtx_insn_list *link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)];
5857 0 : link != NULL_RTX;
5858 0 : link = link->next ())
5859 : {
5860 0 : rtx_insn *insn2 = link->insn ();
5861 0 : r = autopref_multipass_dfa_lookahead_guard_1 (insn1, insn2,
5862 : write);
5863 0 : if (r)
5864 : {
5865 : /* Queue INSN1 until INSN2 can issue. */
5866 0 : r = -stalls;
5867 0 : if (ready_index == 0)
5868 0 : data1->status = AUTOPREF_MULTIPASS_DATA_DONT_DELAY;
5869 0 : goto finish;
5870 : }
5871 : }
5872 : }
5873 : }
5874 :
5875 0 : finish:
5876 0 : if (sched_verbose >= 2
5877 0 : && autopref_multipass_dfa_lookahead_guard_started_dump_p
5878 0 : && (ready_index == ready.n_ready - 1 || r < 0))
5879 : /* This does not /always/ trigger. We don't output EOL if the last
5880 : insn is not recognized (INSN_CODE < 0) and lookahead_guard is not
5881 : called. We can live with this. */
5882 0 : fprintf (sched_dump, "\n");
5883 :
5884 : return r;
5885 : }
5886 :
5887 : /* Define type for target data used in multipass scheduling. */
5888 : #ifndef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T
5889 : # define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T int
5890 : #endif
5891 : typedef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T first_cycle_multipass_data_t;
5892 :
5893 : /* The following structure describe an entry of the stack of choices. */
5894 : struct choice_entry
5895 : {
5896 : /* Ordinal number of the issued insn in the ready queue. */
5897 : int index;
5898 : /* The number of the rest insns whose issues we should try. */
5899 : int rest;
5900 : /* The number of issued essential insns. */
5901 : int n;
5902 : /* State after issuing the insn. */
5903 : state_t state;
5904 : /* Target-specific data. */
5905 : first_cycle_multipass_data_t target_data;
5906 : };
5907 :
5908 : /* The following array is used to implement a stack of choices used in
5909 : function max_issue. */
5910 : static struct choice_entry *choice_stack;
5911 :
5912 : /* This holds the value of the target dfa_lookahead hook. */
5913 : int dfa_lookahead;
5914 :
5915 : /* The following variable value is maximal number of tries of issuing
5916 : insns for the first cycle multipass insn scheduling. We define
5917 : this value as constant*(DFA_LOOKAHEAD**ISSUE_RATE). We would not
5918 : need this constraint if all real insns (with non-negative codes)
5919 : had reservations because in this case the algorithm complexity is
5920 : O(DFA_LOOKAHEAD**ISSUE_RATE). Unfortunately, the dfa descriptions
5921 : might be incomplete and such insn might occur. For such
5922 : descriptions, the complexity of algorithm (without the constraint)
5923 : could achieve DFA_LOOKAHEAD ** N , where N is the queue length. */
5924 : static int max_lookahead_tries;
5925 :
5926 : /* The following function returns maximal (or close to maximal) number
5927 : of insns which can be issued on the same cycle and one of which
5928 : insns is insns with the best rank (the first insn in READY). To
5929 : make this function tries different samples of ready insns. READY
5930 : is current queue `ready'. Global array READY_TRY reflects what
5931 : insns are already issued in this try. The function stops immediately,
5932 : if it reached the such a solution, that all instruction can be issued.
5933 : INDEX will contain index of the best insn in READY. The following
5934 : function is used only for first cycle multipass scheduling.
5935 :
5936 : PRIVILEGED_N >= 0
5937 :
5938 : This function expects recognized insns only. All USEs,
5939 : CLOBBERs, etc must be filtered elsewhere. */
5940 : int
5941 55096841 : max_issue (struct ready_list *ready, int privileged_n, state_t state,
5942 : bool first_cycle_insn_p, int *index)
5943 : {
5944 55096841 : int n, i, all, n_ready, best, delay, tries_num;
5945 55096841 : int more_issue;
5946 55096841 : struct choice_entry *top;
5947 55096841 : rtx_insn *insn;
5948 :
5949 55096841 : if (sched_fusion)
5950 : return 0;
5951 :
5952 55096841 : n_ready = ready->n_ready;
5953 55096841 : gcc_assert (dfa_lookahead >= 1 && privileged_n >= 0
5954 : && privileged_n <= n_ready);
5955 :
5956 : /* Init MAX_LOOKAHEAD_TRIES. */
5957 55096841 : if (max_lookahead_tries == 0)
5958 : {
5959 963981 : max_lookahead_tries = 100;
5960 4774953 : for (i = 0; i < issue_rate; i++)
5961 3810972 : max_lookahead_tries *= dfa_lookahead;
5962 : }
5963 :
5964 : /* Init max_points. */
5965 55096841 : more_issue = issue_rate - cycle_issued_insns;
5966 55096841 : gcc_assert (more_issue >= 0);
5967 :
5968 : /* The number of the issued insns in the best solution. */
5969 55096841 : best = 0;
5970 :
5971 55096841 : top = choice_stack;
5972 :
5973 : /* Set initial state of the search. */
5974 55096841 : memcpy (top->state, state, dfa_state_size);
5975 55096841 : top->rest = dfa_lookahead;
5976 55096841 : top->n = 0;
5977 55096841 : if (targetm.sched.first_cycle_multipass_begin)
5978 54903641 : targetm.sched.first_cycle_multipass_begin (&top->target_data,
5979 : ready_try, n_ready,
5980 : first_cycle_insn_p);
5981 :
5982 : /* Count the number of the insns to search among. */
5983 148004608 : for (all = i = 0; i < n_ready; i++)
5984 92907767 : if (!ready_try [i])
5985 85089884 : all++;
5986 :
5987 55096841 : if (sched_verbose >= 2)
5988 : {
5989 0 : fprintf (sched_dump, ";;\t\tmax_issue among %d insns:", all);
5990 0 : debug_ready_list_1 (ready, ready_try);
5991 : }
5992 :
5993 : /* I is the index of the insn to try next. */
5994 : i = 0;
5995 : tries_num = 0;
5996 1054598891 : for (;;)
5997 : {
5998 554847866 : if (/* If we've reached a dead end or searched enough of what we have
5999 : been asked... */
6000 554847866 : top->rest == 0
6001 : /* or have nothing else to try... */
6002 549451180 : || i >= n_ready
6003 : /* or should not issue more. */
6004 445539038 : || top->n >= more_issue)
6005 : {
6006 : /* ??? (... || i == n_ready). */
6007 111439916 : gcc_assert (i <= n_ready);
6008 :
6009 : /* We should not issue more than issue_rate instructions. */
6010 111439916 : gcc_assert (top->n <= more_issue);
6011 :
6012 111439916 : if (top == choice_stack)
6013 : break;
6014 :
6015 102628328 : if (best < top - choice_stack)
6016 : {
6017 53496236 : if (privileged_n)
6018 : {
6019 : n = privileged_n;
6020 : /* Try to find issued privileged insn. */
6021 106985514 : while (n && !ready_try[--n])
6022 : ;
6023 : }
6024 :
6025 53492756 : if (/* If all insns are equally good... */
6026 : privileged_n == 0
6027 : /* Or a privileged insn will be issued. */
6028 53492756 : || ready_try[n])
6029 : /* Then we have a solution. */
6030 : {
6031 53494396 : best = top - choice_stack;
6032 : /* This is the index of the insn issued first in this
6033 : solution. */
6034 53494396 : *index = choice_stack [1].index;
6035 53494396 : if (top->n == more_issue || best == all)
6036 : break;
6037 : }
6038 : }
6039 :
6040 : /* Set ready-list index to point to the last insn
6041 : ('i++' below will advance it to the next insn). */
6042 56343090 : i = top->index;
6043 :
6044 : /* Backtrack. */
6045 56343090 : ready_try [i] = 0;
6046 :
6047 56343090 : if (targetm.sched.first_cycle_multipass_backtrack)
6048 56223098 : targetm.sched.first_cycle_multipass_backtrack (&top->target_data,
6049 : ready_try, n_ready);
6050 :
6051 56343090 : top--;
6052 56343090 : memcpy (state, top->state, dfa_state_size);
6053 : }
6054 443407950 : else if (!ready_try [i])
6055 : {
6056 141998666 : tries_num++;
6057 141998666 : if (tries_num > max_lookahead_tries)
6058 : break;
6059 141998651 : insn = ready_element (ready, i);
6060 141998651 : delay = state_transition (state, insn);
6061 141998651 : if (delay < 0)
6062 : {
6063 111256674 : if (state_dead_lock_p (state)
6064 111256674 : || insn_finishes_cycle_p (insn))
6065 : /* We won't issue any more instructions in the next
6066 : choice_state. */
6067 5828813 : top->rest = 0;
6068 : else
6069 105427861 : top->rest--;
6070 :
6071 111256674 : n = top->n;
6072 111256674 : if (memcmp (top->state, state, dfa_state_size) != 0)
6073 110250074 : n++;
6074 :
6075 : /* Advance to the next choice_entry. */
6076 111256674 : top++;
6077 : /* Initialize it. */
6078 111256674 : top->rest = dfa_lookahead;
6079 111256674 : top->index = i;
6080 111256674 : top->n = n;
6081 111256674 : memcpy (top->state, state, dfa_state_size);
6082 111256674 : ready_try [i] = 1;
6083 :
6084 111256674 : if (targetm.sched.first_cycle_multipass_issue)
6085 110932326 : targetm.sched.first_cycle_multipass_issue (&top->target_data,
6086 : ready_try, n_ready,
6087 : insn,
6088 110932326 : &((top - 1)
6089 : ->target_data));
6090 :
6091 : i = -1;
6092 : }
6093 : }
6094 :
6095 : /* Increase ready-list index. */
6096 499751025 : i++;
6097 : }
6098 :
6099 55096841 : if (targetm.sched.first_cycle_multipass_end)
6100 107644939 : targetm.sched.first_cycle_multipass_end (best != 0
6101 52741298 : ? &choice_stack[1].target_data
6102 : : NULL);
6103 :
6104 : /* Restore the original state of the DFA. */
6105 55096841 : memcpy (state, choice_stack->state, dfa_state_size);
6106 :
6107 55096841 : return best;
6108 : }
6109 :
6110 : /* The following function chooses insn from READY and modifies
6111 : READY. The following function is used only for first
6112 : cycle multipass scheduling.
6113 : Return:
6114 : -1 if cycle should be advanced,
6115 : 0 if INSN_PTR is set to point to the desirable insn,
6116 : 1 if choose_ready () should be restarted without advancing the cycle. */
6117 : static int
6118 60129640 : choose_ready (struct ready_list *ready, bool first_cycle_insn_p,
6119 : rtx_insn **insn_ptr)
6120 : {
6121 60129640 : if (dbg_cnt (sched_insn) == false)
6122 : {
6123 0 : if (nonscheduled_insns_begin == NULL_RTX)
6124 0 : nonscheduled_insns_begin = current_sched_info->prev_head;
6125 :
6126 0 : rtx_insn *insn = first_nonscheduled_insn ();
6127 :
6128 0 : if (QUEUE_INDEX (insn) == QUEUE_READY)
6129 : /* INSN is in the ready_list. */
6130 : {
6131 0 : ready_remove_insn (insn);
6132 0 : *insn_ptr = insn;
6133 0 : return 0;
6134 : }
6135 :
6136 : /* INSN is in the queue. Advance cycle to move it to the ready list. */
6137 0 : gcc_assert (QUEUE_INDEX (insn) >= 0);
6138 : return -1;
6139 : }
6140 :
6141 60129640 : if (SCHED_GROUP_P (ready_element (ready, 0))
6142 60129640 : || DEBUG_INSN_P (ready_element (ready, 0)))
6143 : {
6144 4179235 : *insn_ptr = ready_remove_first (ready);
6145 4179235 : return 0;
6146 : }
6147 55950405 : else if (dfa_lookahead <= 0)
6148 : {
6149 9617 : if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
6150 16 : *insn_ptr = ready_remove_first_dispatch (ready);
6151 : else
6152 9601 : *insn_ptr = ready_remove_first (ready);
6153 :
6154 9617 : return 0;
6155 : }
6156 : else
6157 : {
6158 : /* Try to choose the best insn. */
6159 55940788 : int index = 0, i;
6160 55940788 : rtx_insn *insn;
6161 :
6162 55940788 : insn = ready_element (ready, 0);
6163 55940788 : if (INSN_CODE (insn) < 0)
6164 : {
6165 847464 : *insn_ptr = ready_remove_first (ready);
6166 847464 : return 0;
6167 : }
6168 :
6169 : /* Filter the search space. */
6170 147995383 : for (i = 0; i < ready->n_ready; i++)
6171 : {
6172 92902059 : ready_try[i] = 0;
6173 :
6174 92902059 : insn = ready_element (ready, i);
6175 :
6176 : /* If this insn is recognizable we should have already
6177 : recognized it earlier.
6178 : ??? Not very clear where this is supposed to be done.
6179 : See dep_cost_1. */
6180 92902059 : gcc_checking_assert (INSN_CODE (insn) >= 0
6181 : || recog_memoized (insn) < 0);
6182 92902059 : if (INSN_CODE (insn) < 0)
6183 : {
6184 : /* Non-recognized insns at position 0 are handled above. */
6185 244559 : gcc_assert (i > 0);
6186 244559 : ready_try[i] = 1;
6187 244559 : continue;
6188 : }
6189 :
6190 92657500 : if (targetm.sched.first_cycle_multipass_dfa_lookahead_guard)
6191 : {
6192 0 : ready_try[i]
6193 0 : = (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
6194 0 : (insn, i));
6195 :
6196 0 : if (ready_try[i] < 0)
6197 : /* Queue instruction for several cycles.
6198 : We need to restart choose_ready as we have changed
6199 : the ready list. */
6200 : {
6201 0 : change_queue_index (insn, -ready_try[i]);
6202 0 : return 1;
6203 : }
6204 :
6205 : /* Make sure that we didn't end up with 0'th insn filtered out.
6206 : Don't be tempted to make life easier for backends and just
6207 : requeue 0'th insn if (ready_try[0] == 0) and restart
6208 : choose_ready. Backends should be very considerate about
6209 : requeueing instructions -- especially the highest priority
6210 : one at position 0. */
6211 0 : gcc_assert (ready_try[i] == 0 || i > 0);
6212 0 : if (ready_try[i])
6213 0 : continue;
6214 : }
6215 :
6216 92657500 : gcc_assert (ready_try[i] == 0);
6217 : /* INSN made it through the scrutiny of filters! */
6218 : }
6219 :
6220 55093324 : if (max_issue (ready, 1, curr_state, first_cycle_insn_p, &index) == 0)
6221 : {
6222 2162327 : *insn_ptr = ready_remove_first (ready);
6223 2162327 : if (sched_verbose >= 4)
6224 0 : fprintf (sched_dump, ";;\t\tChosen insn (but can't issue) : %s \n",
6225 0 : (*current_sched_info->print_insn) (*insn_ptr, 0));
6226 2162327 : return 0;
6227 : }
6228 : else
6229 : {
6230 52930997 : if (sched_verbose >= 4)
6231 0 : fprintf (sched_dump, ";;\t\tChosen insn : %s\n",
6232 0 : (*current_sched_info->print_insn)
6233 0 : (ready_element (ready, index), 0));
6234 :
6235 52930997 : *insn_ptr = ready_remove (ready, index);
6236 52930997 : return 0;
6237 : }
6238 : }
6239 : }
6240 :
6241 : /* This function is called when we have successfully scheduled a
6242 : block. It uses the schedule stored in the scheduled_insns vector
6243 : to rearrange the RTL. PREV_HEAD is used as the anchor to which we
6244 : append the scheduled insns; TAIL is the insn after the scheduled
6245 : block. TARGET_BB is the argument passed to schedule_block. */
6246 :
6247 : static void
6248 10313337 : commit_schedule (rtx_insn *prev_head, rtx_insn *tail, basic_block *target_bb)
6249 : {
6250 10313337 : unsigned int i;
6251 10313337 : rtx_insn *insn;
6252 :
6253 10313337 : last_scheduled_insn = prev_head;
6254 10313337 : for (i = 0;
6255 118934469 : scheduled_insns.iterate (i, &insn);
6256 : i++)
6257 : {
6258 108621132 : if (control_flow_insn_p (last_scheduled_insn)
6259 108621132 : || current_sched_info->advance_target_bb (*target_bb, insn))
6260 : {
6261 48 : *target_bb = current_sched_info->advance_target_bb (*target_bb, 0);
6262 :
6263 48 : if (sched_verbose)
6264 : {
6265 2 : rtx_insn *x;
6266 :
6267 2 : x = next_real_insn (last_scheduled_insn);
6268 2 : gcc_assert (x);
6269 2 : dump_new_block_header (1, *target_bb, x, tail);
6270 : }
6271 :
6272 48 : last_scheduled_insn = bb_note (*target_bb);
6273 : }
6274 :
6275 108621132 : if (current_sched_info->begin_move_insn)
6276 1257 : (*current_sched_info->begin_move_insn) (insn, last_scheduled_insn);
6277 108621132 : move_insn (insn, last_scheduled_insn,
6278 108621132 : current_sched_info->next_tail);
6279 108621132 : if (!DEBUG_INSN_P (insn))
6280 60127402 : reemit_notes (insn);
6281 108621132 : last_scheduled_insn = insn;
6282 : }
6283 :
6284 10313337 : scheduled_insns.truncate (0);
6285 10313337 : }
6286 :
6287 : /* Examine all insns on the ready list and queue those which can't be
6288 : issued in this cycle. TEMP_STATE is temporary scheduler state we
6289 : can use as scratch space. If FIRST_CYCLE_INSN_P is true, no insns
6290 : have been issued for the current cycle, which means it is valid to
6291 : issue an asm statement.
6292 :
6293 : If SHADOWS_ONLY_P is true, we eliminate all real insns and only
6294 : leave those for which SHADOW_P is true. If MODULO_EPILOGUE is true,
6295 : we only leave insns which have an INSN_EXACT_TICK. */
6296 :
6297 : static void
6298 69179689 : prune_ready_list (state_t temp_state, bool first_cycle_insn_p,
6299 : bool shadows_only_p, bool modulo_epilogue_p)
6300 : {
6301 69179689 : int i, pass;
6302 69179689 : bool sched_group_found = false;
6303 69179689 : int min_cost_group = 0;
6304 :
6305 69179689 : if (sched_fusion)
6306 : return;
6307 :
6308 189062256 : for (i = 0; i < ready.n_ready; i++)
6309 : {
6310 124082133 : rtx_insn *insn = ready_element (&ready, i);
6311 124082133 : if (SCHED_GROUP_P (insn))
6312 : {
6313 : sched_group_found = true;
6314 : break;
6315 : }
6316 : }
6317 :
6318 : /* Make two passes if there's a SCHED_GROUP_P insn; make sure to handle
6319 : such an insn first and note its cost. If at least one SCHED_GROUP_P insn
6320 : gets queued, then all other insns get queued for one cycle later. */
6321 223589893 : for (pass = sched_group_found ? 0 : 1; pass < 2; )
6322 : {
6323 85230515 : int n = ready.n_ready;
6324 202853876 : for (i = 0; i < n; i++)
6325 : {
6326 129474621 : rtx_insn *insn = ready_element (&ready, i);
6327 129474621 : int cost = 0;
6328 129474621 : const char *reason = "resource conflict";
6329 :
6330 129474621 : if (DEBUG_INSN_P (insn))
6331 6421107 : continue;
6332 :
6333 8383555 : if (sched_group_found && !SCHED_GROUP_P (insn)
6334 123053724 : && ((pass == 0) || (min_cost_group >= 1)))
6335 : {
6336 124 : if (pass == 0)
6337 105 : continue;
6338 : cost = min_cost_group;
6339 : reason = "not in sched group";
6340 : }
6341 123053390 : else if (modulo_epilogue_p
6342 123053390 : && INSN_EXACT_TICK (insn) == INVALID_TICK)
6343 : {
6344 : cost = max_insn_queue_index;
6345 : reason = "not an epilogue insn";
6346 : }
6347 123053390 : else if (shadows_only_p && !SHADOW_P (insn))
6348 : {
6349 : cost = 1;
6350 : reason = "not a shadow";
6351 : }
6352 123053390 : else if (recog_memoized (insn) < 0)
6353 : {
6354 1166192 : if (!first_cycle_insn_p
6355 1166192 : && (GET_CODE (PATTERN (insn)) == ASM_INPUT
6356 940464 : || asm_noperands (PATTERN (insn)) >= 0))
6357 : cost = 1;
6358 : reason = "asm";
6359 : }
6360 121887198 : else if (sched_pressure != SCHED_PRESSURE_NONE)
6361 : {
6362 23336 : if (sched_pressure == SCHED_PRESSURE_MODEL
6363 23336 : && INSN_TICK (insn) <= clock_var)
6364 : {
6365 0 : memcpy (temp_state, curr_state, dfa_state_size);
6366 0 : if (state_transition (temp_state, insn) >= 0)
6367 0 : INSN_TICK (insn) = clock_var + 1;
6368 : }
6369 : cost = 0;
6370 : }
6371 : else
6372 : {
6373 121863862 : int delay_cost = 0;
6374 :
6375 121863862 : if (delay_htab)
6376 : {
6377 0 : struct delay_pair *delay_entry;
6378 0 : delay_entry
6379 0 : = delay_htab->find_with_hash (insn,
6380 : htab_hash_pointer (insn));
6381 0 : while (delay_entry && delay_cost == 0)
6382 : {
6383 0 : delay_cost = estimate_shadow_tick (delay_entry);
6384 0 : if (delay_cost > max_insn_queue_index)
6385 : delay_cost = max_insn_queue_index;
6386 0 : delay_entry = delay_entry->next_same_i1;
6387 : }
6388 : }
6389 :
6390 121863862 : memcpy (temp_state, curr_state, dfa_state_size);
6391 121863862 : cost = state_transition (temp_state, insn);
6392 121863862 : if (cost < 0)
6393 : cost = 0;
6394 19454343 : else if (cost == 0)
6395 0 : cost = 1;
6396 121863862 : if (cost < delay_cost)
6397 : {
6398 0 : cost = delay_cost;
6399 0 : reason = "shadow tick";
6400 : }
6401 : }
6402 121863881 : if (cost >= 1)
6403 : {
6404 19506944 : if (SCHED_GROUP_P (insn) && cost > min_cost_group)
6405 19506944 : min_cost_group = cost;
6406 19506944 : ready_remove (&ready, i);
6407 : /* Normally we'd want to queue INSN for COST cycles. However,
6408 : if SCHED_GROUP_P is set, then we must ensure that nothing
6409 : else comes between INSN and its predecessor. If there is
6410 : some other insn ready to fire on the next cycle, then that
6411 : invariant would be broken.
6412 :
6413 : So when SCHED_GROUP_P is set, just queue this insn for a
6414 : single cycle. */
6415 19522731 : queue_insn (insn, SCHED_GROUP_P (insn) ? 1 : cost, reason);
6416 19506944 : if (i + 1 < n)
6417 : break;
6418 : }
6419 : }
6420 85230515 : if (i == n)
6421 73379255 : pass++;
6422 : }
6423 : }
6424 :
6425 : /* Called when we detect that the schedule is impossible. We examine the
6426 : backtrack queue to find the earliest insn that caused this condition. */
6427 :
6428 : static struct haifa_saved_data *
6429 0 : verify_shadows (void)
6430 : {
6431 0 : struct haifa_saved_data *save, *earliest_fail = NULL;
6432 0 : for (save = backtrack_queue; save; save = save->next)
6433 : {
6434 0 : int t;
6435 0 : struct delay_pair *pair = save->delay_pair;
6436 0 : rtx_insn *i1 = pair->i1;
6437 :
6438 0 : for (; pair; pair = pair->next_same_i1)
6439 : {
6440 0 : rtx_insn *i2 = pair->i2;
6441 :
6442 0 : if (QUEUE_INDEX (i2) == QUEUE_SCHEDULED)
6443 0 : continue;
6444 :
6445 0 : t = INSN_TICK (i1) + pair_delay (pair);
6446 0 : if (t < clock_var)
6447 : {
6448 0 : if (sched_verbose >= 2)
6449 0 : fprintf (sched_dump,
6450 : ";;\t\tfailed delay requirements for %d/%d (%d->%d)"
6451 : ", not ready\n",
6452 : INSN_UID (pair->i1), INSN_UID (pair->i2),
6453 0 : INSN_TICK (pair->i1), INSN_EXACT_TICK (pair->i2));
6454 : earliest_fail = save;
6455 : break;
6456 : }
6457 0 : if (QUEUE_INDEX (i2) >= 0)
6458 : {
6459 0 : int queued_for = INSN_TICK (i2);
6460 :
6461 0 : if (t < queued_for)
6462 : {
6463 0 : if (sched_verbose >= 2)
6464 0 : fprintf (sched_dump,
6465 : ";;\t\tfailed delay requirements for %d/%d"
6466 : " (%d->%d), queued too late\n",
6467 : INSN_UID (pair->i1), INSN_UID (pair->i2),
6468 0 : INSN_TICK (pair->i1), INSN_EXACT_TICK (pair->i2));
6469 : earliest_fail = save;
6470 : break;
6471 : }
6472 : }
6473 : }
6474 : }
6475 :
6476 0 : return earliest_fail;
6477 : }
6478 :
6479 : /* Print instructions together with useful scheduling information between
6480 : HEAD and TAIL (inclusive). */
6481 : static void
6482 0 : dump_insn_stream (rtx_insn *head, rtx_insn *tail)
6483 : {
6484 0 : fprintf (sched_dump, ";;\t| insn | prio |\n");
6485 :
6486 0 : rtx_insn *next_tail = NEXT_INSN (tail);
6487 0 : for (rtx_insn *insn = head; insn != next_tail; insn = NEXT_INSN (insn))
6488 : {
6489 0 : int priority = NOTE_P (insn) ? 0 : INSN_PRIORITY (insn);
6490 0 : const char *pattern = (NOTE_P (insn)
6491 0 : ? "note"
6492 0 : : str_pattern_slim (PATTERN (insn)));
6493 :
6494 0 : fprintf (sched_dump, ";;\t| %4d | %4d | %-30s ",
6495 0 : INSN_UID (insn), priority, pattern);
6496 :
6497 0 : if (sched_verbose >= 4)
6498 : {
6499 0 : if (NOTE_P (insn) || LABEL_P (insn) || recog_memoized (insn) < 0)
6500 0 : fprintf (sched_dump, "nothing");
6501 : else
6502 0 : print_reservation (sched_dump, insn);
6503 : }
6504 0 : fprintf (sched_dump, "\n");
6505 : }
6506 0 : }
6507 :
6508 : /* Use forward list scheduling to rearrange insns of block pointed to by
6509 : TARGET_BB, possibly bringing insns from subsequent blocks in the same
6510 : region. */
6511 :
6512 : bool
6513 10313337 : schedule_block (basic_block *target_bb, state_t init_state)
6514 : {
6515 10313337 : int i;
6516 10313337 : bool success = modulo_ii == 0;
6517 10313337 : struct sched_block_state ls;
6518 10313337 : state_t temp_state = NULL; /* It is used for multipass scheduling. */
6519 10313337 : int sort_p, advance, start_clock_var;
6520 :
6521 : /* Head/tail info for this block. */
6522 10313337 : rtx_insn *prev_head = current_sched_info->prev_head;
6523 10313337 : rtx_insn *next_tail = current_sched_info->next_tail;
6524 10313337 : rtx_insn *head = NEXT_INSN (prev_head);
6525 10313337 : rtx_insn *tail = PREV_INSN (next_tail);
6526 :
6527 10313337 : if ((current_sched_info->flags & DONT_BREAK_DEPENDENCIES) == 0
6528 10313337 : && sched_pressure != SCHED_PRESSURE_MODEL && !sched_fusion)
6529 10313337 : find_modifiable_mems (head, tail);
6530 :
6531 : /* We used to have code to avoid getting parameters moved from hard
6532 : argument registers into pseudos.
6533 :
6534 : However, it was removed when it proved to be of marginal benefit
6535 : and caused problems because schedule_block and compute_forward_dependences
6536 : had different notions of what the "head" insn was. */
6537 :
6538 10313337 : gcc_assert (head != tail || INSN_P (head));
6539 :
6540 10313337 : haifa_recovery_bb_recently_added_p = false;
6541 :
6542 10313337 : backtrack_queue = NULL;
6543 :
6544 : /* Debug info. */
6545 10313337 : if (sched_verbose)
6546 : {
6547 190 : dump_new_block_header (0, *target_bb, head, tail);
6548 :
6549 190 : if (sched_verbose >= 2)
6550 : {
6551 0 : dump_insn_stream (head, tail);
6552 0 : memset (&rank_for_schedule_stats, 0,
6553 : sizeof (rank_for_schedule_stats));
6554 : }
6555 : }
6556 :
6557 10313337 : if (init_state == NULL)
6558 174 : state_reset (curr_state);
6559 : else
6560 10313163 : memcpy (curr_state, init_state, dfa_state_size);
6561 :
6562 : /* Clear the ready list. */
6563 10313337 : ready.first = ready.veclen - 1;
6564 10313337 : ready.n_ready = 0;
6565 10313337 : ready.n_debug = 0;
6566 :
6567 : /* It is used for first cycle multipass scheduling. */
6568 10313337 : temp_state = alloca (dfa_state_size);
6569 :
6570 10313337 : if (targetm.sched.init)
6571 0 : targetm.sched.init (sched_dump, sched_verbose, ready.veclen);
6572 :
6573 : /* We start inserting insns after PREV_HEAD. */
6574 10313337 : last_scheduled_insn = prev_head;
6575 10313337 : last_nondebug_scheduled_insn = NULL;
6576 10313337 : nonscheduled_insns_begin = NULL;
6577 :
6578 10313337 : gcc_assert ((NOTE_P (last_scheduled_insn)
6579 : || DEBUG_INSN_P (last_scheduled_insn))
6580 : && BLOCK_FOR_INSN (last_scheduled_insn) == *target_bb);
6581 :
6582 : /* Initialize INSN_QUEUE. Q_SIZE is the total number of insns in the
6583 : queue. */
6584 10313337 : q_ptr = 0;
6585 10313337 : q_size = 0;
6586 :
6587 10313337 : insn_queue = XALLOCAVEC (rtx_insn_list *, max_insn_queue_index + 1);
6588 10313337 : memset (insn_queue, 0, (max_insn_queue_index + 1) * sizeof (rtx));
6589 :
6590 : /* Start just before the beginning of time. */
6591 10313337 : clock_var = -1;
6592 :
6593 : /* We need queue and ready lists and clock_var be initialized
6594 : in try_ready () (which is called through init_ready_list ()). */
6595 10313337 : (*current_sched_info->init_ready_list) ();
6596 :
6597 10313337 : if (sched_pressure)
6598 430 : sched_pressure_start_bb (*target_bb);
6599 :
6600 : /* The algorithm is O(n^2) in the number of ready insns at any given
6601 : time in the worst case. Before reload we are more likely to have
6602 : big lists so truncate them to a reasonable size. */
6603 10313337 : if (!reload_completed
6604 931 : && ready.n_ready - ready.n_debug > param_max_sched_ready_insns)
6605 : {
6606 4 : ready_sort_debug (&ready);
6607 4 : ready_sort_real (&ready);
6608 :
6609 : /* Find first free-standing insn past param_max_sched_ready_insns.
6610 : If there are debug insns, we know they're first. */
6611 4 : for (i = param_max_sched_ready_insns + ready.n_debug; i < ready.n_ready;
6612 : i++)
6613 4 : if (!SCHED_GROUP_P (ready_element (&ready, i)))
6614 : break;
6615 :
6616 4 : if (sched_verbose >= 2)
6617 : {
6618 0 : fprintf (sched_dump,
6619 : ";;\t\tReady list on entry: %d insns: ", ready.n_ready);
6620 0 : debug_ready_list (&ready);
6621 0 : fprintf (sched_dump,
6622 : ";;\t\t before reload => truncated to %d insns\n", i);
6623 : }
6624 :
6625 : /* Delay all insns past it for 1 cycle. If debug counter is
6626 : activated make an exception for the insn right after
6627 : nonscheduled_insns_begin. */
6628 4 : {
6629 4 : rtx_insn *skip_insn;
6630 :
6631 4 : if (dbg_cnt (sched_insn) == false)
6632 0 : skip_insn = first_nonscheduled_insn ();
6633 : else
6634 4 : skip_insn = NULL;
6635 :
6636 30 : while (i < ready.n_ready)
6637 : {
6638 26 : rtx_insn *insn;
6639 :
6640 26 : insn = ready_remove (&ready, i);
6641 :
6642 26 : if (insn != skip_insn)
6643 26 : queue_insn (insn, 1, "list truncated");
6644 : }
6645 4 : if (skip_insn)
6646 0 : ready_add (&ready, skip_insn, true);
6647 : }
6648 : }
6649 :
6650 : /* Now we can restore basic block notes and maintain precise cfg. */
6651 10313337 : restore_bb_notes (*target_bb);
6652 :
6653 10313337 : last_clock_var = -1;
6654 :
6655 10313337 : advance = 0;
6656 :
6657 10313337 : gcc_assert (scheduled_insns.length () == 0);
6658 10313337 : sort_p = true;
6659 10313337 : must_backtrack = false;
6660 10313337 : modulo_insns_scheduled = 0;
6661 :
6662 10313337 : ls.modulo_epilogue = false;
6663 10313337 : ls.first_cycle_insn_p = true;
6664 :
6665 : /* Loop until all the insns in BB are scheduled. */
6666 45271138 : while ((*current_sched_info->schedule_more_p) ())
6667 : {
6668 34957801 : perform_replacements_new_cycle ();
6669 34957801 : do
6670 : {
6671 34957801 : start_clock_var = clock_var;
6672 :
6673 34957801 : clock_var++;
6674 :
6675 34957801 : advance_one_cycle ();
6676 :
6677 : /* Add to the ready list all pending insns that can be issued now.
6678 : If there are no ready insns, increment clock until one
6679 : is ready and add all pending insns at that point to the ready
6680 : list. */
6681 34957801 : queue_to_ready (&ready);
6682 :
6683 34957801 : gcc_assert (ready.n_ready);
6684 :
6685 34957801 : if (sched_verbose >= 2)
6686 : {
6687 0 : fprintf (sched_dump, ";;\t\tReady list after queue_to_ready:");
6688 0 : debug_ready_list (&ready);
6689 : }
6690 34957801 : advance -= clock_var - start_clock_var;
6691 : }
6692 34957801 : while (advance > 0);
6693 :
6694 34957801 : if (ls.modulo_epilogue)
6695 : {
6696 0 : int stage = clock_var / modulo_ii;
6697 0 : if (stage > modulo_last_stage * 2 + 2)
6698 : {
6699 0 : if (sched_verbose >= 2)
6700 0 : fprintf (sched_dump,
6701 : ";;\t\tmodulo scheduled succeeded at II %d\n",
6702 : modulo_ii);
6703 0 : success = true;
6704 0 : goto end_schedule;
6705 : }
6706 : }
6707 34957801 : else if (modulo_ii > 0)
6708 : {
6709 0 : int stage = clock_var / modulo_ii;
6710 0 : if (stage > modulo_max_stages)
6711 : {
6712 0 : if (sched_verbose >= 2)
6713 0 : fprintf (sched_dump,
6714 : ";;\t\tfailing schedule due to excessive stages\n");
6715 0 : goto end_schedule;
6716 : }
6717 0 : if (modulo_n_insns == modulo_insns_scheduled
6718 0 : && stage > modulo_last_stage)
6719 : {
6720 0 : if (sched_verbose >= 2)
6721 0 : fprintf (sched_dump,
6722 : ";;\t\tfound kernel after %d stages, II %d\n",
6723 : stage, modulo_ii);
6724 0 : ls.modulo_epilogue = true;
6725 : }
6726 : }
6727 :
6728 34957801 : prune_ready_list (temp_state, true, false, ls.modulo_epilogue);
6729 34957801 : if (ready.n_ready == 0)
6730 4154 : continue;
6731 34953647 : if (must_backtrack)
6732 0 : goto do_backtrack;
6733 :
6734 34953647 : ls.shadows_only_p = false;
6735 34953647 : cycle_issued_insns = 0;
6736 34953647 : ls.can_issue_more = issue_rate;
6737 155094107 : for (;;)
6738 : {
6739 95023877 : rtx_insn *insn;
6740 95023877 : int cost;
6741 95023877 : bool asm_p;
6742 :
6743 95023877 : if (sort_p && ready.n_ready > 0)
6744 : {
6745 : /* Sort the ready list based on priority. This must be
6746 : done every iteration through the loop, as schedule_insn
6747 : may have readied additional insns that will not be
6748 : sorted correctly. */
6749 62020082 : ready_sort (&ready);
6750 :
6751 62020082 : if (sched_verbose >= 2)
6752 : {
6753 0 : fprintf (sched_dump,
6754 : ";;\t\tReady list after ready_sort: ");
6755 0 : debug_ready_list (&ready);
6756 : }
6757 : }
6758 :
6759 : /* We don't want md sched reorder to even see debug isns, so put
6760 : them out right away. */
6761 62020082 : if (ready.n_ready && DEBUG_INSN_P (ready_element (&ready, 0))
6762 101442844 : && (*current_sched_info->schedule_more_p) ())
6763 : {
6764 54912697 : while (ready.n_ready && DEBUG_INSN_P (ready_element (&ready, 0)))
6765 : {
6766 48493730 : rtx_insn *insn = ready_remove_first (&ready);
6767 48493730 : gcc_assert (DEBUG_INSN_P (insn));
6768 48493730 : (*current_sched_info->begin_schedule_ready) (insn);
6769 48493730 : scheduled_insns.safe_push (insn);
6770 48493730 : last_scheduled_insn = insn;
6771 48493730 : advance = schedule_insn (insn);
6772 48493730 : gcc_assert (advance == 0);
6773 48493730 : if (ready.n_ready > 0)
6774 46680361 : ready_sort (&ready);
6775 : }
6776 : }
6777 :
6778 95023877 : if (ls.first_cycle_insn_p && !ready.n_ready)
6779 : break;
6780 :
6781 95022632 : resume_after_backtrack:
6782 : /* Allow the target to reorder the list, typically for
6783 : better instruction bundling. */
6784 95022632 : if (sort_p
6785 95022632 : && (ready.n_ready == 0
6786 60206713 : || !SCHED_GROUP_P (ready_element (&ready, 0))))
6787 : {
6788 90838853 : if (ls.first_cycle_insn_p && targetm.sched.reorder)
6789 34932071 : ls.can_issue_more
6790 34932071 : = targetm.sched.reorder (sched_dump, sched_verbose,
6791 : ready_lastpos (&ready),
6792 : &ready.n_ready, clock_var);
6793 55906782 : else if (!ls.first_cycle_insn_p && targetm.sched.reorder2)
6794 0 : ls.can_issue_more
6795 0 : = targetm.sched.reorder2 (sched_dump, sched_verbose,
6796 0 : ready.n_ready
6797 0 : ? ready_lastpos (&ready) : NULL,
6798 : &ready.n_ready, clock_var);
6799 : }
6800 :
6801 95022632 : restart_choose_ready:
6802 95022632 : if (sched_verbose >= 2)
6803 : {
6804 0 : fprintf (sched_dump, ";;\tReady list (t = %3d): ",
6805 : clock_var);
6806 0 : debug_ready_list (&ready);
6807 0 : if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
6808 0 : print_curr_reg_pressure ();
6809 : }
6810 :
6811 95022632 : if (ready.n_ready == 0
6812 34815919 : && ls.can_issue_more
6813 33060560 : && reload_completed)
6814 : {
6815 : /* Allow scheduling insns directly from the queue in case
6816 : there's nothing better to do (ready list is empty) but
6817 : there are still vacant dispatch slots in the current cycle. */
6818 33057763 : if (sched_verbose >= 6)
6819 0 : fprintf (sched_dump,";;\t\tSecond chance\n");
6820 33057763 : memcpy (temp_state, curr_state, dfa_state_size);
6821 33057763 : if (early_queue_to_ready (temp_state, &ready))
6822 4 : ready_sort (&ready);
6823 : }
6824 :
6825 95022632 : if (ready.n_ready == 0
6826 60206717 : || !ls.can_issue_more
6827 60129640 : || state_dead_lock_p (curr_state)
6828 155152272 : || !(*current_sched_info->schedule_more_p) ())
6829 : break;
6830 :
6831 : /* Select and remove the insn from the ready list. */
6832 60129640 : if (sort_p)
6833 : {
6834 60129640 : int res;
6835 :
6836 60129640 : insn = NULL;
6837 60129640 : res = choose_ready (&ready, ls.first_cycle_insn_p, &insn);
6838 :
6839 60129640 : if (res < 0)
6840 : /* Finish cycle. */
6841 : break;
6842 60129640 : if (res > 0)
6843 0 : goto restart_choose_ready;
6844 :
6845 60129640 : gcc_assert (insn != NULL_RTX);
6846 : }
6847 : else
6848 0 : insn = ready_remove_first (&ready);
6849 :
6850 60129640 : if (sched_pressure != SCHED_PRESSURE_NONE
6851 60129640 : && INSN_TICK (insn) > clock_var)
6852 : {
6853 2238 : ready_add (&ready, insn, true);
6854 2238 : advance = 1;
6855 2238 : break;
6856 : }
6857 :
6858 60127402 : if (targetm.sched.dfa_new_cycle
6859 60127402 : && targetm.sched.dfa_new_cycle (sched_dump, sched_verbose,
6860 : insn, last_clock_var,
6861 : clock_var, &sort_p))
6862 : /* SORT_P is used by the target to override sorting
6863 : of the ready list. This is needed when the target
6864 : has modified its internal structures expecting that
6865 : the insn will be issued next. As we need the insn
6866 : to have the highest priority (so it will be returned by
6867 : the ready_remove_first call above), we invoke
6868 : ready_add (&ready, insn, true).
6869 : But, still, there is one issue: INSN can be later
6870 : discarded by scheduler's front end through
6871 : current_sched_info->can_schedule_ready_p, hence, won't
6872 : be issued next. */
6873 : {
6874 0 : ready_add (&ready, insn, true);
6875 0 : break;
6876 : }
6877 :
6878 60127402 : sort_p = true;
6879 :
6880 60127402 : if (current_sched_info->can_schedule_ready_p
6881 60127402 : && ! (*current_sched_info->can_schedule_ready_p) (insn))
6882 : /* We normally get here only if we don't want to move
6883 : insn from the split block. */
6884 : {
6885 0 : TODO_SPEC (insn) = DEP_POSTPONED;
6886 0 : goto restart_choose_ready;
6887 : }
6888 :
6889 60127402 : if (delay_htab)
6890 : {
6891 : /* If this insn is the first part of a delay-slot pair, record a
6892 : backtrack point. */
6893 0 : struct delay_pair *delay_entry;
6894 0 : delay_entry
6895 0 : = delay_htab->find_with_hash (insn, htab_hash_pointer (insn));
6896 0 : if (delay_entry)
6897 : {
6898 0 : save_backtrack_point (delay_entry, ls);
6899 0 : if (sched_verbose >= 2)
6900 0 : fprintf (sched_dump, ";;\t\tsaving backtrack point\n");
6901 : }
6902 : }
6903 :
6904 : /* DECISION is made. */
6905 :
6906 60127402 : if (modulo_ii > 0 && INSN_UID (insn) < modulo_iter0_max_uid)
6907 : {
6908 0 : modulo_insns_scheduled++;
6909 0 : modulo_last_stage = clock_var / modulo_ii;
6910 : }
6911 60127402 : if (TODO_SPEC (insn) & SPECULATIVE)
6912 0 : generate_recovery_code (insn);
6913 :
6914 60127402 : if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
6915 14 : targetm.sched.dispatch_do (insn, ADD_TO_DISPATCH_WINDOW);
6916 :
6917 : /* Update counters, etc in the scheduler's front end. */
6918 60127402 : (*current_sched_info->begin_schedule_ready) (insn);
6919 60127402 : scheduled_insns.safe_push (insn);
6920 60127402 : gcc_assert (NONDEBUG_INSN_P (insn));
6921 60127402 : last_nondebug_scheduled_insn = last_scheduled_insn = insn;
6922 :
6923 60127402 : if (recog_memoized (insn) >= 0)
6924 : {
6925 59279750 : memcpy (temp_state, curr_state, dfa_state_size);
6926 59279750 : cost = state_transition (curr_state, insn);
6927 59279750 : if (sched_pressure != SCHED_PRESSURE_WEIGHTED && !sched_fusion)
6928 59276496 : gcc_assert (cost < 0);
6929 59279750 : if (memcmp (temp_state, curr_state, dfa_state_size) != 0)
6930 58888368 : cycle_issued_insns++;
6931 : asm_p = false;
6932 : }
6933 : else
6934 847652 : asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
6935 847652 : || asm_noperands (PATTERN (insn)) >= 0);
6936 :
6937 60127402 : if (targetm.sched.variable_issue)
6938 0 : ls.can_issue_more =
6939 0 : targetm.sched.variable_issue (sched_dump, sched_verbose,
6940 : insn, ls.can_issue_more);
6941 : /* A naked CLOBBER or USE generates no instruction, so do
6942 : not count them against the issue rate. */
6943 60127402 : else if (GET_CODE (PATTERN (insn)) != USE
6944 60127402 : && GET_CODE (PATTERN (insn)) != CLOBBER)
6945 59336922 : ls.can_issue_more--;
6946 60127402 : advance = schedule_insn (insn);
6947 :
6948 60127402 : if (SHADOW_P (insn))
6949 0 : ls.shadows_only_p = true;
6950 :
6951 : /* After issuing an asm insn we should start a new cycle. */
6952 60127402 : if (advance == 0 && asm_p)
6953 57172 : advance = 1;
6954 :
6955 60127402 : if (must_backtrack)
6956 : break;
6957 :
6958 60127402 : if (advance != 0)
6959 : break;
6960 :
6961 60070230 : ls.first_cycle_insn_p = false;
6962 60070230 : if (ready.n_ready > 0)
6963 34221888 : prune_ready_list (temp_state, false, ls.shadows_only_p,
6964 34221888 : ls.modulo_epilogue);
6965 60070230 : }
6966 :
6967 34953647 : do_backtrack:
6968 34953647 : if (!must_backtrack)
6969 35197428 : for (i = 0; i < ready.n_ready; i++)
6970 : {
6971 243781 : rtx_insn *insn = ready_element (&ready, i);
6972 243781 : if (INSN_EXACT_TICK (insn) == clock_var)
6973 : {
6974 0 : must_backtrack = true;
6975 0 : clock_var++;
6976 0 : break;
6977 : }
6978 : }
6979 34953647 : if (must_backtrack && modulo_ii > 0)
6980 : {
6981 0 : if (modulo_backtracks_left == 0)
6982 0 : goto end_schedule;
6983 0 : modulo_backtracks_left--;
6984 : }
6985 34953647 : while (must_backtrack)
6986 : {
6987 0 : struct haifa_saved_data *failed;
6988 0 : rtx_insn *failed_insn;
6989 :
6990 0 : must_backtrack = false;
6991 0 : failed = verify_shadows ();
6992 0 : gcc_assert (failed);
6993 :
6994 0 : failed_insn = failed->delay_pair->i1;
6995 : /* Clear these queues. */
6996 0 : perform_replacements_new_cycle ();
6997 0 : toggle_cancelled_flags (false);
6998 0 : unschedule_insns_until (failed_insn);
6999 0 : while (failed != backtrack_queue)
7000 0 : free_topmost_backtrack_point (true);
7001 0 : restore_last_backtrack_point (&ls);
7002 0 : if (sched_verbose >= 2)
7003 0 : fprintf (sched_dump, ";;\t\trewind to cycle %d\n", clock_var);
7004 : /* Delay by at least a cycle. This could cause additional
7005 : backtracking. */
7006 0 : queue_insn (failed_insn, 1, "backtracked");
7007 0 : advance = 0;
7008 0 : if (must_backtrack)
7009 0 : continue;
7010 0 : if (ready.n_ready > 0)
7011 0 : goto resume_after_backtrack;
7012 : else
7013 : {
7014 0 : if (clock_var == 0 && ls.first_cycle_insn_p)
7015 0 : goto end_schedule;
7016 : advance = 1;
7017 : break;
7018 : }
7019 : }
7020 34953647 : ls.first_cycle_insn_p = true;
7021 : }
7022 10313337 : if (ls.modulo_epilogue)
7023 0 : success = true;
7024 10313337 : end_schedule:
7025 10313337 : if (!ls.first_cycle_insn_p || advance)
7026 878 : advance_one_cycle ();
7027 10313337 : perform_replacements_new_cycle ();
7028 10313337 : if (modulo_ii > 0)
7029 : {
7030 : /* Once again, debug insn suckiness: they can be on the ready list
7031 : even if they have unresolved dependencies. To make our view
7032 : of the world consistent, remove such "ready" insns. */
7033 0 : restart_debug_insn_loop:
7034 0 : for (i = ready.n_ready - 1; i >= 0; i--)
7035 : {
7036 0 : rtx_insn *x;
7037 :
7038 0 : x = ready_element (&ready, i);
7039 0 : if (DEPS_LIST_FIRST (INSN_HARD_BACK_DEPS (x)) != NULL
7040 0 : || DEPS_LIST_FIRST (INSN_SPEC_BACK_DEPS (x)) != NULL)
7041 : {
7042 0 : ready_remove (&ready, i);
7043 0 : goto restart_debug_insn_loop;
7044 : }
7045 : }
7046 0 : for (i = ready.n_ready - 1; i >= 0; i--)
7047 : {
7048 0 : rtx_insn *x;
7049 :
7050 0 : x = ready_element (&ready, i);
7051 0 : resolve_dependencies (x);
7052 : }
7053 0 : for (i = 0; i <= max_insn_queue_index; i++)
7054 : {
7055 : rtx_insn_list *link;
7056 0 : while ((link = insn_queue[i]) != NULL)
7057 : {
7058 0 : rtx_insn *x = link->insn ();
7059 0 : insn_queue[i] = link->next ();
7060 0 : QUEUE_INDEX (x) = QUEUE_NOWHERE;
7061 0 : free_INSN_LIST_node (link);
7062 0 : resolve_dependencies (x);
7063 : }
7064 : }
7065 : }
7066 :
7067 10313337 : if (!success)
7068 0 : undo_all_replacements ();
7069 :
7070 : /* Debug info. */
7071 10313337 : if (sched_verbose)
7072 : {
7073 190 : fprintf (sched_dump, ";;\tReady list (final): ");
7074 190 : debug_ready_list (&ready);
7075 : }
7076 :
7077 10313337 : if (modulo_ii == 0 && current_sched_info->queue_must_finish_empty)
7078 : /* Sanity check -- queue must be empty now. Meaningless if region has
7079 : multiple bbs. */
7080 10313289 : gcc_assert (!q_size && !ready.n_ready && !ready.n_debug);
7081 48 : else if (modulo_ii == 0)
7082 : {
7083 : /* We must maintain QUEUE_INDEX between blocks in region. */
7084 60 : for (i = ready.n_ready - 1; i >= 0; i--)
7085 : {
7086 12 : rtx_insn *x;
7087 :
7088 12 : x = ready_element (&ready, i);
7089 12 : QUEUE_INDEX (x) = QUEUE_NOWHERE;
7090 12 : TODO_SPEC (x) = HARD_DEP;
7091 : }
7092 :
7093 48 : if (q_size)
7094 0 : for (i = 0; i <= max_insn_queue_index; i++)
7095 : {
7096 0 : rtx_insn_list *link;
7097 0 : for (link = insn_queue[i]; link; link = link->next ())
7098 : {
7099 0 : rtx_insn *x;
7100 :
7101 0 : x = link->insn ();
7102 0 : QUEUE_INDEX (x) = QUEUE_NOWHERE;
7103 0 : TODO_SPEC (x) = HARD_DEP;
7104 : }
7105 0 : free_INSN_LIST_list (&insn_queue[i]);
7106 : }
7107 : }
7108 :
7109 10313337 : if (sched_pressure == SCHED_PRESSURE_MODEL)
7110 0 : model_end_schedule ();
7111 :
7112 10313337 : if (success)
7113 : {
7114 10313337 : commit_schedule (prev_head, tail, target_bb);
7115 10313337 : if (sched_verbose)
7116 190 : fprintf (sched_dump, ";; total time = %d\n", clock_var);
7117 : }
7118 : else
7119 0 : last_scheduled_insn = tail;
7120 :
7121 10313337 : scheduled_insns.truncate (0);
7122 :
7123 10313337 : if (!current_sched_info->queue_must_finish_empty
7124 10313289 : || haifa_recovery_bb_recently_added_p)
7125 : {
7126 : /* INSN_TICK (minimum clock tick at which the insn becomes
7127 : ready) may be not correct for the insn in the subsequent
7128 : blocks of the region. We should use a correct value of
7129 : `clock_var' or modify INSN_TICK. It is better to keep
7130 : clock_var value equal to 0 at the start of a basic block.
7131 : Therefore we modify INSN_TICK here. */
7132 48 : fix_inter_tick (NEXT_INSN (prev_head), last_scheduled_insn);
7133 : }
7134 :
7135 10313337 : if (targetm.sched.finish)
7136 : {
7137 0 : targetm.sched.finish (sched_dump, sched_verbose);
7138 : /* Target might have added some instructions to the scheduled block
7139 : in its md_finish () hook. These new insns don't have any data
7140 : initialized and to identify them we extend h_i_d so that they'll
7141 : get zero luids. */
7142 0 : sched_extend_luids ();
7143 : }
7144 :
7145 : /* Update head/tail boundaries. */
7146 10313337 : head = NEXT_INSN (prev_head);
7147 10313337 : tail = last_scheduled_insn;
7148 :
7149 10313337 : if (sched_verbose)
7150 : {
7151 190 : fprintf (sched_dump, ";; new head = %d\n;; new tail = %d\n",
7152 190 : INSN_UID (head), INSN_UID (tail));
7153 :
7154 190 : if (sched_verbose >= 2)
7155 : {
7156 0 : dump_insn_stream (head, tail);
7157 0 : print_rank_for_schedule_stats (";; TOTAL ", &rank_for_schedule_stats,
7158 : NULL);
7159 : }
7160 :
7161 190 : fprintf (sched_dump, "\n");
7162 : }
7163 :
7164 10313337 : head = restore_other_notes (head, NULL);
7165 :
7166 10313337 : current_sched_info->head = head;
7167 10313337 : current_sched_info->tail = tail;
7168 :
7169 10313337 : free_backtrack_queue ();
7170 :
7171 10313337 : return success;
7172 : }
7173 :
7174 : /* Set_priorities: compute priority of each insn in the block. */
7175 :
7176 : int
7177 10314356 : set_priorities (rtx_insn *head, rtx_insn *tail)
7178 : {
7179 10314356 : rtx_insn *insn;
7180 10314356 : int n_insn;
7181 10314356 : int sched_max_insns_priority =
7182 10314356 : current_sched_info->sched_max_insns_priority;
7183 10314356 : rtx_insn *prev_head;
7184 :
7185 10314356 : if (head == tail && ! INSN_P (head))
7186 0 : gcc_unreachable ();
7187 :
7188 10314356 : n_insn = 0;
7189 :
7190 10314356 : prev_head = PREV_INSN (head);
7191 135077853 : for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
7192 : {
7193 114449141 : if (!INSN_P (insn))
7194 5823530 : continue;
7195 :
7196 108625611 : n_insn++;
7197 108625611 : (void) priority (insn);
7198 :
7199 108625611 : gcc_assert (INSN_PRIORITY_KNOWN (insn));
7200 :
7201 108625611 : sched_max_insns_priority = MAX (sched_max_insns_priority,
7202 : INSN_PRIORITY (insn));
7203 : }
7204 :
7205 10314356 : current_sched_info->sched_max_insns_priority = sched_max_insns_priority;
7206 :
7207 10314356 : return n_insn;
7208 : }
7209 :
7210 : /* Set sched_dump and sched_verbose for the desired debugging output. */
7211 : void
7212 964480 : setup_sched_dump (void)
7213 : {
7214 964480 : sched_verbose = sched_verbose_param;
7215 964480 : sched_dump = dump_file;
7216 964480 : if (!dump_file)
7217 964443 : sched_verbose = 0;
7218 964480 : }
7219 :
7220 : /* Allocate data for register pressure sensitive scheduling. */
7221 : static void
7222 964480 : alloc_global_sched_pressure_data (void)
7223 : {
7224 964480 : if (sched_pressure != SCHED_PRESSURE_NONE)
7225 : {
7226 57 : int i, max_regno = max_reg_num ();
7227 :
7228 57 : if (sched_dump != NULL)
7229 : /* We need info about pseudos for rtl dumps about pseudo
7230 : classes and costs. */
7231 0 : regstat_init_n_sets_and_refs ();
7232 57 : ira_set_pseudo_classes (true, sched_verbose ? sched_dump : NULL);
7233 57 : sched_regno_pressure_class
7234 57 : = (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class));
7235 8652 : for (i = 0; i < max_regno; i++)
7236 17190 : sched_regno_pressure_class[i]
7237 8595 : = (i < FIRST_PSEUDO_REGISTER
7238 8595 : ? ira_pressure_class_translate[REGNO_REG_CLASS (i)]
7239 3351 : : ira_pressure_class_translate[reg_allocno_class (i)]);
7240 57 : curr_reg_live = BITMAP_ALLOC (NULL);
7241 57 : if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
7242 : {
7243 57 : saved_reg_live = BITMAP_ALLOC (NULL);
7244 57 : region_ref_regs = BITMAP_ALLOC (NULL);
7245 : }
7246 57 : if (sched_pressure == SCHED_PRESSURE_MODEL)
7247 0 : tmp_bitmap = BITMAP_ALLOC (NULL);
7248 :
7249 : /* Calculate number of CALL_SAVED_REGS and FIXED_REGS in register classes
7250 : that we calculate register pressure for. */
7251 287 : for (int c = 0; c < ira_pressure_classes_num; ++c)
7252 : {
7253 230 : enum reg_class cl = ira_pressure_classes[c];
7254 :
7255 230 : call_saved_regs_num[cl] = 0;
7256 230 : fixed_regs_num[cl] = 0;
7257 :
7258 2905 : for (int i = 0; i < ira_class_hard_regs_num[cl]; ++i)
7259 : {
7260 2675 : unsigned int regno = ira_class_hard_regs[cl][i];
7261 2675 : if (fixed_regs[regno])
7262 0 : ++fixed_regs_num[cl];
7263 2675 : else if (!crtl->abi->clobbers_full_reg_p (regno))
7264 332 : ++call_saved_regs_num[cl];
7265 : }
7266 : }
7267 : }
7268 964480 : }
7269 :
7270 : /* Free data for register pressure sensitive scheduling. Also called
7271 : from schedule_region when stopping sched-pressure early. */
7272 : void
7273 964480 : free_global_sched_pressure_data (void)
7274 : {
7275 964480 : if (sched_pressure != SCHED_PRESSURE_NONE)
7276 : {
7277 57 : if (regstat_n_sets_and_refs != NULL)
7278 0 : regstat_free_n_sets_and_refs ();
7279 57 : if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
7280 : {
7281 57 : BITMAP_FREE (region_ref_regs);
7282 57 : BITMAP_FREE (saved_reg_live);
7283 : }
7284 57 : if (sched_pressure == SCHED_PRESSURE_MODEL)
7285 0 : BITMAP_FREE (tmp_bitmap);
7286 57 : BITMAP_FREE (curr_reg_live);
7287 57 : free (sched_regno_pressure_class);
7288 : }
7289 964480 : }
7290 :
7291 : /* Initialize some global state for the scheduler. This function works
7292 : with the common data shared between all the schedulers. It is called
7293 : from the scheduler specific initialization routine. */
7294 :
7295 : void
7296 964480 : sched_init (void)
7297 : {
7298 964480 : if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
7299 3 : targetm.sched.dispatch_do (NULL, DISPATCH_INIT);
7300 :
7301 964480 : if (live_range_shrinkage_p)
7302 35 : sched_pressure = SCHED_PRESSURE_WEIGHTED;
7303 964445 : else if (flag_sched_pressure
7304 50 : && !reload_completed
7305 22 : && common_sched_info->sched_pass_id == SCHED_RGN_PASS)
7306 22 : sched_pressure = ((enum sched_pressure_algorithm)
7307 22 : param_sched_pressure_algorithm);
7308 : else
7309 964423 : sched_pressure = SCHED_PRESSURE_NONE;
7310 :
7311 964480 : if (sched_pressure != SCHED_PRESSURE_NONE)
7312 57 : ira_setup_eliminable_regset ();
7313 :
7314 : /* Initialize SPEC_INFO. */
7315 964480 : if (targetm.sched.set_sched_flags)
7316 : {
7317 0 : spec_info = &spec_info_var;
7318 0 : targetm.sched.set_sched_flags (spec_info);
7319 :
7320 0 : if (spec_info->mask != 0)
7321 : {
7322 0 : spec_info->data_weakness_cutoff
7323 0 : = (param_sched_spec_prob_cutoff * MAX_DEP_WEAK) / 100;
7324 0 : spec_info->control_weakness_cutoff
7325 0 : = (param_sched_spec_prob_cutoff * REG_BR_PROB_BASE) / 100;
7326 : }
7327 : else
7328 : /* So we won't read anything accidentally. */
7329 0 : spec_info = NULL;
7330 :
7331 : }
7332 : else
7333 : /* So we won't read anything accidentally. */
7334 964480 : spec_info = 0;
7335 :
7336 : /* Initialize issue_rate. */
7337 964480 : if (targetm.sched.issue_rate)
7338 964480 : issue_rate = targetm.sched.issue_rate ();
7339 : else
7340 0 : issue_rate = 1;
7341 :
7342 964480 : if (targetm.sched.first_cycle_multipass_dfa_lookahead
7343 : /* Don't use max_issue with reg_pressure scheduling. Multipass
7344 : scheduling and reg_pressure scheduling undo each other's decisions. */
7345 964480 : && sched_pressure == SCHED_PRESSURE_NONE)
7346 964423 : dfa_lookahead = targetm.sched.first_cycle_multipass_dfa_lookahead ();
7347 : else
7348 57 : dfa_lookahead = 0;
7349 :
7350 : /* Set to "0" so that we recalculate. */
7351 964480 : max_lookahead_tries = 0;
7352 :
7353 964480 : if (targetm.sched.init_dfa_pre_cycle_insn)
7354 0 : targetm.sched.init_dfa_pre_cycle_insn ();
7355 :
7356 964480 : if (targetm.sched.init_dfa_post_cycle_insn)
7357 0 : targetm.sched.init_dfa_post_cycle_insn ();
7358 :
7359 964480 : dfa_start ();
7360 964480 : dfa_state_size = state_size ();
7361 :
7362 964480 : init_alias_analysis ();
7363 :
7364 964480 : if (!sched_no_dce)
7365 964480 : df_set_flags (DF_LR_RUN_DCE);
7366 964480 : df_note_add_problem ();
7367 :
7368 : /* More problems needed for interloop dep calculation in SMS. */
7369 964480 : if (common_sched_info->sched_pass_id == SCHED_SMS_PASS)
7370 : {
7371 267 : df_rd_add_problem ();
7372 267 : df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
7373 : }
7374 :
7375 964480 : df_analyze ();
7376 :
7377 : /* Do not run DCE after reload, as this can kill nops inserted
7378 : by bundling. */
7379 964480 : if (reload_completed)
7380 963984 : df_clear_flags (DF_LR_RUN_DCE);
7381 :
7382 964480 : regstat_compute_calls_crossed ();
7383 :
7384 964480 : if (targetm.sched.init_global)
7385 964480 : targetm.sched.init_global (sched_dump, sched_verbose, get_max_uid () + 1);
7386 :
7387 964480 : alloc_global_sched_pressure_data ();
7388 :
7389 964480 : curr_state = xmalloc (dfa_state_size);
7390 964480 : }
7391 :
7392 : static void haifa_init_only_bb (basic_block, basic_block);
7393 :
7394 : /* Initialize data structures specific to the Haifa scheduler. */
7395 : void
7396 964349 : haifa_sched_init (void)
7397 : {
7398 964349 : setup_sched_dump ();
7399 964349 : sched_init ();
7400 :
7401 964349 : scheduled_insns.create (0);
7402 :
7403 964349 : if (spec_info != NULL)
7404 : {
7405 0 : sched_deps_info->use_deps_list = 1;
7406 0 : sched_deps_info->generate_spec_deps = 1;
7407 : }
7408 :
7409 : /* Initialize luids, dependency caches, target and h_i_d for the
7410 : whole function. */
7411 964349 : {
7412 964349 : sched_init_bbs ();
7413 :
7414 964349 : auto_vec<basic_block> bbs (n_basic_blocks_for_fn (cfun));
7415 964349 : basic_block bb;
7416 11296870 : FOR_EACH_BB_FN (bb, cfun)
7417 10332521 : bbs.quick_push (bb);
7418 964349 : sched_init_luids (bbs);
7419 964349 : sched_deps_init (true);
7420 964349 : sched_extend_target ();
7421 964349 : haifa_init_h_i_d (bbs);
7422 964349 : }
7423 :
7424 964349 : sched_init_only_bb = haifa_init_only_bb;
7425 964349 : sched_split_block = sched_split_block_1;
7426 964349 : sched_create_empty_bb = sched_create_empty_bb_1;
7427 964349 : haifa_recovery_bb_ever_added_p = false;
7428 :
7429 964349 : nr_begin_data = nr_begin_control = nr_be_in_data = nr_be_in_control = 0;
7430 964349 : before_recovery = 0;
7431 964349 : after_recovery = 0;
7432 :
7433 964349 : modulo_ii = 0;
7434 964349 : }
7435 :
7436 : /* Finish work with the data specific to the Haifa scheduler. */
7437 : void
7438 964349 : haifa_sched_finish (void)
7439 : {
7440 964349 : sched_create_empty_bb = NULL;
7441 964349 : sched_split_block = NULL;
7442 964349 : sched_init_only_bb = NULL;
7443 :
7444 964349 : if (spec_info && spec_info->dump)
7445 : {
7446 0 : char c = reload_completed ? 'a' : 'b';
7447 :
7448 0 : fprintf (spec_info->dump,
7449 : ";; %s:\n", current_function_name ());
7450 :
7451 0 : fprintf (spec_info->dump,
7452 : ";; Procedure %cr-begin-data-spec motions == %d\n",
7453 : c, nr_begin_data);
7454 0 : fprintf (spec_info->dump,
7455 : ";; Procedure %cr-be-in-data-spec motions == %d\n",
7456 : c, nr_be_in_data);
7457 0 : fprintf (spec_info->dump,
7458 : ";; Procedure %cr-begin-control-spec motions == %d\n",
7459 : c, nr_begin_control);
7460 0 : fprintf (spec_info->dump,
7461 : ";; Procedure %cr-be-in-control-spec motions == %d\n",
7462 : c, nr_be_in_control);
7463 : }
7464 :
7465 964349 : scheduled_insns.release ();
7466 :
7467 : /* Finalize h_i_d, dependency caches, and luids for the whole
7468 : function. Target will be finalized in md_global_finish (). */
7469 964349 : sched_deps_finish ();
7470 964349 : sched_finish_luids ();
7471 964349 : current_sched_info = NULL;
7472 964349 : insn_queue = NULL;
7473 964349 : sched_finish ();
7474 964349 : }
7475 :
7476 : /* Free global data used during insn scheduling. This function works with
7477 : the common data shared between the schedulers. */
7478 :
7479 : void
7480 964480 : sched_finish (void)
7481 : {
7482 964480 : haifa_finish_h_i_d ();
7483 964480 : free_global_sched_pressure_data ();
7484 964480 : free (curr_state);
7485 :
7486 964480 : if (targetm.sched.finish_global)
7487 0 : targetm.sched.finish_global (sched_dump, sched_verbose);
7488 :
7489 964480 : end_alias_analysis ();
7490 :
7491 964480 : regstat_free_calls_crossed ();
7492 :
7493 964480 : dfa_finish ();
7494 964480 : }
7495 :
7496 : /* Free all delay_pair structures that were recorded. */
7497 : void
7498 0 : free_delay_pairs (void)
7499 : {
7500 0 : if (delay_htab)
7501 : {
7502 0 : delay_htab->empty ();
7503 0 : delay_htab_i2->empty ();
7504 : }
7505 0 : }
7506 :
7507 : /* Fix INSN_TICKs of the instructions in the current block as well as
7508 : INSN_TICKs of their dependents.
7509 : HEAD and TAIL are the begin and the end of the current scheduled block. */
7510 : static void
7511 48 : fix_inter_tick (rtx_insn *head, rtx_insn *tail)
7512 : {
7513 : /* Set of instructions with corrected INSN_TICK. */
7514 48 : auto_bitmap processed;
7515 : /* ??? It is doubtful if we should assume that cycle advance happens on
7516 : basic block boundaries. Basically insns that are unconditionally ready
7517 : on the start of the block are more preferable then those which have
7518 : a one cycle dependency over insn from the previous block. */
7519 48 : int next_clock = clock_var + 1;
7520 :
7521 : /* Iterates over scheduled instructions and fix their INSN_TICKs and
7522 : INSN_TICKs of dependent instructions, so that INSN_TICKs are consistent
7523 : across different blocks. */
7524 835 : for (tail = NEXT_INSN (tail); head != tail; head = NEXT_INSN (head))
7525 : {
7526 787 : if (INSN_P (head))
7527 : {
7528 787 : int tick;
7529 787 : sd_iterator_def sd_it;
7530 787 : dep_t dep;
7531 :
7532 787 : tick = INSN_TICK (head);
7533 787 : gcc_assert (tick >= MIN_TICK);
7534 :
7535 : /* Fix INSN_TICK of instruction from just scheduled block. */
7536 787 : if (bitmap_set_bit (processed, INSN_LUID (head)))
7537 : {
7538 60 : tick -= next_clock;
7539 :
7540 60 : if (tick < MIN_TICK)
7541 : tick = MIN_TICK;
7542 :
7543 60 : INSN_TICK (head) = tick;
7544 : }
7545 :
7546 787 : if (DEBUG_INSN_P (head))
7547 120 : continue;
7548 :
7549 2899 : FOR_EACH_DEP (head, SD_LIST_RES_FORW, sd_it, dep)
7550 : {
7551 2232 : rtx_insn *next;
7552 :
7553 2232 : next = DEP_CON (dep);
7554 2232 : tick = INSN_TICK (next);
7555 :
7556 2232 : if (tick != INVALID_TICK
7557 : /* If NEXT has its INSN_TICK calculated, fix it.
7558 : If not - it will be properly calculated from
7559 : scratch later in fix_tick_ready. */
7560 2232 : && bitmap_set_bit (processed, INSN_LUID (next)))
7561 : {
7562 739 : tick -= next_clock;
7563 :
7564 739 : if (tick < MIN_TICK)
7565 : tick = MIN_TICK;
7566 :
7567 739 : if (tick > INTER_TICK (next))
7568 739 : INTER_TICK (next) = tick;
7569 : else
7570 : tick = INTER_TICK (next);
7571 :
7572 739 : INSN_TICK (next) = tick;
7573 : }
7574 : }
7575 : }
7576 : }
7577 48 : }
7578 :
7579 : /* Check if NEXT is ready to be added to the ready or queue list.
7580 : If "yes", add it to the proper list.
7581 : Returns:
7582 : -1 - is not ready yet,
7583 : 0 - added to the ready list,
7584 : 0 < N - queued for N cycles. */
7585 : int
7586 311309911 : try_ready (rtx_insn *next)
7587 : {
7588 311309911 : ds_t old_ts, new_ts;
7589 :
7590 311309911 : old_ts = TODO_SPEC (next);
7591 :
7592 311309911 : gcc_assert (!(old_ts & ~(SPECULATIVE | HARD_DEP | DEP_CONTROL | DEP_POSTPONED))
7593 : && (old_ts == HARD_DEP
7594 : || old_ts == DEP_POSTPONED
7595 : || (old_ts & SPECULATIVE)
7596 : || old_ts == DEP_CONTROL));
7597 :
7598 311309911 : new_ts = recompute_todo_spec (next, false);
7599 :
7600 311309911 : if (new_ts & (HARD_DEP | DEP_POSTPONED))
7601 202688743 : gcc_assert (new_ts == old_ts
7602 : && QUEUE_INDEX (next) == QUEUE_NOWHERE);
7603 108621168 : else if (current_sched_info->new_ready)
7604 108619911 : new_ts = current_sched_info->new_ready (next, new_ts);
7605 :
7606 : /* * if !(old_ts & SPECULATIVE) (e.g. HARD_DEP or 0), then insn might
7607 : have its original pattern or changed (speculative) one. This is due
7608 : to changing ebb in region scheduling.
7609 : * But if (old_ts & SPECULATIVE), then we are pretty sure that insn
7610 : has speculative pattern.
7611 :
7612 : We can't assert (!(new_ts & HARD_DEP) || new_ts == old_ts) here because
7613 : control-speculative NEXT could have been discarded by sched-rgn.cc
7614 : (the same case as when discarded by can_schedule_ready_p ()). */
7615 :
7616 311309911 : if ((new_ts & SPECULATIVE)
7617 : /* If (old_ts == new_ts), then (old_ts & SPECULATIVE) and we don't
7618 : need to change anything. */
7619 0 : && new_ts != old_ts)
7620 : {
7621 0 : int res;
7622 0 : rtx new_pat;
7623 :
7624 0 : gcc_assert ((new_ts & SPECULATIVE) && !(new_ts & ~SPECULATIVE));
7625 :
7626 0 : res = haifa_speculate_insn (next, new_ts, &new_pat);
7627 :
7628 0 : switch (res)
7629 : {
7630 : case -1:
7631 : /* It would be nice to change DEP_STATUS of all dependences,
7632 : which have ((DEP_STATUS & SPECULATIVE) == new_ts) to HARD_DEP,
7633 : so we won't reanalyze anything. */
7634 : new_ts = HARD_DEP;
7635 : break;
7636 :
7637 0 : case 0:
7638 : /* We follow the rule, that every speculative insn
7639 : has non-null ORIG_PAT. */
7640 0 : if (!ORIG_PAT (next))
7641 0 : ORIG_PAT (next) = PATTERN (next);
7642 : break;
7643 :
7644 0 : case 1:
7645 0 : if (!ORIG_PAT (next))
7646 : /* If we gonna to overwrite the original pattern of insn,
7647 : save it. */
7648 0 : ORIG_PAT (next) = PATTERN (next);
7649 :
7650 0 : res = haifa_change_pattern (next, new_pat);
7651 0 : gcc_assert (res);
7652 : break;
7653 :
7654 0 : default:
7655 0 : gcc_unreachable ();
7656 : }
7657 : }
7658 :
7659 : /* We need to restore pattern only if (new_ts == 0), because otherwise it is
7660 : either correct (new_ts & SPECULATIVE),
7661 : or we simply don't care (new_ts & HARD_DEP). */
7662 :
7663 311309911 : gcc_assert (!ORIG_PAT (next)
7664 : || !IS_SPECULATION_BRANCHY_CHECK_P (next));
7665 :
7666 311309911 : TODO_SPEC (next) = new_ts;
7667 :
7668 311309911 : if (new_ts & (HARD_DEP | DEP_POSTPONED))
7669 : {
7670 : /* We can't assert (QUEUE_INDEX (next) == QUEUE_NOWHERE) here because
7671 : control-speculative NEXT could have been discarded by sched-rgn.cc
7672 : (the same case as when discarded by can_schedule_ready_p ()). */
7673 : /*gcc_assert (QUEUE_INDEX (next) == QUEUE_NOWHERE);*/
7674 :
7675 202688767 : change_queue_index (next, QUEUE_NOWHERE);
7676 :
7677 202688767 : return -1;
7678 : }
7679 108621144 : else if (!(new_ts & BEGIN_SPEC)
7680 108621144 : && ORIG_PAT (next) && PREDICATED_PAT (next) == NULL_RTX
7681 108621144 : && !IS_SPECULATION_CHECK_P (next))
7682 : /* We should change pattern of every previously speculative
7683 : instruction - and we determine if NEXT was speculative by using
7684 : ORIG_PAT field. Except one case - speculation checks have ORIG_PAT
7685 : pat too, so skip them. */
7686 : {
7687 0 : bool success = haifa_change_pattern (next, ORIG_PAT (next));
7688 0 : gcc_assert (success);
7689 0 : ORIG_PAT (next) = 0;
7690 : }
7691 :
7692 108621144 : if (sched_verbose >= 2)
7693 : {
7694 0 : fprintf (sched_dump, ";;\t\tdependencies resolved: insn %s",
7695 0 : (*current_sched_info->print_insn) (next, 0));
7696 :
7697 0 : if (spec_info && spec_info->dump)
7698 : {
7699 0 : if (new_ts & BEGIN_DATA)
7700 0 : fprintf (spec_info->dump, "; data-spec;");
7701 0 : if (new_ts & BEGIN_CONTROL)
7702 0 : fprintf (spec_info->dump, "; control-spec;");
7703 0 : if (new_ts & BE_IN_CONTROL)
7704 0 : fprintf (spec_info->dump, "; in-control-spec;");
7705 : }
7706 0 : if (TODO_SPEC (next) & DEP_CONTROL)
7707 0 : fprintf (sched_dump, " predicated");
7708 0 : fprintf (sched_dump, "\n");
7709 : }
7710 :
7711 108621144 : adjust_priority (next);
7712 :
7713 108621144 : return fix_tick_ready (next);
7714 : }
7715 :
7716 : /* Calculate INSN_TICK of NEXT and add it to either ready or queue list. */
7717 : static int
7718 108932384 : fix_tick_ready (rtx_insn *next)
7719 : {
7720 108932384 : int tick, delay;
7721 :
7722 108932384 : if (!DEBUG_INSN_P (next) && !sd_lists_empty_p (next, SD_LIST_RES_BACK))
7723 : {
7724 42084101 : int full_p;
7725 42084101 : sd_iterator_def sd_it;
7726 42084101 : dep_t dep;
7727 :
7728 42084101 : tick = INSN_TICK (next);
7729 : /* if tick is not equal to INVALID_TICK, then update
7730 : INSN_TICK of NEXT with the most recent resolved dependence
7731 : cost. Otherwise, recalculate from scratch. */
7732 42084101 : full_p = (tick == INVALID_TICK);
7733 :
7734 189783037 : FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
7735 : {
7736 147698948 : rtx_insn *pro = DEP_PRO (dep);
7737 147698948 : int tick1;
7738 :
7739 147698948 : gcc_assert (INSN_TICK (pro) >= MIN_TICK);
7740 :
7741 147698948 : tick1 = INSN_TICK (pro) + dep_cost (dep);
7742 147698948 : if (tick1 > tick)
7743 : tick = tick1;
7744 :
7745 147698948 : if (!full_p)
7746 : break;
7747 : }
7748 : }
7749 : else
7750 : tick = -1;
7751 :
7752 108932384 : INSN_TICK (next) = tick;
7753 :
7754 108932384 : delay = tick - clock_var;
7755 108932384 : if (delay <= 0 || sched_pressure != SCHED_PRESSURE_NONE || sched_fusion)
7756 89535717 : delay = QUEUE_READY;
7757 :
7758 108932384 : change_queue_index (next, delay);
7759 :
7760 108932384 : return delay;
7761 : }
7762 :
7763 : /* Move NEXT to the proper queue list with (DELAY >= 1),
7764 : or add it to the ready list (DELAY == QUEUE_READY),
7765 : or remove it from ready and queue lists at all (DELAY == QUEUE_NOWHERE). */
7766 : static void
7767 311621151 : change_queue_index (rtx_insn *next, int delay)
7768 : {
7769 311621151 : int i = QUEUE_INDEX (next);
7770 :
7771 311621151 : gcc_assert (QUEUE_NOWHERE <= delay && delay <= max_insn_queue_index
7772 : && delay != 0);
7773 311621151 : gcc_assert (i != QUEUE_SCHEDULED);
7774 :
7775 311621151 : if ((delay > 0 && NEXT_Q_AFTER (q_ptr, delay) == i)
7776 311500958 : || (delay < 0 && delay == i))
7777 : /* We have nothing to do. */
7778 : return;
7779 :
7780 : /* Remove NEXT from wherever it is now. */
7781 108759411 : if (i == QUEUE_READY)
7782 0 : ready_remove_insn (next);
7783 108759411 : else if (i >= 0)
7784 138267 : queue_remove (next);
7785 :
7786 : /* Add it to the proper place. */
7787 108759411 : if (delay == QUEUE_READY)
7788 89482937 : ready_add (readyp, next, false);
7789 19276474 : else if (delay >= 1)
7790 19276474 : queue_insn (next, delay, "change queue index");
7791 :
7792 108759411 : if (sched_verbose >= 2)
7793 : {
7794 0 : fprintf (sched_dump, ";;\t\ttick updated: insn %s",
7795 0 : (*current_sched_info->print_insn) (next, 0));
7796 :
7797 0 : if (delay == QUEUE_READY)
7798 0 : fprintf (sched_dump, " into ready\n");
7799 0 : else if (delay >= 1)
7800 0 : fprintf (sched_dump, " into queue with cost=%d\n", delay);
7801 : else
7802 0 : fprintf (sched_dump, " removed from ready or queue lists\n");
7803 : }
7804 : }
7805 :
7806 : static int sched_ready_n_insns = -1;
7807 :
7808 : /* Initialize per region data structures. */
7809 : void
7810 10331445 : sched_extend_ready_list (int new_sched_ready_n_insns)
7811 : {
7812 10331445 : int i;
7813 :
7814 10331445 : if (sched_ready_n_insns == -1)
7815 : /* At the first call we need to initialize one more choice_stack
7816 : entry. */
7817 : {
7818 10331332 : i = 0;
7819 10331332 : sched_ready_n_insns = 0;
7820 10331332 : scheduled_insns.reserve (new_sched_ready_n_insns);
7821 : }
7822 : else
7823 113 : i = sched_ready_n_insns + 1;
7824 :
7825 10331445 : ready.veclen = new_sched_ready_n_insns + issue_rate;
7826 10331445 : ready.vec = XRESIZEVEC (rtx_insn *, ready.vec, ready.veclen);
7827 :
7828 10331445 : gcc_assert (new_sched_ready_n_insns >= sched_ready_n_insns);
7829 :
7830 10331445 : ready_try = (signed char *) xrecalloc (ready_try, new_sched_ready_n_insns,
7831 : sched_ready_n_insns,
7832 : sizeof (*ready_try));
7833 :
7834 : /* We allocate +1 element to save initial state in the choice_stack[0]
7835 : entry. */
7836 10331445 : choice_stack = XRESIZEVEC (struct choice_entry, choice_stack,
7837 : new_sched_ready_n_insns + 1);
7838 :
7839 129285316 : for (; i <= new_sched_ready_n_insns; i++)
7840 : {
7841 118953871 : choice_stack[i].state = xmalloc (dfa_state_size);
7842 :
7843 118953871 : if (targetm.sched.first_cycle_multipass_init)
7844 118648174 : targetm.sched.first_cycle_multipass_init (&(choice_stack[i]
7845 : .target_data));
7846 : }
7847 :
7848 10331445 : sched_ready_n_insns = new_sched_ready_n_insns;
7849 10331445 : }
7850 :
7851 : /* Free per region data structures. */
7852 : void
7853 10331332 : sched_finish_ready_list (void)
7854 : {
7855 10331332 : int i;
7856 :
7857 10331332 : free (ready.vec);
7858 10331332 : ready.vec = NULL;
7859 10331332 : ready.veclen = 0;
7860 :
7861 10331332 : free (ready_try);
7862 10331332 : ready_try = NULL;
7863 :
7864 129285203 : for (i = 0; i <= sched_ready_n_insns; i++)
7865 : {
7866 118953871 : if (targetm.sched.first_cycle_multipass_fini)
7867 118648174 : targetm.sched.first_cycle_multipass_fini (&(choice_stack[i]
7868 : .target_data));
7869 :
7870 118953871 : free (choice_stack [i].state);
7871 : }
7872 10331332 : free (choice_stack);
7873 10331332 : choice_stack = NULL;
7874 :
7875 10331332 : sched_ready_n_insns = -1;
7876 10331332 : }
7877 :
7878 : static int
7879 23702372 : haifa_luid_for_non_insn (rtx x)
7880 : {
7881 23702372 : gcc_assert (NOTE_P (x) || LABEL_P (x));
7882 :
7883 23702372 : return 0;
7884 : }
7885 :
7886 : /* Generates recovery code for INSN. */
7887 : static void
7888 0 : generate_recovery_code (rtx_insn *insn)
7889 : {
7890 0 : if (TODO_SPEC (insn) & BEGIN_SPEC)
7891 0 : begin_speculative_block (insn);
7892 :
7893 : /* Here we have insn with no dependencies to
7894 : instructions other then CHECK_SPEC ones. */
7895 :
7896 0 : if (TODO_SPEC (insn) & BE_IN_SPEC)
7897 0 : add_to_speculative_block (insn);
7898 0 : }
7899 :
7900 : /* Helper function.
7901 : Tries to add speculative dependencies of type FS between instructions
7902 : in deps_list L and TWIN. */
7903 : static void
7904 0 : process_insn_forw_deps_be_in_spec (rtx_insn *insn, rtx_insn *twin, ds_t fs)
7905 : {
7906 0 : sd_iterator_def sd_it;
7907 0 : dep_t dep;
7908 :
7909 0 : FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
7910 : {
7911 0 : ds_t ds;
7912 0 : rtx_insn *consumer;
7913 :
7914 0 : consumer = DEP_CON (dep);
7915 :
7916 0 : ds = DEP_STATUS (dep);
7917 :
7918 0 : if (/* If we want to create speculative dep. */
7919 : fs
7920 : /* And we can do that because this is a true dep. */
7921 0 : && (ds & DEP_TYPES) == DEP_TRUE)
7922 : {
7923 0 : gcc_assert (!(ds & BE_IN_SPEC));
7924 :
7925 0 : if (/* If this dep can be overcome with 'begin speculation'. */
7926 0 : ds & BEGIN_SPEC)
7927 : /* Then we have a choice: keep the dep 'begin speculative'
7928 : or transform it into 'be in speculative'. */
7929 : {
7930 0 : if (/* In try_ready we assert that if insn once became ready
7931 : it can be removed from the ready (or queue) list only
7932 : due to backend decision. Hence we can't let the
7933 : probability of the speculative dep to decrease. */
7934 0 : ds_weak (ds) <= ds_weak (fs))
7935 : {
7936 0 : ds_t new_ds;
7937 :
7938 0 : new_ds = (ds & ~BEGIN_SPEC) | fs;
7939 :
7940 0 : if (/* consumer can 'be in speculative'. */
7941 0 : sched_insn_is_legitimate_for_speculation_p (consumer,
7942 : new_ds))
7943 : /* Transform it to be in speculative. */
7944 0 : ds = new_ds;
7945 : }
7946 : }
7947 : else
7948 : /* Mark the dep as 'be in speculative'. */
7949 0 : ds |= fs;
7950 : }
7951 :
7952 0 : {
7953 0 : dep_def _new_dep, *new_dep = &_new_dep;
7954 :
7955 0 : init_dep_1 (new_dep, twin, consumer, DEP_TYPE (dep), ds);
7956 0 : sd_add_dep (new_dep, false);
7957 : }
7958 : }
7959 0 : }
7960 :
7961 : /* Generates recovery code for BEGIN speculative INSN. */
7962 : static void
7963 0 : begin_speculative_block (rtx_insn *insn)
7964 : {
7965 0 : if (TODO_SPEC (insn) & BEGIN_DATA)
7966 0 : nr_begin_data++;
7967 0 : if (TODO_SPEC (insn) & BEGIN_CONTROL)
7968 0 : nr_begin_control++;
7969 :
7970 0 : create_check_block_twin (insn, false);
7971 :
7972 0 : TODO_SPEC (insn) &= ~BEGIN_SPEC;
7973 0 : }
7974 :
7975 : static void haifa_init_insn (rtx_insn *);
7976 :
7977 : /* Generates recovery code for BE_IN speculative INSN. */
7978 : static void
7979 0 : add_to_speculative_block (rtx_insn *insn)
7980 : {
7981 0 : ds_t ts;
7982 0 : sd_iterator_def sd_it;
7983 0 : dep_t dep;
7984 0 : auto_vec<rtx_insn *, 10> twins;
7985 :
7986 0 : ts = TODO_SPEC (insn);
7987 0 : gcc_assert (!(ts & ~BE_IN_SPEC));
7988 :
7989 0 : if (ts & BE_IN_DATA)
7990 0 : nr_be_in_data++;
7991 0 : if (ts & BE_IN_CONTROL)
7992 0 : nr_be_in_control++;
7993 :
7994 0 : TODO_SPEC (insn) &= ~BE_IN_SPEC;
7995 0 : gcc_assert (!TODO_SPEC (insn));
7996 :
7997 0 : DONE_SPEC (insn) |= ts;
7998 :
7999 : /* First we convert all simple checks to branchy. */
8000 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
8001 0 : sd_iterator_cond (&sd_it, &dep);)
8002 : {
8003 0 : rtx_insn *check = DEP_PRO (dep);
8004 :
8005 0 : if (IS_SPECULATION_SIMPLE_CHECK_P (check))
8006 : {
8007 0 : create_check_block_twin (check, true);
8008 :
8009 : /* Restart search. */
8010 0 : sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
8011 : }
8012 : else
8013 : /* Continue search. */
8014 0 : sd_iterator_next (&sd_it);
8015 : }
8016 :
8017 0 : auto_vec<rtx_insn *> priorities_roots;
8018 0 : clear_priorities (insn, &priorities_roots);
8019 :
8020 0 : while (1)
8021 : {
8022 0 : rtx_insn *check, *twin;
8023 0 : basic_block rec;
8024 :
8025 : /* Get the first backward dependency of INSN. */
8026 0 : sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
8027 0 : if (!sd_iterator_cond (&sd_it, &dep))
8028 : /* INSN has no backward dependencies left. */
8029 : break;
8030 :
8031 0 : gcc_assert ((DEP_STATUS (dep) & BEGIN_SPEC) == 0
8032 : && (DEP_STATUS (dep) & BE_IN_SPEC) != 0
8033 : && (DEP_STATUS (dep) & DEP_TYPES) == DEP_TRUE);
8034 :
8035 0 : check = DEP_PRO (dep);
8036 :
8037 0 : gcc_assert (!IS_SPECULATION_CHECK_P (check) && !ORIG_PAT (check)
8038 : && QUEUE_INDEX (check) == QUEUE_NOWHERE);
8039 :
8040 0 : rec = BLOCK_FOR_INSN (check);
8041 :
8042 0 : twin = emit_insn_before (copy_insn (PATTERN (insn)), BB_END (rec));
8043 0 : haifa_init_insn (twin);
8044 :
8045 0 : sd_copy_back_deps (twin, insn, true);
8046 :
8047 0 : if (sched_verbose && spec_info->dump)
8048 : /* INSN_BB (insn) isn't determined for twin insns yet.
8049 : So we can't use current_sched_info->print_insn. */
8050 0 : fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
8051 0 : INSN_UID (twin), rec->index);
8052 :
8053 0 : twins.safe_push (twin);
8054 :
8055 : /* Add dependences between TWIN and all appropriate
8056 : instructions from REC. */
8057 0 : FOR_EACH_DEP (insn, SD_LIST_SPEC_BACK, sd_it, dep)
8058 : {
8059 0 : rtx_insn *pro = DEP_PRO (dep);
8060 :
8061 0 : gcc_assert (DEP_TYPE (dep) == REG_DEP_TRUE);
8062 :
8063 : /* INSN might have dependencies from the instructions from
8064 : several recovery blocks. At this iteration we process those
8065 : producers that reside in REC. */
8066 0 : if (BLOCK_FOR_INSN (pro) == rec)
8067 : {
8068 0 : dep_def _new_dep, *new_dep = &_new_dep;
8069 :
8070 0 : init_dep (new_dep, pro, twin, REG_DEP_TRUE);
8071 0 : sd_add_dep (new_dep, false);
8072 : }
8073 : }
8074 :
8075 0 : process_insn_forw_deps_be_in_spec (insn, twin, ts);
8076 :
8077 : /* Remove all dependencies between INSN and insns in REC. */
8078 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
8079 0 : sd_iterator_cond (&sd_it, &dep);)
8080 : {
8081 0 : rtx_insn *pro = DEP_PRO (dep);
8082 :
8083 0 : if (BLOCK_FOR_INSN (pro) == rec)
8084 0 : sd_delete_dep (sd_it);
8085 : else
8086 0 : sd_iterator_next (&sd_it);
8087 : }
8088 0 : }
8089 :
8090 : /* We couldn't have added the dependencies between INSN and TWINS earlier
8091 : because that would make TWINS appear in the INSN_BACK_DEPS (INSN). */
8092 0 : unsigned int i;
8093 0 : rtx_insn *twin;
8094 0 : FOR_EACH_VEC_ELT_REVERSE (twins, i, twin)
8095 : {
8096 0 : dep_def _new_dep, *new_dep = &_new_dep;
8097 :
8098 0 : init_dep (new_dep, insn, twin, REG_DEP_OUTPUT);
8099 0 : sd_add_dep (new_dep, false);
8100 : }
8101 :
8102 0 : calc_priorities (priorities_roots);
8103 0 : }
8104 :
8105 : /* Extends and fills with zeros (only the new part) array pointed to by P. */
8106 : void *
8107 10331552 : xrecalloc (void *p, size_t new_nmemb, size_t old_nmemb, size_t size)
8108 : {
8109 10331552 : gcc_assert (new_nmemb >= old_nmemb);
8110 10331552 : p = XRESIZEVAR (void, p, new_nmemb * size);
8111 10331552 : memset (((char *) p) + old_nmemb * size, 0, (new_nmemb - old_nmemb) * size);
8112 10331552 : return p;
8113 : }
8114 :
8115 : /* Helper function.
8116 : Find fallthru edge from PRED. */
8117 : edge
8118 108 : find_fallthru_edge_from (basic_block pred)
8119 : {
8120 108 : edge e;
8121 108 : basic_block succ;
8122 :
8123 108 : succ = pred->next_bb;
8124 108 : gcc_assert (succ->prev_bb == pred);
8125 :
8126 324 : if (EDGE_COUNT (pred->succs) <= EDGE_COUNT (succ->preds))
8127 : {
8128 35 : e = find_fallthru_edge (pred->succs);
8129 :
8130 35 : if (e)
8131 : {
8132 23 : gcc_assert (e->dest == succ || e->dest->index == EXIT_BLOCK);
8133 : return e;
8134 : }
8135 : }
8136 : else
8137 : {
8138 73 : e = find_fallthru_edge (succ->preds);
8139 :
8140 73 : if (e)
8141 : {
8142 73 : gcc_assert (e->src == pred);
8143 : return e;
8144 : }
8145 : }
8146 :
8147 : return NULL;
8148 : }
8149 :
8150 : /* Extend per basic block data structures. */
8151 : static void
8152 964556 : sched_extend_bb (void)
8153 : {
8154 : /* The following is done to keep current_sched_info->next_tail non null. */
8155 964556 : rtx_insn *end = BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
8156 964556 : rtx_insn *insn = DEBUG_INSN_P (end) ? prev_nondebug_insn (end) : end;
8157 964556 : if (NEXT_INSN (end) == 0
8158 964556 : || (!NOTE_P (insn)
8159 964094 : && !LABEL_P (insn)
8160 : /* Don't emit a NOTE if it would end up before a BARRIER. */
8161 964075 : && !BARRIER_P (next_nondebug_insn (end))))
8162 : {
8163 552 : rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
8164 : /* Make note appear outside BB. */
8165 552 : set_block_for_insn (note, NULL);
8166 552 : BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb) = end;
8167 : }
8168 964556 : }
8169 :
8170 : /* Init per basic block data structures. */
8171 : void
8172 964556 : sched_init_bbs (void)
8173 : {
8174 964556 : sched_extend_bb ();
8175 964556 : }
8176 :
8177 : /* Initialize BEFORE_RECOVERY variable. */
8178 : static void
8179 0 : init_before_recovery (basic_block *before_recovery_ptr)
8180 : {
8181 0 : basic_block last;
8182 0 : edge e;
8183 :
8184 0 : last = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
8185 0 : e = find_fallthru_edge_from (last);
8186 :
8187 0 : if (e)
8188 : {
8189 : /* We create two basic blocks:
8190 : 1. Single instruction block is inserted right after E->SRC
8191 : and has jump to
8192 : 2. Empty block right before EXIT_BLOCK.
8193 : Between these two blocks recovery blocks will be emitted. */
8194 :
8195 0 : basic_block single, empty;
8196 :
8197 : /* If the fallthrough edge to exit we've found is from the block we've
8198 : created before, don't do anything more. */
8199 0 : if (last == after_recovery)
8200 : return;
8201 :
8202 0 : adding_bb_to_current_region_p = false;
8203 :
8204 0 : single = sched_create_empty_bb (last);
8205 0 : empty = sched_create_empty_bb (single);
8206 :
8207 : /* Add new blocks to the root loop. */
8208 0 : if (current_loops != NULL)
8209 : {
8210 0 : add_bb_to_loop (single, (*current_loops->larray)[0]);
8211 0 : add_bb_to_loop (empty, (*current_loops->larray)[0]);
8212 : }
8213 :
8214 0 : single->count = last->count;
8215 0 : empty->count = last->count;
8216 0 : BB_COPY_PARTITION (single, last);
8217 0 : BB_COPY_PARTITION (empty, last);
8218 :
8219 0 : redirect_edge_succ (e, single);
8220 0 : make_single_succ_edge (single, empty, 0);
8221 0 : make_single_succ_edge (empty, EXIT_BLOCK_PTR_FOR_FN (cfun),
8222 : EDGE_FALLTHRU);
8223 :
8224 0 : rtx_code_label *label = block_label (empty);
8225 0 : rtx_jump_insn *x = emit_jump_insn_after (targetm.gen_jump (label),
8226 0 : BB_END (single));
8227 0 : JUMP_LABEL (x) = label;
8228 0 : LABEL_NUSES (label)++;
8229 0 : haifa_init_insn (x);
8230 :
8231 0 : emit_barrier_after (x);
8232 :
8233 0 : sched_init_only_bb (empty, NULL);
8234 0 : sched_init_only_bb (single, NULL);
8235 0 : sched_extend_bb ();
8236 :
8237 0 : adding_bb_to_current_region_p = true;
8238 0 : before_recovery = single;
8239 0 : after_recovery = empty;
8240 :
8241 0 : if (before_recovery_ptr)
8242 0 : *before_recovery_ptr = before_recovery;
8243 :
8244 0 : if (sched_verbose >= 2 && spec_info->dump)
8245 0 : fprintf (spec_info->dump,
8246 : ";;\t\tFixed fallthru to EXIT : %d->>%d->%d->>EXIT\n",
8247 : last->index, single->index, empty->index);
8248 : }
8249 : else
8250 0 : before_recovery = last;
8251 : }
8252 :
8253 : /* Returns new recovery block. */
8254 : basic_block
8255 0 : sched_create_recovery_block (basic_block *before_recovery_ptr)
8256 : {
8257 0 : rtx_insn *barrier;
8258 0 : basic_block rec;
8259 :
8260 0 : haifa_recovery_bb_recently_added_p = true;
8261 0 : haifa_recovery_bb_ever_added_p = true;
8262 :
8263 0 : init_before_recovery (before_recovery_ptr);
8264 :
8265 0 : barrier = get_last_bb_insn (before_recovery);
8266 0 : gcc_assert (BARRIER_P (barrier));
8267 :
8268 0 : rtx_insn *label = emit_label_after (gen_label_rtx (), barrier);
8269 :
8270 0 : rec = create_basic_block (label, label, before_recovery);
8271 :
8272 : /* A recovery block always ends with an unconditional jump. */
8273 0 : emit_barrier_after (BB_END (rec));
8274 :
8275 0 : if (BB_PARTITION (before_recovery) != BB_UNPARTITIONED)
8276 0 : BB_SET_PARTITION (rec, BB_COLD_PARTITION);
8277 :
8278 0 : if (sched_verbose && spec_info->dump)
8279 0 : fprintf (spec_info->dump, ";;\t\tGenerated recovery block rec%d\n",
8280 : rec->index);
8281 :
8282 0 : return rec;
8283 : }
8284 :
8285 : /* Create edges: FIRST_BB -> REC; FIRST_BB -> SECOND_BB; REC -> SECOND_BB
8286 : and emit necessary jumps. */
8287 : void
8288 0 : sched_create_recovery_edges (basic_block first_bb, basic_block rec,
8289 : basic_block second_bb)
8290 : {
8291 0 : int edge_flags;
8292 :
8293 : /* This is fixing of incoming edge. */
8294 : /* ??? Which other flags should be specified? */
8295 0 : if (BB_PARTITION (first_bb) != BB_PARTITION (rec))
8296 : /* Partition type is the same, if it is "unpartitioned". */
8297 : edge_flags = EDGE_CROSSING;
8298 : else
8299 0 : edge_flags = 0;
8300 :
8301 0 : edge e2 = single_succ_edge (first_bb);
8302 0 : edge e = make_edge (first_bb, rec, edge_flags);
8303 :
8304 : /* TODO: The actual probability can be determined and is computed as
8305 : 'todo_spec' variable in create_check_block_twin and
8306 : in sel-sched.cc `check_ds' in create_speculation_check. */
8307 0 : e->probability = profile_probability::very_unlikely ();
8308 0 : rec->count = e->count ();
8309 0 : e2->probability = e->probability.invert ();
8310 :
8311 0 : rtx_code_label *label = block_label (second_bb);
8312 0 : rtx_jump_insn *jump = emit_jump_insn_after (targetm.gen_jump (label),
8313 0 : BB_END (rec));
8314 0 : JUMP_LABEL (jump) = label;
8315 0 : LABEL_NUSES (label)++;
8316 :
8317 0 : if (BB_PARTITION (second_bb) != BB_PARTITION (rec))
8318 : /* Partition type is the same, if it is "unpartitioned". */
8319 : {
8320 : /* Rewritten from cfgrtl.cc. */
8321 0 : if (crtl->has_bb_partition && targetm_common.have_named_sections)
8322 : {
8323 : /* We don't need the same note for the check because
8324 : any_condjump_p (check) == true. */
8325 0 : CROSSING_JUMP_P (jump) = 1;
8326 : }
8327 : edge_flags = EDGE_CROSSING;
8328 : }
8329 : else
8330 : edge_flags = 0;
8331 :
8332 0 : make_single_succ_edge (rec, second_bb, edge_flags);
8333 0 : if (dom_info_available_p (CDI_DOMINATORS))
8334 0 : set_immediate_dominator (CDI_DOMINATORS, rec, first_bb);
8335 0 : }
8336 :
8337 : /* This function creates recovery code for INSN. If MUTATE_P is nonzero,
8338 : INSN is a simple check, that should be converted to branchy one. */
8339 : static void
8340 0 : create_check_block_twin (rtx_insn *insn, bool mutate_p)
8341 : {
8342 0 : basic_block rec;
8343 0 : rtx_insn *label, *check, *twin;
8344 0 : rtx check_pat;
8345 0 : ds_t fs;
8346 0 : sd_iterator_def sd_it;
8347 0 : dep_t dep;
8348 0 : dep_def _new_dep, *new_dep = &_new_dep;
8349 0 : ds_t todo_spec;
8350 :
8351 0 : gcc_assert (ORIG_PAT (insn) != NULL_RTX);
8352 :
8353 0 : if (!mutate_p)
8354 0 : todo_spec = TODO_SPEC (insn);
8355 : else
8356 : {
8357 0 : gcc_assert (IS_SPECULATION_SIMPLE_CHECK_P (insn)
8358 : && (TODO_SPEC (insn) & SPECULATIVE) == 0);
8359 :
8360 0 : todo_spec = CHECK_SPEC (insn);
8361 : }
8362 :
8363 0 : todo_spec &= SPECULATIVE;
8364 :
8365 : /* Create recovery block. */
8366 0 : if (mutate_p || targetm.sched.needs_block_p (todo_spec))
8367 : {
8368 0 : rec = sched_create_recovery_block (NULL);
8369 0 : label = BB_HEAD (rec);
8370 : }
8371 : else
8372 : {
8373 0 : rec = EXIT_BLOCK_PTR_FOR_FN (cfun);
8374 0 : label = NULL;
8375 : }
8376 :
8377 : /* Emit CHECK. */
8378 0 : check_pat = targetm.sched.gen_spec_check (insn, label, todo_spec);
8379 :
8380 0 : if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
8381 : {
8382 : /* To have mem_reg alive at the beginning of second_bb,
8383 : we emit check BEFORE insn, so insn after splitting
8384 : insn will be at the beginning of second_bb, which will
8385 : provide us with the correct life information. */
8386 0 : check = emit_jump_insn_before (check_pat, insn);
8387 0 : JUMP_LABEL (check) = label;
8388 0 : LABEL_NUSES (label)++;
8389 : }
8390 : else
8391 0 : check = emit_insn_before (check_pat, insn);
8392 :
8393 : /* Extend data structures. */
8394 0 : haifa_init_insn (check);
8395 :
8396 : /* CHECK is being added to current region. Extend ready list. */
8397 0 : gcc_assert (sched_ready_n_insns != -1);
8398 0 : sched_extend_ready_list (sched_ready_n_insns + 1);
8399 :
8400 0 : if (current_sched_info->add_remove_insn)
8401 0 : current_sched_info->add_remove_insn (insn, 0);
8402 :
8403 0 : RECOVERY_BLOCK (check) = rec;
8404 :
8405 0 : if (sched_verbose && spec_info->dump)
8406 0 : fprintf (spec_info->dump, ";;\t\tGenerated check insn : %s\n",
8407 0 : (*current_sched_info->print_insn) (check, 0));
8408 :
8409 0 : gcc_assert (ORIG_PAT (insn));
8410 :
8411 : /* Initialize TWIN (twin is a duplicate of original instruction
8412 : in the recovery block). */
8413 0 : if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
8414 : {
8415 0 : sd_iterator_def sd_it;
8416 0 : dep_t dep;
8417 :
8418 0 : FOR_EACH_DEP (insn, SD_LIST_RES_BACK, sd_it, dep)
8419 0 : if ((DEP_STATUS (dep) & DEP_OUTPUT) != 0)
8420 : {
8421 0 : struct _dep _dep2, *dep2 = &_dep2;
8422 :
8423 0 : init_dep (dep2, DEP_PRO (dep), check, REG_DEP_TRUE);
8424 :
8425 0 : sd_add_dep (dep2, true);
8426 : }
8427 :
8428 0 : twin = emit_insn_after (ORIG_PAT (insn), BB_END (rec));
8429 0 : haifa_init_insn (twin);
8430 :
8431 0 : if (sched_verbose && spec_info->dump)
8432 : /* INSN_BB (insn) isn't determined for twin insns yet.
8433 : So we can't use current_sched_info->print_insn. */
8434 0 : fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
8435 0 : INSN_UID (twin), rec->index);
8436 : }
8437 : else
8438 : {
8439 0 : ORIG_PAT (check) = ORIG_PAT (insn);
8440 0 : HAS_INTERNAL_DEP (check) = 1;
8441 0 : twin = check;
8442 : /* ??? We probably should change all OUTPUT dependencies to
8443 : (TRUE | OUTPUT). */
8444 : }
8445 :
8446 : /* Copy all resolved back dependencies of INSN to TWIN. This will
8447 : provide correct value for INSN_TICK (TWIN). */
8448 0 : sd_copy_back_deps (twin, insn, true);
8449 :
8450 0 : if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
8451 : /* In case of branchy check, fix CFG. */
8452 : {
8453 0 : basic_block first_bb, second_bb;
8454 0 : rtx_insn *jump;
8455 :
8456 0 : first_bb = BLOCK_FOR_INSN (check);
8457 0 : second_bb = sched_split_block (first_bb, check);
8458 :
8459 0 : sched_create_recovery_edges (first_bb, rec, second_bb);
8460 :
8461 0 : sched_init_only_bb (second_bb, first_bb);
8462 0 : sched_init_only_bb (rec, EXIT_BLOCK_PTR_FOR_FN (cfun));
8463 :
8464 0 : jump = BB_END (rec);
8465 0 : haifa_init_insn (jump);
8466 : }
8467 :
8468 : /* Move backward dependences from INSN to CHECK and
8469 : move forward dependences from INSN to TWIN. */
8470 :
8471 : /* First, create dependencies between INSN's producers and CHECK & TWIN. */
8472 0 : FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
8473 : {
8474 0 : rtx_insn *pro = DEP_PRO (dep);
8475 0 : ds_t ds;
8476 :
8477 : /* If BEGIN_DATA: [insn ~~TRUE~~> producer]:
8478 : check --TRUE--> producer ??? or ANTI ???
8479 : twin --TRUE--> producer
8480 : twin --ANTI--> check
8481 :
8482 : If BEGIN_CONTROL: [insn ~~ANTI~~> producer]:
8483 : check --ANTI--> producer
8484 : twin --ANTI--> producer
8485 : twin --ANTI--> check
8486 :
8487 : If BE_IN_SPEC: [insn ~~TRUE~~> producer]:
8488 : check ~~TRUE~~> producer
8489 : twin ~~TRUE~~> producer
8490 : twin --ANTI--> check */
8491 :
8492 0 : ds = DEP_STATUS (dep);
8493 :
8494 0 : if (ds & BEGIN_SPEC)
8495 : {
8496 0 : gcc_assert (!mutate_p);
8497 0 : ds &= ~BEGIN_SPEC;
8498 : }
8499 :
8500 0 : init_dep_1 (new_dep, pro, check, DEP_TYPE (dep), ds);
8501 0 : sd_add_dep (new_dep, false);
8502 :
8503 0 : if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
8504 : {
8505 0 : DEP_CON (new_dep) = twin;
8506 0 : sd_add_dep (new_dep, false);
8507 : }
8508 : }
8509 :
8510 : /* Second, remove backward dependencies of INSN. */
8511 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
8512 0 : sd_iterator_cond (&sd_it, &dep);)
8513 : {
8514 0 : if ((DEP_STATUS (dep) & BEGIN_SPEC)
8515 0 : || mutate_p)
8516 : /* We can delete this dep because we overcome it with
8517 : BEGIN_SPECULATION. */
8518 0 : sd_delete_dep (sd_it);
8519 : else
8520 0 : sd_iterator_next (&sd_it);
8521 : }
8522 :
8523 : /* Future Speculations. Determine what BE_IN speculations will be like. */
8524 0 : fs = 0;
8525 :
8526 : /* Fields (DONE_SPEC (x) & BEGIN_SPEC) and CHECK_SPEC (x) are set only
8527 : here. */
8528 :
8529 0 : gcc_assert (!DONE_SPEC (insn));
8530 :
8531 0 : if (!mutate_p)
8532 : {
8533 0 : ds_t ts = TODO_SPEC (insn);
8534 :
8535 0 : DONE_SPEC (insn) = ts & BEGIN_SPEC;
8536 0 : CHECK_SPEC (check) = ts & BEGIN_SPEC;
8537 :
8538 : /* Luckiness of future speculations solely depends upon initial
8539 : BEGIN speculation. */
8540 0 : if (ts & BEGIN_DATA)
8541 0 : fs = set_dep_weak (fs, BE_IN_DATA, get_dep_weak (ts, BEGIN_DATA));
8542 0 : if (ts & BEGIN_CONTROL)
8543 0 : fs = set_dep_weak (fs, BE_IN_CONTROL,
8544 : get_dep_weak (ts, BEGIN_CONTROL));
8545 : }
8546 : else
8547 0 : CHECK_SPEC (check) = CHECK_SPEC (insn);
8548 :
8549 : /* Future speculations: call the helper. */
8550 0 : process_insn_forw_deps_be_in_spec (insn, twin, fs);
8551 :
8552 0 : if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
8553 : {
8554 : /* Which types of dependencies should we use here is,
8555 : generally, machine-dependent question... But, for now,
8556 : it is not. */
8557 :
8558 0 : if (!mutate_p)
8559 : {
8560 0 : init_dep (new_dep, insn, check, REG_DEP_TRUE);
8561 0 : sd_add_dep (new_dep, false);
8562 :
8563 0 : init_dep (new_dep, insn, twin, REG_DEP_OUTPUT);
8564 0 : sd_add_dep (new_dep, false);
8565 : }
8566 : else
8567 : {
8568 0 : if (spec_info->dump)
8569 0 : fprintf (spec_info->dump, ";;\t\tRemoved simple check : %s\n",
8570 0 : (*current_sched_info->print_insn) (insn, 0));
8571 :
8572 : /* Remove all dependencies of the INSN. */
8573 0 : {
8574 0 : sd_it = sd_iterator_start (insn, (SD_LIST_FORW
8575 : | SD_LIST_BACK
8576 : | SD_LIST_RES_BACK));
8577 0 : while (sd_iterator_cond (&sd_it, &dep))
8578 0 : sd_delete_dep (sd_it);
8579 : }
8580 :
8581 : /* If former check (INSN) already was moved to the ready (or queue)
8582 : list, add new check (CHECK) there too. */
8583 0 : if (QUEUE_INDEX (insn) != QUEUE_NOWHERE)
8584 0 : try_ready (check);
8585 :
8586 : /* Remove old check from instruction stream and free its
8587 : data. */
8588 0 : sched_remove_insn (insn);
8589 : }
8590 :
8591 0 : init_dep (new_dep, check, twin, REG_DEP_ANTI);
8592 0 : sd_add_dep (new_dep, false);
8593 : }
8594 : else
8595 : {
8596 0 : init_dep_1 (new_dep, insn, check, REG_DEP_TRUE, DEP_TRUE | DEP_OUTPUT);
8597 0 : sd_add_dep (new_dep, false);
8598 : }
8599 :
8600 0 : if (!mutate_p)
8601 : /* Fix priorities. If MUTATE_P is nonzero, this is not necessary,
8602 : because it'll be done later in add_to_speculative_block. */
8603 : {
8604 0 : auto_vec<rtx_insn *> priorities_roots;
8605 :
8606 0 : clear_priorities (twin, &priorities_roots);
8607 0 : calc_priorities (priorities_roots);
8608 0 : }
8609 0 : }
8610 :
8611 : /* Removes dependency between instructions in the recovery block REC
8612 : and usual region instructions. It keeps inner dependences so it
8613 : won't be necessary to recompute them. */
8614 : static void
8615 0 : fix_recovery_deps (basic_block rec)
8616 : {
8617 0 : rtx_insn *note, *insn, *jump;
8618 0 : auto_vec<rtx_insn *, 10> ready_list;
8619 0 : auto_bitmap in_ready;
8620 :
8621 : /* NOTE - a basic block note. */
8622 0 : note = NEXT_INSN (BB_HEAD (rec));
8623 0 : gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
8624 0 : insn = BB_END (rec);
8625 0 : gcc_assert (JUMP_P (insn));
8626 0 : insn = PREV_INSN (insn);
8627 :
8628 0 : do
8629 : {
8630 0 : sd_iterator_def sd_it;
8631 0 : dep_t dep;
8632 :
8633 0 : for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
8634 0 : sd_iterator_cond (&sd_it, &dep);)
8635 : {
8636 0 : rtx_insn *consumer = DEP_CON (dep);
8637 :
8638 0 : if (BLOCK_FOR_INSN (consumer) != rec)
8639 : {
8640 0 : sd_delete_dep (sd_it);
8641 :
8642 0 : if (bitmap_set_bit (in_ready, INSN_LUID (consumer)))
8643 0 : ready_list.safe_push (consumer);
8644 : }
8645 : else
8646 : {
8647 0 : gcc_assert ((DEP_STATUS (dep) & DEP_TYPES) == DEP_TRUE);
8648 :
8649 0 : sd_iterator_next (&sd_it);
8650 : }
8651 : }
8652 :
8653 0 : insn = PREV_INSN (insn);
8654 : }
8655 0 : while (insn != note);
8656 :
8657 : /* Try to add instructions to the ready or queue list. */
8658 0 : unsigned int i;
8659 0 : rtx_insn *temp;
8660 0 : FOR_EACH_VEC_ELT_REVERSE (ready_list, i, temp)
8661 0 : try_ready (temp);
8662 :
8663 : /* Fixing jump's dependences. */
8664 0 : insn = BB_HEAD (rec);
8665 0 : jump = BB_END (rec);
8666 :
8667 0 : gcc_assert (LABEL_P (insn));
8668 0 : insn = NEXT_INSN (insn);
8669 :
8670 0 : gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
8671 0 : add_jump_dependencies (insn, jump);
8672 0 : }
8673 :
8674 : /* Change pattern of INSN to NEW_PAT. Invalidate cached haifa
8675 : instruction data. */
8676 : static bool
8677 0 : haifa_change_pattern (rtx_insn *insn, rtx new_pat)
8678 : {
8679 0 : int t;
8680 :
8681 0 : t = validate_change (insn, &PATTERN (insn), new_pat, 0);
8682 0 : if (!t)
8683 : return false;
8684 :
8685 0 : update_insn_after_change (insn);
8686 0 : return true;
8687 : }
8688 :
8689 : /* -1 - can't speculate,
8690 : 0 - for speculation with REQUEST mode it is OK to use
8691 : current instruction pattern,
8692 : 1 - need to change pattern for *NEW_PAT to be speculative. */
8693 : int
8694 0 : sched_speculate_insn (rtx_insn *insn, ds_t request, rtx *new_pat)
8695 : {
8696 0 : gcc_assert (current_sched_info->flags & DO_SPECULATION
8697 : && (request & SPECULATIVE)
8698 : && sched_insn_is_legitimate_for_speculation_p (insn, request));
8699 :
8700 0 : if ((request & spec_info->mask) != request)
8701 : return -1;
8702 :
8703 0 : if (request & BE_IN_SPEC
8704 0 : && !(request & BEGIN_SPEC))
8705 : return 0;
8706 :
8707 0 : return targetm.sched.speculate_insn (insn, request, new_pat);
8708 : }
8709 :
8710 : static int
8711 0 : haifa_speculate_insn (rtx_insn *insn, ds_t request, rtx *new_pat)
8712 : {
8713 0 : gcc_assert (sched_deps_info->generate_spec_deps
8714 : && !IS_SPECULATION_CHECK_P (insn));
8715 :
8716 0 : if (HAS_INTERNAL_DEP (insn)
8717 0 : || SCHED_GROUP_P (insn))
8718 : return -1;
8719 :
8720 0 : return sched_speculate_insn (insn, request, new_pat);
8721 : }
8722 :
8723 : /* Print some information about block BB, which starts with HEAD and
8724 : ends with TAIL, before scheduling it.
8725 : I is zero, if scheduler is about to start with the fresh ebb. */
8726 : static void
8727 192 : dump_new_block_header (int i, basic_block bb, rtx_insn *head, rtx_insn *tail)
8728 : {
8729 192 : if (!i)
8730 190 : fprintf (sched_dump,
8731 : ";; ======================================================\n");
8732 : else
8733 2 : fprintf (sched_dump,
8734 : ";; =====================ADVANCING TO=====================\n");
8735 192 : fprintf (sched_dump,
8736 : ";; -- basic block %d from %d to %d -- %s reload\n",
8737 192 : bb->index, INSN_UID (head), INSN_UID (tail),
8738 192 : (reload_completed ? "after" : "before"));
8739 192 : fprintf (sched_dump,
8740 : ";; ======================================================\n");
8741 192 : fprintf (sched_dump, "\n");
8742 192 : }
8743 :
8744 : /* Unlink basic block notes and labels and saves them, so they
8745 : can be easily restored. We unlink basic block notes in EBB to
8746 : provide back-compatibility with the previous code, as target backends
8747 : assume, that there'll be only instructions between
8748 : current_sched_info->{head and tail}. We restore these notes as soon
8749 : as we can.
8750 : FIRST (LAST) is the first (last) basic block in the ebb.
8751 : NB: In usual case (FIRST == LAST) nothing is really done. */
8752 : void
8753 10313337 : unlink_bb_notes (basic_block first, basic_block last)
8754 : {
8755 : /* We DON'T unlink basic block notes of the first block in the ebb. */
8756 10313337 : if (first == last)
8757 : return;
8758 :
8759 13 : bb_header = XNEWVEC (rtx_insn *, last_basic_block_for_fn (cfun));
8760 :
8761 : /* Make a sentinel. */
8762 13 : if (last->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
8763 13 : bb_header[last->next_bb->index] = 0;
8764 :
8765 13 : first = first->next_bb;
8766 81 : do
8767 : {
8768 47 : rtx_insn *prev, *label, *note, *next;
8769 :
8770 47 : label = BB_HEAD (last);
8771 47 : if (LABEL_P (label))
8772 0 : note = NEXT_INSN (label);
8773 : else
8774 : note = label;
8775 47 : gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
8776 :
8777 47 : prev = PREV_INSN (label);
8778 47 : next = NEXT_INSN (note);
8779 47 : gcc_assert (prev && next);
8780 :
8781 47 : SET_NEXT_INSN (prev) = next;
8782 47 : SET_PREV_INSN (next) = prev;
8783 :
8784 47 : bb_header[last->index] = label;
8785 :
8786 47 : if (last == first)
8787 : break;
8788 :
8789 34 : last = last->prev_bb;
8790 34 : }
8791 : while (1);
8792 : }
8793 :
8794 : /* Restore basic block notes.
8795 : FIRST is the first basic block in the ebb. */
8796 : static void
8797 10313337 : restore_bb_notes (basic_block first)
8798 : {
8799 10313337 : if (!bb_header)
8800 : return;
8801 :
8802 : /* We DON'T unlink basic block notes of the first block in the ebb. */
8803 13 : first = first->next_bb;
8804 : /* Remember: FIRST is actually a second basic block in the ebb. */
8805 :
8806 13 : while (first != EXIT_BLOCK_PTR_FOR_FN (cfun)
8807 60 : && bb_header[first->index])
8808 : {
8809 47 : rtx_insn *prev, *label, *note, *next;
8810 :
8811 47 : label = bb_header[first->index];
8812 47 : prev = PREV_INSN (label);
8813 47 : next = NEXT_INSN (prev);
8814 :
8815 47 : if (LABEL_P (label))
8816 0 : note = NEXT_INSN (label);
8817 : else
8818 : note = label;
8819 47 : gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
8820 :
8821 47 : bb_header[first->index] = 0;
8822 :
8823 47 : SET_NEXT_INSN (prev) = label;
8824 47 : SET_NEXT_INSN (note) = next;
8825 47 : SET_PREV_INSN (next) = note;
8826 :
8827 47 : first = first->next_bb;
8828 : }
8829 :
8830 13 : free (bb_header);
8831 13 : bb_header = 0;
8832 : }
8833 :
8834 : /* Helper function.
8835 : Fix CFG after both in- and inter-block movement of
8836 : control_flow_insn_p JUMP. */
8837 : static void
8838 1 : fix_jump_move (rtx_insn *jump)
8839 : {
8840 1 : basic_block bb, jump_bb, jump_bb_next;
8841 :
8842 1 : bb = BLOCK_FOR_INSN (PREV_INSN (jump));
8843 1 : jump_bb = BLOCK_FOR_INSN (jump);
8844 1 : jump_bb_next = jump_bb->next_bb;
8845 :
8846 1 : gcc_assert (common_sched_info->sched_pass_id == SCHED_EBB_PASS
8847 : || IS_SPECULATION_BRANCHY_CHECK_P (jump));
8848 :
8849 1 : if (!NOTE_INSN_BASIC_BLOCK_P (BB_END (jump_bb_next)))
8850 : /* if jump_bb_next is not empty. */
8851 0 : BB_END (jump_bb) = BB_END (jump_bb_next);
8852 :
8853 1 : if (BB_END (bb) != PREV_INSN (jump))
8854 : /* Then there are instruction after jump that should be placed
8855 : to jump_bb_next. */
8856 1 : BB_END (jump_bb_next) = BB_END (bb);
8857 : else
8858 : /* Otherwise jump_bb_next is empty. */
8859 0 : BB_END (jump_bb_next) = NEXT_INSN (BB_HEAD (jump_bb_next));
8860 :
8861 : /* To make assertion in move_insn happy. */
8862 1 : BB_END (bb) = PREV_INSN (jump);
8863 :
8864 1 : update_bb_for_insn (jump_bb_next);
8865 1 : }
8866 :
8867 : /* Fix CFG after interblock movement of control_flow_insn_p JUMP. */
8868 : static void
8869 0 : move_block_after_check (rtx_insn *jump)
8870 : {
8871 0 : basic_block bb, jump_bb, jump_bb_next;
8872 0 : vec<edge, va_gc> *t;
8873 :
8874 0 : bb = BLOCK_FOR_INSN (PREV_INSN (jump));
8875 0 : jump_bb = BLOCK_FOR_INSN (jump);
8876 0 : jump_bb_next = jump_bb->next_bb;
8877 :
8878 0 : update_bb_for_insn (jump_bb);
8879 :
8880 0 : gcc_assert (IS_SPECULATION_CHECK_P (jump)
8881 : || IS_SPECULATION_CHECK_P (BB_END (jump_bb_next)));
8882 :
8883 0 : unlink_block (jump_bb_next);
8884 0 : link_block (jump_bb_next, bb);
8885 :
8886 0 : t = bb->succs;
8887 0 : bb->succs = 0;
8888 0 : move_succs (&(jump_bb->succs), bb);
8889 0 : move_succs (&(jump_bb_next->succs), jump_bb);
8890 0 : move_succs (&t, jump_bb_next);
8891 :
8892 0 : df_mark_solutions_dirty ();
8893 :
8894 0 : common_sched_info->fix_recovery_cfg
8895 0 : (bb->index, jump_bb->index, jump_bb_next->index);
8896 0 : }
8897 :
8898 : /* Helper function for move_block_after_check.
8899 : This functions attaches edge vector pointed to by SUCCSP to
8900 : block TO. */
8901 : static void
8902 0 : move_succs (vec<edge, va_gc> **succsp, basic_block to)
8903 : {
8904 0 : edge e;
8905 0 : edge_iterator ei;
8906 :
8907 0 : gcc_assert (to->succs == 0);
8908 :
8909 0 : to->succs = *succsp;
8910 :
8911 0 : FOR_EACH_EDGE (e, ei, to->succs)
8912 0 : e->src = to;
8913 :
8914 0 : *succsp = 0;
8915 0 : }
8916 :
8917 : /* Remove INSN from the instruction stream.
8918 : INSN should have any dependencies. */
8919 : static void
8920 0 : sched_remove_insn (rtx_insn *insn)
8921 : {
8922 0 : sd_finish_insn (insn);
8923 :
8924 0 : change_queue_index (insn, QUEUE_NOWHERE);
8925 0 : current_sched_info->add_remove_insn (insn, 1);
8926 0 : delete_insn (insn);
8927 0 : }
8928 :
8929 : /* Clear priorities of all instructions, that are forward dependent on INSN.
8930 : Store in vector pointed to by ROOTS_PTR insns on which priority () should
8931 : be invoked to initialize all cleared priorities. */
8932 : static void
8933 0 : clear_priorities (rtx_insn *insn, rtx_vec_t *roots_ptr)
8934 : {
8935 0 : sd_iterator_def sd_it;
8936 0 : dep_t dep;
8937 0 : bool insn_is_root_p = true;
8938 :
8939 0 : gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
8940 :
8941 0 : FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
8942 : {
8943 0 : rtx_insn *pro = DEP_PRO (dep);
8944 :
8945 0 : if (INSN_PRIORITY_STATUS (pro) >= 0
8946 0 : && QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
8947 : {
8948 : /* If DEP doesn't contribute to priority then INSN itself should
8949 : be added to priority roots. */
8950 0 : if (contributes_to_priority_p (dep))
8951 0 : insn_is_root_p = false;
8952 :
8953 0 : INSN_PRIORITY_STATUS (pro) = -1;
8954 0 : clear_priorities (pro, roots_ptr);
8955 : }
8956 : }
8957 :
8958 0 : if (insn_is_root_p)
8959 0 : roots_ptr->safe_push (insn);
8960 0 : }
8961 :
8962 : /* Recompute priorities of instructions, whose priorities might have been
8963 : changed. ROOTS is a vector of instructions whose priority computation will
8964 : trigger initialization of all cleared priorities. */
8965 : static void
8966 0 : calc_priorities (const rtx_vec_t &roots)
8967 : {
8968 0 : int i;
8969 0 : rtx_insn *insn;
8970 :
8971 0 : FOR_EACH_VEC_ELT (roots, i, insn)
8972 0 : priority (insn);
8973 0 : }
8974 :
8975 :
8976 : /* Add dependences between JUMP and other instructions in the recovery
8977 : block. INSN is the first insn the recovery block. */
8978 : static void
8979 0 : add_jump_dependencies (rtx_insn *insn, rtx_insn *jump)
8980 : {
8981 0 : do
8982 : {
8983 0 : insn = NEXT_INSN (insn);
8984 0 : if (insn == jump)
8985 : break;
8986 :
8987 0 : if (dep_list_size (insn, SD_LIST_FORW) == 0)
8988 : {
8989 0 : dep_def _new_dep, *new_dep = &_new_dep;
8990 :
8991 0 : init_dep (new_dep, insn, jump, REG_DEP_ANTI);
8992 0 : sd_add_dep (new_dep, false);
8993 : }
8994 : }
8995 : while (1);
8996 :
8997 0 : gcc_assert (!sd_lists_empty_p (jump, SD_LIST_BACK));
8998 0 : }
8999 :
9000 : /* Extend data structures for logical insn UID. */
9001 : void
9002 967243 : sched_extend_luids (void)
9003 : {
9004 967243 : int new_luids_max_uid = get_max_uid () + 1;
9005 :
9006 967243 : sched_luids.safe_grow_cleared (new_luids_max_uid, true);
9007 967243 : }
9008 :
9009 : /* Initialize LUID for INSN. */
9010 : void
9011 132342689 : sched_init_insn_luid (rtx_insn *insn)
9012 : {
9013 132342689 : int i = INSN_P (insn) ? 1 : common_sched_info->luid_for_non_insn (insn);
9014 23703933 : int luid;
9015 :
9016 23703933 : if (i >= 0)
9017 : {
9018 132341128 : luid = sched_max_luid;
9019 132341128 : sched_max_luid += i;
9020 : }
9021 : else
9022 : luid = -1;
9023 :
9024 132342689 : SET_INSN_LUID (insn, luid);
9025 132342689 : }
9026 :
9027 : /* Initialize luids for BBS.
9028 : The hook common_sched_info->luid_for_non_insn () is used to determine
9029 : if notes, labels, etc. need luids. */
9030 : void
9031 965119 : sched_init_luids (const bb_vec_t &bbs)
9032 : {
9033 965119 : int i;
9034 965119 : basic_block bb;
9035 :
9036 965119 : sched_extend_luids ();
9037 11298690 : FOR_EACH_VEC_ELT (bbs, i, bb)
9038 : {
9039 10333571 : rtx_insn *insn;
9040 :
9041 142674929 : FOR_BB_INSNS (bb, insn)
9042 132341358 : sched_init_insn_luid (insn);
9043 : }
9044 965119 : }
9045 :
9046 : /* Free LUIDs. */
9047 : void
9048 965119 : sched_finish_luids (void)
9049 : {
9050 965119 : sched_luids.release ();
9051 965119 : sched_max_luid = 1;
9052 965119 : }
9053 :
9054 : /* Return logical uid of INSN. Helpful while debugging. */
9055 : int
9056 0 : insn_luid (rtx_insn *insn)
9057 : {
9058 0 : return INSN_LUID (insn);
9059 : }
9060 :
9061 : /* Extend per insn data in the target. */
9062 : void
9063 1932978 : sched_extend_target (void)
9064 : {
9065 1932978 : if (targetm.sched.h_i_d_extended)
9066 0 : targetm.sched.h_i_d_extended ();
9067 1932978 : }
9068 :
9069 : /* Extend global scheduler structures (those, that live across calls to
9070 : schedule_block) to include information about just emitted INSN. */
9071 : static void
9072 965119 : extend_h_i_d (void)
9073 : {
9074 965119 : int reserve = (get_max_uid () + 1 - h_i_d.length ());
9075 965119 : if (reserve > 0
9076 1929600 : && ! h_i_d.space (reserve))
9077 : {
9078 964481 : h_i_d.safe_grow_cleared (3U * get_max_uid () / 2, true);
9079 964481 : sched_extend_target ();
9080 : }
9081 965119 : }
9082 :
9083 : /* Initialize h_i_d entry of the INSN with default values.
9084 : Values, that are not explicitly initialized here, hold zero. */
9085 : static void
9086 132341358 : init_h_i_d (rtx_insn *insn)
9087 : {
9088 132341358 : if (INSN_LUID (insn) > 0)
9089 : {
9090 132339797 : INSN_COST (insn) = -1;
9091 132339797 : QUEUE_INDEX (insn) = QUEUE_NOWHERE;
9092 132339797 : INSN_TICK (insn) = INVALID_TICK;
9093 132339797 : INSN_EXACT_TICK (insn) = INVALID_TICK;
9094 132339797 : INTER_TICK (insn) = INVALID_TICK;
9095 132339797 : TODO_SPEC (insn) = HARD_DEP;
9096 132339797 : INSN_AUTOPREF_MULTIPASS_DATA (insn)[0].status
9097 132339797 : = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
9098 132339797 : INSN_AUTOPREF_MULTIPASS_DATA (insn)[1].status
9099 132339797 : = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
9100 : }
9101 132341358 : }
9102 :
9103 : /* Initialize haifa_insn_data for BBS. */
9104 : void
9105 965119 : haifa_init_h_i_d (const bb_vec_t &bbs)
9106 : {
9107 965119 : int i;
9108 965119 : basic_block bb;
9109 :
9110 965119 : extend_h_i_d ();
9111 11298690 : FOR_EACH_VEC_ELT (bbs, i, bb)
9112 : {
9113 10333571 : rtx_insn *insn;
9114 :
9115 142674929 : FOR_BB_INSNS (bb, insn)
9116 132341358 : init_h_i_d (insn);
9117 : }
9118 965119 : }
9119 :
9120 : /* Finalize haifa_insn_data. */
9121 : void
9122 964480 : haifa_finish_h_i_d (void)
9123 : {
9124 964480 : int i;
9125 964480 : haifa_insn_data_t data;
9126 964480 : reg_use_data *use, *next_use;
9127 964480 : reg_set_data *set, *next_set;
9128 :
9129 309052319 : FOR_EACH_VEC_ELT (h_i_d, i, data)
9130 : {
9131 308087839 : free (data->max_reg_pressure);
9132 308087839 : free (data->reg_pressure);
9133 308090201 : for (use = data->reg_use_list; use != NULL; use = next_use)
9134 : {
9135 2362 : next_use = use->next_insn_use;
9136 2362 : free (use);
9137 : }
9138 308090067 : for (set = data->reg_set_list; set != NULL; set = next_set)
9139 : {
9140 2228 : next_set = set->next_insn_set;
9141 2228 : free (set);
9142 : }
9143 :
9144 : }
9145 964480 : h_i_d.release ();
9146 964480 : }
9147 :
9148 : /* Init data for the new insn INSN. */
9149 : static void
9150 0 : haifa_init_insn (rtx_insn *insn)
9151 : {
9152 0 : gcc_assert (insn != NULL);
9153 :
9154 0 : sched_extend_luids ();
9155 0 : sched_init_insn_luid (insn);
9156 0 : sched_extend_target ();
9157 0 : sched_deps_init (false);
9158 0 : extend_h_i_d ();
9159 0 : init_h_i_d (insn);
9160 :
9161 0 : if (adding_bb_to_current_region_p)
9162 : {
9163 0 : sd_init_insn (insn);
9164 :
9165 : /* Extend dependency caches by one element. */
9166 0 : extend_dependency_caches (1, false);
9167 : }
9168 0 : if (sched_pressure != SCHED_PRESSURE_NONE)
9169 0 : init_insn_reg_pressure_info (insn);
9170 0 : }
9171 :
9172 : /* Init data for the new basic block BB which comes after AFTER. */
9173 : static void
9174 1 : haifa_init_only_bb (basic_block bb, basic_block after)
9175 : {
9176 1 : gcc_assert (bb != NULL);
9177 :
9178 1 : sched_init_bbs ();
9179 :
9180 1 : if (common_sched_info->add_block)
9181 : /* This changes only data structures of the front-end. */
9182 1 : common_sched_info->add_block (bb, after);
9183 1 : }
9184 :
9185 : /* A generic version of sched_split_block (). */
9186 : basic_block
9187 67 : sched_split_block_1 (basic_block first_bb, rtx after)
9188 : {
9189 67 : edge e;
9190 :
9191 67 : e = split_block (first_bb, after);
9192 67 : gcc_assert (e->src == first_bb);
9193 :
9194 : /* sched_split_block emits note if *check == BB_END. Probably it
9195 : is better to rip that note off. */
9196 :
9197 67 : return e->dest;
9198 : }
9199 :
9200 : /* A generic version of sched_create_empty_bb (). */
9201 : basic_block
9202 0 : sched_create_empty_bb_1 (basic_block after)
9203 : {
9204 0 : return create_empty_bb (after);
9205 : }
9206 :
9207 : /* Insert PAT as an INSN into the schedule and update the necessary data
9208 : structures to account for it. */
9209 : rtx_insn *
9210 0 : sched_emit_insn (rtx pat)
9211 : {
9212 0 : rtx_insn *insn = emit_insn_before (pat, first_nonscheduled_insn ());
9213 0 : haifa_init_insn (insn);
9214 :
9215 0 : if (current_sched_info->add_remove_insn)
9216 0 : current_sched_info->add_remove_insn (insn, 0);
9217 :
9218 0 : (*current_sched_info->begin_schedule_ready) (insn);
9219 0 : scheduled_insns.safe_push (insn);
9220 :
9221 0 : last_scheduled_insn = insn;
9222 0 : return insn;
9223 : }
9224 :
9225 : /* This function returns a candidate satisfying dispatch constraints from
9226 : the ready list. */
9227 :
9228 : static rtx_insn *
9229 16 : ready_remove_first_dispatch (struct ready_list *ready)
9230 : {
9231 16 : int i;
9232 16 : rtx_insn *insn = ready_element (ready, 0);
9233 :
9234 16 : if (ready->n_ready == 1
9235 0 : || !INSN_P (insn)
9236 0 : || INSN_CODE (insn) < 0
9237 0 : || !active_insn_p (insn)
9238 16 : || targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
9239 16 : return ready_remove_first (ready);
9240 :
9241 0 : for (i = 1; i < ready->n_ready; i++)
9242 : {
9243 0 : insn = ready_element (ready, i);
9244 :
9245 0 : if (!INSN_P (insn)
9246 0 : || INSN_CODE (insn) < 0
9247 0 : || !active_insn_p (insn))
9248 0 : continue;
9249 :
9250 0 : if (targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
9251 : {
9252 : /* Return ith element of ready. */
9253 0 : insn = ready_remove (ready, i);
9254 0 : return insn;
9255 : }
9256 : }
9257 :
9258 0 : if (targetm.sched.dispatch (NULL, DISPATCH_VIOLATION))
9259 0 : return ready_remove_first (ready);
9260 :
9261 0 : for (i = 1; i < ready->n_ready; i++)
9262 : {
9263 0 : insn = ready_element (ready, i);
9264 :
9265 0 : if (!INSN_P (insn)
9266 0 : || INSN_CODE (insn) < 0
9267 0 : || !active_insn_p (insn))
9268 0 : continue;
9269 :
9270 : /* Return i-th element of ready. */
9271 0 : if (targetm.sched.dispatch (insn, IS_CMP))
9272 0 : return ready_remove (ready, i);
9273 : }
9274 :
9275 0 : return ready_remove_first (ready);
9276 : }
9277 :
9278 : /* Get number of ready insn in the ready list. */
9279 :
9280 : int
9281 0 : number_in_ready (void)
9282 : {
9283 0 : return ready.n_ready;
9284 : }
9285 :
9286 : /* Get number of ready's in the ready list. */
9287 :
9288 : rtx_insn *
9289 267919350 : get_ready_element (int i)
9290 : {
9291 267919350 : return ready_element (&ready, i);
9292 : }
9293 :
9294 : #endif /* INSN_SCHEDULING */
|