OSDN Git Service

2007-09-26 Vincent Celier <celier@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
1 /* Swing Modulo Scheduling implementation.
2    Copyright (C) 2004, 2005, 2006, 2007
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 "toplev.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 "toplev.h"
38 #include "recog.h"
39 #include "sched-int.h"
40 #include "target.h"
41 #include "cfglayout.h"
42 #include "cfgloop.h"
43 #include "cfghooks.h"
44 #include "expr.h"
45 #include "params.h"
46 #include "gcov-io.h"
47 #include "ddg.h"
48 #include "timevar.h"
49 #include "tree-pass.h"
50 #include "dbgcnt.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 PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
120                              + 1 + (ps)->ii - 1) / (ps)->ii)
121
122 /* A single instruction in the partial schedule.  */
123 struct ps_insn
124 {
125   /* The corresponding DDG_NODE.  */
126   ddg_node_ptr node;
127
128   /* The (absolute) cycle in which the PS instruction is scheduled.
129      Same as SCHED_TIME (node).  */
130   int cycle;
131
132   /* The next/prev PS_INSN in the same row.  */
133   ps_insn_ptr next_in_row,
134               prev_in_row;
135
136   /* The number of nodes in the same row that come after this node.  */
137   int row_rest_count;
138 };
139
140 /* Holds the partial schedule as an array of II rows.  Each entry of the
141    array points to a linked list of PS_INSNs, which represents the
142    instructions that are scheduled for that row.  */
143 struct partial_schedule
144 {
145   int ii;       /* Number of rows in the partial schedule.  */
146   int history;  /* Threshold for conflict checking using DFA.  */
147
148   /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii).  */
149   ps_insn_ptr *rows;
150
151   /* The earliest absolute cycle of an insn in the partial schedule.  */
152   int min_cycle;
153
154   /* The latest absolute cycle of an insn in the partial schedule.  */
155   int max_cycle;
156
157   ddg_ptr g;    /* The DDG of the insns in the partial schedule.  */
158 };
159
160 /* We use this to record all the register replacements we do in
161    the kernel so we can undo SMS if it is not profitable.  */
162 struct undo_replace_buff_elem
163 {
164   rtx insn;
165   rtx orig_reg;
166   rtx new_reg;
167   struct undo_replace_buff_elem *next;
168 };
169
170
171   
172 static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
173 static void free_partial_schedule (partial_schedule_ptr);
174 static void reset_partial_schedule (partial_schedule_ptr, int new_ii);
175 void print_partial_schedule (partial_schedule_ptr, FILE *);
176 static void verify_partial_schedule (partial_schedule_ptr, sbitmap);
177 static ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
178                                                 ddg_node_ptr node, int cycle,
179                                                 sbitmap must_precede,
180                                                 sbitmap must_follow);
181 static void rotate_partial_schedule (partial_schedule_ptr, int);
182 void set_row_column_for_ps (partial_schedule_ptr);
183 static void ps_insert_empty_row (partial_schedule_ptr, int, sbitmap);
184 static int compute_split_row (sbitmap, int, int, int, ddg_node_ptr);
185
186 \f
187 /* This page defines constants and structures for the modulo scheduling
188    driver.  */
189
190 /* As in haifa-sched.c:  */
191 /* issue_rate is the number of insns that can be scheduled in the same
192    machine cycle.  It can be defined in the config/mach/mach.h file,
193    otherwise we set it to 1.  */
194
195 static int issue_rate;
196
197 static int sms_order_nodes (ddg_ptr, int, int * result);
198 static void set_node_sched_params (ddg_ptr);
199 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *);
200 static void permute_partial_schedule (partial_schedule_ptr ps, rtx last);
201 static void generate_prolog_epilog (partial_schedule_ptr, struct loop *loop,
202                                     rtx, rtx);
203 static void duplicate_insns_of_cycles (partial_schedule_ptr ps,
204                                        int from_stage, int to_stage,
205                                        int is_prolog, rtx count_reg);
206
207 #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
208 #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
209 #define SCHED_FIRST_REG_MOVE(x) \
210         (((node_sched_params_ptr)(x)->aux.info)->first_reg_move)
211 #define SCHED_NREG_MOVES(x) \
212         (((node_sched_params_ptr)(x)->aux.info)->nreg_moves)
213 #define SCHED_ROW(x) (((node_sched_params_ptr)(x)->aux.info)->row)
214 #define SCHED_STAGE(x) (((node_sched_params_ptr)(x)->aux.info)->stage)
215 #define SCHED_COLUMN(x) (((node_sched_params_ptr)(x)->aux.info)->column)
216
217 /* The scheduling parameters held for each node.  */
218 typedef struct node_sched_params
219 {
220   int asap;     /* A lower-bound on the absolute scheduling cycle.  */
221   int time;     /* The absolute scheduling cycle (time >= asap).  */
222
223   /* The following field (first_reg_move) is a pointer to the first
224      register-move instruction added to handle the modulo-variable-expansion
225      of the register defined by this node.  This register-move copies the
226      original register defined by the node.  */
227   rtx first_reg_move;
228
229   /* The number of register-move instructions added, immediately preceding
230      first_reg_move.  */
231   int nreg_moves;
232
233   int row;    /* Holds time % ii.  */
234   int stage;  /* Holds time / ii.  */
235
236   /* The column of a node inside the ps.  If nodes u, v are on the same row,
237      u will precede v if column (u) < column (v).  */
238   int column;
239 } *node_sched_params_ptr;
240
241 \f
242 /* The following three functions are copied from the current scheduler
243    code in order to use sched_analyze() for computing the dependencies.
244    They are used when initializing the sched_info structure.  */
245 static const char *
246 sms_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
247 {
248   static char tmp[80];
249
250   sprintf (tmp, "i%4d", INSN_UID (insn));
251   return tmp;
252 }
253
254 static void
255 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
256                                regset cond_exec ATTRIBUTE_UNUSED,
257                                regset used ATTRIBUTE_UNUSED,
258                                regset set ATTRIBUTE_UNUSED)
259 {
260 }
261
262 static struct sched_info sms_sched_info =
263 {
264   NULL,
265   NULL,
266   NULL,
267   NULL,
268   NULL,
269   sms_print_insn,
270   NULL,
271   compute_jump_reg_dependencies,
272   NULL, NULL,
273   NULL, NULL,
274   0, 0, 0,
275
276   NULL, NULL, NULL, NULL, NULL,
277   0
278 };
279
280
281 /* Given HEAD and TAIL which are the first and last insns in a loop;
282    return the register which controls the loop.  Return zero if it has
283    more than one occurrence in the loop besides the control part or the
284    do-loop pattern is not of the form we expect.  */
285 static rtx
286 doloop_register_get (rtx head ATTRIBUTE_UNUSED, rtx tail ATTRIBUTE_UNUSED)
287 {
288 #ifdef HAVE_doloop_end
289   rtx reg, condition, insn, first_insn_not_to_check;
290
291   if (!JUMP_P (tail))
292     return NULL_RTX;
293
294   /* TODO: Free SMS's dependence on doloop_condition_get.  */
295   condition = doloop_condition_get (tail);
296   if (! condition)
297     return NULL_RTX;
298
299   if (REG_P (XEXP (condition, 0)))
300     reg = XEXP (condition, 0);
301   else if (GET_CODE (XEXP (condition, 0)) == PLUS
302            && REG_P (XEXP (XEXP (condition, 0), 0)))
303     reg = XEXP (XEXP (condition, 0), 0);
304   else
305     gcc_unreachable ();
306
307   /* Check that the COUNT_REG has no other occurrences in the loop
308      until the decrement.  We assume the control part consists of
309      either a single (parallel) branch-on-count or a (non-parallel)
310      branch immediately preceded by a single (decrement) insn.  */
311   first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail
312                              : PREV_INSN (tail));
313
314   for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
315     if (reg_mentioned_p (reg, insn))
316       {
317         if (dump_file)
318         {
319           fprintf (dump_file, "SMS count_reg found ");
320           print_rtl_single (dump_file, reg);
321           fprintf (dump_file, " outside control in insn:\n");
322           print_rtl_single (dump_file, insn);
323         }
324
325         return NULL_RTX;
326       }
327
328   return reg;
329 #else
330   return NULL_RTX;
331 #endif
332 }
333
334 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
335    that the number of iterations is a compile-time constant.  If so,
336    return the rtx that sets COUNT_REG to a constant, and set COUNT to
337    this constant.  Otherwise return 0.  */
338 static rtx
339 const_iteration_count (rtx count_reg, basic_block pre_header,
340                        HOST_WIDEST_INT * count)
341 {
342   rtx insn;
343   rtx head, tail;
344
345   if (! pre_header)
346     return NULL_RTX;
347
348   get_ebb_head_tail (pre_header, pre_header, &head, &tail);
349
350   for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
351     if (INSN_P (insn) && single_set (insn) &&
352         rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
353       {
354         rtx pat = single_set (insn);
355
356         if (GET_CODE (SET_SRC (pat)) == CONST_INT)
357           {
358             *count = INTVAL (SET_SRC (pat));
359             return insn;
360           }
361
362         return NULL_RTX;
363       }
364
365   return NULL_RTX;
366 }
367
368 /* A very simple resource-based lower bound on the initiation interval.
369    ??? Improve the accuracy of this bound by considering the
370    utilization of various units.  */
371 static int
372 res_MII (ddg_ptr g)
373 {
374   if (targetm.sched.sms_res_mii)
375     return targetm.sched.sms_res_mii (g); 
376   
377   return (g->num_nodes / issue_rate);
378 }
379
380
381 /* Points to the array that contains the sched data for each node.  */
382 static node_sched_params_ptr node_sched_params;
383
384 /* Allocate sched_params for each node and initialize it.  Assumes that
385    the aux field of each node contain the asap bound (computed earlier),
386    and copies it into the sched_params field.  */
387 static void
388 set_node_sched_params (ddg_ptr g)
389 {
390   int i;
391
392   /* Allocate for each node in the DDG a place to hold the "sched_data".  */
393   /* Initialize ASAP/ALAP/HIGHT to zero.  */
394   node_sched_params = (node_sched_params_ptr)
395                        xcalloc (g->num_nodes,
396                                 sizeof (struct node_sched_params));
397
398   /* Set the pointer of the general data of the node to point to the
399      appropriate sched_params structure.  */
400   for (i = 0; i < g->num_nodes; i++)
401     {
402       /* Watch out for aliasing problems?  */
403       node_sched_params[i].asap = g->nodes[i].aux.count;
404       g->nodes[i].aux.info = &node_sched_params[i];
405     }
406 }
407
408 static void
409 print_node_sched_params (FILE *file, int num_nodes, ddg_ptr g)
410 {
411   int i;
412
413   if (! file)
414     return;
415   for (i = 0; i < num_nodes; i++)
416     {
417       node_sched_params_ptr nsp = &node_sched_params[i];
418       rtx reg_move = nsp->first_reg_move;
419       int j;
420
421       fprintf (file, "Node = %d; INSN = %d\n", i,
422                (INSN_UID (g->nodes[i].insn)));
423       fprintf (file, " asap = %d:\n", nsp->asap);
424       fprintf (file, " time = %d:\n", nsp->time);
425       fprintf (file, " nreg_moves = %d:\n", nsp->nreg_moves);
426       for (j = 0; j < nsp->nreg_moves; j++)
427         {
428           fprintf (file, " reg_move = ");
429           print_rtl_single (file, reg_move);
430           reg_move = PREV_INSN (reg_move);
431         }
432     }
433 }
434
435 /*
436    Breaking intra-loop register anti-dependences:
437    Each intra-loop register anti-dependence implies a cross-iteration true
438    dependence of distance 1. Therefore, we can remove such false dependencies
439    and figure out if the partial schedule broke them by checking if (for a
440    true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
441    if so generate a register move.   The number of such moves is equal to:
442               SCHED_TIME (use) - SCHED_TIME (def)       { 0 broken
443    nreg_moves = ----------------------------------- + 1 - {   dependence.
444                             ii                          { 1 if not.
445 */
446 static struct undo_replace_buff_elem *
447 generate_reg_moves (partial_schedule_ptr ps, bool rescan)
448 {
449   ddg_ptr g = ps->g;
450   int ii = ps->ii;
451   int i;
452   struct undo_replace_buff_elem *reg_move_replaces = NULL;
453
454   for (i = 0; i < g->num_nodes; i++)
455     {
456       ddg_node_ptr u = &g->nodes[i];
457       ddg_edge_ptr e;
458       int nreg_moves = 0, i_reg_move;
459       sbitmap *uses_of_defs;
460       rtx last_reg_move;
461       rtx prev_reg, old_reg;
462
463       /* Compute the number of reg_moves needed for u, by looking at life
464          ranges started at u (excluding self-loops).  */
465       for (e = u->out; e; e = e->next_out)
466         if (e->type == TRUE_DEP && e->dest != e->src)
467           {
468             int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
469
470             if (e->distance == 1)
471               nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
472
473             /* If dest precedes src in the schedule of the kernel, then dest
474                will read before src writes and we can save one reg_copy.  */
475             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
476                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
477               nreg_moves4e--;
478
479             nreg_moves = MAX (nreg_moves, nreg_moves4e);
480           }
481
482       if (nreg_moves == 0)
483         continue;
484
485       /* Every use of the register defined by node may require a different
486          copy of this register, depending on the time the use is scheduled.
487          Set a bitmap vector, telling which nodes use each copy of this
488          register.  */
489       uses_of_defs = sbitmap_vector_alloc (nreg_moves, g->num_nodes);
490       sbitmap_vector_zero (uses_of_defs, nreg_moves);
491       for (e = u->out; e; e = e->next_out)
492         if (e->type == TRUE_DEP && e->dest != e->src)
493           {
494             int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
495
496             if (e->distance == 1)
497               dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
498
499             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
500                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
501               dest_copy--;
502
503             if (dest_copy)
504               SET_BIT (uses_of_defs[dest_copy - 1], e->dest->cuid);
505           }
506
507       /* Now generate the reg_moves, attaching relevant uses to them.  */
508       SCHED_NREG_MOVES (u) = nreg_moves;
509       old_reg = prev_reg = copy_rtx (SET_DEST (single_set (u->insn)));
510       last_reg_move = u->insn;
511
512       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
513         {
514           unsigned int i_use = 0;
515           rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
516           rtx reg_move = gen_move_insn (new_reg, prev_reg);
517           sbitmap_iterator sbi;
518
519           add_insn_before (reg_move, last_reg_move, NULL);
520           last_reg_move = reg_move;
521
522           if (!SCHED_FIRST_REG_MOVE (u))
523             SCHED_FIRST_REG_MOVE (u) = reg_move;
524
525           EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use, sbi)
526             {
527               struct undo_replace_buff_elem *rep;
528
529               rep = (struct undo_replace_buff_elem *)
530                     xcalloc (1, sizeof (struct undo_replace_buff_elem));
531               rep->insn = g->nodes[i_use].insn;
532               rep->orig_reg = old_reg;
533               rep->new_reg = new_reg;
534
535               if (! reg_move_replaces)
536                 reg_move_replaces = rep;
537               else
538                 {
539                   rep->next = reg_move_replaces;
540                   reg_move_replaces = rep;
541                 }
542
543               replace_rtx (g->nodes[i_use].insn, old_reg, new_reg);
544               if (rescan)
545                 df_insn_rescan (g->nodes[i_use].insn);
546             }
547
548           prev_reg = new_reg;
549         }
550       sbitmap_vector_free (uses_of_defs);
551     }
552   return reg_move_replaces;
553 }
554
555 /* Free memory allocated for the undo buffer.  */
556 static void
557 free_undo_replace_buff (struct undo_replace_buff_elem *reg_move_replaces)
558 {
559
560   while (reg_move_replaces)
561     {
562       struct undo_replace_buff_elem *rep = reg_move_replaces;
563
564       reg_move_replaces = reg_move_replaces->next;
565       free (rep);
566     }
567 }
568
569 /* Bump the SCHED_TIMEs of all nodes to start from zero.  Set the values
570    of SCHED_ROW and SCHED_STAGE.  */
571 static void
572 normalize_sched_times (partial_schedule_ptr ps)
573 {
574   int row;
575   int amount = PS_MIN_CYCLE (ps);
576   int ii = ps->ii;
577   ps_insn_ptr crr_insn;
578
579   for (row = 0; row < ii; row++)
580     for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
581       {
582         ddg_node_ptr u = crr_insn->node;
583         int normalized_time = SCHED_TIME (u) - amount;
584
585         if (dump_file)
586           fprintf (dump_file, "crr_insn->node=%d, crr_insn->cycle=%d,\
587                    min_cycle=%d\n", crr_insn->node->cuid, SCHED_TIME
588                    (u), ps->min_cycle);
589         gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
590         gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
591         SCHED_TIME (u) = normalized_time;
592         SCHED_ROW (u) = normalized_time % ii;
593         SCHED_STAGE (u) = normalized_time / ii;
594       }
595 }
596
597 /* Set SCHED_COLUMN of each node according to its position in PS.  */
598 static void
599 set_columns_for_ps (partial_schedule_ptr ps)
600 {
601   int row;
602
603   for (row = 0; row < ps->ii; row++)
604     {
605       ps_insn_ptr cur_insn = ps->rows[row];
606       int column = 0;
607
608       for (; cur_insn; cur_insn = cur_insn->next_in_row)
609         SCHED_COLUMN (cur_insn->node) = column++;
610     }
611 }
612
613 /* Permute the insns according to their order in PS, from row 0 to
614    row ii-1, and position them right before LAST.  This schedules
615    the insns of the loop kernel.  */
616 static void
617 permute_partial_schedule (partial_schedule_ptr ps, rtx last)
618 {
619   int ii = ps->ii;
620   int row;
621   ps_insn_ptr ps_ij;
622
623   for (row = 0; row < ii ; row++)
624     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
625       if (PREV_INSN (last) != ps_ij->node->insn)
626         reorder_insns_nobb (ps_ij->node->first_note, ps_ij->node->insn,
627                             PREV_INSN (last));
628 }
629
630 static void
631 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
632                            int to_stage, int for_prolog, rtx count_reg)
633 {
634   int row;
635   ps_insn_ptr ps_ij;
636
637   for (row = 0; row < ps->ii; row++)
638     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
639       {
640         ddg_node_ptr u_node = ps_ij->node;
641         int j, i_reg_moves;
642         rtx reg_move = NULL_RTX;
643
644         /* Do not duplicate any insn which refers to count_reg as it
645            belongs to the control part.
646            TODO: This should be done by analyzing the control part of
647            the loop.  */
648         if (reg_mentioned_p (count_reg, u_node->insn))
649           continue;
650
651         if (for_prolog)
652           {
653             /* SCHED_STAGE (u_node) >= from_stage == 0.  Generate increasing
654                number of reg_moves starting with the second occurrence of
655                u_node, which is generated if its SCHED_STAGE <= to_stage.  */
656             i_reg_moves = to_stage - SCHED_STAGE (u_node) + 1;
657             i_reg_moves = MAX (i_reg_moves, 0);
658             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
659
660             /* The reg_moves start from the *first* reg_move backwards.  */
661             if (i_reg_moves)
662               {
663                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
664                 for (j = 1; j < i_reg_moves; j++)
665                   reg_move = PREV_INSN (reg_move);
666               }
667           }
668         else /* It's for the epilog.  */
669           {
670             /* SCHED_STAGE (u_node) <= to_stage.  Generate all reg_moves,
671                starting to decrease one stage after u_node no longer occurs;
672                that is, generate all reg_moves until
673                SCHED_STAGE (u_node) == from_stage - 1.  */
674             i_reg_moves = SCHED_NREG_MOVES (u_node)
675                        - (from_stage - SCHED_STAGE (u_node) - 1);
676             i_reg_moves = MAX (i_reg_moves, 0);
677             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
678
679             /* The reg_moves start from the *last* reg_move forwards.  */
680             if (i_reg_moves)
681               {
682                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
683                 for (j = 1; j < SCHED_NREG_MOVES (u_node); j++)
684                   reg_move = PREV_INSN (reg_move);
685               }
686           }
687
688         for (j = 0; j < i_reg_moves; j++, reg_move = NEXT_INSN (reg_move))
689           emit_insn (copy_rtx (PATTERN (reg_move)));
690         if (SCHED_STAGE (u_node) >= from_stage
691             && SCHED_STAGE (u_node) <= to_stage)
692           duplicate_insn_chain (u_node->first_note, u_node->insn);
693       }
694 }
695
696
697 /* Generate the instructions (including reg_moves) for prolog & epilog.  */
698 static void
699 generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
700                         rtx count_reg, rtx count_init)
701 {
702   int i;
703   int last_stage = PS_STAGE_COUNT (ps) - 1;
704   edge e;
705   
706   /* Generate the prolog, inserting its insns on the loop-entry edge.  */
707   start_sequence ();
708
709   if (!count_init)
710     {
711       /* Generate instructions at the beginning of the prolog to
712          adjust the loop count by STAGE_COUNT.  If loop count is constant
713          (count_init), this constant is adjusted by STAGE_COUNT in
714          generate_prolog_epilog function.  */
715       rtx sub_reg = NULL_RTX;
716
717       sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS,
718                                      count_reg, GEN_INT (last_stage),
719                                      count_reg, 1, OPTAB_DIRECT);
720       gcc_assert (REG_P (sub_reg));
721       if (REGNO (sub_reg) != REGNO (count_reg))
722         emit_move_insn (count_reg, sub_reg);
723     }
724
725   for (i = 0; i < last_stage; i++)
726     duplicate_insns_of_cycles (ps, 0, i, 1, count_reg);
727   
728   /* Put the prolog on the entry edge.  */
729   e = loop_preheader_edge (loop);
730   split_edge_and_insert (e, get_insns ());
731
732   end_sequence ();
733
734   /* Generate the epilog, inserting its insns on the loop-exit edge.  */
735   start_sequence ();
736
737   for (i = 0; i < last_stage; i++)
738     duplicate_insns_of_cycles (ps, i + 1, last_stage, 0, count_reg);
739   
740   /* Put the epilogue on the exit edge.  */
741   gcc_assert (single_exit (loop));
742   e = single_exit (loop);
743   split_edge_and_insert (e, get_insns ());
744   end_sequence ();
745 }
746
747 /* Return true if all the BBs of the loop are empty except the
748    loop header.  */
749 static bool
750 loop_single_full_bb_p (struct loop *loop)
751 {
752   unsigned i;
753   basic_block *bbs = get_loop_body (loop);
754
755   for (i = 0; i < loop->num_nodes ; i++)
756     {
757       rtx head, tail;
758       bool empty_bb = true;
759
760       if (bbs[i] == loop->header)
761         continue;
762
763       /* Make sure that basic blocks other than the header
764          have only notes labels or jumps.  */
765       get_ebb_head_tail (bbs[i], bbs[i], &head, &tail);
766       for (; head != NEXT_INSN (tail); head = NEXT_INSN (head))
767         {
768           if (NOTE_P (head) || LABEL_P (head)
769               || (INSN_P (head) && JUMP_P (head)))
770             continue;
771           empty_bb = false;
772           break;
773         }
774
775       if (! empty_bb)
776         {
777           free (bbs);
778           return false;
779         }
780     }
781   free (bbs);
782   return true;
783 }
784
785 /* A simple loop from SMS point of view; it is a loop that is composed of
786    either a single basic block or two BBs - a header and a latch.  */
787 #define SIMPLE_SMS_LOOP_P(loop) ((loop->num_nodes < 3 )                     \
788                                   && (EDGE_COUNT (loop->latch->preds) == 1) \
789                                   && (EDGE_COUNT (loop->latch->succs) == 1))
790
791 /* Return true if the loop is in its canonical form and false if not.
792    i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit.  */
793 static bool
794 loop_canon_p (struct loop *loop)
795 {
796
797   if (loop->inner || !loop_outer (loop))
798     return false;
799
800   if (!single_exit (loop))
801     {
802       if (dump_file)
803         {
804           rtx insn = BB_END (loop->header);
805  
806           fprintf (dump_file, "SMS loop many exits ");
807                   fprintf (dump_file, " %s %d (file, line)\n",
808                            insn_file (insn), insn_line (insn));
809         }
810       return false;
811     }
812
813   if (! SIMPLE_SMS_LOOP_P (loop) && ! loop_single_full_bb_p (loop))
814     {
815       if (dump_file)
816         {
817           rtx insn = BB_END (loop->header);
818  
819           fprintf (dump_file, "SMS loop many BBs. ");
820           fprintf (dump_file, " %s %d (file, line)\n",
821                    insn_file (insn), insn_line (insn));
822         }
823       return false;
824     }
825
826     return true;
827 }
828
829 /* If there are more than one entry for the loop,
830    make it one by splitting the first entry edge and
831    redirecting the others to the new BB.  */
832 static void
833 canon_loop (struct loop *loop)
834 {
835   edge e;
836   edge_iterator i;
837
838   /* Avoid annoying special cases of edges going to exit
839      block.  */
840   FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
841     if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
842       split_edge (e);
843
844   if (loop->latch == loop->header
845       || EDGE_COUNT (loop->latch->succs) > 1)
846     {
847       FOR_EACH_EDGE (e, i, loop->header->preds)
848         if (e->src == loop->latch)
849           break;
850       split_edge (e);
851     }
852 }
853
854 /* Probability in % that the sms-ed loop rolls enough so that optimized
855    version may be entered.  Just a guess.  */
856 #define PROB_SMS_ENOUGH_ITERATIONS 80
857
858 /* Used to calculate the upper bound of ii.  */
859 #define MAXII_FACTOR 2
860
861 /* Main entry point, perform SMS scheduling on the loops of the function
862    that consist of single basic blocks.  */
863 static void
864 sms_schedule (void)
865 {
866   rtx insn;
867   ddg_ptr *g_arr, g;
868   int * node_order;
869   int maxii;
870   loop_iterator li;
871   partial_schedule_ptr ps;
872   basic_block bb = NULL;
873   struct loop *loop;
874   basic_block condition_bb = NULL;
875   edge latch_edge;
876   gcov_type trip_count = 0;
877
878   loop_optimizer_init (LOOPS_HAVE_PREHEADERS
879                        | LOOPS_HAVE_RECORDED_EXITS);
880   if (number_of_loops () <= 1)
881     {
882       loop_optimizer_finalize ();
883       return;  /* There are no loops to schedule.  */
884     }
885
886   /* Initialize issue_rate.  */
887   if (targetm.sched.issue_rate)
888     {
889       int temp = reload_completed;
890
891       reload_completed = 1;
892       issue_rate = targetm.sched.issue_rate ();
893       reload_completed = temp;
894     }
895   else
896     issue_rate = 1;
897
898   /* Initialize the scheduler.  */
899   current_sched_info = &sms_sched_info;
900
901   /* Init Data Flow analysis, to be used in interloop dep calculation.  */
902   df_set_flags (DF_LR_RUN_DCE);
903   df_rd_add_problem ();
904   df_note_add_problem ();
905   df_chain_add_problem (DF_DU_CHAIN);
906   df_analyze ();
907   regstat_compute_calls_crossed ();
908   sched_init ();
909
910   /* Allocate memory to hold the DDG array one entry for each loop.
911      We use loop->num as index into this array.  */
912   g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
913
914   /* Build DDGs for all the relevant loops and hold them in G_ARR
915      indexed by the loop index.  */
916   FOR_EACH_LOOP (li, loop, 0)
917     {
918       rtx head, tail;
919       rtx count_reg;
920
921       /* For debugging.  */
922       if (dbg_cnt (sms_sched_loop) == false)
923         {
924           if (dump_file)
925             fprintf (dump_file, "SMS reached max limit... \n");
926
927           break;
928         }
929
930       if (! loop_canon_p (loop))
931         continue;
932
933       if (! loop_single_full_bb_p (loop))
934         continue;
935
936       bb = loop->header;
937
938       get_ebb_head_tail (bb, bb, &head, &tail);
939       latch_edge = loop_latch_edge (loop);
940       gcc_assert (single_exit (loop));
941       if (single_exit (loop)->count)
942         trip_count = latch_edge->count / single_exit (loop)->count;
943
944       /* Perfrom SMS only on loops that their average count is above threshold.  */
945
946       if ( latch_edge->count
947           && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
948         {
949           if (dump_file)
950             {
951               fprintf (dump_file, " %s %d (file, line)\n",
952                        insn_file (tail), insn_line (tail));
953               fprintf (dump_file, "SMS single-bb-loop\n");
954               if (profile_info && flag_branch_probabilities)
955                 {
956                   fprintf (dump_file, "SMS loop-count ");
957                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
958                            (HOST_WIDEST_INT) bb->count);
959                   fprintf (dump_file, "\n");
960                   fprintf (dump_file, "SMS trip-count ");
961                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
962                            (HOST_WIDEST_INT) trip_count);
963                   fprintf (dump_file, "\n");
964                   fprintf (dump_file, "SMS profile-sum-max ");
965                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
966                            (HOST_WIDEST_INT) profile_info->sum_max);
967                   fprintf (dump_file, "\n");
968                 }
969             }
970           continue;
971         }
972
973       /* Make sure this is a doloop.  */
974       if ( !(count_reg = doloop_register_get (head, tail)))
975         continue;
976
977       /* Don't handle BBs with calls or barriers, or !single_set insns,
978          or auto-increment insns (to avoid creating invalid reg-moves
979          for the auto-increment insns).  
980          ??? Should handle auto-increment insns.
981          ??? Should handle insns defining subregs.  */
982      for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
983       {
984          rtx set;
985
986         if (CALL_P (insn)
987             || BARRIER_P (insn)
988             || (INSN_P (insn) && !JUMP_P (insn)
989                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE)
990             || (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0)
991             || (INSN_P (insn) && (set = single_set (insn))
992                 && GET_CODE (SET_DEST (set)) == SUBREG))
993         break;
994       }
995
996       if (insn != NEXT_INSN (tail))
997         {
998           if (dump_file)
999             {
1000               if (CALL_P (insn))
1001                 fprintf (dump_file, "SMS loop-with-call\n");
1002               else if (BARRIER_P (insn))
1003                 fprintf (dump_file, "SMS loop-with-barrier\n");
1004               else if (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0)
1005                 fprintf (dump_file, "SMS reg inc\n");
1006               else if ((INSN_P (insn) && !JUMP_P (insn)
1007                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
1008                 fprintf (dump_file, "SMS loop-with-not-single-set\n");
1009               else
1010                fprintf (dump_file, "SMS loop with subreg in lhs\n");
1011               print_rtl_single (dump_file, insn);
1012             }
1013
1014           continue;
1015         }
1016
1017       if (! (g = create_ddg (bb, 0)))
1018         {
1019           if (dump_file)
1020             fprintf (dump_file, "SMS doloop\n");
1021           continue;
1022         }
1023
1024       g_arr[loop->num] = g;
1025     }
1026
1027   /* We don't want to perform SMS on new loops - created by versioning.  */
1028   FOR_EACH_LOOP (li, loop, 0)
1029     {
1030       rtx head, tail;
1031       rtx count_reg, count_init;
1032       int mii, rec_mii;
1033       unsigned stage_count = 0;
1034       HOST_WIDEST_INT loop_count = 0;
1035
1036       if (! (g = g_arr[loop->num]))
1037         continue;
1038
1039       if (dump_file)
1040         print_ddg (dump_file, g);
1041
1042       get_ebb_head_tail (loop->header, loop->header, &head, &tail);
1043
1044       latch_edge = loop_latch_edge (loop);
1045       gcc_assert (single_exit (loop));
1046       if (single_exit (loop)->count)
1047         trip_count = latch_edge->count / single_exit (loop)->count;
1048
1049       if (dump_file)
1050         {
1051           fprintf (dump_file, " %s %d (file, line)\n",
1052                    insn_file (tail), insn_line (tail));
1053           fprintf (dump_file, "SMS single-bb-loop\n");
1054           if (profile_info && flag_branch_probabilities)
1055             {
1056               fprintf (dump_file, "SMS loop-count ");
1057               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1058                        (HOST_WIDEST_INT) bb->count);
1059               fprintf (dump_file, "\n");
1060               fprintf (dump_file, "SMS profile-sum-max ");
1061               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1062                        (HOST_WIDEST_INT) profile_info->sum_max);
1063               fprintf (dump_file, "\n");
1064             }
1065           fprintf (dump_file, "SMS doloop\n");
1066           fprintf (dump_file, "SMS built-ddg %d\n", g->num_nodes);
1067           fprintf (dump_file, "SMS num-loads %d\n", g->num_loads);
1068           fprintf (dump_file, "SMS num-stores %d\n", g->num_stores);
1069         }
1070
1071
1072       /* In case of th loop have doloop register it gets special
1073          handling.  */
1074       count_init = NULL_RTX;
1075       if ((count_reg = doloop_register_get (head, tail)))
1076         {
1077           basic_block pre_header;
1078
1079           pre_header = loop_preheader_edge (loop)->src;
1080           count_init = const_iteration_count (count_reg, pre_header,
1081                                               &loop_count);
1082         }
1083       gcc_assert (count_reg);
1084
1085       if (dump_file && count_init)
1086         {
1087           fprintf (dump_file, "SMS const-doloop ");
1088           fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1089                      loop_count);
1090           fprintf (dump_file, "\n");
1091         }
1092
1093       node_order = XNEWVEC (int, g->num_nodes);
1094
1095       mii = 1; /* Need to pass some estimate of mii.  */
1096       rec_mii = sms_order_nodes (g, mii, node_order);
1097       mii = MAX (res_MII (g), rec_mii);
1098       maxii = MAXII_FACTOR * mii;
1099
1100       if (dump_file)
1101         fprintf (dump_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
1102                  rec_mii, mii, maxii);
1103
1104       /* After sms_order_nodes and before sms_schedule_by_order, to copy over
1105          ASAP.  */
1106       set_node_sched_params (g);
1107
1108       ps = sms_schedule_by_order (g, mii, maxii, node_order);
1109
1110       if (ps)
1111         stage_count = PS_STAGE_COUNT (ps);
1112
1113       /* Stage count of 1 means that there is no interleaving between
1114          iterations, let the scheduling passes do the job.  */
1115       if (stage_count < 1
1116           || (count_init && (loop_count <= stage_count))
1117           || (flag_branch_probabilities && (trip_count <= stage_count)))
1118         {
1119           if (dump_file)
1120             {
1121               fprintf (dump_file, "SMS failed... \n");
1122               fprintf (dump_file, "SMS sched-failed (stage-count=%d, loop-count=", stage_count);
1123               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
1124               fprintf (dump_file, ", trip-count=");
1125               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count);
1126               fprintf (dump_file, ")\n");
1127             }
1128           continue;
1129         }
1130       else
1131         {
1132           struct undo_replace_buff_elem *reg_move_replaces;
1133
1134           if (dump_file)
1135             {
1136               fprintf (dump_file,
1137                        "SMS succeeded %d %d (with ii, sc)\n", ps->ii,
1138                        stage_count);
1139               print_partial_schedule (ps, dump_file);
1140               fprintf (dump_file,
1141                        "SMS Branch (%d) will later be scheduled at cycle %d.\n",
1142                        g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1);
1143             }
1144
1145           /* Set the stage boundaries.  If the DDG is built with closing_branch_deps,
1146              the closing_branch was scheduled and should appear in the last (ii-1)
1147              row.  Otherwise, we are free to schedule the branch, and we let nodes
1148              that were scheduled at the first PS_MIN_CYCLE cycle appear in the first
1149              row; this should reduce stage_count to minimum.  
1150              TODO: Revisit the issue of scheduling the insns of the
1151              control part relative to the branch when the control part
1152              has more than one insn.  */
1153           normalize_sched_times (ps);
1154           rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
1155           set_columns_for_ps (ps);
1156           
1157           canon_loop (loop);
1158
1159           /* case the BCT count is not known , Do loop-versioning */
1160           if (count_reg && ! count_init)
1161             {
1162               rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
1163                                              GEN_INT(stage_count));
1164               unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS
1165                                * REG_BR_PROB_BASE) / 100;
1166
1167               loop_version (loop, comp_rtx, &condition_bb,
1168                             prob, prob, REG_BR_PROB_BASE - prob,
1169                             true);
1170              }
1171
1172           /* Set new iteration count of loop kernel.  */
1173           if (count_reg && count_init)
1174             SET_SRC (single_set (count_init)) = GEN_INT (loop_count
1175                                                      - stage_count + 1);
1176
1177           /* Now apply the scheduled kernel to the RTL of the loop.  */
1178           permute_partial_schedule (ps, g->closing_branch->first_note);
1179
1180           /* Mark this loop as software pipelined so the later
1181              scheduling passes doesn't touch it.  */
1182           if (! flag_resched_modulo_sched)
1183             g->bb->flags |= BB_DISABLE_SCHEDULE;
1184           /* The life-info is not valid any more.  */
1185           df_set_bb_dirty (g->bb);
1186
1187           reg_move_replaces = generate_reg_moves (ps, true);
1188           if (dump_file)
1189             print_node_sched_params (dump_file, g->num_nodes, g);
1190           /* Generate prolog and epilog.  */
1191           generate_prolog_epilog (ps, loop, count_reg, count_init);
1192  
1193           free_undo_replace_buff (reg_move_replaces);
1194         }
1195
1196       free_partial_schedule (ps);
1197       free (node_sched_params);
1198       free (node_order);
1199       free_ddg (g);
1200     }
1201
1202   regstat_free_calls_crossed ();
1203   free (g_arr);
1204
1205   /* Release scheduler data, needed until now because of DFA.  */
1206   sched_finish ();
1207   loop_optimizer_finalize ();
1208 }
1209
1210 /* The SMS scheduling algorithm itself
1211    -----------------------------------
1212    Input: 'O' an ordered list of insns of a loop.
1213    Output: A scheduling of the loop - kernel, prolog, and epilogue.
1214
1215    'Q' is the empty Set
1216    'PS' is the partial schedule; it holds the currently scheduled nodes with
1217         their cycle/slot.
1218    'PSP' previously scheduled predecessors.
1219    'PSS' previously scheduled successors.
1220    't(u)' the cycle where u is scheduled.
1221    'l(u)' is the latency of u.
1222    'd(v,u)' is the dependence distance from v to u.
1223    'ASAP(u)' the earliest time at which u could be scheduled as computed in
1224              the node ordering phase.
1225    'check_hardware_resources_conflicts(u, PS, c)'
1226                              run a trace around cycle/slot through DFA model
1227                              to check resource conflicts involving instruction u
1228                              at cycle c given the partial schedule PS.
1229    'add_to_partial_schedule_at_time(u, PS, c)'
1230                              Add the node/instruction u to the partial schedule
1231                              PS at time c.
1232    'calculate_register_pressure(PS)'
1233                              Given a schedule of instructions, calculate the register
1234                              pressure it implies.  One implementation could be the
1235                              maximum number of overlapping live ranges.
1236    'maxRP' The maximum allowed register pressure, it is usually derived from the number
1237            registers available in the hardware.
1238
1239    1. II = MII.
1240    2. PS = empty list
1241    3. for each node u in O in pre-computed order
1242    4.   if (PSP(u) != Q && PSS(u) == Q) then
1243    5.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1244    6.     start = Early_start; end = Early_start + II - 1; step = 1
1245    11.  else if (PSP(u) == Q && PSS(u) != Q) then
1246    12.      Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1247    13.     start = Late_start; end = Late_start - II + 1; step = -1
1248    14.  else if (PSP(u) != Q && PSS(u) != Q) then
1249    15.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1250    16.     Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1251    17.     start = Early_start;
1252    18.     end = min(Early_start + II - 1 , Late_start);
1253    19.     step = 1
1254    20.     else "if (PSP(u) == Q && PSS(u) == Q)"
1255    21.    start = ASAP(u); end = start + II - 1; step = 1
1256    22.  endif
1257
1258    23.  success = false
1259    24.  for (c = start ; c != end ; c += step)
1260    25.     if check_hardware_resources_conflicts(u, PS, c) then
1261    26.       add_to_partial_schedule_at_time(u, PS, c)
1262    27.       success = true
1263    28.       break
1264    29.     endif
1265    30.  endfor
1266    31.  if (success == false) then
1267    32.    II = II + 1
1268    33.    if (II > maxII) then
1269    34.       finish - failed to schedule
1270    35.   endif
1271    36.    goto 2.
1272    37.  endif
1273    38. endfor
1274    39. if (calculate_register_pressure(PS) > maxRP) then
1275    40.    goto 32.
1276    41. endif
1277    42. compute epilogue & prologue
1278    43. finish - succeeded to schedule
1279 */
1280
1281 /* A limit on the number of cycles that resource conflicts can span.  ??? Should
1282    be provided by DFA, and be dependent on the type of insn scheduled.  Currently
1283    set to 0 to save compile time.  */
1284 #define DFA_HISTORY SMS_DFA_HISTORY
1285
1286 /* A threshold for the number of repeated unsuccessful attempts to insert
1287    an empty row, before we flush the partial schedule and start over.  */
1288 #define MAX_SPLIT_NUM 10
1289 /* Given the partial schedule PS, this function calculates and returns the
1290    cycles in which we can schedule the node with the given index I.
1291    NOTE: Here we do the backtracking in SMS, in some special cases. We have
1292    noticed that there are several cases in which we fail    to SMS the loop
1293    because the sched window of a node is empty    due to tight data-deps. In
1294    such cases we want to unschedule    some of the predecessors/successors
1295    until we get non-empty    scheduling window.  It returns -1 if the
1296    scheduling window is empty and zero otherwise.  */
1297
1298 static int
1299 get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i,
1300                   sbitmap sched_nodes, int ii, int *start_p, int *step_p, int *end_p)
1301 {
1302   int start, step, end;
1303   ddg_edge_ptr e;
1304   int u = nodes_order [i];
1305   ddg_node_ptr u_node = &ps->g->nodes[u];
1306   sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
1307   sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
1308   sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1309   sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1310   int psp_not_empty;
1311   int pss_not_empty;
1312
1313   /* 1. compute sched window for u (start, end, step).  */
1314   sbitmap_zero (psp);
1315   sbitmap_zero (pss);
1316   psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1317   pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1318
1319   if (psp_not_empty && !pss_not_empty)
1320     {
1321       int early_start = INT_MIN;
1322
1323       end = INT_MAX;
1324       for (e = u_node->in; e != 0; e = e->next_in)
1325         {
1326           ddg_node_ptr v_node = e->src;
1327
1328           if (dump_file)
1329             {     
1330               fprintf (dump_file, "\nProcessing edge: ");
1331               print_ddg_edge (dump_file, e);
1332               fprintf (dump_file,
1333                        "\nScheduling %d (%d) in psp_not_empty,"
1334                        " checking node %d (%d): ", u_node->cuid,
1335                        INSN_UID (u_node->insn), v_node->cuid, INSN_UID
1336                        (v_node->insn));
1337             }
1338
1339           if (TEST_BIT (sched_nodes, v_node->cuid))
1340             {
1341               int node_st = SCHED_TIME (v_node)
1342                             + e->latency - (e->distance * ii);
1343
1344               early_start = MAX (early_start, node_st);
1345
1346               if (e->data_type == MEM_DEP)
1347                 end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1348             }
1349         }
1350       start = early_start;
1351       end = MIN (end, early_start + ii);
1352       step = 1;
1353
1354       if (dump_file)
1355         fprintf (dump_file,
1356                  "\nScheduling %d (%d) in a window (%d..%d) with step %d\n",
1357                  u_node->cuid, INSN_UID (u_node->insn), start, end, step);
1358     }
1359
1360   else if (!psp_not_empty && pss_not_empty)
1361     {
1362       int late_start = INT_MAX;
1363
1364       end = INT_MIN;
1365       for (e = u_node->out; e != 0; e = e->next_out)
1366         {
1367           ddg_node_ptr v_node = e->dest;
1368
1369           if (dump_file)
1370             {
1371               fprintf (dump_file, "\nProcessing edge:");
1372               print_ddg_edge (dump_file, e);
1373               fprintf (dump_file,
1374                        "\nScheduling %d (%d) in pss_not_empty,"
1375                        " checking node %d (%d): ", u_node->cuid,
1376                        INSN_UID (u_node->insn), v_node->cuid, INSN_UID
1377                        (v_node->insn));
1378             }
1379
1380           if (TEST_BIT (sched_nodes, v_node->cuid))
1381             {
1382               late_start = MIN (late_start,
1383                                 SCHED_TIME (v_node) - e->latency
1384                                 + (e->distance * ii));
1385                if (dump_file)
1386                  fprintf (dump_file, "late_start = %d;", late_start);
1387
1388               if (e->data_type == MEM_DEP)
1389                 end = MAX (end, SCHED_TIME (v_node) - ii + 1);
1390              if (dump_file)
1391                  fprintf (dump_file, "end = %d\n", end);
1392
1393             }
1394           else if (dump_file)
1395             fprintf (dump_file, "the node is not scheduled\n");
1396
1397         }
1398       start = late_start;
1399       end = MAX (end, late_start - ii);
1400       step = -1;
1401
1402       if (dump_file)
1403         fprintf (dump_file,
1404                  "\nScheduling %d (%d) in a window (%d..%d) with step %d\n",
1405                  u_node->cuid, INSN_UID (u_node->insn), start, end, step);
1406
1407     }
1408
1409   else if (psp_not_empty && pss_not_empty)
1410     {
1411       int early_start = INT_MIN;
1412       int late_start = INT_MAX;
1413
1414       start = INT_MIN;
1415       end = INT_MAX;
1416       for (e = u_node->in; e != 0; e = e->next_in)
1417         {
1418           ddg_node_ptr v_node = e->src;
1419
1420           if (dump_file)
1421             {
1422               fprintf (dump_file, "\nProcessing edge:");
1423               print_ddg_edge (dump_file, e);
1424               fprintf (dump_file,
1425                        "\nScheduling %d (%d) in psp_pss_not_empty,"
1426                        " checking p %d (%d): ", u_node->cuid, INSN_UID
1427                        (u_node->insn), v_node->cuid, INSN_UID
1428                        (v_node->insn));
1429             }
1430
1431           if (TEST_BIT (sched_nodes, v_node->cuid))
1432             {
1433               early_start = MAX (early_start,
1434                                  SCHED_TIME (v_node) + e->latency
1435                                  - (e->distance * ii));
1436               if (e->data_type == MEM_DEP)
1437                 end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1438             }
1439         }
1440       for (e = u_node->out; e != 0; e = e->next_out)
1441         {
1442           ddg_node_ptr v_node = e->dest;
1443
1444           if (dump_file)
1445             {
1446               fprintf (dump_file, "\nProcessing edge:");
1447               print_ddg_edge (dump_file, e);
1448               fprintf (dump_file,
1449                        "\nScheduling %d (%d) in psp_pss_not_empty,"
1450                        " checking s %d (%d): ", u_node->cuid, INSN_UID
1451                        (u_node->insn), v_node->cuid, INSN_UID
1452                        (v_node->insn));
1453             }
1454
1455           if (TEST_BIT (sched_nodes, v_node->cuid))
1456             {
1457               late_start = MIN (late_start,
1458                                 SCHED_TIME (v_node) - e->latency
1459                                 + (e->distance * ii));
1460               if (e->data_type == MEM_DEP)
1461                 start = MAX (start, SCHED_TIME (v_node) - ii + 1);
1462             }
1463         }
1464       start = MAX (start, early_start);
1465       end = MIN (end, MIN (early_start + ii, late_start + 1));
1466       step = 1;
1467     }
1468   else /* psp is empty && pss is empty.  */
1469     {
1470       start = SCHED_ASAP (u_node);
1471       end = start + ii;
1472       step = 1;
1473     }
1474
1475   *start_p = start;
1476   *step_p = step;
1477   *end_p = end;
1478   sbitmap_free (psp);
1479   sbitmap_free (pss);
1480
1481   if ((start >= end && step == 1) || (start <= end && step == -1))
1482     {
1483       if (dump_file)
1484         fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
1485                  start, end, step);
1486     return -1;
1487     }
1488
1489     return 0;
1490 }
1491
1492 /* This function implements the scheduling algorithm for SMS according to the
1493    above algorithm.  */
1494 static partial_schedule_ptr
1495 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
1496 {
1497   int ii = mii;
1498   int i, c, success, num_splits = 0;
1499   int flush_and_start_over = true;
1500   int num_nodes = g->num_nodes;
1501   ddg_edge_ptr e;
1502   ps_insn_ptr psi;
1503   int start, end, step; /* Place together into one struct?  */
1504   sbitmap sched_nodes = sbitmap_alloc (num_nodes);
1505   sbitmap must_precede = sbitmap_alloc (num_nodes);
1506   sbitmap must_follow = sbitmap_alloc (num_nodes);
1507   sbitmap tobe_scheduled = sbitmap_alloc (num_nodes);
1508
1509   partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
1510
1511   sbitmap_ones (tobe_scheduled);
1512   sbitmap_zero (sched_nodes);
1513
1514   while (flush_and_start_over && (ii < maxii))
1515     {
1516
1517       if (dump_file)
1518         fprintf (dump_file, "Starting with ii=%d\n", ii);
1519       flush_and_start_over = false;
1520       sbitmap_zero (sched_nodes);
1521
1522       for (i = 0; i < num_nodes; i++)
1523         {
1524           int u = nodes_order[i];
1525           ddg_node_ptr u_node = &ps->g->nodes[u];
1526           rtx insn = u_node->insn;
1527
1528           if (!INSN_P (insn))
1529             {
1530               RESET_BIT (tobe_scheduled, u);
1531               continue;
1532             }
1533
1534           if (JUMP_P (insn)) /* Closing branch handled later.  */
1535             {
1536               RESET_BIT (tobe_scheduled, u);
1537               continue;
1538             }
1539
1540           if (TEST_BIT (sched_nodes, u))
1541             continue;
1542
1543           /* Try to get non-empty scheduling window.  */
1544          success = 0;
1545          if (get_sched_window (ps, nodes_order, i, sched_nodes, ii, &start,
1546                                 &step, &end) == 0)
1547             {
1548               if (dump_file)
1549                 fprintf (dump_file, "\nTrying to schedule node %d \
1550                         INSN = %d  in (%d .. %d) step %d\n", u, (INSN_UID
1551                         (g->nodes[u].insn)), start, end, step);
1552               /* Use must_follow & must_precede bitmaps to determine order
1553                  of nodes within the cycle.  */
1554
1555               /* use must_follow & must_precede bitmaps to determine order
1556                  of nodes within the cycle.  */
1557               sbitmap_zero (must_precede);
1558               sbitmap_zero (must_follow);
1559               /* TODO: We can add an insn to the must_precede or must_follow
1560                  bitmaps only if it has tight dependence to U and they
1561                  both scheduled in the same row.  The current check is less
1562                  conservative and content with the fact that both U and the
1563                  insn are scheduled in the same row.  */
1564               for (e = u_node->in; e != 0; e = e->next_in)
1565                 if (TEST_BIT (sched_nodes, e->src->cuid)
1566                     && (SMODULO (SCHED_TIME (e->src), ii) ==
1567                         SMODULO (start, ii)))
1568                   SET_BIT (must_precede, e->src->cuid);
1569
1570               for (e = u_node->out; e != 0; e = e->next_out)
1571                 if (TEST_BIT (sched_nodes, e->dest->cuid)
1572                     && (SMODULO (SCHED_TIME (e->dest), ii) ==
1573                         SMODULO ((end - step), ii)))
1574                   SET_BIT (must_follow, e->dest->cuid);
1575
1576               gcc_assert ((step > 0 && start < end)
1577                           || (step < 0 && start > end));
1578
1579               for (c = start; c != end; c += step)
1580                 {
1581                   verify_partial_schedule (ps, sched_nodes);
1582
1583                   psi = ps_add_node_check_conflicts (ps, u_node, c,
1584                                                      must_precede,
1585                                                      must_follow);
1586
1587                   if (psi)
1588                     {
1589                       SCHED_TIME (u_node) = c;
1590                       SET_BIT (sched_nodes, u);
1591                       success = 1;
1592                       num_splits = 0;
1593                       if (dump_file)
1594                         fprintf (dump_file, "Scheduled w/o split in %d\n", c);
1595
1596                       break;
1597                     }
1598                 }
1599               verify_partial_schedule (ps, sched_nodes);
1600             }
1601             if (!success)
1602             {
1603               int split_row;
1604
1605               if (ii++ == maxii)
1606                 break;
1607
1608               if (num_splits >= MAX_SPLIT_NUM)
1609                 {
1610                   num_splits = 0;
1611                   flush_and_start_over = true;
1612                   verify_partial_schedule (ps, sched_nodes);
1613                   reset_partial_schedule (ps, ii);
1614                   verify_partial_schedule (ps, sched_nodes);
1615                   break;
1616                 }
1617
1618               num_splits++;
1619               if (step == 1)
1620                 split_row = compute_split_row (sched_nodes, start, end,
1621                                                ps->ii, u_node);
1622               else
1623                 split_row = compute_split_row (sched_nodes, end, start,
1624                                                ps->ii, u_node);
1625
1626               ps_insert_empty_row (ps, split_row, sched_nodes);
1627               i--;              /* Go back and retry node i.  */
1628
1629               if (dump_file)
1630                 fprintf (dump_file, "num_splits=%d\n", num_splits);
1631             }
1632
1633           /* ??? If (success), check register pressure estimates.  */
1634         }                       /* Continue with next node.  */
1635     }                           /* While flush_and_start_over.  */
1636   if (ii >= maxii)
1637     {
1638       free_partial_schedule (ps);
1639       ps = NULL;
1640     }
1641   else
1642     gcc_assert (sbitmap_equal (tobe_scheduled, sched_nodes));
1643
1644   sbitmap_free (sched_nodes);
1645   sbitmap_free (must_precede);
1646   sbitmap_free (must_follow);
1647   sbitmap_free (tobe_scheduled);
1648
1649   return ps;
1650 }
1651
1652 /* This function inserts a new empty row into PS at the position
1653    according to SPLITROW, keeping all already scheduled instructions
1654    intact and updating their SCHED_TIME and cycle accordingly.  */
1655 static void
1656 ps_insert_empty_row (partial_schedule_ptr ps, int split_row,
1657                      sbitmap sched_nodes)
1658 {
1659   ps_insn_ptr crr_insn;
1660   ps_insn_ptr *rows_new;
1661   int ii = ps->ii;
1662   int new_ii = ii + 1;
1663   int row;
1664
1665   verify_partial_schedule (ps, sched_nodes);
1666
1667   /* We normalize sched_time and rotate ps to have only non-negative sched
1668      times, for simplicity of updating cycles after inserting new row.  */
1669   split_row -= ps->min_cycle;
1670   split_row = SMODULO (split_row, ii);
1671   if (dump_file)
1672     fprintf (dump_file, "split_row=%d\n", split_row);
1673
1674   normalize_sched_times (ps);
1675   rotate_partial_schedule (ps, ps->min_cycle);
1676
1677   rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
1678   for (row = 0; row < split_row; row++)
1679     {
1680       rows_new[row] = ps->rows[row];
1681       ps->rows[row] = NULL;
1682       for (crr_insn = rows_new[row];
1683            crr_insn; crr_insn = crr_insn->next_in_row)
1684         {
1685           ddg_node_ptr u = crr_insn->node;
1686           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii);
1687
1688           SCHED_TIME (u) = new_time;
1689           crr_insn->cycle = new_time;
1690           SCHED_ROW (u) = new_time % new_ii;
1691           SCHED_STAGE (u) = new_time / new_ii;
1692         }
1693
1694     }
1695
1696   rows_new[split_row] = NULL;
1697
1698   for (row = split_row; row < ii; row++)
1699     {
1700       rows_new[row + 1] = ps->rows[row];
1701       ps->rows[row] = NULL;
1702       for (crr_insn = rows_new[row + 1];
1703            crr_insn; crr_insn = crr_insn->next_in_row)
1704         {
1705           ddg_node_ptr u = crr_insn->node;
1706           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii) + 1;
1707
1708           SCHED_TIME (u) = new_time;
1709           crr_insn->cycle = new_time;
1710           SCHED_ROW (u) = new_time % new_ii;
1711           SCHED_STAGE (u) = new_time / new_ii;
1712         }
1713     }
1714
1715   /* Updating ps.  */
1716   ps->min_cycle = ps->min_cycle + ps->min_cycle / ii
1717     + (SMODULO (ps->min_cycle, ii) >= split_row ? 1 : 0);
1718   ps->max_cycle = ps->max_cycle + ps->max_cycle / ii
1719     + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0);
1720   free (ps->rows);
1721   ps->rows = rows_new;
1722   ps->ii = new_ii;
1723   gcc_assert (ps->min_cycle >= 0);
1724
1725   verify_partial_schedule (ps, sched_nodes);
1726
1727   if (dump_file)
1728     fprintf (dump_file, "min_cycle=%d, max_cycle=%d\n", ps->min_cycle,
1729              ps->max_cycle);
1730 }
1731
1732 /* Given U_NODE which is the node that failed to be scheduled; LOW and
1733    UP which are the boundaries of it's scheduling window; compute using
1734    SCHED_NODES and II a row in the partial schedule that can be splitted
1735    which will separate a critical predecessor from a critical successor
1736    thereby expanding the window, and return it.  */
1737 static int
1738 compute_split_row (sbitmap sched_nodes, int low, int up, int ii,
1739                    ddg_node_ptr u_node)
1740 {
1741   ddg_edge_ptr e;
1742   int lower = INT_MIN, upper = INT_MAX;
1743   ddg_node_ptr crit_pred = NULL;
1744   ddg_node_ptr crit_succ = NULL;
1745   int crit_cycle;
1746
1747   for (e = u_node->in; e != 0; e = e->next_in)
1748     {
1749       ddg_node_ptr v_node = e->src;
1750
1751       if (TEST_BIT (sched_nodes, v_node->cuid)
1752           && (low == SCHED_TIME (v_node) + e->latency - (e->distance * ii)))
1753         if (SCHED_TIME (v_node) > lower)
1754           {
1755             crit_pred = v_node;
1756             lower = SCHED_TIME (v_node);
1757           }
1758     }
1759
1760   if (crit_pred != NULL)
1761     {
1762       crit_cycle = SCHED_TIME (crit_pred) + 1;
1763       return SMODULO (crit_cycle, ii);
1764     }
1765
1766   for (e = u_node->out; e != 0; e = e->next_out)
1767     {
1768       ddg_node_ptr v_node = e->dest;
1769       if (TEST_BIT (sched_nodes, v_node->cuid)
1770           && (up == SCHED_TIME (v_node) - e->latency + (e->distance * ii)))
1771         if (SCHED_TIME (v_node) < upper)
1772           {
1773             crit_succ = v_node;
1774             upper = SCHED_TIME (v_node);
1775           }
1776     }
1777
1778   if (crit_succ != NULL)
1779     {
1780       crit_cycle = SCHED_TIME (crit_succ);
1781       return SMODULO (crit_cycle, ii);
1782     }
1783
1784   if (dump_file)
1785     fprintf (dump_file, "Both crit_pred and crit_succ are NULL\n");
1786
1787   return SMODULO ((low + up + 1) / 2, ii);
1788 }
1789
1790 static void
1791 verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes)
1792 {
1793   int row;
1794   ps_insn_ptr crr_insn;
1795
1796   for (row = 0; row < ps->ii; row++)
1797     for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
1798       {
1799         ddg_node_ptr u = crr_insn->node;
1800
1801         gcc_assert (TEST_BIT (sched_nodes, u->cuid));
1802         /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
1803            popcount (sched_nodes) == number of insns in ps.  */
1804         gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
1805         gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
1806       }
1807 }
1808
1809 \f
1810 /* This page implements the algorithm for ordering the nodes of a DDG
1811    for modulo scheduling, activated through the
1812    "int sms_order_nodes (ddg_ptr, int mii, int * result)" API.  */
1813
1814 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
1815 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
1816 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
1817 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
1818 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
1819 #define DEPTH(x) (ASAP ((x)))
1820
1821 typedef struct node_order_params * nopa;
1822
1823 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
1824 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
1825 static nopa  calculate_order_params (ddg_ptr, int mii);
1826 static int find_max_asap (ddg_ptr, sbitmap);
1827 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
1828 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
1829
1830 enum sms_direction {BOTTOMUP, TOPDOWN};
1831
1832 struct node_order_params
1833 {
1834   int asap;
1835   int alap;
1836   int height;
1837 };
1838
1839 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1.  */
1840 static void
1841 check_nodes_order (int *node_order, int num_nodes)
1842 {
1843   int i;
1844   sbitmap tmp = sbitmap_alloc (num_nodes);
1845
1846   sbitmap_zero (tmp);
1847
1848   for (i = 0; i < num_nodes; i++)
1849     {
1850       int u = node_order[i];
1851
1852       gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u));
1853
1854       SET_BIT (tmp, u);
1855     }
1856
1857   sbitmap_free (tmp);
1858 }
1859
1860 /* Order the nodes of G for scheduling and pass the result in
1861    NODE_ORDER.  Also set aux.count of each node to ASAP.
1862    Return the recMII for the given DDG.  */
1863 static int
1864 sms_order_nodes (ddg_ptr g, int mii, int * node_order)
1865 {
1866   int i;
1867   int rec_mii = 0;
1868   ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
1869
1870   nopa nops = calculate_order_params (g, mii);
1871
1872   if (dump_file)
1873     print_sccs (dump_file, sccs, g);
1874
1875   order_nodes_of_sccs (sccs, node_order);
1876
1877   if (sccs->num_sccs > 0)
1878     /* First SCC has the largest recurrence_length.  */
1879     rec_mii = sccs->sccs[0]->recurrence_length;
1880
1881   /* Save ASAP before destroying node_order_params.  */
1882   for (i = 0; i < g->num_nodes; i++)
1883     {
1884       ddg_node_ptr v = &g->nodes[i];
1885       v->aux.count = ASAP (v);
1886     }
1887
1888   free (nops);
1889   free_ddg_all_sccs (sccs);
1890   check_nodes_order (node_order, g->num_nodes);
1891
1892   return rec_mii;
1893 }
1894
1895 static void
1896 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
1897 {
1898   int i, pos = 0;
1899   ddg_ptr g = all_sccs->ddg;
1900   int num_nodes = g->num_nodes;
1901   sbitmap prev_sccs = sbitmap_alloc (num_nodes);
1902   sbitmap on_path = sbitmap_alloc (num_nodes);
1903   sbitmap tmp = sbitmap_alloc (num_nodes);
1904   sbitmap ones = sbitmap_alloc (num_nodes);
1905
1906   sbitmap_zero (prev_sccs);
1907   sbitmap_ones (ones);
1908
1909   /* Perfrom the node ordering starting from the SCC with the highest recMII.
1910      For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc.  */
1911   for (i = 0; i < all_sccs->num_sccs; i++)
1912     {
1913       ddg_scc_ptr scc = all_sccs->sccs[i];
1914
1915       /* Add nodes on paths from previous SCCs to the current SCC.  */
1916       find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
1917       sbitmap_a_or_b (tmp, scc->nodes, on_path);
1918
1919       /* Add nodes on paths from the current SCC to previous SCCs.  */
1920       find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
1921       sbitmap_a_or_b (tmp, tmp, on_path);
1922
1923       /* Remove nodes of previous SCCs from current extended SCC.  */
1924       sbitmap_difference (tmp, tmp, prev_sccs);
1925
1926       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1927       /* Above call to order_nodes_in_scc updated prev_sccs |= tmp.  */
1928     }
1929
1930   /* Handle the remaining nodes that do not belong to any scc.  Each call
1931      to order_nodes_in_scc handles a single connected component.  */
1932   while (pos < g->num_nodes)
1933     {
1934       sbitmap_difference (tmp, ones, prev_sccs);
1935       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1936     }
1937   sbitmap_free (prev_sccs);
1938   sbitmap_free (on_path);
1939   sbitmap_free (tmp);
1940   sbitmap_free (ones);
1941 }
1942
1943 /* MII is needed if we consider backarcs (that do not close recursive cycles).  */
1944 static struct node_order_params *
1945 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
1946 {
1947   int u;
1948   int max_asap;
1949   int num_nodes = g->num_nodes;
1950   ddg_edge_ptr e;
1951   /* Allocate a place to hold ordering params for each node in the DDG.  */
1952   nopa node_order_params_arr;
1953
1954   /* Initialize of ASAP/ALAP/HEIGHT to zero.  */
1955   node_order_params_arr = (nopa) xcalloc (num_nodes,
1956                                           sizeof (struct node_order_params));
1957
1958   /* Set the aux pointer of each node to point to its order_params structure.  */
1959   for (u = 0; u < num_nodes; u++)
1960     g->nodes[u].aux.info = &node_order_params_arr[u];
1961
1962   /* Disregarding a backarc from each recursive cycle to obtain a DAG,
1963      calculate ASAP, ALAP, mobility, distance, and height for each node
1964      in the dependence (direct acyclic) graph.  */
1965
1966   /* We assume that the nodes in the array are in topological order.  */
1967
1968   max_asap = 0;
1969   for (u = 0; u < num_nodes; u++)
1970     {
1971       ddg_node_ptr u_node = &g->nodes[u];
1972
1973       ASAP (u_node) = 0;
1974       for (e = u_node->in; e; e = e->next_in)
1975         if (e->distance == 0)
1976           ASAP (u_node) = MAX (ASAP (u_node),
1977                                ASAP (e->src) + e->latency);
1978       max_asap = MAX (max_asap, ASAP (u_node));
1979     }
1980
1981   for (u = num_nodes - 1; u > -1; u--)
1982     {
1983       ddg_node_ptr u_node = &g->nodes[u];
1984
1985       ALAP (u_node) = max_asap;
1986       HEIGHT (u_node) = 0;
1987       for (e = u_node->out; e; e = e->next_out)
1988         if (e->distance == 0)
1989           {
1990             ALAP (u_node) = MIN (ALAP (u_node),
1991                                  ALAP (e->dest) - e->latency);
1992             HEIGHT (u_node) = MAX (HEIGHT (u_node),
1993                                    HEIGHT (e->dest) + e->latency);
1994           }
1995     }
1996
1997   return node_order_params_arr;
1998 }
1999
2000 static int
2001 find_max_asap (ddg_ptr g, sbitmap nodes)
2002 {
2003   unsigned int u = 0;
2004   int max_asap = -1;
2005   int result = -1;
2006   sbitmap_iterator sbi;
2007
2008   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2009     {
2010       ddg_node_ptr u_node = &g->nodes[u];
2011
2012       if (max_asap < ASAP (u_node))
2013         {
2014           max_asap = ASAP (u_node);
2015           result = u;
2016         }
2017     }
2018   return result;
2019 }
2020
2021 static int
2022 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
2023 {
2024   unsigned int u = 0;
2025   int max_hv = -1;
2026   int min_mob = INT_MAX;
2027   int result = -1;
2028   sbitmap_iterator sbi;
2029
2030   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2031     {
2032       ddg_node_ptr u_node = &g->nodes[u];
2033
2034       if (max_hv < HEIGHT (u_node))
2035         {
2036           max_hv = HEIGHT (u_node);
2037           min_mob = MOB (u_node);
2038           result = u;
2039         }
2040       else if ((max_hv == HEIGHT (u_node))
2041                && (min_mob > MOB (u_node)))
2042         {
2043           min_mob = MOB (u_node);
2044           result = u;
2045         }
2046     }
2047   return result;
2048 }
2049
2050 static int
2051 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
2052 {
2053   unsigned int u = 0;
2054   int max_dv = -1;
2055   int min_mob = INT_MAX;
2056   int result = -1;
2057   sbitmap_iterator sbi;
2058
2059   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2060     {
2061       ddg_node_ptr u_node = &g->nodes[u];
2062
2063       if (max_dv < DEPTH (u_node))
2064         {
2065           max_dv = DEPTH (u_node);
2066           min_mob = MOB (u_node);
2067           result = u;
2068         }
2069       else if ((max_dv == DEPTH (u_node))
2070                && (min_mob > MOB (u_node)))
2071         {
2072           min_mob = MOB (u_node);
2073           result = u;
2074         }
2075     }
2076   return result;
2077 }
2078
2079 /* Places the nodes of SCC into the NODE_ORDER array starting
2080    at position POS, according to the SMS ordering algorithm.
2081    NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
2082    the NODE_ORDER array, starting from position zero.  */
2083 static int
2084 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
2085                     int * node_order, int pos)
2086 {
2087   enum sms_direction dir;
2088   int num_nodes = g->num_nodes;
2089   sbitmap workset = sbitmap_alloc (num_nodes);
2090   sbitmap tmp = sbitmap_alloc (num_nodes);
2091   sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
2092   sbitmap predecessors = sbitmap_alloc (num_nodes);
2093   sbitmap successors = sbitmap_alloc (num_nodes);
2094
2095   sbitmap_zero (predecessors);
2096   find_predecessors (predecessors, g, nodes_ordered);
2097
2098   sbitmap_zero (successors);
2099   find_successors (successors, g, nodes_ordered);
2100
2101   sbitmap_zero (tmp);
2102   if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
2103     {
2104       sbitmap_copy (workset, tmp);
2105       dir = BOTTOMUP;
2106     }
2107   else if (sbitmap_a_and_b_cg (tmp, successors, scc))
2108     {
2109       sbitmap_copy (workset, tmp);
2110       dir = TOPDOWN;
2111     }
2112   else
2113     {
2114       int u;
2115
2116       sbitmap_zero (workset);
2117       if ((u = find_max_asap (g, scc)) >= 0)
2118         SET_BIT (workset, u);
2119       dir = BOTTOMUP;
2120     }
2121
2122   sbitmap_zero (zero_bitmap);
2123   while (!sbitmap_equal (workset, zero_bitmap))
2124     {
2125       int v;
2126       ddg_node_ptr v_node;
2127       sbitmap v_node_preds;
2128       sbitmap v_node_succs;
2129
2130       if (dir == TOPDOWN)
2131         {
2132           while (!sbitmap_equal (workset, zero_bitmap))
2133             {
2134               v = find_max_hv_min_mob (g, workset);
2135               v_node = &g->nodes[v];
2136               node_order[pos++] = v;
2137               v_node_succs = NODE_SUCCESSORS (v_node);
2138               sbitmap_a_and_b (tmp, v_node_succs, scc);
2139
2140               /* Don't consider the already ordered successors again.  */
2141               sbitmap_difference (tmp, tmp, nodes_ordered);
2142               sbitmap_a_or_b (workset, workset, tmp);
2143               RESET_BIT (workset, v);
2144               SET_BIT (nodes_ordered, v);
2145             }
2146           dir = BOTTOMUP;
2147           sbitmap_zero (predecessors);
2148           find_predecessors (predecessors, g, nodes_ordered);
2149           sbitmap_a_and_b (workset, predecessors, scc);
2150         }
2151       else
2152         {
2153           while (!sbitmap_equal (workset, zero_bitmap))
2154             {
2155               v = find_max_dv_min_mob (g, workset);
2156               v_node = &g->nodes[v];
2157               node_order[pos++] = v;
2158               v_node_preds = NODE_PREDECESSORS (v_node);
2159               sbitmap_a_and_b (tmp, v_node_preds, scc);
2160
2161               /* Don't consider the already ordered predecessors again.  */
2162               sbitmap_difference (tmp, tmp, nodes_ordered);
2163               sbitmap_a_or_b (workset, workset, tmp);
2164               RESET_BIT (workset, v);
2165               SET_BIT (nodes_ordered, v);
2166             }
2167           dir = TOPDOWN;
2168           sbitmap_zero (successors);
2169           find_successors (successors, g, nodes_ordered);
2170           sbitmap_a_and_b (workset, successors, scc);
2171         }
2172     }
2173   sbitmap_free (tmp);
2174   sbitmap_free (workset);
2175   sbitmap_free (zero_bitmap);
2176   sbitmap_free (predecessors);
2177   sbitmap_free (successors);
2178   return pos;
2179 }
2180
2181 \f
2182 /* This page contains functions for manipulating partial-schedules during
2183    modulo scheduling.  */
2184
2185 /* Create a partial schedule and allocate a memory to hold II rows.  */
2186
2187 static partial_schedule_ptr
2188 create_partial_schedule (int ii, ddg_ptr g, int history)
2189 {
2190   partial_schedule_ptr ps = XNEW (struct partial_schedule);
2191   ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
2192   ps->ii = ii;
2193   ps->history = history;
2194   ps->min_cycle = INT_MAX;
2195   ps->max_cycle = INT_MIN;
2196   ps->g = g;
2197
2198   return ps;
2199 }
2200
2201 /* Free the PS_INSNs in rows array of the given partial schedule.
2202    ??? Consider caching the PS_INSN's.  */
2203 static void
2204 free_ps_insns (partial_schedule_ptr ps)
2205 {
2206   int i;
2207
2208   for (i = 0; i < ps->ii; i++)
2209     {
2210       while (ps->rows[i])
2211         {
2212           ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
2213
2214           free (ps->rows[i]);
2215           ps->rows[i] = ps_insn;
2216         }
2217       ps->rows[i] = NULL;
2218     }
2219 }
2220
2221 /* Free all the memory allocated to the partial schedule.  */
2222
2223 static void
2224 free_partial_schedule (partial_schedule_ptr ps)
2225 {
2226   if (!ps)
2227     return;
2228   free_ps_insns (ps);
2229   free (ps->rows);
2230   free (ps);
2231 }
2232
2233 /* Clear the rows array with its PS_INSNs, and create a new one with
2234    NEW_II rows.  */
2235
2236 static void
2237 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
2238 {
2239   if (!ps)
2240     return;
2241   free_ps_insns (ps);
2242   if (new_ii == ps->ii)
2243     return;
2244   ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
2245                                                  * sizeof (ps_insn_ptr));
2246   memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
2247   ps->ii = new_ii;
2248   ps->min_cycle = INT_MAX;
2249   ps->max_cycle = INT_MIN;
2250 }
2251
2252 /* Prints the partial schedule as an ii rows array, for each rows
2253    print the ids of the insns in it.  */
2254 void
2255 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
2256 {
2257   int i;
2258
2259   for (i = 0; i < ps->ii; i++)
2260     {
2261       ps_insn_ptr ps_i = ps->rows[i];
2262
2263       fprintf (dump, "\n[CYCLE %d ]: ", i);
2264       while (ps_i)
2265         {
2266           fprintf (dump, "%d, ",
2267                    INSN_UID (ps_i->node->insn));
2268           ps_i = ps_i->next_in_row;
2269         }
2270     }
2271 }
2272
2273 /* Creates an object of PS_INSN and initializes it to the given parameters.  */
2274 static ps_insn_ptr
2275 create_ps_insn (ddg_node_ptr node, int rest_count, int cycle)
2276 {
2277   ps_insn_ptr ps_i = XNEW (struct ps_insn);
2278
2279   ps_i->node = node;
2280   ps_i->next_in_row = NULL;
2281   ps_i->prev_in_row = NULL;
2282   ps_i->row_rest_count = rest_count;
2283   ps_i->cycle = cycle;
2284
2285   return ps_i;
2286 }
2287
2288
2289 /* Removes the given PS_INSN from the partial schedule.  Returns false if the
2290    node is not found in the partial schedule, else returns true.  */
2291 static bool
2292 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
2293 {
2294   int row;
2295
2296   if (!ps || !ps_i)
2297     return false;
2298
2299   row = SMODULO (ps_i->cycle, ps->ii);
2300   if (! ps_i->prev_in_row)
2301     {
2302       if (ps_i != ps->rows[row])
2303         return false;
2304
2305       ps->rows[row] = ps_i->next_in_row;
2306       if (ps->rows[row])
2307         ps->rows[row]->prev_in_row = NULL;
2308     }
2309   else
2310     {
2311       ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
2312       if (ps_i->next_in_row)
2313         ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
2314     }
2315   free (ps_i);
2316   return true;
2317 }
2318
2319 /* Unlike what literature describes for modulo scheduling (which focuses
2320    on VLIW machines) the order of the instructions inside a cycle is
2321    important.  Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
2322    where the current instruction should go relative to the already
2323    scheduled instructions in the given cycle.  Go over these
2324    instructions and find the first possible column to put it in.  */
2325 static bool
2326 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
2327                      sbitmap must_precede, sbitmap must_follow)
2328 {
2329   ps_insn_ptr next_ps_i;
2330   ps_insn_ptr first_must_follow = NULL;
2331   ps_insn_ptr last_must_precede = NULL;
2332   int row;
2333
2334   if (! ps_i)
2335     return false;
2336
2337   row = SMODULO (ps_i->cycle, ps->ii);
2338
2339   /* Find the first must follow and the last must precede
2340      and insert the node immediately after the must precede
2341      but make sure that it there is no must follow after it.  */
2342   for (next_ps_i = ps->rows[row];
2343        next_ps_i;
2344        next_ps_i = next_ps_i->next_in_row)
2345     {
2346       if (TEST_BIT (must_follow, next_ps_i->node->cuid)
2347           && ! first_must_follow)
2348         first_must_follow = next_ps_i;
2349       if (TEST_BIT (must_precede, next_ps_i->node->cuid))
2350         {
2351           /* If we have already met a node that must follow, then
2352              there is no possible column.  */
2353           if (first_must_follow)
2354             return false;
2355           else
2356             last_must_precede = next_ps_i;
2357         }
2358     }
2359
2360   /* Now insert the node after INSERT_AFTER_PSI.  */
2361
2362   if (! last_must_precede)
2363     {
2364       ps_i->next_in_row = ps->rows[row];
2365       ps_i->prev_in_row = NULL;
2366       if (ps_i->next_in_row)
2367         ps_i->next_in_row->prev_in_row = ps_i;
2368       ps->rows[row] = ps_i;
2369     }
2370   else
2371     {
2372       ps_i->next_in_row = last_must_precede->next_in_row;
2373       last_must_precede->next_in_row = ps_i;
2374       ps_i->prev_in_row = last_must_precede;
2375       if (ps_i->next_in_row)
2376         ps_i->next_in_row->prev_in_row = ps_i;
2377     }
2378
2379   return true;
2380 }
2381
2382 /* Advances the PS_INSN one column in its current row; returns false
2383    in failure and true in success.  Bit N is set in MUST_FOLLOW if 
2384    the node with cuid N must be come after the node pointed to by 
2385    PS_I when scheduled in the same cycle.  */
2386 static int
2387 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
2388                         sbitmap must_follow)
2389 {
2390   ps_insn_ptr prev, next;
2391   int row;
2392   ddg_node_ptr next_node;
2393
2394   if (!ps || !ps_i)
2395     return false;
2396
2397   row = SMODULO (ps_i->cycle, ps->ii);
2398
2399   if (! ps_i->next_in_row)
2400     return false;
2401
2402   next_node = ps_i->next_in_row->node;
2403
2404   /* Check if next_in_row is dependent on ps_i, both having same sched
2405      times (typically ANTI_DEP).  If so, ps_i cannot skip over it.  */
2406   if (TEST_BIT (must_follow, next_node->cuid))
2407     return false;
2408
2409   /* Advance PS_I over its next_in_row in the doubly linked list.  */
2410   prev = ps_i->prev_in_row;
2411   next = ps_i->next_in_row;
2412
2413   if (ps_i == ps->rows[row])
2414     ps->rows[row] = next;
2415
2416   ps_i->next_in_row = next->next_in_row;
2417
2418   if (next->next_in_row)
2419     next->next_in_row->prev_in_row = ps_i;
2420
2421   next->next_in_row = ps_i;
2422   ps_i->prev_in_row = next;
2423
2424   next->prev_in_row = prev;
2425   if (prev)
2426     prev->next_in_row = next;
2427
2428   return true;
2429 }
2430
2431 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
2432    Returns 0 if this is not possible and a PS_INSN otherwise.  Bit N is 
2433    set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come 
2434    before/after (respectively) the node pointed to by PS_I when scheduled 
2435    in the same cycle.  */
2436 static ps_insn_ptr
2437 add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle,
2438                 sbitmap must_precede, sbitmap must_follow)
2439 {
2440   ps_insn_ptr ps_i;
2441   int rest_count = 1;
2442   int row = SMODULO (cycle, ps->ii);
2443
2444   if (ps->rows[row]
2445       && ps->rows[row]->row_rest_count >= issue_rate)
2446     return NULL;
2447
2448   if (ps->rows[row])
2449     rest_count += ps->rows[row]->row_rest_count;
2450
2451   ps_i = create_ps_insn (node, rest_count, cycle);
2452
2453   /* Finds and inserts PS_I according to MUST_FOLLOW and
2454      MUST_PRECEDE.  */
2455   if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
2456     {
2457       free (ps_i);
2458       return NULL;
2459     }
2460
2461   return ps_i;
2462 }
2463
2464 /* Advance time one cycle.  Assumes DFA is being used.  */
2465 static void
2466 advance_one_cycle (void)
2467 {
2468   if (targetm.sched.dfa_pre_cycle_insn)
2469     state_transition (curr_state,
2470                       targetm.sched.dfa_pre_cycle_insn ());
2471
2472   state_transition (curr_state, NULL);
2473
2474   if (targetm.sched.dfa_post_cycle_insn)
2475     state_transition (curr_state,
2476                       targetm.sched.dfa_post_cycle_insn ());
2477 }
2478
2479
2480
2481 /* Checks if PS has resource conflicts according to DFA, starting from
2482    FROM cycle to TO cycle; returns true if there are conflicts and false
2483    if there are no conflicts.  Assumes DFA is being used.  */
2484 static int
2485 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
2486 {
2487   int cycle;
2488
2489   state_reset (curr_state);
2490
2491   for (cycle = from; cycle <= to; cycle++)
2492     {
2493       ps_insn_ptr crr_insn;
2494       /* Holds the remaining issue slots in the current row.  */
2495       int can_issue_more = issue_rate;
2496
2497       /* Walk through the DFA for the current row.  */
2498       for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
2499            crr_insn;
2500            crr_insn = crr_insn->next_in_row)
2501         {
2502           rtx insn = crr_insn->node->insn;
2503
2504           if (!INSN_P (insn))
2505             continue;
2506
2507           /* Check if there is room for the current insn.  */
2508           if (!can_issue_more || state_dead_lock_p (curr_state))
2509             return true;
2510
2511           /* Update the DFA state and return with failure if the DFA found
2512              recource conflicts.  */
2513           if (state_transition (curr_state, insn) >= 0)
2514             return true;
2515
2516           if (targetm.sched.variable_issue)
2517             can_issue_more =
2518               targetm.sched.variable_issue (sched_dump, sched_verbose,
2519                                             insn, can_issue_more);
2520           /* A naked CLOBBER or USE generates no instruction, so don't
2521              let them consume issue slots.  */
2522           else if (GET_CODE (PATTERN (insn)) != USE
2523                    && GET_CODE (PATTERN (insn)) != CLOBBER)
2524             can_issue_more--;
2525         }
2526
2527       /* Advance the DFA to the next cycle.  */
2528       advance_one_cycle ();
2529     }
2530   return false;
2531 }
2532
2533 /* Checks if the given node causes resource conflicts when added to PS at
2534    cycle C.  If not the node is added to PS and returned; otherwise zero
2535    is returned.  Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with 
2536    cuid N must be come before/after (respectively) the node pointed to by 
2537    PS_I when scheduled in the same cycle.  */
2538 ps_insn_ptr
2539 ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n,
2540                              int c, sbitmap must_precede,
2541                              sbitmap must_follow)
2542 {
2543   int has_conflicts = 0;
2544   ps_insn_ptr ps_i;
2545
2546   /* First add the node to the PS, if this succeeds check for
2547      conflicts, trying different issue slots in the same row.  */
2548   if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
2549     return NULL; /* Failed to insert the node at the given cycle.  */
2550
2551   has_conflicts = ps_has_conflicts (ps, c, c)
2552                   || (ps->history > 0
2553                       && ps_has_conflicts (ps,
2554                                            c - ps->history,
2555                                            c + ps->history));
2556
2557   /* Try different issue slots to find one that the given node can be
2558      scheduled in without conflicts.  */
2559   while (has_conflicts)
2560     {
2561       if (! ps_insn_advance_column (ps, ps_i, must_follow))
2562         break;
2563       has_conflicts = ps_has_conflicts (ps, c, c)
2564                       || (ps->history > 0
2565                           && ps_has_conflicts (ps,
2566                                                c - ps->history,
2567                                                c + ps->history));
2568     }
2569
2570   if (has_conflicts)
2571     {
2572       remove_node_from_ps (ps, ps_i);
2573       return NULL;
2574     }
2575
2576   ps->min_cycle = MIN (ps->min_cycle, c);
2577   ps->max_cycle = MAX (ps->max_cycle, c);
2578   return ps_i;
2579 }
2580
2581 /* Rotate the rows of PS such that insns scheduled at time
2582    START_CYCLE will appear in row 0.  Updates max/min_cycles.  */
2583 void
2584 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
2585 {
2586   int i, row, backward_rotates;
2587   int last_row = ps->ii - 1;
2588
2589   if (start_cycle == 0)
2590     return;
2591
2592   backward_rotates = SMODULO (start_cycle, ps->ii);
2593
2594   /* Revisit later and optimize this into a single loop.  */
2595   for (i = 0; i < backward_rotates; i++)
2596     {
2597       ps_insn_ptr first_row = ps->rows[0];
2598
2599       for (row = 0; row < last_row; row++)
2600         ps->rows[row] = ps->rows[row+1];
2601
2602       ps->rows[last_row] = first_row;
2603     }
2604
2605   ps->max_cycle -= start_cycle;
2606   ps->min_cycle -= start_cycle;
2607 }
2608
2609 #endif /* INSN_SCHEDULING */
2610 \f
2611 static bool
2612 gate_handle_sms (void)
2613 {
2614   return (optimize > 0 && flag_modulo_sched);
2615 }
2616
2617
2618 /* Run instruction scheduler.  */
2619 /* Perform SMS module scheduling.  */
2620 static unsigned int
2621 rest_of_handle_sms (void)
2622 {
2623 #ifdef INSN_SCHEDULING
2624   basic_block bb;
2625
2626   /* Collect loop information to be used in SMS.  */
2627   cfg_layout_initialize (0);
2628   sms_schedule ();
2629
2630   /* Update the life information, because we add pseudos.  */
2631   max_regno = max_reg_num ();
2632
2633   /* Finalize layout changes.  */
2634   FOR_EACH_BB (bb)
2635     if (bb->next_bb != EXIT_BLOCK_PTR)
2636       bb->aux = bb->next_bb;
2637   free_dominance_info (CDI_DOMINATORS);
2638   cfg_layout_finalize ();
2639 #endif /* INSN_SCHEDULING */
2640   return 0;
2641 }
2642
2643 struct tree_opt_pass pass_sms =
2644 {
2645   "sms",                                /* name */
2646   gate_handle_sms,                      /* gate */
2647   rest_of_handle_sms,                   /* execute */
2648   NULL,                                 /* sub */
2649   NULL,                                 /* next */
2650   0,                                    /* static_pass_number */
2651   TV_SMS,                               /* tv_id */
2652   0,                                    /* properties_required */
2653   0,                                    /* properties_provided */
2654   0,                                    /* properties_destroyed */
2655   TODO_dump_func,                       /* todo_flags_start */
2656   TODO_df_finish | TODO_verify_rtl_sharing |
2657   TODO_dump_func |
2658   TODO_ggc_collect,                     /* todo_flags_finish */
2659   'm'                                   /* letter */
2660 };
2661