]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/modulo-sched.c
LANGUAGES: Fix typos.
[thirdparty/gcc.git] / gcc / modulo-sched.c
1 /* Swing Modulo Scheduling implementation.
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.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
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "diagnostic-core.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "hard-reg-set.h"
31 #include "regs.h"
32 #include "function.h"
33 #include "flags.h"
34 #include "insn-config.h"
35 #include "insn-attr.h"
36 #include "except.h"
37 #include "recog.h"
38 #include "sched-int.h"
39 #include "target.h"
40 #include "cfglayout.h"
41 #include "cfgloop.h"
42 #include "cfghooks.h"
43 #include "expr.h"
44 #include "params.h"
45 #include "gcov-io.h"
46 #include "ddg.h"
47 #include "timevar.h"
48 #include "tree-pass.h"
49 #include "dbgcnt.h"
50 #include "df.h"
51
52 #ifdef INSN_SCHEDULING
53
54 /* This file contains the implementation of the Swing Modulo Scheduler,
55 described in the following references:
56 [1] J. Llosa, A. Gonzalez, E. Ayguade, M. Valero., and J. Eckhardt.
57 Lifetime--sensitive modulo scheduling in a production environment.
58 IEEE Trans. on Comps., 50(3), March 2001
59 [2] J. Llosa, A. Gonzalez, E. Ayguade, and M. Valero.
60 Swing Modulo Scheduling: A Lifetime Sensitive Approach.
61 PACT '96 , pages 80-87, October 1996 (Boston - Massachusetts - USA).
62
63 The basic structure is:
64 1. Build a data-dependence graph (DDG) for each loop.
65 2. Use the DDG to order the insns of a loop (not in topological order
66 necessarily, but rather) trying to place each insn after all its
67 predecessors _or_ after all its successors.
68 3. Compute MII: a lower bound on the number of cycles to schedule the loop.
69 4. Use the ordering to perform list-scheduling of the loop:
70 1. Set II = MII. We will try to schedule the loop within II cycles.
71 2. Try to schedule the insns one by one according to the ordering.
72 For each insn compute an interval of cycles by considering already-
73 scheduled preds and succs (and associated latencies); try to place
74 the insn in the cycles of this window checking for potential
75 resource conflicts (using the DFA interface).
76 Note: this is different from the cycle-scheduling of schedule_insns;
77 here the insns are not scheduled monotonically top-down (nor bottom-
78 up).
79 3. If failed in scheduling all insns - bump II++ and try again, unless
80 II reaches an upper bound MaxII, in which case report failure.
81 5. If we succeeded in scheduling the loop within II cycles, we now
82 generate prolog and epilog, decrease the counter of the loop, and
83 perform modulo variable expansion for live ranges that span more than
84 II cycles (i.e. use register copies to prevent a def from overwriting
85 itself before reaching the use).
86
87 SMS works with countable loops (1) whose control part can be easily
88 decoupled from the rest of the loop and (2) whose loop count can
89 be easily adjusted. This is because we peel a constant number of
90 iterations into a prologue and epilogue for which we want to avoid
91 emitting the control part, and a kernel which is to iterate that
92 constant number of iterations less than the original loop. So the
93 control part should be a set of insns clearly identified and having
94 its own iv, not otherwise used in the loop (at-least for now), which
95 initializes a register before the loop to the number of iterations.
96 Currently SMS relies on the do-loop pattern to recognize such loops,
97 where (1) the control part comprises of all insns defining and/or
98 using a certain 'count' register and (2) the loop count can be
99 adjusted by modifying this register prior to the loop.
100 TODO: Rely on cfgloop analysis instead. */
101 \f
102 /* This page defines partial-schedule structures and functions for
103 modulo scheduling. */
104
105 typedef struct partial_schedule *partial_schedule_ptr;
106 typedef struct ps_insn *ps_insn_ptr;
107
108 /* The minimum (absolute) cycle that a node of ps was scheduled in. */
109 #define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle)
110
111 /* The maximum (absolute) cycle that a node of ps was scheduled in. */
112 #define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle)
113
114 /* Perform signed modulo, always returning a non-negative value. */
115 #define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y))
116
117 /* The number of different iterations the nodes in ps span, assuming
118 the stage boundaries are placed efficiently. */
119 #define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \
120 + 1 + ii - 1) / ii)
121 /* The stage count of ps. */
122 #define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count)
123
124 /* A single instruction in the partial schedule. */
125 struct ps_insn
126 {
127 /* Identifies the instruction to be scheduled. Values smaller than
128 the ddg's num_nodes refer directly to ddg nodes. A value of
129 X - num_nodes refers to register move X. */
130 int id;
131
132 /* The (absolute) cycle in which the PS instruction is scheduled.
133 Same as SCHED_TIME (node). */
134 int cycle;
135
136 /* The next/prev PS_INSN in the same row. */
137 ps_insn_ptr next_in_row,
138 prev_in_row;
139
140 };
141
142 /* Information about a register move that has been added to a partial
143 schedule. */
144 struct ps_reg_move_info
145 {
146 /* The source of the move is defined by the ps_insn with id DEF.
147 The destination is used by the ps_insns with the ids in USES. */
148 int def;
149 sbitmap uses;
150
151 /* The original form of USES' instructions used OLD_REG, but they
152 should now use NEW_REG. */
153 rtx old_reg;
154 rtx new_reg;
155
156 /* The number of consecutive stages that the move occupies. */
157 int num_consecutive_stages;
158
159 /* An instruction that sets NEW_REG to the correct value. The first
160 move associated with DEF will have an rhs of OLD_REG; later moves
161 use the result of the previous move. */
162 rtx insn;
163 };
164
165 typedef struct ps_reg_move_info ps_reg_move_info;
166 DEF_VEC_O (ps_reg_move_info);
167 DEF_VEC_ALLOC_O (ps_reg_move_info, heap);
168
169 /* Holds the partial schedule as an array of II rows. Each entry of the
170 array points to a linked list of PS_INSNs, which represents the
171 instructions that are scheduled for that row. */
172 struct partial_schedule
173 {
174 int ii; /* Number of rows in the partial schedule. */
175 int history; /* Threshold for conflict checking using DFA. */
176
177 /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). */
178 ps_insn_ptr *rows;
179
180 /* All the moves added for this partial schedule. Index X has
181 a ps_insn id of X + g->num_nodes. */
182 VEC (ps_reg_move_info, heap) *reg_moves;
183
184 /* rows_length[i] holds the number of instructions in the row.
185 It is used only (as an optimization) to back off quickly from
186 trying to schedule a node in a full row; that is, to avoid running
187 through futile DFA state transitions. */
188 int *rows_length;
189
190 /* The earliest absolute cycle of an insn in the partial schedule. */
191 int min_cycle;
192
193 /* The latest absolute cycle of an insn in the partial schedule. */
194 int max_cycle;
195
196 ddg_ptr g; /* The DDG of the insns in the partial schedule. */
197
198 int stage_count; /* The stage count of the partial schedule. */
199 };
200
201
202 static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
203 static void free_partial_schedule (partial_schedule_ptr);
204 static void reset_partial_schedule (partial_schedule_ptr, int new_ii);
205 void print_partial_schedule (partial_schedule_ptr, FILE *);
206 static void verify_partial_schedule (partial_schedule_ptr, sbitmap);
207 static ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
208 int, int, sbitmap, sbitmap);
209 static void rotate_partial_schedule (partial_schedule_ptr, int);
210 void set_row_column_for_ps (partial_schedule_ptr);
211 static void ps_insert_empty_row (partial_schedule_ptr, int, sbitmap);
212 static int compute_split_row (sbitmap, int, int, int, ddg_node_ptr);
213
214 \f
215 /* This page defines constants and structures for the modulo scheduling
216 driver. */
217
218 static int sms_order_nodes (ddg_ptr, int, int *, int *);
219 static void set_node_sched_params (ddg_ptr);
220 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *);
221 static void permute_partial_schedule (partial_schedule_ptr, rtx);
222 static void generate_prolog_epilog (partial_schedule_ptr, struct loop *,
223 rtx, rtx);
224 static int calculate_stage_count (partial_schedule_ptr, int);
225 static void calculate_must_precede_follow (ddg_node_ptr, int, int,
226 int, int, sbitmap, sbitmap, sbitmap);
227 static int get_sched_window (partial_schedule_ptr, ddg_node_ptr,
228 sbitmap, int, int *, int *, int *);
229 static bool try_scheduling_node_in_cycle (partial_schedule_ptr, int, int,
230 sbitmap, int *, sbitmap, sbitmap);
231 static void remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr);
232
233 #define NODE_ASAP(node) ((node)->aux.count)
234
235 #define SCHED_PARAMS(x) VEC_index (node_sched_params, node_sched_param_vec, x)
236 #define SCHED_TIME(x) (SCHED_PARAMS (x)->time)
237 #define SCHED_ROW(x) (SCHED_PARAMS (x)->row)
238 #define SCHED_STAGE(x) (SCHED_PARAMS (x)->stage)
239 #define SCHED_COLUMN(x) (SCHED_PARAMS (x)->column)
240
241 /* The scheduling parameters held for each node. */
242 typedef struct node_sched_params
243 {
244 int time; /* The absolute scheduling cycle. */
245
246 int row; /* Holds time % ii. */
247 int stage; /* Holds time / ii. */
248
249 /* The column of a node inside the ps. If nodes u, v are on the same row,
250 u will precede v if column (u) < column (v). */
251 int column;
252 } *node_sched_params_ptr;
253
254 typedef struct node_sched_params node_sched_params;
255 DEF_VEC_O (node_sched_params);
256 DEF_VEC_ALLOC_O (node_sched_params, heap);
257 \f
258 /* The following three functions are copied from the current scheduler
259 code in order to use sched_analyze() for computing the dependencies.
260 They are used when initializing the sched_info structure. */
261 static const char *
262 sms_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED)
263 {
264 static char tmp[80];
265
266 sprintf (tmp, "i%4d", INSN_UID (insn));
267 return tmp;
268 }
269
270 static void
271 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
272 regset used ATTRIBUTE_UNUSED)
273 {
274 }
275
276 static struct common_sched_info_def sms_common_sched_info;
277
278 static struct sched_deps_info_def sms_sched_deps_info =
279 {
280 compute_jump_reg_dependencies,
281 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
282 NULL,
283 0, 0, 0
284 };
285
286 static struct haifa_sched_info sms_sched_info =
287 {
288 NULL,
289 NULL,
290 NULL,
291 NULL,
292 NULL,
293 sms_print_insn,
294 NULL,
295 NULL, /* insn_finishes_block_p */
296 NULL, NULL,
297 NULL, NULL,
298 0, 0,
299
300 NULL, NULL, NULL, NULL,
301 NULL, NULL,
302 0
303 };
304
305 /* Partial schedule instruction ID in PS is a register move. Return
306 information about it. */
307 static struct ps_reg_move_info *
308 ps_reg_move (partial_schedule_ptr ps, int id)
309 {
310 gcc_checking_assert (id >= ps->g->num_nodes);
311 return VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes);
312 }
313
314 /* Return the rtl instruction that is being scheduled by partial schedule
315 instruction ID, which belongs to schedule PS. */
316 static rtx
317 ps_rtl_insn (partial_schedule_ptr ps, int id)
318 {
319 if (id < ps->g->num_nodes)
320 return ps->g->nodes[id].insn;
321 else
322 return ps_reg_move (ps, id)->insn;
323 }
324
325 /* Partial schedule instruction ID, which belongs to PS, occurred in
326 the original (unscheduled) loop. Return the first instruction
327 in the loop that was associated with ps_rtl_insn (PS, ID).
328 If the instruction had some notes before it, this is the first
329 of those notes. */
330 static rtx
331 ps_first_note (partial_schedule_ptr ps, int id)
332 {
333 gcc_assert (id < ps->g->num_nodes);
334 return ps->g->nodes[id].first_note;
335 }
336
337 /* Return the number of consecutive stages that are occupied by
338 partial schedule instruction ID in PS. */
339 static int
340 ps_num_consecutive_stages (partial_schedule_ptr ps, int id)
341 {
342 if (id < ps->g->num_nodes)
343 return 1;
344 else
345 return ps_reg_move (ps, id)->num_consecutive_stages;
346 }
347
348 /* Given HEAD and TAIL which are the first and last insns in a loop;
349 return the register which controls the loop. Return zero if it has
350 more than one occurrence in the loop besides the control part or the
351 do-loop pattern is not of the form we expect. */
352 static rtx
353 doloop_register_get (rtx head ATTRIBUTE_UNUSED, rtx tail ATTRIBUTE_UNUSED)
354 {
355 #ifdef HAVE_doloop_end
356 rtx reg, condition, insn, first_insn_not_to_check;
357
358 if (!JUMP_P (tail))
359 return NULL_RTX;
360
361 /* TODO: Free SMS's dependence on doloop_condition_get. */
362 condition = doloop_condition_get (tail);
363 if (! condition)
364 return NULL_RTX;
365
366 if (REG_P (XEXP (condition, 0)))
367 reg = XEXP (condition, 0);
368 else if (GET_CODE (XEXP (condition, 0)) == PLUS
369 && REG_P (XEXP (XEXP (condition, 0), 0)))
370 reg = XEXP (XEXP (condition, 0), 0);
371 else
372 gcc_unreachable ();
373
374 /* Check that the COUNT_REG has no other occurrences in the loop
375 until the decrement. We assume the control part consists of
376 either a single (parallel) branch-on-count or a (non-parallel)
377 branch immediately preceded by a single (decrement) insn. */
378 first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail
379 : prev_nondebug_insn (tail));
380
381 for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
382 if (!DEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn))
383 {
384 if (dump_file)
385 {
386 fprintf (dump_file, "SMS count_reg found ");
387 print_rtl_single (dump_file, reg);
388 fprintf (dump_file, " outside control in insn:\n");
389 print_rtl_single (dump_file, insn);
390 }
391
392 return NULL_RTX;
393 }
394
395 return reg;
396 #else
397 return NULL_RTX;
398 #endif
399 }
400
401 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
402 that the number of iterations is a compile-time constant. If so,
403 return the rtx that sets COUNT_REG to a constant, and set COUNT to
404 this constant. Otherwise return 0. */
405 static rtx
406 const_iteration_count (rtx count_reg, basic_block pre_header,
407 HOST_WIDEST_INT * count)
408 {
409 rtx insn;
410 rtx head, tail;
411
412 if (! pre_header)
413 return NULL_RTX;
414
415 get_ebb_head_tail (pre_header, pre_header, &head, &tail);
416
417 for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
418 if (NONDEBUG_INSN_P (insn) && single_set (insn) &&
419 rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
420 {
421 rtx pat = single_set (insn);
422
423 if (CONST_INT_P (SET_SRC (pat)))
424 {
425 *count = INTVAL (SET_SRC (pat));
426 return insn;
427 }
428
429 return NULL_RTX;
430 }
431
432 return NULL_RTX;
433 }
434
435 /* A very simple resource-based lower bound on the initiation interval.
436 ??? Improve the accuracy of this bound by considering the
437 utilization of various units. */
438 static int
439 res_MII (ddg_ptr g)
440 {
441 if (targetm.sched.sms_res_mii)
442 return targetm.sched.sms_res_mii (g);
443
444 return ((g->num_nodes - g->num_debug) / issue_rate);
445 }
446
447
448 /* A vector that contains the sched data for each ps_insn. */
449 static VEC (node_sched_params, heap) *node_sched_param_vec;
450
451 /* Allocate sched_params for each node and initialize it. */
452 static void
453 set_node_sched_params (ddg_ptr g)
454 {
455 VEC_truncate (node_sched_params, node_sched_param_vec, 0);
456 VEC_safe_grow_cleared (node_sched_params, heap,
457 node_sched_param_vec, g->num_nodes);
458 }
459
460 /* Make sure that node_sched_param_vec has an entry for every move in PS. */
461 static void
462 extend_node_sched_params (partial_schedule_ptr ps)
463 {
464 VEC_safe_grow_cleared (node_sched_params, heap, node_sched_param_vec,
465 ps->g->num_nodes + VEC_length (ps_reg_move_info,
466 ps->reg_moves));
467 }
468
469 /* Update the sched_params (time, row and stage) for node U using the II,
470 the CYCLE of U and MIN_CYCLE.
471 We're not simply taking the following
472 SCHED_STAGE (u) = CALC_STAGE_COUNT (SCHED_TIME (u), min_cycle, ii);
473 because the stages may not be aligned on cycle 0. */
474 static void
475 update_node_sched_params (int u, int ii, int cycle, int min_cycle)
476 {
477 int sc_until_cycle_zero;
478 int stage;
479
480 SCHED_TIME (u) = cycle;
481 SCHED_ROW (u) = SMODULO (cycle, ii);
482
483 /* The calculation of stage count is done adding the number
484 of stages before cycle zero and after cycle zero. */
485 sc_until_cycle_zero = CALC_STAGE_COUNT (-1, min_cycle, ii);
486
487 if (SCHED_TIME (u) < 0)
488 {
489 stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii);
490 SCHED_STAGE (u) = sc_until_cycle_zero - stage;
491 }
492 else
493 {
494 stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii);
495 SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1;
496 }
497 }
498
499 static void
500 print_node_sched_params (FILE *file, int num_nodes, partial_schedule_ptr ps)
501 {
502 int i;
503
504 if (! file)
505 return;
506 for (i = 0; i < num_nodes; i++)
507 {
508 node_sched_params_ptr nsp = SCHED_PARAMS (i);
509
510 fprintf (file, "Node = %d; INSN = %d\n", i,
511 INSN_UID (ps_rtl_insn (ps, i)));
512 fprintf (file, " asap = %d:\n", NODE_ASAP (&ps->g->nodes[i]));
513 fprintf (file, " time = %d:\n", nsp->time);
514 fprintf (file, " stage = %d:\n", nsp->stage);
515 }
516 }
517
518 /* Set SCHED_COLUMN for each instruction in row ROW of PS. */
519 static void
520 set_columns_for_row (partial_schedule_ptr ps, int row)
521 {
522 ps_insn_ptr cur_insn;
523 int column;
524
525 column = 0;
526 for (cur_insn = ps->rows[row]; cur_insn; cur_insn = cur_insn->next_in_row)
527 SCHED_COLUMN (cur_insn->id) = column++;
528 }
529
530 /* Set SCHED_COLUMN for each instruction in PS. */
531 static void
532 set_columns_for_ps (partial_schedule_ptr ps)
533 {
534 int row;
535
536 for (row = 0; row < ps->ii; row++)
537 set_columns_for_row (ps, row);
538 }
539
540 /* Try to schedule the move with ps_insn identifier I_REG_MOVE in PS.
541 Its single predecessor has already been scheduled, as has its
542 ddg node successors. (The move may have also another move as its
543 successor, in which case that successor will be scheduled later.)
544
545 The move is part of a chain that satisfies register dependencies
546 between a producing ddg node and various consuming ddg nodes.
547 If some of these dependencies have a distance of 1 (meaning that
548 the use is upward-exposed) then DISTANCE1_USES is nonnull and
549 contains the set of uses with distance-1 dependencies.
550 DISTANCE1_USES is null otherwise.
551
552 MUST_FOLLOW is a scratch bitmap that is big enough to hold
553 all current ps_insn ids.
554
555 Return true on success. */
556 static bool
557 schedule_reg_move (partial_schedule_ptr ps, int i_reg_move,
558 sbitmap distance1_uses, sbitmap must_follow)
559 {
560 unsigned int u;
561 int this_time, this_distance, this_start, this_end, this_latency;
562 int start, end, c, ii;
563 sbitmap_iterator sbi;
564 ps_reg_move_info *move;
565 rtx this_insn;
566 ps_insn_ptr psi;
567
568 move = ps_reg_move (ps, i_reg_move);
569 ii = ps->ii;
570 if (dump_file)
571 {
572 fprintf (dump_file, "Scheduling register move INSN %d; ii = %d"
573 ", min cycle = %d\n\n", INSN_UID (move->insn), ii,
574 PS_MIN_CYCLE (ps));
575 print_rtl_single (dump_file, move->insn);
576 fprintf (dump_file, "\n%11s %11s %5s\n", "start", "end", "time");
577 fprintf (dump_file, "=========== =========== =====\n");
578 }
579
580 start = INT_MIN;
581 end = INT_MAX;
582
583 /* For dependencies of distance 1 between a producer ddg node A
584 and consumer ddg node B, we have a chain of dependencies:
585
586 A --(T,L1,1)--> M1 --(T,L2,0)--> M2 ... --(T,Ln,0)--> B
587
588 where Mi is the ith move. For dependencies of distance 0 between
589 a producer ddg node A and consumer ddg node C, we have a chain of
590 dependencies:
591
592 A --(T,L1',0)--> M1' --(T,L2',0)--> M2' ... --(T,Ln',0)--> C
593
594 where Mi' occupies the same position as Mi but occurs a stage later.
595 We can only schedule each move once, so if we have both types of
596 chain, we model the second as:
597
598 A --(T,L1',1)--> M1 --(T,L2',0)--> M2 ... --(T,Ln',-1)--> C
599
600 First handle the dependencies between the previously-scheduled
601 predecessor and the move. */
602 this_insn = ps_rtl_insn (ps, move->def);
603 this_latency = insn_latency (this_insn, move->insn);
604 this_distance = distance1_uses && move->def < ps->g->num_nodes ? 1 : 0;
605 this_time = SCHED_TIME (move->def) - this_distance * ii;
606 this_start = this_time + this_latency;
607 this_end = this_time + ii;
608 if (dump_file)
609 fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n",
610 this_start, this_end, SCHED_TIME (move->def),
611 INSN_UID (this_insn), this_latency, this_distance,
612 INSN_UID (move->insn));
613
614 if (start < this_start)
615 start = this_start;
616 if (end > this_end)
617 end = this_end;
618
619 /* Handle the dependencies between the move and previously-scheduled
620 successors. */
621 EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, u, sbi)
622 {
623 this_insn = ps_rtl_insn (ps, u);
624 this_latency = insn_latency (move->insn, this_insn);
625 if (distance1_uses && !TEST_BIT (distance1_uses, u))
626 this_distance = -1;
627 else
628 this_distance = 0;
629 this_time = SCHED_TIME (u) + this_distance * ii;
630 this_start = this_time - ii;
631 this_end = this_time - this_latency;
632 if (dump_file)
633 fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n",
634 this_start, this_end, SCHED_TIME (u), INSN_UID (move->insn),
635 this_latency, this_distance, INSN_UID (this_insn));
636
637 if (start < this_start)
638 start = this_start;
639 if (end > this_end)
640 end = this_end;
641 }
642
643 if (dump_file)
644 {
645 fprintf (dump_file, "----------- ----------- -----\n");
646 fprintf (dump_file, "%11d %11d %5s %s\n", start, end, "", "(max, min)");
647 }
648
649 sbitmap_zero (must_follow);
650 SET_BIT (must_follow, move->def);
651
652 start = MAX (start, end - (ii - 1));
653 for (c = end; c >= start; c--)
654 {
655 psi = ps_add_node_check_conflicts (ps, i_reg_move, c,
656 move->uses, must_follow);
657 if (psi)
658 {
659 update_node_sched_params (i_reg_move, ii, c, PS_MIN_CYCLE (ps));
660 if (dump_file)
661 fprintf (dump_file, "\nScheduled register move INSN %d at"
662 " time %d, row %d\n\n", INSN_UID (move->insn), c,
663 SCHED_ROW (i_reg_move));
664 return true;
665 }
666 }
667
668 if (dump_file)
669 fprintf (dump_file, "\nNo available slot\n\n");
670
671 return false;
672 }
673
674 /*
675 Breaking intra-loop register anti-dependences:
676 Each intra-loop register anti-dependence implies a cross-iteration true
677 dependence of distance 1. Therefore, we can remove such false dependencies
678 and figure out if the partial schedule broke them by checking if (for a
679 true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
680 if so generate a register move. The number of such moves is equal to:
681 SCHED_TIME (use) - SCHED_TIME (def) { 0 broken
682 nreg_moves = ----------------------------------- + 1 - { dependence.
683 ii { 1 if not.
684 */
685 static bool
686 schedule_reg_moves (partial_schedule_ptr ps)
687 {
688 ddg_ptr g = ps->g;
689 int ii = ps->ii;
690 int i;
691
692 for (i = 0; i < g->num_nodes; i++)
693 {
694 ddg_node_ptr u = &g->nodes[i];
695 ddg_edge_ptr e;
696 int nreg_moves = 0, i_reg_move;
697 rtx prev_reg, old_reg;
698 int first_move;
699 int distances[2];
700 sbitmap must_follow;
701 sbitmap distance1_uses;
702 rtx set = single_set (u->insn);
703
704 /* Skip instructions that do not set a register. */
705 if ((set && !REG_P (SET_DEST (set))))
706 continue;
707
708 /* Compute the number of reg_moves needed for u, by looking at life
709 ranges started at u (excluding self-loops). */
710 distances[0] = distances[1] = false;
711 for (e = u->out; e; e = e->next_out)
712 if (e->type == TRUE_DEP && e->dest != e->src)
713 {
714 int nreg_moves4e = (SCHED_TIME (e->dest->cuid)
715 - SCHED_TIME (e->src->cuid)) / ii;
716
717 if (e->distance == 1)
718 nreg_moves4e = (SCHED_TIME (e->dest->cuid)
719 - SCHED_TIME (e->src->cuid) + ii) / ii;
720
721 /* If dest precedes src in the schedule of the kernel, then dest
722 will read before src writes and we can save one reg_copy. */
723 if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid)
724 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid))
725 nreg_moves4e--;
726
727 if (nreg_moves4e >= 1)
728 {
729 /* !single_set instructions are not supported yet and
730 thus we do not except to encounter them in the loop
731 except from the doloop part. For the latter case
732 we assume no regmoves are generated as the doloop
733 instructions are tied to the branch with an edge. */
734 gcc_assert (set);
735 /* If the instruction contains auto-inc register then
736 validate that the regmov is being generated for the
737 target regsiter rather then the inc'ed register. */
738 gcc_assert (!autoinc_var_is_used_p (u->insn, e->dest->insn));
739 }
740
741 if (nreg_moves4e)
742 {
743 gcc_assert (e->distance < 2);
744 distances[e->distance] = true;
745 }
746 nreg_moves = MAX (nreg_moves, nreg_moves4e);
747 }
748
749 if (nreg_moves == 0)
750 continue;
751
752 /* Create NREG_MOVES register moves. */
753 first_move = VEC_length (ps_reg_move_info, ps->reg_moves);
754 VEC_safe_grow_cleared (ps_reg_move_info, heap, ps->reg_moves,
755 first_move + nreg_moves);
756 extend_node_sched_params (ps);
757
758 /* Record the moves associated with this node. */
759 first_move += ps->g->num_nodes;
760
761 /* Generate each move. */
762 old_reg = prev_reg = SET_DEST (single_set (u->insn));
763 for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
764 {
765 ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move);
766
767 move->def = i_reg_move > 0 ? first_move + i_reg_move - 1 : i;
768 move->uses = sbitmap_alloc (first_move + nreg_moves);
769 move->old_reg = old_reg;
770 move->new_reg = gen_reg_rtx (GET_MODE (prev_reg));
771 move->num_consecutive_stages = distances[0] && distances[1] ? 2 : 1;
772 move->insn = gen_move_insn (move->new_reg, copy_rtx (prev_reg));
773 sbitmap_zero (move->uses);
774
775 prev_reg = move->new_reg;
776 }
777
778 distance1_uses = distances[1] ? sbitmap_alloc (g->num_nodes) : NULL;
779
780 /* Every use of the register defined by node may require a different
781 copy of this register, depending on the time the use is scheduled.
782 Record which uses require which move results. */
783 for (e = u->out; e; e = e->next_out)
784 if (e->type == TRUE_DEP && e->dest != e->src)
785 {
786 int dest_copy = (SCHED_TIME (e->dest->cuid)
787 - SCHED_TIME (e->src->cuid)) / ii;
788
789 if (e->distance == 1)
790 dest_copy = (SCHED_TIME (e->dest->cuid)
791 - SCHED_TIME (e->src->cuid) + ii) / ii;
792
793 if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid)
794 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid))
795 dest_copy--;
796
797 if (dest_copy)
798 {
799 ps_reg_move_info *move;
800
801 move = ps_reg_move (ps, first_move + dest_copy - 1);
802 SET_BIT (move->uses, e->dest->cuid);
803 if (e->distance == 1)
804 SET_BIT (distance1_uses, e->dest->cuid);
805 }
806 }
807
808 must_follow = sbitmap_alloc (first_move + nreg_moves);
809 for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
810 if (!schedule_reg_move (ps, first_move + i_reg_move,
811 distance1_uses, must_follow))
812 break;
813 sbitmap_free (must_follow);
814 if (distance1_uses)
815 sbitmap_free (distance1_uses);
816 if (i_reg_move < nreg_moves)
817 return false;
818 }
819 return true;
820 }
821
822 /* Emit the moves associatied with PS. Apply the substitutions
823 associated with them. */
824 static void
825 apply_reg_moves (partial_schedule_ptr ps)
826 {
827 ps_reg_move_info *move;
828 int i;
829
830 FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
831 {
832 unsigned int i_use;
833 sbitmap_iterator sbi;
834
835 EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, i_use, sbi)
836 {
837 replace_rtx (ps->g->nodes[i_use].insn, move->old_reg, move->new_reg);
838 df_insn_rescan (ps->g->nodes[i_use].insn);
839 }
840 }
841 }
842
843 /* Bump the SCHED_TIMEs of all nodes by AMOUNT. Set the values of
844 SCHED_ROW and SCHED_STAGE. Instruction scheduled on cycle AMOUNT
845 will move to cycle zero. */
846 static void
847 reset_sched_times (partial_schedule_ptr ps, int amount)
848 {
849 int row;
850 int ii = ps->ii;
851 ps_insn_ptr crr_insn;
852
853 for (row = 0; row < ii; row++)
854 for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
855 {
856 int u = crr_insn->id;
857 int normalized_time = SCHED_TIME (u) - amount;
858 int new_min_cycle = PS_MIN_CYCLE (ps) - amount;
859
860 if (dump_file)
861 {
862 /* Print the scheduling times after the rotation. */
863 rtx insn = ps_rtl_insn (ps, u);
864
865 fprintf (dump_file, "crr_insn->node=%d (insn id %d), "
866 "crr_insn->cycle=%d, min_cycle=%d", u,
867 INSN_UID (insn), normalized_time, new_min_cycle);
868 if (JUMP_P (insn))
869 fprintf (dump_file, " (branch)");
870 fprintf (dump_file, "\n");
871 }
872
873 gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
874 gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
875
876 crr_insn->cycle = normalized_time;
877 update_node_sched_params (u, ii, normalized_time, new_min_cycle);
878 }
879 }
880
881 /* Permute the insns according to their order in PS, from row 0 to
882 row ii-1, and position them right before LAST. This schedules
883 the insns of the loop kernel. */
884 static void
885 permute_partial_schedule (partial_schedule_ptr ps, rtx last)
886 {
887 int ii = ps->ii;
888 int row;
889 ps_insn_ptr ps_ij;
890
891 for (row = 0; row < ii ; row++)
892 for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
893 {
894 rtx insn = ps_rtl_insn (ps, ps_ij->id);
895
896 if (PREV_INSN (last) != insn)
897 {
898 if (ps_ij->id < ps->g->num_nodes)
899 reorder_insns_nobb (ps_first_note (ps, ps_ij->id), insn,
900 PREV_INSN (last));
901 else
902 add_insn_before (insn, last, NULL);
903 }
904 }
905 }
906
907 /* Set bitmaps TMP_FOLLOW and TMP_PRECEDE to MUST_FOLLOW and MUST_PRECEDE
908 respectively only if cycle C falls on the border of the scheduling
909 window boundaries marked by START and END cycles. STEP is the
910 direction of the window. */
911 static inline void
912 set_must_precede_follow (sbitmap *tmp_follow, sbitmap must_follow,
913 sbitmap *tmp_precede, sbitmap must_precede, int c,
914 int start, int end, int step)
915 {
916 *tmp_precede = NULL;
917 *tmp_follow = NULL;
918
919 if (c == start)
920 {
921 if (step == 1)
922 *tmp_precede = must_precede;
923 else /* step == -1. */
924 *tmp_follow = must_follow;
925 }
926 if (c == end - step)
927 {
928 if (step == 1)
929 *tmp_follow = must_follow;
930 else /* step == -1. */
931 *tmp_precede = must_precede;
932 }
933
934 }
935
936 /* Return True if the branch can be moved to row ii-1 while
937 normalizing the partial schedule PS to start from cycle zero and thus
938 optimize the SC. Otherwise return False. */
939 static bool
940 optimize_sc (partial_schedule_ptr ps, ddg_ptr g)
941 {
942 int amount = PS_MIN_CYCLE (ps);
943 sbitmap sched_nodes = sbitmap_alloc (g->num_nodes);
944 int start, end, step;
945 int ii = ps->ii;
946 bool ok = false;
947 int stage_count, stage_count_curr;
948
949 /* Compare the SC after normalization and SC after bringing the branch
950 to row ii-1. If they are equal just bail out. */
951 stage_count = calculate_stage_count (ps, amount);
952 stage_count_curr =
953 calculate_stage_count (ps, SCHED_TIME (g->closing_branch->cuid) - (ii - 1));
954
955 if (stage_count == stage_count_curr)
956 {
957 if (dump_file)
958 fprintf (dump_file, "SMS SC already optimized.\n");
959
960 ok = false;
961 goto clear;
962 }
963
964 if (dump_file)
965 {
966 fprintf (dump_file, "SMS Trying to optimize branch location\n");
967 fprintf (dump_file, "SMS partial schedule before trial:\n");
968 print_partial_schedule (ps, dump_file);
969 }
970
971 /* First, normalize the partial scheduling. */
972 reset_sched_times (ps, amount);
973 rotate_partial_schedule (ps, amount);
974 if (dump_file)
975 {
976 fprintf (dump_file,
977 "SMS partial schedule after normalization (ii, %d, SC %d):\n",
978 ii, stage_count);
979 print_partial_schedule (ps, dump_file);
980 }
981
982 if (SMODULO (SCHED_TIME (g->closing_branch->cuid), ii) == ii - 1)
983 {
984 ok = true;
985 goto clear;
986 }
987
988 sbitmap_ones (sched_nodes);
989
990 /* Calculate the new placement of the branch. It should be in row
991 ii-1 and fall into it's scheduling window. */
992 if (get_sched_window (ps, g->closing_branch, sched_nodes, ii, &start,
993 &step, &end) == 0)
994 {
995 bool success;
996 ps_insn_ptr next_ps_i;
997 int branch_cycle = SCHED_TIME (g->closing_branch->cuid);
998 int row = SMODULO (branch_cycle, ps->ii);
999 int num_splits = 0;
1000 sbitmap must_precede, must_follow, tmp_precede, tmp_follow;
1001 int c;
1002
1003 if (dump_file)
1004 fprintf (dump_file, "\nTrying to schedule node %d "
1005 "INSN = %d in (%d .. %d) step %d\n",
1006 g->closing_branch->cuid,
1007 (INSN_UID (g->closing_branch->insn)), start, end, step);
1008
1009 gcc_assert ((step > 0 && start < end) || (step < 0 && start > end));
1010 if (step == 1)
1011 {
1012 c = start + ii - SMODULO (start, ii) - 1;
1013 gcc_assert (c >= start);
1014 if (c >= end)
1015 {
1016 ok = false;
1017 if (dump_file)
1018 fprintf (dump_file,
1019 "SMS failed to schedule branch at cycle: %d\n", c);
1020 goto clear;
1021 }
1022 }
1023 else
1024 {
1025 c = start - SMODULO (start, ii) - 1;
1026 gcc_assert (c <= start);
1027
1028 if (c <= end)
1029 {
1030 if (dump_file)
1031 fprintf (dump_file,
1032 "SMS failed to schedule branch at cycle: %d\n", c);
1033 ok = false;
1034 goto clear;
1035 }
1036 }
1037
1038 must_precede = sbitmap_alloc (g->num_nodes);
1039 must_follow = sbitmap_alloc (g->num_nodes);
1040
1041 /* Try to schedule the branch is it's new cycle. */
1042 calculate_must_precede_follow (g->closing_branch, start, end,
1043 step, ii, sched_nodes,
1044 must_precede, must_follow);
1045
1046 set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede,
1047 must_precede, c, start, end, step);
1048
1049 /* Find the element in the partial schedule related to the closing
1050 branch so we can remove it from it's current cycle. */
1051 for (next_ps_i = ps->rows[row];
1052 next_ps_i; next_ps_i = next_ps_i->next_in_row)
1053 if (next_ps_i->id == g->closing_branch->cuid)
1054 break;
1055
1056 remove_node_from_ps (ps, next_ps_i);
1057 success =
1058 try_scheduling_node_in_cycle (ps, g->closing_branch->cuid, c,
1059 sched_nodes, &num_splits,
1060 tmp_precede, tmp_follow);
1061 gcc_assert (num_splits == 0);
1062 if (!success)
1063 {
1064 if (dump_file)
1065 fprintf (dump_file,
1066 "SMS failed to schedule branch at cycle: %d, "
1067 "bringing it back to cycle %d\n", c, branch_cycle);
1068
1069 /* The branch was failed to be placed in row ii - 1.
1070 Put it back in it's original place in the partial
1071 schedualing. */
1072 set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede,
1073 must_precede, branch_cycle, start, end,
1074 step);
1075 success =
1076 try_scheduling_node_in_cycle (ps, g->closing_branch->cuid,
1077 branch_cycle, sched_nodes,
1078 &num_splits, tmp_precede,
1079 tmp_follow);
1080 gcc_assert (success && (num_splits == 0));
1081 ok = false;
1082 }
1083 else
1084 {
1085 /* The branch is placed in row ii - 1. */
1086 if (dump_file)
1087 fprintf (dump_file,
1088 "SMS success in moving branch to cycle %d\n", c);
1089
1090 update_node_sched_params (g->closing_branch->cuid, ii, c,
1091 PS_MIN_CYCLE (ps));
1092 ok = true;
1093 }
1094
1095 free (must_precede);
1096 free (must_follow);
1097 }
1098
1099 clear:
1100 free (sched_nodes);
1101 return ok;
1102 }
1103
1104 static void
1105 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
1106 int to_stage, rtx count_reg)
1107 {
1108 int row;
1109 ps_insn_ptr ps_ij;
1110
1111 for (row = 0; row < ps->ii; row++)
1112 for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
1113 {
1114 int u = ps_ij->id;
1115 int first_u, last_u;
1116 rtx u_insn;
1117
1118 /* Do not duplicate any insn which refers to count_reg as it
1119 belongs to the control part.
1120 The closing branch is scheduled as well and thus should
1121 be ignored.
1122 TODO: This should be done by analyzing the control part of
1123 the loop. */
1124 u_insn = ps_rtl_insn (ps, u);
1125 if (reg_mentioned_p (count_reg, u_insn)
1126 || JUMP_P (u_insn))
1127 continue;
1128
1129 first_u = SCHED_STAGE (u);
1130 last_u = first_u + ps_num_consecutive_stages (ps, u) - 1;
1131 if (from_stage <= last_u && to_stage >= first_u)
1132 {
1133 if (u < ps->g->num_nodes)
1134 duplicate_insn_chain (ps_first_note (ps, u), u_insn);
1135 else
1136 emit_insn (copy_rtx (PATTERN (u_insn)));
1137 }
1138 }
1139 }
1140
1141
1142 /* Generate the instructions (including reg_moves) for prolog & epilog. */
1143 static void
1144 generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
1145 rtx count_reg, rtx count_init)
1146 {
1147 int i;
1148 int last_stage = PS_STAGE_COUNT (ps) - 1;
1149 edge e;
1150
1151 /* Generate the prolog, inserting its insns on the loop-entry edge. */
1152 start_sequence ();
1153
1154 if (!count_init)
1155 {
1156 /* Generate instructions at the beginning of the prolog to
1157 adjust the loop count by STAGE_COUNT. If loop count is constant
1158 (count_init), this constant is adjusted by STAGE_COUNT in
1159 generate_prolog_epilog function. */
1160 rtx sub_reg = NULL_RTX;
1161
1162 sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS,
1163 count_reg, GEN_INT (last_stage),
1164 count_reg, 1, OPTAB_DIRECT);
1165 gcc_assert (REG_P (sub_reg));
1166 if (REGNO (sub_reg) != REGNO (count_reg))
1167 emit_move_insn (count_reg, sub_reg);
1168 }
1169
1170 for (i = 0; i < last_stage; i++)
1171 duplicate_insns_of_cycles (ps, 0, i, count_reg);
1172
1173 /* Put the prolog on the entry edge. */
1174 e = loop_preheader_edge (loop);
1175 split_edge_and_insert (e, get_insns ());
1176 if (!flag_resched_modulo_sched)
1177 e->dest->flags |= BB_DISABLE_SCHEDULE;
1178
1179 end_sequence ();
1180
1181 /* Generate the epilog, inserting its insns on the loop-exit edge. */
1182 start_sequence ();
1183
1184 for (i = 0; i < last_stage; i++)
1185 duplicate_insns_of_cycles (ps, i + 1, last_stage, count_reg);
1186
1187 /* Put the epilogue on the exit edge. */
1188 gcc_assert (single_exit (loop));
1189 e = single_exit (loop);
1190 split_edge_and_insert (e, get_insns ());
1191 if (!flag_resched_modulo_sched)
1192 e->dest->flags |= BB_DISABLE_SCHEDULE;
1193
1194 end_sequence ();
1195 }
1196
1197 /* Mark LOOP as software pipelined so the later
1198 scheduling passes don't touch it. */
1199 static void
1200 mark_loop_unsched (struct loop *loop)
1201 {
1202 unsigned i;
1203 basic_block *bbs = get_loop_body (loop);
1204
1205 for (i = 0; i < loop->num_nodes; i++)
1206 bbs[i]->flags |= BB_DISABLE_SCHEDULE;
1207
1208 free (bbs);
1209 }
1210
1211 /* Return true if all the BBs of the loop are empty except the
1212 loop header. */
1213 static bool
1214 loop_single_full_bb_p (struct loop *loop)
1215 {
1216 unsigned i;
1217 basic_block *bbs = get_loop_body (loop);
1218
1219 for (i = 0; i < loop->num_nodes ; i++)
1220 {
1221 rtx head, tail;
1222 bool empty_bb = true;
1223
1224 if (bbs[i] == loop->header)
1225 continue;
1226
1227 /* Make sure that basic blocks other than the header
1228 have only notes labels or jumps. */
1229 get_ebb_head_tail (bbs[i], bbs[i], &head, &tail);
1230 for (; head != NEXT_INSN (tail); head = NEXT_INSN (head))
1231 {
1232 if (NOTE_P (head) || LABEL_P (head)
1233 || (INSN_P (head) && (DEBUG_INSN_P (head) || JUMP_P (head))))
1234 continue;
1235 empty_bb = false;
1236 break;
1237 }
1238
1239 if (! empty_bb)
1240 {
1241 free (bbs);
1242 return false;
1243 }
1244 }
1245 free (bbs);
1246 return true;
1247 }
1248
1249 /* Dump file:line from INSN's location info to dump_file. */
1250
1251 static void
1252 dump_insn_locator (rtx insn)
1253 {
1254 if (dump_file && INSN_LOCATOR (insn))
1255 {
1256 const char *file = insn_file (insn);
1257 if (file)
1258 fprintf (dump_file, " %s:%i", file, insn_line (insn));
1259 }
1260 }
1261
1262 /* A simple loop from SMS point of view; it is a loop that is composed of
1263 either a single basic block or two BBs - a header and a latch. */
1264 #define SIMPLE_SMS_LOOP_P(loop) ((loop->num_nodes < 3 ) \
1265 && (EDGE_COUNT (loop->latch->preds) == 1) \
1266 && (EDGE_COUNT (loop->latch->succs) == 1))
1267
1268 /* Return true if the loop is in its canonical form and false if not.
1269 i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit. */
1270 static bool
1271 loop_canon_p (struct loop *loop)
1272 {
1273
1274 if (loop->inner || !loop_outer (loop))
1275 {
1276 if (dump_file)
1277 fprintf (dump_file, "SMS loop inner or !loop_outer\n");
1278 return false;
1279 }
1280
1281 if (!single_exit (loop))
1282 {
1283 if (dump_file)
1284 {
1285 rtx insn = BB_END (loop->header);
1286
1287 fprintf (dump_file, "SMS loop many exits");
1288 dump_insn_locator (insn);
1289 fprintf (dump_file, "\n");
1290 }
1291 return false;
1292 }
1293
1294 if (! SIMPLE_SMS_LOOP_P (loop) && ! loop_single_full_bb_p (loop))
1295 {
1296 if (dump_file)
1297 {
1298 rtx insn = BB_END (loop->header);
1299
1300 fprintf (dump_file, "SMS loop many BBs.");
1301 dump_insn_locator (insn);
1302 fprintf (dump_file, "\n");
1303 }
1304 return false;
1305 }
1306
1307 return true;
1308 }
1309
1310 /* If there are more than one entry for the loop,
1311 make it one by splitting the first entry edge and
1312 redirecting the others to the new BB. */
1313 static void
1314 canon_loop (struct loop *loop)
1315 {
1316 edge e;
1317 edge_iterator i;
1318
1319 /* Avoid annoying special cases of edges going to exit
1320 block. */
1321 FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
1322 if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
1323 split_edge (e);
1324
1325 if (loop->latch == loop->header
1326 || EDGE_COUNT (loop->latch->succs) > 1)
1327 {
1328 FOR_EACH_EDGE (e, i, loop->header->preds)
1329 if (e->src == loop->latch)
1330 break;
1331 split_edge (e);
1332 }
1333 }
1334
1335 /* Setup infos. */
1336 static void
1337 setup_sched_infos (void)
1338 {
1339 memcpy (&sms_common_sched_info, &haifa_common_sched_info,
1340 sizeof (sms_common_sched_info));
1341 sms_common_sched_info.sched_pass_id = SCHED_SMS_PASS;
1342 common_sched_info = &sms_common_sched_info;
1343
1344 sched_deps_info = &sms_sched_deps_info;
1345 current_sched_info = &sms_sched_info;
1346 }
1347
1348 /* Probability in % that the sms-ed loop rolls enough so that optimized
1349 version may be entered. Just a guess. */
1350 #define PROB_SMS_ENOUGH_ITERATIONS 80
1351
1352 /* Used to calculate the upper bound of ii. */
1353 #define MAXII_FACTOR 2
1354
1355 /* Main entry point, perform SMS scheduling on the loops of the function
1356 that consist of single basic blocks. */
1357 static void
1358 sms_schedule (void)
1359 {
1360 rtx insn;
1361 ddg_ptr *g_arr, g;
1362 int * node_order;
1363 int maxii, max_asap;
1364 loop_iterator li;
1365 partial_schedule_ptr ps;
1366 basic_block bb = NULL;
1367 struct loop *loop;
1368 basic_block condition_bb = NULL;
1369 edge latch_edge;
1370 gcov_type trip_count = 0;
1371
1372 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
1373 | LOOPS_HAVE_RECORDED_EXITS);
1374 if (number_of_loops () <= 1)
1375 {
1376 loop_optimizer_finalize ();
1377 return; /* There are no loops to schedule. */
1378 }
1379
1380 /* Initialize issue_rate. */
1381 if (targetm.sched.issue_rate)
1382 {
1383 int temp = reload_completed;
1384
1385 reload_completed = 1;
1386 issue_rate = targetm.sched.issue_rate ();
1387 reload_completed = temp;
1388 }
1389 else
1390 issue_rate = 1;
1391
1392 /* Initialize the scheduler. */
1393 setup_sched_infos ();
1394 haifa_sched_init ();
1395
1396 /* Allocate memory to hold the DDG array one entry for each loop.
1397 We use loop->num as index into this array. */
1398 g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
1399
1400 if (dump_file)
1401 {
1402 fprintf (dump_file, "\n\nSMS analysis phase\n");
1403 fprintf (dump_file, "===================\n\n");
1404 }
1405
1406 /* Build DDGs for all the relevant loops and hold them in G_ARR
1407 indexed by the loop index. */
1408 FOR_EACH_LOOP (li, loop, 0)
1409 {
1410 rtx head, tail;
1411 rtx count_reg;
1412
1413 /* For debugging. */
1414 if (dbg_cnt (sms_sched_loop) == false)
1415 {
1416 if (dump_file)
1417 fprintf (dump_file, "SMS reached max limit... \n");
1418
1419 break;
1420 }
1421
1422 if (dump_file)
1423 {
1424 rtx insn = BB_END (loop->header);
1425
1426 fprintf (dump_file, "SMS loop num: %d", loop->num);
1427 dump_insn_locator (insn);
1428 fprintf (dump_file, "\n");
1429 }
1430
1431 if (! loop_canon_p (loop))
1432 continue;
1433
1434 if (! loop_single_full_bb_p (loop))
1435 {
1436 if (dump_file)
1437 fprintf (dump_file, "SMS not loop_single_full_bb_p\n");
1438 continue;
1439 }
1440
1441 bb = loop->header;
1442
1443 get_ebb_head_tail (bb, bb, &head, &tail);
1444 latch_edge = loop_latch_edge (loop);
1445 gcc_assert (single_exit (loop));
1446 if (single_exit (loop)->count)
1447 trip_count = latch_edge->count / single_exit (loop)->count;
1448
1449 /* Perform SMS only on loops that their average count is above threshold. */
1450
1451 if ( latch_edge->count
1452 && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
1453 {
1454 if (dump_file)
1455 {
1456 dump_insn_locator (tail);
1457 fprintf (dump_file, "\nSMS single-bb-loop\n");
1458 if (profile_info && flag_branch_probabilities)
1459 {
1460 fprintf (dump_file, "SMS loop-count ");
1461 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1462 (HOST_WIDEST_INT) bb->count);
1463 fprintf (dump_file, "\n");
1464 fprintf (dump_file, "SMS trip-count ");
1465 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1466 (HOST_WIDEST_INT) trip_count);
1467 fprintf (dump_file, "\n");
1468 fprintf (dump_file, "SMS profile-sum-max ");
1469 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1470 (HOST_WIDEST_INT) profile_info->sum_max);
1471 fprintf (dump_file, "\n");
1472 }
1473 }
1474 continue;
1475 }
1476
1477 /* Make sure this is a doloop. */
1478 if ( !(count_reg = doloop_register_get (head, tail)))
1479 {
1480 if (dump_file)
1481 fprintf (dump_file, "SMS doloop_register_get failed\n");
1482 continue;
1483 }
1484
1485 /* Don't handle BBs with calls or barriers
1486 or !single_set with the exception of instructions that include
1487 count_reg---these instructions are part of the control part
1488 that do-loop recognizes.
1489 ??? Should handle insns defining subregs. */
1490 for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
1491 {
1492 rtx set;
1493
1494 if (CALL_P (insn)
1495 || BARRIER_P (insn)
1496 || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
1497 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE
1498 && !reg_mentioned_p (count_reg, insn))
1499 || (INSN_P (insn) && (set = single_set (insn))
1500 && GET_CODE (SET_DEST (set)) == SUBREG))
1501 break;
1502 }
1503
1504 if (insn != NEXT_INSN (tail))
1505 {
1506 if (dump_file)
1507 {
1508 if (CALL_P (insn))
1509 fprintf (dump_file, "SMS loop-with-call\n");
1510 else if (BARRIER_P (insn))
1511 fprintf (dump_file, "SMS loop-with-barrier\n");
1512 else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
1513 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
1514 fprintf (dump_file, "SMS loop-with-not-single-set\n");
1515 else
1516 fprintf (dump_file, "SMS loop with subreg in lhs\n");
1517 print_rtl_single (dump_file, insn);
1518 }
1519
1520 continue;
1521 }
1522
1523 /* Always schedule the closing branch with the rest of the
1524 instructions. The branch is rotated to be in row ii-1 at the
1525 end of the scheduling procedure to make sure it's the last
1526 instruction in the iteration. */
1527 if (! (g = create_ddg (bb, 1)))
1528 {
1529 if (dump_file)
1530 fprintf (dump_file, "SMS create_ddg failed\n");
1531 continue;
1532 }
1533
1534 g_arr[loop->num] = g;
1535 if (dump_file)
1536 fprintf (dump_file, "...OK\n");
1537
1538 }
1539 if (dump_file)
1540 {
1541 fprintf (dump_file, "\nSMS transformation phase\n");
1542 fprintf (dump_file, "=========================\n\n");
1543 }
1544
1545 /* We don't want to perform SMS on new loops - created by versioning. */
1546 FOR_EACH_LOOP (li, loop, 0)
1547 {
1548 rtx head, tail;
1549 rtx count_reg, count_init;
1550 int mii, rec_mii, stage_count, min_cycle;
1551 HOST_WIDEST_INT loop_count = 0;
1552 bool opt_sc_p;
1553
1554 if (! (g = g_arr[loop->num]))
1555 continue;
1556
1557 if (dump_file)
1558 {
1559 rtx insn = BB_END (loop->header);
1560
1561 fprintf (dump_file, "SMS loop num: %d", loop->num);
1562 dump_insn_locator (insn);
1563 fprintf (dump_file, "\n");
1564
1565 print_ddg (dump_file, g);
1566 }
1567
1568 get_ebb_head_tail (loop->header, loop->header, &head, &tail);
1569
1570 latch_edge = loop_latch_edge (loop);
1571 gcc_assert (single_exit (loop));
1572 if (single_exit (loop)->count)
1573 trip_count = latch_edge->count / single_exit (loop)->count;
1574
1575 if (dump_file)
1576 {
1577 dump_insn_locator (tail);
1578 fprintf (dump_file, "\nSMS single-bb-loop\n");
1579 if (profile_info && flag_branch_probabilities)
1580 {
1581 fprintf (dump_file, "SMS loop-count ");
1582 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1583 (HOST_WIDEST_INT) bb->count);
1584 fprintf (dump_file, "\n");
1585 fprintf (dump_file, "SMS profile-sum-max ");
1586 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1587 (HOST_WIDEST_INT) profile_info->sum_max);
1588 fprintf (dump_file, "\n");
1589 }
1590 fprintf (dump_file, "SMS doloop\n");
1591 fprintf (dump_file, "SMS built-ddg %d\n", g->num_nodes);
1592 fprintf (dump_file, "SMS num-loads %d\n", g->num_loads);
1593 fprintf (dump_file, "SMS num-stores %d\n", g->num_stores);
1594 }
1595
1596
1597 /* In case of th loop have doloop register it gets special
1598 handling. */
1599 count_init = NULL_RTX;
1600 if ((count_reg = doloop_register_get (head, tail)))
1601 {
1602 basic_block pre_header;
1603
1604 pre_header = loop_preheader_edge (loop)->src;
1605 count_init = const_iteration_count (count_reg, pre_header,
1606 &loop_count);
1607 }
1608 gcc_assert (count_reg);
1609
1610 if (dump_file && count_init)
1611 {
1612 fprintf (dump_file, "SMS const-doloop ");
1613 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1614 loop_count);
1615 fprintf (dump_file, "\n");
1616 }
1617
1618 node_order = XNEWVEC (int, g->num_nodes);
1619
1620 mii = 1; /* Need to pass some estimate of mii. */
1621 rec_mii = sms_order_nodes (g, mii, node_order, &max_asap);
1622 mii = MAX (res_MII (g), rec_mii);
1623 maxii = MAX (max_asap, MAXII_FACTOR * mii);
1624
1625 if (dump_file)
1626 fprintf (dump_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
1627 rec_mii, mii, maxii);
1628
1629 for (;;)
1630 {
1631 set_node_sched_params (g);
1632
1633 stage_count = 0;
1634 opt_sc_p = false;
1635 ps = sms_schedule_by_order (g, mii, maxii, node_order);
1636
1637 if (ps)
1638 {
1639 /* Try to achieve optimized SC by normalizing the partial
1640 schedule (having the cycles start from cycle zero).
1641 The branch location must be placed in row ii-1 in the
1642 final scheduling. If failed, shift all instructions to
1643 position the branch in row ii-1. */
1644 opt_sc_p = optimize_sc (ps, g);
1645 if (opt_sc_p)
1646 stage_count = calculate_stage_count (ps, 0);
1647 else
1648 {
1649 /* Bring the branch to cycle ii-1. */
1650 int amount = (SCHED_TIME (g->closing_branch->cuid)
1651 - (ps->ii - 1));
1652
1653 if (dump_file)
1654 fprintf (dump_file, "SMS schedule branch at cycle ii-1\n");
1655
1656 stage_count = calculate_stage_count (ps, amount);
1657 }
1658
1659 gcc_assert (stage_count >= 1);
1660 }
1661
1662 /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of
1663 1 means that there is no interleaving between iterations thus
1664 we let the scheduling passes do the job in this case. */
1665 if (stage_count < PARAM_VALUE (PARAM_SMS_MIN_SC)
1666 || (count_init && (loop_count <= stage_count))
1667 || (flag_branch_probabilities && (trip_count <= stage_count)))
1668 {
1669 if (dump_file)
1670 {
1671 fprintf (dump_file, "SMS failed... \n");
1672 fprintf (dump_file, "SMS sched-failed (stage-count=%d,"
1673 " loop-count=", stage_count);
1674 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
1675 fprintf (dump_file, ", trip-count=");
1676 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count);
1677 fprintf (dump_file, ")\n");
1678 }
1679 break;
1680 }
1681
1682 if (!opt_sc_p)
1683 {
1684 /* Rotate the partial schedule to have the branch in row ii-1. */
1685 int amount = SCHED_TIME (g->closing_branch->cuid) - (ps->ii - 1);
1686
1687 reset_sched_times (ps, amount);
1688 rotate_partial_schedule (ps, amount);
1689 }
1690
1691 set_columns_for_ps (ps);
1692
1693 min_cycle = PS_MIN_CYCLE (ps) - SMODULO (PS_MIN_CYCLE (ps), ps->ii);
1694 if (!schedule_reg_moves (ps))
1695 {
1696 mii = ps->ii + 1;
1697 free_partial_schedule (ps);
1698 continue;
1699 }
1700
1701 /* Moves that handle incoming values might have been added
1702 to a new first stage. Bump the stage count if so.
1703
1704 ??? Perhaps we could consider rotating the schedule here
1705 instead? */
1706 if (PS_MIN_CYCLE (ps) < min_cycle)
1707 {
1708 reset_sched_times (ps, 0);
1709 stage_count++;
1710 }
1711
1712 /* The stage count should now be correct without rotation. */
1713 gcc_checking_assert (stage_count == calculate_stage_count (ps, 0));
1714 PS_STAGE_COUNT (ps) = stage_count;
1715
1716 canon_loop (loop);
1717
1718 if (dump_file)
1719 {
1720 dump_insn_locator (tail);
1721 fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
1722 ps->ii, stage_count);
1723 print_partial_schedule (ps, dump_file);
1724 }
1725
1726 /* case the BCT count is not known , Do loop-versioning */
1727 if (count_reg && ! count_init)
1728 {
1729 rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
1730 GEN_INT(stage_count));
1731 unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS
1732 * REG_BR_PROB_BASE) / 100;
1733
1734 loop_version (loop, comp_rtx, &condition_bb,
1735 prob, prob, REG_BR_PROB_BASE - prob,
1736 true);
1737 }
1738
1739 /* Set new iteration count of loop kernel. */
1740 if (count_reg && count_init)
1741 SET_SRC (single_set (count_init)) = GEN_INT (loop_count
1742 - stage_count + 1);
1743
1744 /* Now apply the scheduled kernel to the RTL of the loop. */
1745 permute_partial_schedule (ps, g->closing_branch->first_note);
1746
1747 /* Mark this loop as software pipelined so the later
1748 scheduling passes don't touch it. */
1749 if (! flag_resched_modulo_sched)
1750 mark_loop_unsched (loop);
1751
1752 /* The life-info is not valid any more. */
1753 df_set_bb_dirty (g->bb);
1754
1755 apply_reg_moves (ps);
1756 if (dump_file)
1757 print_node_sched_params (dump_file, g->num_nodes, ps);
1758 /* Generate prolog and epilog. */
1759 generate_prolog_epilog (ps, loop, count_reg, count_init);
1760 break;
1761 }
1762
1763 free_partial_schedule (ps);
1764 VEC_free (node_sched_params, heap, node_sched_param_vec);
1765 free (node_order);
1766 free_ddg (g);
1767 }
1768
1769 free (g_arr);
1770
1771 /* Release scheduler data, needed until now because of DFA. */
1772 haifa_sched_finish ();
1773 loop_optimizer_finalize ();
1774 }
1775
1776 /* The SMS scheduling algorithm itself
1777 -----------------------------------
1778 Input: 'O' an ordered list of insns of a loop.
1779 Output: A scheduling of the loop - kernel, prolog, and epilogue.
1780
1781 'Q' is the empty Set
1782 'PS' is the partial schedule; it holds the currently scheduled nodes with
1783 their cycle/slot.
1784 'PSP' previously scheduled predecessors.
1785 'PSS' previously scheduled successors.
1786 't(u)' the cycle where u is scheduled.
1787 'l(u)' is the latency of u.
1788 'd(v,u)' is the dependence distance from v to u.
1789 'ASAP(u)' the earliest time at which u could be scheduled as computed in
1790 the node ordering phase.
1791 'check_hardware_resources_conflicts(u, PS, c)'
1792 run a trace around cycle/slot through DFA model
1793 to check resource conflicts involving instruction u
1794 at cycle c given the partial schedule PS.
1795 'add_to_partial_schedule_at_time(u, PS, c)'
1796 Add the node/instruction u to the partial schedule
1797 PS at time c.
1798 'calculate_register_pressure(PS)'
1799 Given a schedule of instructions, calculate the register
1800 pressure it implies. One implementation could be the
1801 maximum number of overlapping live ranges.
1802 'maxRP' The maximum allowed register pressure, it is usually derived from the number
1803 registers available in the hardware.
1804
1805 1. II = MII.
1806 2. PS = empty list
1807 3. for each node u in O in pre-computed order
1808 4. if (PSP(u) != Q && PSS(u) == Q) then
1809 5. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1810 6. start = Early_start; end = Early_start + II - 1; step = 1
1811 11. else if (PSP(u) == Q && PSS(u) != Q) then
1812 12. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1813 13. start = Late_start; end = Late_start - II + 1; step = -1
1814 14. else if (PSP(u) != Q && PSS(u) != Q) then
1815 15. Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1816 16. Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1817 17. start = Early_start;
1818 18. end = min(Early_start + II - 1 , Late_start);
1819 19. step = 1
1820 20. else "if (PSP(u) == Q && PSS(u) == Q)"
1821 21. start = ASAP(u); end = start + II - 1; step = 1
1822 22. endif
1823
1824 23. success = false
1825 24. for (c = start ; c != end ; c += step)
1826 25. if check_hardware_resources_conflicts(u, PS, c) then
1827 26. add_to_partial_schedule_at_time(u, PS, c)
1828 27. success = true
1829 28. break
1830 29. endif
1831 30. endfor
1832 31. if (success == false) then
1833 32. II = II + 1
1834 33. if (II > maxII) then
1835 34. finish - failed to schedule
1836 35. endif
1837 36. goto 2.
1838 37. endif
1839 38. endfor
1840 39. if (calculate_register_pressure(PS) > maxRP) then
1841 40. goto 32.
1842 41. endif
1843 42. compute epilogue & prologue
1844 43. finish - succeeded to schedule
1845
1846 ??? The algorithm restricts the scheduling window to II cycles.
1847 In rare cases, it may be better to allow windows of II+1 cycles.
1848 The window would then start and end on the same row, but with
1849 different "must precede" and "must follow" requirements. */
1850
1851 /* A limit on the number of cycles that resource conflicts can span. ??? Should
1852 be provided by DFA, and be dependent on the type of insn scheduled. Currently
1853 set to 0 to save compile time. */
1854 #define DFA_HISTORY SMS_DFA_HISTORY
1855
1856 /* A threshold for the number of repeated unsuccessful attempts to insert
1857 an empty row, before we flush the partial schedule and start over. */
1858 #define MAX_SPLIT_NUM 10
1859 /* Given the partial schedule PS, this function calculates and returns the
1860 cycles in which we can schedule the node with the given index I.
1861 NOTE: Here we do the backtracking in SMS, in some special cases. We have
1862 noticed that there are several cases in which we fail to SMS the loop
1863 because the sched window of a node is empty due to tight data-deps. In
1864 such cases we want to unschedule some of the predecessors/successors
1865 until we get non-empty scheduling window. It returns -1 if the
1866 scheduling window is empty and zero otherwise. */
1867
1868 static int
1869 get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
1870 sbitmap sched_nodes, int ii, int *start_p, int *step_p,
1871 int *end_p)
1872 {
1873 int start, step, end;
1874 int early_start, late_start;
1875 ddg_edge_ptr e;
1876 sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
1877 sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
1878 sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1879 sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1880 int psp_not_empty;
1881 int pss_not_empty;
1882 int count_preds;
1883 int count_succs;
1884
1885 /* 1. compute sched window for u (start, end, step). */
1886 sbitmap_zero (psp);
1887 sbitmap_zero (pss);
1888 psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1889 pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1890
1891 /* We first compute a forward range (start <= end), then decide whether
1892 to reverse it. */
1893 early_start = INT_MIN;
1894 late_start = INT_MAX;
1895 start = INT_MIN;
1896 end = INT_MAX;
1897 step = 1;
1898
1899 count_preds = 0;
1900 count_succs = 0;
1901
1902 if (dump_file && (psp_not_empty || pss_not_empty))
1903 {
1904 fprintf (dump_file, "\nAnalyzing dependencies for node %d (INSN %d)"
1905 "; ii = %d\n\n", u_node->cuid, INSN_UID (u_node->insn), ii);
1906 fprintf (dump_file, "%11s %11s %11s %11s %5s\n",
1907 "start", "early start", "late start", "end", "time");
1908 fprintf (dump_file, "=========== =========== =========== ==========="
1909 " =====\n");
1910 }
1911 /* Calculate early_start and limit end. Both bounds are inclusive. */
1912 if (psp_not_empty)
1913 for (e = u_node->in; e != 0; e = e->next_in)
1914 {
1915 int v = e->src->cuid;
1916
1917 if (TEST_BIT (sched_nodes, v))
1918 {
1919 int p_st = SCHED_TIME (v);
1920 int earliest = p_st + e->latency - (e->distance * ii);
1921 int latest = (e->data_type == MEM_DEP ? p_st + ii - 1 : INT_MAX);
1922
1923 if (dump_file)
1924 {
1925 fprintf (dump_file, "%11s %11d %11s %11d %5d",
1926 "", earliest, "", latest, p_st);
1927 print_ddg_edge (dump_file, e);
1928 fprintf (dump_file, "\n");
1929 }
1930
1931 early_start = MAX (early_start, earliest);
1932 end = MIN (end, latest);
1933
1934 if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1935 count_preds++;
1936 }
1937 }
1938
1939 /* Calculate late_start and limit start. Both bounds are inclusive. */
1940 if (pss_not_empty)
1941 for (e = u_node->out; e != 0; e = e->next_out)
1942 {
1943 int v = e->dest->cuid;
1944
1945 if (TEST_BIT (sched_nodes, v))
1946 {
1947 int s_st = SCHED_TIME (v);
1948 int earliest = (e->data_type == MEM_DEP ? s_st - ii + 1 : INT_MIN);
1949 int latest = s_st - e->latency + (e->distance * ii);
1950
1951 if (dump_file)
1952 {
1953 fprintf (dump_file, "%11d %11s %11d %11s %5d",
1954 earliest, "", latest, "", s_st);
1955 print_ddg_edge (dump_file, e);
1956 fprintf (dump_file, "\n");
1957 }
1958
1959 start = MAX (start, earliest);
1960 late_start = MIN (late_start, latest);
1961
1962 if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1963 count_succs++;
1964 }
1965 }
1966
1967 if (dump_file && (psp_not_empty || pss_not_empty))
1968 {
1969 fprintf (dump_file, "----------- ----------- ----------- -----------"
1970 " -----\n");
1971 fprintf (dump_file, "%11d %11d %11d %11d %5s %s\n",
1972 start, early_start, late_start, end, "",
1973 "(max, max, min, min)");
1974 }
1975
1976 /* Get a target scheduling window no bigger than ii. */
1977 if (early_start == INT_MIN && late_start == INT_MAX)
1978 early_start = NODE_ASAP (u_node);
1979 else if (early_start == INT_MIN)
1980 early_start = late_start - (ii - 1);
1981 late_start = MIN (late_start, early_start + (ii - 1));
1982
1983 /* Apply memory dependence limits. */
1984 start = MAX (start, early_start);
1985 end = MIN (end, late_start);
1986
1987 if (dump_file && (psp_not_empty || pss_not_empty))
1988 fprintf (dump_file, "%11s %11d %11d %11s %5s final window\n",
1989 "", start, end, "", "");
1990
1991 /* If there are at least as many successors as predecessors, schedule the
1992 node close to its successors. */
1993 if (pss_not_empty && count_succs >= count_preds)
1994 {
1995 int tmp = end;
1996 end = start;
1997 start = tmp;
1998 step = -1;
1999 }
2000
2001 /* Now that we've finalized the window, make END an exclusive rather
2002 than an inclusive bound. */
2003 end += step;
2004
2005 *start_p = start;
2006 *step_p = step;
2007 *end_p = end;
2008 sbitmap_free (psp);
2009 sbitmap_free (pss);
2010
2011 if ((start >= end && step == 1) || (start <= end && step == -1))
2012 {
2013 if (dump_file)
2014 fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
2015 start, end, step);
2016 return -1;
2017 }
2018
2019 return 0;
2020 }
2021
2022 /* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the
2023 node currently been scheduled. At the end of the calculation
2024 MUST_PRECEDE/MUST_FOLLOW contains all predecessors/successors of
2025 U_NODE which are (1) already scheduled in the first/last row of
2026 U_NODE's scheduling window, (2) whose dependence inequality with U
2027 becomes an equality when U is scheduled in this same row, and (3)
2028 whose dependence latency is zero.
2029
2030 The first and last rows are calculated using the following parameters:
2031 START/END rows - The cycles that begins/ends the traversal on the window;
2032 searching for an empty cycle to schedule U_NODE.
2033 STEP - The direction in which we traverse the window.
2034 II - The initiation interval. */
2035
2036 static void
2037 calculate_must_precede_follow (ddg_node_ptr u_node, int start, int end,
2038 int step, int ii, sbitmap sched_nodes,
2039 sbitmap must_precede, sbitmap must_follow)
2040 {
2041 ddg_edge_ptr e;
2042 int first_cycle_in_window, last_cycle_in_window;
2043
2044 gcc_assert (must_precede && must_follow);
2045
2046 /* Consider the following scheduling window:
2047 {first_cycle_in_window, first_cycle_in_window+1, ...,
2048 last_cycle_in_window}. If step is 1 then the following will be
2049 the order we traverse the window: {start=first_cycle_in_window,
2050 first_cycle_in_window+1, ..., end=last_cycle_in_window+1},
2051 or {start=last_cycle_in_window, last_cycle_in_window-1, ...,
2052 end=first_cycle_in_window-1} if step is -1. */
2053 first_cycle_in_window = (step == 1) ? start : end - step;
2054 last_cycle_in_window = (step == 1) ? end - step : start;
2055
2056 sbitmap_zero (must_precede);
2057 sbitmap_zero (must_follow);
2058
2059 if (dump_file)
2060 fprintf (dump_file, "\nmust_precede: ");
2061
2062 /* Instead of checking if:
2063 (SMODULO (SCHED_TIME (e->src), ii) == first_row_in_window)
2064 && ((SCHED_TIME (e->src) + e->latency - (e->distance * ii)) ==
2065 first_cycle_in_window)
2066 && e->latency == 0
2067 we use the fact that latency is non-negative:
2068 SCHED_TIME (e->src) - (e->distance * ii) <=
2069 SCHED_TIME (e->src) + e->latency - (e->distance * ii)) <=
2070 first_cycle_in_window
2071 and check only if
2072 SCHED_TIME (e->src) - (e->distance * ii) == first_cycle_in_window */
2073 for (e = u_node->in; e != 0; e = e->next_in)
2074 if (TEST_BIT (sched_nodes, e->src->cuid)
2075 && ((SCHED_TIME (e->src->cuid) - (e->distance * ii)) ==
2076 first_cycle_in_window))
2077 {
2078 if (dump_file)
2079 fprintf (dump_file, "%d ", e->src->cuid);
2080
2081 SET_BIT (must_precede, e->src->cuid);
2082 }
2083
2084 if (dump_file)
2085 fprintf (dump_file, "\nmust_follow: ");
2086
2087 /* Instead of checking if:
2088 (SMODULO (SCHED_TIME (e->dest), ii) == last_row_in_window)
2089 && ((SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) ==
2090 last_cycle_in_window)
2091 && e->latency == 0
2092 we use the fact that latency is non-negative:
2093 SCHED_TIME (e->dest) + (e->distance * ii) >=
2094 SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >=
2095 last_cycle_in_window
2096 and check only if
2097 SCHED_TIME (e->dest) + (e->distance * ii) == last_cycle_in_window */
2098 for (e = u_node->out; e != 0; e = e->next_out)
2099 if (TEST_BIT (sched_nodes, e->dest->cuid)
2100 && ((SCHED_TIME (e->dest->cuid) + (e->distance * ii)) ==
2101 last_cycle_in_window))
2102 {
2103 if (dump_file)
2104 fprintf (dump_file, "%d ", e->dest->cuid);
2105
2106 SET_BIT (must_follow, e->dest->cuid);
2107 }
2108
2109 if (dump_file)
2110 fprintf (dump_file, "\n");
2111 }
2112
2113 /* Return 1 if U_NODE can be scheduled in CYCLE. Use the following
2114 parameters to decide if that's possible:
2115 PS - The partial schedule.
2116 U - The serial number of U_NODE.
2117 NUM_SPLITS - The number of row splits made so far.
2118 MUST_PRECEDE - The nodes that must precede U_NODE. (only valid at
2119 the first row of the scheduling window)
2120 MUST_FOLLOW - The nodes that must follow U_NODE. (only valid at the
2121 last row of the scheduling window) */
2122
2123 static bool
2124 try_scheduling_node_in_cycle (partial_schedule_ptr ps,
2125 int u, int cycle, sbitmap sched_nodes,
2126 int *num_splits, sbitmap must_precede,
2127 sbitmap must_follow)
2128 {
2129 ps_insn_ptr psi;
2130 bool success = 0;
2131
2132 verify_partial_schedule (ps, sched_nodes);
2133 psi = ps_add_node_check_conflicts (ps, u, cycle, must_precede, must_follow);
2134 if (psi)
2135 {
2136 SCHED_TIME (u) = cycle;
2137 SET_BIT (sched_nodes, u);
2138 success = 1;
2139 *num_splits = 0;
2140 if (dump_file)
2141 fprintf (dump_file, "Scheduled w/o split in %d\n", cycle);
2142
2143 }
2144
2145 return success;
2146 }
2147
2148 /* This function implements the scheduling algorithm for SMS according to the
2149 above algorithm. */
2150 static partial_schedule_ptr
2151 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
2152 {
2153 int ii = mii;
2154 int i, c, success, num_splits = 0;
2155 int flush_and_start_over = true;
2156 int num_nodes = g->num_nodes;
2157 int start, end, step; /* Place together into one struct? */
2158 sbitmap sched_nodes = sbitmap_alloc (num_nodes);
2159 sbitmap must_precede = sbitmap_alloc (num_nodes);
2160 sbitmap must_follow = sbitmap_alloc (num_nodes);
2161 sbitmap tobe_scheduled = sbitmap_alloc (num_nodes);
2162
2163 partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
2164
2165 sbitmap_ones (tobe_scheduled);
2166 sbitmap_zero (sched_nodes);
2167
2168 while (flush_and_start_over && (ii < maxii))
2169 {
2170
2171 if (dump_file)
2172 fprintf (dump_file, "Starting with ii=%d\n", ii);
2173 flush_and_start_over = false;
2174 sbitmap_zero (sched_nodes);
2175
2176 for (i = 0; i < num_nodes; i++)
2177 {
2178 int u = nodes_order[i];
2179 ddg_node_ptr u_node = &ps->g->nodes[u];
2180 rtx insn = u_node->insn;
2181
2182 if (!NONDEBUG_INSN_P (insn))
2183 {
2184 RESET_BIT (tobe_scheduled, u);
2185 continue;
2186 }
2187
2188 if (TEST_BIT (sched_nodes, u))
2189 continue;
2190
2191 /* Try to get non-empty scheduling window. */
2192 success = 0;
2193 if (get_sched_window (ps, u_node, sched_nodes, ii, &start,
2194 &step, &end) == 0)
2195 {
2196 if (dump_file)
2197 fprintf (dump_file, "\nTrying to schedule node %d "
2198 "INSN = %d in (%d .. %d) step %d\n", u, (INSN_UID
2199 (g->nodes[u].insn)), start, end, step);
2200
2201 gcc_assert ((step > 0 && start < end)
2202 || (step < 0 && start > end));
2203
2204 calculate_must_precede_follow (u_node, start, end, step, ii,
2205 sched_nodes, must_precede,
2206 must_follow);
2207
2208 for (c = start; c != end; c += step)
2209 {
2210 sbitmap tmp_precede, tmp_follow;
2211
2212 set_must_precede_follow (&tmp_follow, must_follow,
2213 &tmp_precede, must_precede,
2214 c, start, end, step);
2215 success =
2216 try_scheduling_node_in_cycle (ps, u, c,
2217 sched_nodes,
2218 &num_splits, tmp_precede,
2219 tmp_follow);
2220 if (success)
2221 break;
2222 }
2223
2224 verify_partial_schedule (ps, sched_nodes);
2225 }
2226 if (!success)
2227 {
2228 int split_row;
2229
2230 if (ii++ == maxii)
2231 break;
2232
2233 if (num_splits >= MAX_SPLIT_NUM)
2234 {
2235 num_splits = 0;
2236 flush_and_start_over = true;
2237 verify_partial_schedule (ps, sched_nodes);
2238 reset_partial_schedule (ps, ii);
2239 verify_partial_schedule (ps, sched_nodes);
2240 break;
2241 }
2242
2243 num_splits++;
2244 /* The scheduling window is exclusive of 'end'
2245 whereas compute_split_window() expects an inclusive,
2246 ordered range. */
2247 if (step == 1)
2248 split_row = compute_split_row (sched_nodes, start, end - 1,
2249 ps->ii, u_node);
2250 else
2251 split_row = compute_split_row (sched_nodes, end + 1, start,
2252 ps->ii, u_node);
2253
2254 ps_insert_empty_row (ps, split_row, sched_nodes);
2255 i--; /* Go back and retry node i. */
2256
2257 if (dump_file)
2258 fprintf (dump_file, "num_splits=%d\n", num_splits);
2259 }
2260
2261 /* ??? If (success), check register pressure estimates. */
2262 } /* Continue with next node. */
2263 } /* While flush_and_start_over. */
2264 if (ii >= maxii)
2265 {
2266 free_partial_schedule (ps);
2267 ps = NULL;
2268 }
2269 else
2270 gcc_assert (sbitmap_equal (tobe_scheduled, sched_nodes));
2271
2272 sbitmap_free (sched_nodes);
2273 sbitmap_free (must_precede);
2274 sbitmap_free (must_follow);
2275 sbitmap_free (tobe_scheduled);
2276
2277 return ps;
2278 }
2279
2280 /* This function inserts a new empty row into PS at the position
2281 according to SPLITROW, keeping all already scheduled instructions
2282 intact and updating their SCHED_TIME and cycle accordingly. */
2283 static void
2284 ps_insert_empty_row (partial_schedule_ptr ps, int split_row,
2285 sbitmap sched_nodes)
2286 {
2287 ps_insn_ptr crr_insn;
2288 ps_insn_ptr *rows_new;
2289 int ii = ps->ii;
2290 int new_ii = ii + 1;
2291 int row;
2292 int *rows_length_new;
2293
2294 verify_partial_schedule (ps, sched_nodes);
2295
2296 /* We normalize sched_time and rotate ps to have only non-negative sched
2297 times, for simplicity of updating cycles after inserting new row. */
2298 split_row -= ps->min_cycle;
2299 split_row = SMODULO (split_row, ii);
2300 if (dump_file)
2301 fprintf (dump_file, "split_row=%d\n", split_row);
2302
2303 reset_sched_times (ps, PS_MIN_CYCLE (ps));
2304 rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
2305
2306 rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
2307 rows_length_new = (int *) xcalloc (new_ii, sizeof (int));
2308 for (row = 0; row < split_row; row++)
2309 {
2310 rows_new[row] = ps->rows[row];
2311 rows_length_new[row] = ps->rows_length[row];
2312 ps->rows[row] = NULL;
2313 for (crr_insn = rows_new[row];
2314 crr_insn; crr_insn = crr_insn->next_in_row)
2315 {
2316 int u = crr_insn->id;
2317 int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii);
2318
2319 SCHED_TIME (u) = new_time;
2320 crr_insn->cycle = new_time;
2321 SCHED_ROW (u) = new_time % new_ii;
2322 SCHED_STAGE (u) = new_time / new_ii;
2323 }
2324
2325 }
2326
2327 rows_new[split_row] = NULL;
2328
2329 for (row = split_row; row < ii; row++)
2330 {
2331 rows_new[row + 1] = ps->rows[row];
2332 rows_length_new[row + 1] = ps->rows_length[row];
2333 ps->rows[row] = NULL;
2334 for (crr_insn = rows_new[row + 1];
2335 crr_insn; crr_insn = crr_insn->next_in_row)
2336 {
2337 int u = crr_insn->id;
2338 int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii) + 1;
2339
2340 SCHED_TIME (u) = new_time;
2341 crr_insn->cycle = new_time;
2342 SCHED_ROW (u) = new_time % new_ii;
2343 SCHED_STAGE (u) = new_time / new_ii;
2344 }
2345 }
2346
2347 /* Updating ps. */
2348 ps->min_cycle = ps->min_cycle + ps->min_cycle / ii
2349 + (SMODULO (ps->min_cycle, ii) >= split_row ? 1 : 0);
2350 ps->max_cycle = ps->max_cycle + ps->max_cycle / ii
2351 + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0);
2352 free (ps->rows);
2353 ps->rows = rows_new;
2354 free (ps->rows_length);
2355 ps->rows_length = rows_length_new;
2356 ps->ii = new_ii;
2357 gcc_assert (ps->min_cycle >= 0);
2358
2359 verify_partial_schedule (ps, sched_nodes);
2360
2361 if (dump_file)
2362 fprintf (dump_file, "min_cycle=%d, max_cycle=%d\n", ps->min_cycle,
2363 ps->max_cycle);
2364 }
2365
2366 /* Given U_NODE which is the node that failed to be scheduled; LOW and
2367 UP which are the boundaries of it's scheduling window; compute using
2368 SCHED_NODES and II a row in the partial schedule that can be split
2369 which will separate a critical predecessor from a critical successor
2370 thereby expanding the window, and return it. */
2371 static int
2372 compute_split_row (sbitmap sched_nodes, int low, int up, int ii,
2373 ddg_node_ptr u_node)
2374 {
2375 ddg_edge_ptr e;
2376 int lower = INT_MIN, upper = INT_MAX;
2377 int crit_pred = -1;
2378 int crit_succ = -1;
2379 int crit_cycle;
2380
2381 for (e = u_node->in; e != 0; e = e->next_in)
2382 {
2383 int v = e->src->cuid;
2384
2385 if (TEST_BIT (sched_nodes, v)
2386 && (low == SCHED_TIME (v) + e->latency - (e->distance * ii)))
2387 if (SCHED_TIME (v) > lower)
2388 {
2389 crit_pred = v;
2390 lower = SCHED_TIME (v);
2391 }
2392 }
2393
2394 if (crit_pred >= 0)
2395 {
2396 crit_cycle = SCHED_TIME (crit_pred) + 1;
2397 return SMODULO (crit_cycle, ii);
2398 }
2399
2400 for (e = u_node->out; e != 0; e = e->next_out)
2401 {
2402 int v = e->dest->cuid;
2403
2404 if (TEST_BIT (sched_nodes, v)
2405 && (up == SCHED_TIME (v) - e->latency + (e->distance * ii)))
2406 if (SCHED_TIME (v) < upper)
2407 {
2408 crit_succ = v;
2409 upper = SCHED_TIME (v);
2410 }
2411 }
2412
2413 if (crit_succ >= 0)
2414 {
2415 crit_cycle = SCHED_TIME (crit_succ);
2416 return SMODULO (crit_cycle, ii);
2417 }
2418
2419 if (dump_file)
2420 fprintf (dump_file, "Both crit_pred and crit_succ are NULL\n");
2421
2422 return SMODULO ((low + up + 1) / 2, ii);
2423 }
2424
2425 static void
2426 verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes)
2427 {
2428 int row;
2429 ps_insn_ptr crr_insn;
2430
2431 for (row = 0; row < ps->ii; row++)
2432 {
2433 int length = 0;
2434
2435 for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
2436 {
2437 int u = crr_insn->id;
2438
2439 length++;
2440 gcc_assert (TEST_BIT (sched_nodes, u));
2441 /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
2442 popcount (sched_nodes) == number of insns in ps. */
2443 gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
2444 gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
2445 }
2446
2447 gcc_assert (ps->rows_length[row] == length);
2448 }
2449 }
2450
2451 \f
2452 /* This page implements the algorithm for ordering the nodes of a DDG
2453 for modulo scheduling, activated through the
2454 "int sms_order_nodes (ddg_ptr, int mii, int * result)" API. */
2455
2456 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
2457 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
2458 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
2459 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
2460 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
2461 #define DEPTH(x) (ASAP ((x)))
2462
2463 typedef struct node_order_params * nopa;
2464
2465 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
2466 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
2467 static nopa calculate_order_params (ddg_ptr, int, int *);
2468 static int find_max_asap (ddg_ptr, sbitmap);
2469 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
2470 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
2471
2472 enum sms_direction {BOTTOMUP, TOPDOWN};
2473
2474 struct node_order_params
2475 {
2476 int asap;
2477 int alap;
2478 int height;
2479 };
2480
2481 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1. */
2482 static void
2483 check_nodes_order (int *node_order, int num_nodes)
2484 {
2485 int i;
2486 sbitmap tmp = sbitmap_alloc (num_nodes);
2487
2488 sbitmap_zero (tmp);
2489
2490 if (dump_file)
2491 fprintf (dump_file, "SMS final nodes order: \n");
2492
2493 for (i = 0; i < num_nodes; i++)
2494 {
2495 int u = node_order[i];
2496
2497 if (dump_file)
2498 fprintf (dump_file, "%d ", u);
2499 gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u));
2500
2501 SET_BIT (tmp, u);
2502 }
2503
2504 if (dump_file)
2505 fprintf (dump_file, "\n");
2506
2507 sbitmap_free (tmp);
2508 }
2509
2510 /* Order the nodes of G for scheduling and pass the result in
2511 NODE_ORDER. Also set aux.count of each node to ASAP.
2512 Put maximal ASAP to PMAX_ASAP. Return the recMII for the given DDG. */
2513 static int
2514 sms_order_nodes (ddg_ptr g, int mii, int * node_order, int *pmax_asap)
2515 {
2516 int i;
2517 int rec_mii = 0;
2518 ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
2519
2520 nopa nops = calculate_order_params (g, mii, pmax_asap);
2521
2522 if (dump_file)
2523 print_sccs (dump_file, sccs, g);
2524
2525 order_nodes_of_sccs (sccs, node_order);
2526
2527 if (sccs->num_sccs > 0)
2528 /* First SCC has the largest recurrence_length. */
2529 rec_mii = sccs->sccs[0]->recurrence_length;
2530
2531 /* Save ASAP before destroying node_order_params. */
2532 for (i = 0; i < g->num_nodes; i++)
2533 {
2534 ddg_node_ptr v = &g->nodes[i];
2535 v->aux.count = ASAP (v);
2536 }
2537
2538 free (nops);
2539 free_ddg_all_sccs (sccs);
2540 check_nodes_order (node_order, g->num_nodes);
2541
2542 return rec_mii;
2543 }
2544
2545 static void
2546 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
2547 {
2548 int i, pos = 0;
2549 ddg_ptr g = all_sccs->ddg;
2550 int num_nodes = g->num_nodes;
2551 sbitmap prev_sccs = sbitmap_alloc (num_nodes);
2552 sbitmap on_path = sbitmap_alloc (num_nodes);
2553 sbitmap tmp = sbitmap_alloc (num_nodes);
2554 sbitmap ones = sbitmap_alloc (num_nodes);
2555
2556 sbitmap_zero (prev_sccs);
2557 sbitmap_ones (ones);
2558
2559 /* Perform the node ordering starting from the SCC with the highest recMII.
2560 For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc. */
2561 for (i = 0; i < all_sccs->num_sccs; i++)
2562 {
2563 ddg_scc_ptr scc = all_sccs->sccs[i];
2564
2565 /* Add nodes on paths from previous SCCs to the current SCC. */
2566 find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
2567 sbitmap_a_or_b (tmp, scc->nodes, on_path);
2568
2569 /* Add nodes on paths from the current SCC to previous SCCs. */
2570 find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
2571 sbitmap_a_or_b (tmp, tmp, on_path);
2572
2573 /* Remove nodes of previous SCCs from current extended SCC. */
2574 sbitmap_difference (tmp, tmp, prev_sccs);
2575
2576 pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2577 /* Above call to order_nodes_in_scc updated prev_sccs |= tmp. */
2578 }
2579
2580 /* Handle the remaining nodes that do not belong to any scc. Each call
2581 to order_nodes_in_scc handles a single connected component. */
2582 while (pos < g->num_nodes)
2583 {
2584 sbitmap_difference (tmp, ones, prev_sccs);
2585 pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2586 }
2587 sbitmap_free (prev_sccs);
2588 sbitmap_free (on_path);
2589 sbitmap_free (tmp);
2590 sbitmap_free (ones);
2591 }
2592
2593 /* MII is needed if we consider backarcs (that do not close recursive cycles). */
2594 static struct node_order_params *
2595 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED, int *pmax_asap)
2596 {
2597 int u;
2598 int max_asap;
2599 int num_nodes = g->num_nodes;
2600 ddg_edge_ptr e;
2601 /* Allocate a place to hold ordering params for each node in the DDG. */
2602 nopa node_order_params_arr;
2603
2604 /* Initialize of ASAP/ALAP/HEIGHT to zero. */
2605 node_order_params_arr = (nopa) xcalloc (num_nodes,
2606 sizeof (struct node_order_params));
2607
2608 /* Set the aux pointer of each node to point to its order_params structure. */
2609 for (u = 0; u < num_nodes; u++)
2610 g->nodes[u].aux.info = &node_order_params_arr[u];
2611
2612 /* Disregarding a backarc from each recursive cycle to obtain a DAG,
2613 calculate ASAP, ALAP, mobility, distance, and height for each node
2614 in the dependence (direct acyclic) graph. */
2615
2616 /* We assume that the nodes in the array are in topological order. */
2617
2618 max_asap = 0;
2619 for (u = 0; u < num_nodes; u++)
2620 {
2621 ddg_node_ptr u_node = &g->nodes[u];
2622
2623 ASAP (u_node) = 0;
2624 for (e = u_node->in; e; e = e->next_in)
2625 if (e->distance == 0)
2626 ASAP (u_node) = MAX (ASAP (u_node),
2627 ASAP (e->src) + e->latency);
2628 max_asap = MAX (max_asap, ASAP (u_node));
2629 }
2630
2631 for (u = num_nodes - 1; u > -1; u--)
2632 {
2633 ddg_node_ptr u_node = &g->nodes[u];
2634
2635 ALAP (u_node) = max_asap;
2636 HEIGHT (u_node) = 0;
2637 for (e = u_node->out; e; e = e->next_out)
2638 if (e->distance == 0)
2639 {
2640 ALAP (u_node) = MIN (ALAP (u_node),
2641 ALAP (e->dest) - e->latency);
2642 HEIGHT (u_node) = MAX (HEIGHT (u_node),
2643 HEIGHT (e->dest) + e->latency);
2644 }
2645 }
2646 if (dump_file)
2647 {
2648 fprintf (dump_file, "\nOrder params\n");
2649 for (u = 0; u < num_nodes; u++)
2650 {
2651 ddg_node_ptr u_node = &g->nodes[u];
2652
2653 fprintf (dump_file, "node %d, ASAP: %d, ALAP: %d, HEIGHT: %d\n", u,
2654 ASAP (u_node), ALAP (u_node), HEIGHT (u_node));
2655 }
2656 }
2657
2658 *pmax_asap = max_asap;
2659 return node_order_params_arr;
2660 }
2661
2662 static int
2663 find_max_asap (ddg_ptr g, sbitmap nodes)
2664 {
2665 unsigned int u = 0;
2666 int max_asap = -1;
2667 int result = -1;
2668 sbitmap_iterator sbi;
2669
2670 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2671 {
2672 ddg_node_ptr u_node = &g->nodes[u];
2673
2674 if (max_asap < ASAP (u_node))
2675 {
2676 max_asap = ASAP (u_node);
2677 result = u;
2678 }
2679 }
2680 return result;
2681 }
2682
2683 static int
2684 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
2685 {
2686 unsigned int u = 0;
2687 int max_hv = -1;
2688 int min_mob = INT_MAX;
2689 int result = -1;
2690 sbitmap_iterator sbi;
2691
2692 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2693 {
2694 ddg_node_ptr u_node = &g->nodes[u];
2695
2696 if (max_hv < HEIGHT (u_node))
2697 {
2698 max_hv = HEIGHT (u_node);
2699 min_mob = MOB (u_node);
2700 result = u;
2701 }
2702 else if ((max_hv == HEIGHT (u_node))
2703 && (min_mob > MOB (u_node)))
2704 {
2705 min_mob = MOB (u_node);
2706 result = u;
2707 }
2708 }
2709 return result;
2710 }
2711
2712 static int
2713 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
2714 {
2715 unsigned int u = 0;
2716 int max_dv = -1;
2717 int min_mob = INT_MAX;
2718 int result = -1;
2719 sbitmap_iterator sbi;
2720
2721 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2722 {
2723 ddg_node_ptr u_node = &g->nodes[u];
2724
2725 if (max_dv < DEPTH (u_node))
2726 {
2727 max_dv = DEPTH (u_node);
2728 min_mob = MOB (u_node);
2729 result = u;
2730 }
2731 else if ((max_dv == DEPTH (u_node))
2732 && (min_mob > MOB (u_node)))
2733 {
2734 min_mob = MOB (u_node);
2735 result = u;
2736 }
2737 }
2738 return result;
2739 }
2740
2741 /* Places the nodes of SCC into the NODE_ORDER array starting
2742 at position POS, according to the SMS ordering algorithm.
2743 NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
2744 the NODE_ORDER array, starting from position zero. */
2745 static int
2746 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
2747 int * node_order, int pos)
2748 {
2749 enum sms_direction dir;
2750 int num_nodes = g->num_nodes;
2751 sbitmap workset = sbitmap_alloc (num_nodes);
2752 sbitmap tmp = sbitmap_alloc (num_nodes);
2753 sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
2754 sbitmap predecessors = sbitmap_alloc (num_nodes);
2755 sbitmap successors = sbitmap_alloc (num_nodes);
2756
2757 sbitmap_zero (predecessors);
2758 find_predecessors (predecessors, g, nodes_ordered);
2759
2760 sbitmap_zero (successors);
2761 find_successors (successors, g, nodes_ordered);
2762
2763 sbitmap_zero (tmp);
2764 if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
2765 {
2766 sbitmap_copy (workset, tmp);
2767 dir = BOTTOMUP;
2768 }
2769 else if (sbitmap_a_and_b_cg (tmp, successors, scc))
2770 {
2771 sbitmap_copy (workset, tmp);
2772 dir = TOPDOWN;
2773 }
2774 else
2775 {
2776 int u;
2777
2778 sbitmap_zero (workset);
2779 if ((u = find_max_asap (g, scc)) >= 0)
2780 SET_BIT (workset, u);
2781 dir = BOTTOMUP;
2782 }
2783
2784 sbitmap_zero (zero_bitmap);
2785 while (!sbitmap_equal (workset, zero_bitmap))
2786 {
2787 int v;
2788 ddg_node_ptr v_node;
2789 sbitmap v_node_preds;
2790 sbitmap v_node_succs;
2791
2792 if (dir == TOPDOWN)
2793 {
2794 while (!sbitmap_equal (workset, zero_bitmap))
2795 {
2796 v = find_max_hv_min_mob (g, workset);
2797 v_node = &g->nodes[v];
2798 node_order[pos++] = v;
2799 v_node_succs = NODE_SUCCESSORS (v_node);
2800 sbitmap_a_and_b (tmp, v_node_succs, scc);
2801
2802 /* Don't consider the already ordered successors again. */
2803 sbitmap_difference (tmp, tmp, nodes_ordered);
2804 sbitmap_a_or_b (workset, workset, tmp);
2805 RESET_BIT (workset, v);
2806 SET_BIT (nodes_ordered, v);
2807 }
2808 dir = BOTTOMUP;
2809 sbitmap_zero (predecessors);
2810 find_predecessors (predecessors, g, nodes_ordered);
2811 sbitmap_a_and_b (workset, predecessors, scc);
2812 }
2813 else
2814 {
2815 while (!sbitmap_equal (workset, zero_bitmap))
2816 {
2817 v = find_max_dv_min_mob (g, workset);
2818 v_node = &g->nodes[v];
2819 node_order[pos++] = v;
2820 v_node_preds = NODE_PREDECESSORS (v_node);
2821 sbitmap_a_and_b (tmp, v_node_preds, scc);
2822
2823 /* Don't consider the already ordered predecessors again. */
2824 sbitmap_difference (tmp, tmp, nodes_ordered);
2825 sbitmap_a_or_b (workset, workset, tmp);
2826 RESET_BIT (workset, v);
2827 SET_BIT (nodes_ordered, v);
2828 }
2829 dir = TOPDOWN;
2830 sbitmap_zero (successors);
2831 find_successors (successors, g, nodes_ordered);
2832 sbitmap_a_and_b (workset, successors, scc);
2833 }
2834 }
2835 sbitmap_free (tmp);
2836 sbitmap_free (workset);
2837 sbitmap_free (zero_bitmap);
2838 sbitmap_free (predecessors);
2839 sbitmap_free (successors);
2840 return pos;
2841 }
2842
2843 \f
2844 /* This page contains functions for manipulating partial-schedules during
2845 modulo scheduling. */
2846
2847 /* Create a partial schedule and allocate a memory to hold II rows. */
2848
2849 static partial_schedule_ptr
2850 create_partial_schedule (int ii, ddg_ptr g, int history)
2851 {
2852 partial_schedule_ptr ps = XNEW (struct partial_schedule);
2853 ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
2854 ps->rows_length = (int *) xcalloc (ii, sizeof (int));
2855 ps->reg_moves = NULL;
2856 ps->ii = ii;
2857 ps->history = history;
2858 ps->min_cycle = INT_MAX;
2859 ps->max_cycle = INT_MIN;
2860 ps->g = g;
2861
2862 return ps;
2863 }
2864
2865 /* Free the PS_INSNs in rows array of the given partial schedule.
2866 ??? Consider caching the PS_INSN's. */
2867 static void
2868 free_ps_insns (partial_schedule_ptr ps)
2869 {
2870 int i;
2871
2872 for (i = 0; i < ps->ii; i++)
2873 {
2874 while (ps->rows[i])
2875 {
2876 ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
2877
2878 free (ps->rows[i]);
2879 ps->rows[i] = ps_insn;
2880 }
2881 ps->rows[i] = NULL;
2882 }
2883 }
2884
2885 /* Free all the memory allocated to the partial schedule. */
2886
2887 static void
2888 free_partial_schedule (partial_schedule_ptr ps)
2889 {
2890 ps_reg_move_info *move;
2891 unsigned int i;
2892
2893 if (!ps)
2894 return;
2895
2896 FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
2897 sbitmap_free (move->uses);
2898 VEC_free (ps_reg_move_info, heap, ps->reg_moves);
2899
2900 free_ps_insns (ps);
2901 free (ps->rows);
2902 free (ps->rows_length);
2903 free (ps);
2904 }
2905
2906 /* Clear the rows array with its PS_INSNs, and create a new one with
2907 NEW_II rows. */
2908
2909 static void
2910 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
2911 {
2912 if (!ps)
2913 return;
2914 free_ps_insns (ps);
2915 if (new_ii == ps->ii)
2916 return;
2917 ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
2918 * sizeof (ps_insn_ptr));
2919 memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
2920 ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int));
2921 memset (ps->rows_length, 0, new_ii * sizeof (int));
2922 ps->ii = new_ii;
2923 ps->min_cycle = INT_MAX;
2924 ps->max_cycle = INT_MIN;
2925 }
2926
2927 /* Prints the partial schedule as an ii rows array, for each rows
2928 print the ids of the insns in it. */
2929 void
2930 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
2931 {
2932 int i;
2933
2934 for (i = 0; i < ps->ii; i++)
2935 {
2936 ps_insn_ptr ps_i = ps->rows[i];
2937
2938 fprintf (dump, "\n[ROW %d ]: ", i);
2939 while (ps_i)
2940 {
2941 rtx insn = ps_rtl_insn (ps, ps_i->id);
2942
2943 if (JUMP_P (insn))
2944 fprintf (dump, "%d (branch), ", INSN_UID (insn));
2945 else
2946 fprintf (dump, "%d, ", INSN_UID (insn));
2947
2948 ps_i = ps_i->next_in_row;
2949 }
2950 }
2951 }
2952
2953 /* Creates an object of PS_INSN and initializes it to the given parameters. */
2954 static ps_insn_ptr
2955 create_ps_insn (int id, int cycle)
2956 {
2957 ps_insn_ptr ps_i = XNEW (struct ps_insn);
2958
2959 ps_i->id = id;
2960 ps_i->next_in_row = NULL;
2961 ps_i->prev_in_row = NULL;
2962 ps_i->cycle = cycle;
2963
2964 return ps_i;
2965 }
2966
2967
2968 /* Removes the given PS_INSN from the partial schedule. */
2969 static void
2970 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
2971 {
2972 int row;
2973
2974 gcc_assert (ps && ps_i);
2975
2976 row = SMODULO (ps_i->cycle, ps->ii);
2977 if (! ps_i->prev_in_row)
2978 {
2979 gcc_assert (ps_i == ps->rows[row]);
2980 ps->rows[row] = ps_i->next_in_row;
2981 if (ps->rows[row])
2982 ps->rows[row]->prev_in_row = NULL;
2983 }
2984 else
2985 {
2986 ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
2987 if (ps_i->next_in_row)
2988 ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
2989 }
2990
2991 ps->rows_length[row] -= 1;
2992 free (ps_i);
2993 return;
2994 }
2995
2996 /* Unlike what literature describes for modulo scheduling (which focuses
2997 on VLIW machines) the order of the instructions inside a cycle is
2998 important. Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
2999 where the current instruction should go relative to the already
3000 scheduled instructions in the given cycle. Go over these
3001 instructions and find the first possible column to put it in. */
3002 static bool
3003 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
3004 sbitmap must_precede, sbitmap must_follow)
3005 {
3006 ps_insn_ptr next_ps_i;
3007 ps_insn_ptr first_must_follow = NULL;
3008 ps_insn_ptr last_must_precede = NULL;
3009 ps_insn_ptr last_in_row = NULL;
3010 int row;
3011
3012 if (! ps_i)
3013 return false;
3014
3015 row = SMODULO (ps_i->cycle, ps->ii);
3016
3017 /* Find the first must follow and the last must precede
3018 and insert the node immediately after the must precede
3019 but make sure that it there is no must follow after it. */
3020 for (next_ps_i = ps->rows[row];
3021 next_ps_i;
3022 next_ps_i = next_ps_i->next_in_row)
3023 {
3024 if (must_follow
3025 && TEST_BIT (must_follow, next_ps_i->id)
3026 && ! first_must_follow)
3027 first_must_follow = next_ps_i;
3028 if (must_precede && TEST_BIT (must_precede, next_ps_i->id))
3029 {
3030 /* If we have already met a node that must follow, then
3031 there is no possible column. */
3032 if (first_must_follow)
3033 return false;
3034 else
3035 last_must_precede = next_ps_i;
3036 }
3037 /* The closing branch must be the last in the row. */
3038 if (must_precede
3039 && TEST_BIT (must_precede, next_ps_i->id)
3040 && JUMP_P (ps_rtl_insn (ps, next_ps_i->id)))
3041 return false;
3042
3043 last_in_row = next_ps_i;
3044 }
3045
3046 /* The closing branch is scheduled as well. Make sure there is no
3047 dependent instruction after it as the branch should be the last
3048 instruction in the row. */
3049 if (JUMP_P (ps_rtl_insn (ps, ps_i->id)))
3050 {
3051 if (first_must_follow)
3052 return false;
3053 if (last_in_row)
3054 {
3055 /* Make the branch the last in the row. New instructions
3056 will be inserted at the beginning of the row or after the
3057 last must_precede instruction thus the branch is guaranteed
3058 to remain the last instruction in the row. */
3059 last_in_row->next_in_row = ps_i;
3060 ps_i->prev_in_row = last_in_row;
3061 ps_i->next_in_row = NULL;
3062 }
3063 else
3064 ps->rows[row] = ps_i;
3065 return true;
3066 }
3067
3068 /* Now insert the node after INSERT_AFTER_PSI. */
3069
3070 if (! last_must_precede)
3071 {
3072 ps_i->next_in_row = ps->rows[row];
3073 ps_i->prev_in_row = NULL;
3074 if (ps_i->next_in_row)
3075 ps_i->next_in_row->prev_in_row = ps_i;
3076 ps->rows[row] = ps_i;
3077 }
3078 else
3079 {
3080 ps_i->next_in_row = last_must_precede->next_in_row;
3081 last_must_precede->next_in_row = ps_i;
3082 ps_i->prev_in_row = last_must_precede;
3083 if (ps_i->next_in_row)
3084 ps_i->next_in_row->prev_in_row = ps_i;
3085 }
3086
3087 return true;
3088 }
3089
3090 /* Advances the PS_INSN one column in its current row; returns false
3091 in failure and true in success. Bit N is set in MUST_FOLLOW if
3092 the node with cuid N must be come after the node pointed to by
3093 PS_I when scheduled in the same cycle. */
3094 static int
3095 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
3096 sbitmap must_follow)
3097 {
3098 ps_insn_ptr prev, next;
3099 int row;
3100
3101 if (!ps || !ps_i)
3102 return false;
3103
3104 row = SMODULO (ps_i->cycle, ps->ii);
3105
3106 if (! ps_i->next_in_row)
3107 return false;
3108
3109 /* Check if next_in_row is dependent on ps_i, both having same sched
3110 times (typically ANTI_DEP). If so, ps_i cannot skip over it. */
3111 if (must_follow && TEST_BIT (must_follow, ps_i->next_in_row->id))
3112 return false;
3113
3114 /* Advance PS_I over its next_in_row in the doubly linked list. */
3115 prev = ps_i->prev_in_row;
3116 next = ps_i->next_in_row;
3117
3118 if (ps_i == ps->rows[row])
3119 ps->rows[row] = next;
3120
3121 ps_i->next_in_row = next->next_in_row;
3122
3123 if (next->next_in_row)
3124 next->next_in_row->prev_in_row = ps_i;
3125
3126 next->next_in_row = ps_i;
3127 ps_i->prev_in_row = next;
3128
3129 next->prev_in_row = prev;
3130 if (prev)
3131 prev->next_in_row = next;
3132
3133 return true;
3134 }
3135
3136 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
3137 Returns 0 if this is not possible and a PS_INSN otherwise. Bit N is
3138 set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come
3139 before/after (respectively) the node pointed to by PS_I when scheduled
3140 in the same cycle. */
3141 static ps_insn_ptr
3142 add_node_to_ps (partial_schedule_ptr ps, int id, int cycle,
3143 sbitmap must_precede, sbitmap must_follow)
3144 {
3145 ps_insn_ptr ps_i;
3146 int row = SMODULO (cycle, ps->ii);
3147
3148 if (ps->rows_length[row] >= issue_rate)
3149 return NULL;
3150
3151 ps_i = create_ps_insn (id, cycle);
3152
3153 /* Finds and inserts PS_I according to MUST_FOLLOW and
3154 MUST_PRECEDE. */
3155 if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
3156 {
3157 free (ps_i);
3158 return NULL;
3159 }
3160
3161 ps->rows_length[row] += 1;
3162 return ps_i;
3163 }
3164
3165 /* Advance time one cycle. Assumes DFA is being used. */
3166 static void
3167 advance_one_cycle (void)
3168 {
3169 if (targetm.sched.dfa_pre_cycle_insn)
3170 state_transition (curr_state,
3171 targetm.sched.dfa_pre_cycle_insn ());
3172
3173 state_transition (curr_state, NULL);
3174
3175 if (targetm.sched.dfa_post_cycle_insn)
3176 state_transition (curr_state,
3177 targetm.sched.dfa_post_cycle_insn ());
3178 }
3179
3180
3181
3182 /* Checks if PS has resource conflicts according to DFA, starting from
3183 FROM cycle to TO cycle; returns true if there are conflicts and false
3184 if there are no conflicts. Assumes DFA is being used. */
3185 static int
3186 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
3187 {
3188 int cycle;
3189
3190 state_reset (curr_state);
3191
3192 for (cycle = from; cycle <= to; cycle++)
3193 {
3194 ps_insn_ptr crr_insn;
3195 /* Holds the remaining issue slots in the current row. */
3196 int can_issue_more = issue_rate;
3197
3198 /* Walk through the DFA for the current row. */
3199 for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
3200 crr_insn;
3201 crr_insn = crr_insn->next_in_row)
3202 {
3203 rtx insn = ps_rtl_insn (ps, crr_insn->id);
3204
3205 if (!NONDEBUG_INSN_P (insn))
3206 continue;
3207
3208 /* Check if there is room for the current insn. */
3209 if (!can_issue_more || state_dead_lock_p (curr_state))
3210 return true;
3211
3212 /* Update the DFA state and return with failure if the DFA found
3213 resource conflicts. */
3214 if (state_transition (curr_state, insn) >= 0)
3215 return true;
3216
3217 if (targetm.sched.variable_issue)
3218 can_issue_more =
3219 targetm.sched.variable_issue (sched_dump, sched_verbose,
3220 insn, can_issue_more);
3221 /* A naked CLOBBER or USE generates no instruction, so don't
3222 let them consume issue slots. */
3223 else if (GET_CODE (PATTERN (insn)) != USE
3224 && GET_CODE (PATTERN (insn)) != CLOBBER)
3225 can_issue_more--;
3226 }
3227
3228 /* Advance the DFA to the next cycle. */
3229 advance_one_cycle ();
3230 }
3231 return false;
3232 }
3233
3234 /* Checks if the given node causes resource conflicts when added to PS at
3235 cycle C. If not the node is added to PS and returned; otherwise zero
3236 is returned. Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with
3237 cuid N must be come before/after (respectively) the node pointed to by
3238 PS_I when scheduled in the same cycle. */
3239 ps_insn_ptr
3240 ps_add_node_check_conflicts (partial_schedule_ptr ps, int n,
3241 int c, sbitmap must_precede,
3242 sbitmap must_follow)
3243 {
3244 int has_conflicts = 0;
3245 ps_insn_ptr ps_i;
3246
3247 /* First add the node to the PS, if this succeeds check for
3248 conflicts, trying different issue slots in the same row. */
3249 if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
3250 return NULL; /* Failed to insert the node at the given cycle. */
3251
3252 has_conflicts = ps_has_conflicts (ps, c, c)
3253 || (ps->history > 0
3254 && ps_has_conflicts (ps,
3255 c - ps->history,
3256 c + ps->history));
3257
3258 /* Try different issue slots to find one that the given node can be
3259 scheduled in without conflicts. */
3260 while (has_conflicts)
3261 {
3262 if (! ps_insn_advance_column (ps, ps_i, must_follow))
3263 break;
3264 has_conflicts = ps_has_conflicts (ps, c, c)
3265 || (ps->history > 0
3266 && ps_has_conflicts (ps,
3267 c - ps->history,
3268 c + ps->history));
3269 }
3270
3271 if (has_conflicts)
3272 {
3273 remove_node_from_ps (ps, ps_i);
3274 return NULL;
3275 }
3276
3277 ps->min_cycle = MIN (ps->min_cycle, c);
3278 ps->max_cycle = MAX (ps->max_cycle, c);
3279 return ps_i;
3280 }
3281
3282 /* Calculate the stage count of the partial schedule PS. The calculation
3283 takes into account the rotation amount passed in ROTATION_AMOUNT. */
3284 int
3285 calculate_stage_count (partial_schedule_ptr ps, int rotation_amount)
3286 {
3287 int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount;
3288 int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount;
3289 int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii);
3290
3291 /* The calculation of stage count is done adding the number of stages
3292 before cycle zero and after cycle zero. */
3293 stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii);
3294
3295 return stage_count;
3296 }
3297
3298 /* Rotate the rows of PS such that insns scheduled at time
3299 START_CYCLE will appear in row 0. Updates max/min_cycles. */
3300 void
3301 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
3302 {
3303 int i, row, backward_rotates;
3304 int last_row = ps->ii - 1;
3305
3306 if (start_cycle == 0)
3307 return;
3308
3309 backward_rotates = SMODULO (start_cycle, ps->ii);
3310
3311 /* Revisit later and optimize this into a single loop. */
3312 for (i = 0; i < backward_rotates; i++)
3313 {
3314 ps_insn_ptr first_row = ps->rows[0];
3315 int first_row_length = ps->rows_length[0];
3316
3317 for (row = 0; row < last_row; row++)
3318 {
3319 ps->rows[row] = ps->rows[row + 1];
3320 ps->rows_length[row] = ps->rows_length[row + 1];
3321 }
3322
3323 ps->rows[last_row] = first_row;
3324 ps->rows_length[last_row] = first_row_length;
3325 }
3326
3327 ps->max_cycle -= start_cycle;
3328 ps->min_cycle -= start_cycle;
3329 }
3330
3331 #endif /* INSN_SCHEDULING */
3332 \f
3333 static bool
3334 gate_handle_sms (void)
3335 {
3336 return (optimize > 0 && flag_modulo_sched);
3337 }
3338
3339
3340 /* Run instruction scheduler. */
3341 /* Perform SMS module scheduling. */
3342 static unsigned int
3343 rest_of_handle_sms (void)
3344 {
3345 #ifdef INSN_SCHEDULING
3346 basic_block bb;
3347
3348 /* Collect loop information to be used in SMS. */
3349 cfg_layout_initialize (0);
3350 sms_schedule ();
3351
3352 /* Update the life information, because we add pseudos. */
3353 max_regno = max_reg_num ();
3354
3355 /* Finalize layout changes. */
3356 FOR_EACH_BB (bb)
3357 if (bb->next_bb != EXIT_BLOCK_PTR)
3358 bb->aux = bb->next_bb;
3359 free_dominance_info (CDI_DOMINATORS);
3360 cfg_layout_finalize ();
3361 #endif /* INSN_SCHEDULING */
3362 return 0;
3363 }
3364
3365 struct rtl_opt_pass pass_sms =
3366 {
3367 {
3368 RTL_PASS,
3369 "sms", /* name */
3370 gate_handle_sms, /* gate */
3371 rest_of_handle_sms, /* execute */
3372 NULL, /* sub */
3373 NULL, /* next */
3374 0, /* static_pass_number */
3375 TV_SMS, /* tv_id */
3376 0, /* properties_required */
3377 0, /* properties_provided */
3378 0, /* properties_destroyed */
3379 0, /* todo_flags_start */
3380 TODO_df_finish
3381 | TODO_verify_flow
3382 | TODO_verify_rtl_sharing
3383 | TODO_ggc_collect /* todo_flags_finish */
3384 }
3385 };