OSDN Git Service

Change SMS behavior upon failure
[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
51 #ifdef INSN_SCHEDULING
52
53 /* This file contains the implementation of the Swing Modulo Scheduler,
54    described in the following references:
55    [1] J. Llosa, A. Gonzalez, E. Ayguade, M. Valero., and J. Eckhardt.
56        Lifetime--sensitive modulo scheduling in a production environment.
57        IEEE Trans. on Comps., 50(3), March 2001
58    [2] J. Llosa, A. Gonzalez, E. Ayguade, and M. Valero.
59        Swing Modulo Scheduling: A Lifetime Sensitive Approach.
60        PACT '96 , pages 80-87, October 1996 (Boston - Massachusetts - USA).
61
62    The basic structure is:
63    1. Build a data-dependence graph (DDG) for each loop.
64    2. Use the DDG to order the insns of a loop (not in topological order
65       necessarily, but rather) trying to place each insn after all its
66       predecessors _or_ after all its successors.
67    3. Compute MII: a lower bound on the number of cycles to schedule the loop.
68    4. Use the ordering to perform list-scheduling of the loop:
69       1. Set II = MII.  We will try to schedule the loop within II cycles.
70       2. Try to schedule the insns one by one according to the ordering.
71          For each insn compute an interval of cycles by considering already-
72          scheduled preds and succs (and associated latencies); try to place
73          the insn in the cycles of this window checking for potential
74          resource conflicts (using the DFA interface).
75          Note: this is different from the cycle-scheduling of schedule_insns;
76          here the insns are not scheduled monotonically top-down (nor bottom-
77          up).
78       3. If failed in scheduling all insns - bump II++ and try again, unless
79          II reaches an upper bound MaxII, in which case report failure.
80    5. If we succeeded in scheduling the loop within II cycles, we now
81       generate prolog and epilog, decrease the counter of the loop, and
82       perform modulo variable expansion for live ranges that span more than
83       II cycles (i.e. use register copies to prevent a def from overwriting
84       itself before reaching the use).
85
86     SMS works with countable loops (1) whose control part can be easily
87     decoupled from the rest of the loop and (2) whose loop count can
88     be easily adjusted.  This is because we peel a constant number of
89     iterations into a prologue and epilogue for which we want to avoid
90     emitting the control part, and a kernel which is to iterate that
91     constant number of iterations less than the original loop.  So the
92     control part should be a set of insns clearly identified and having
93     its own iv, not otherwise used in the loop (at-least for now), which
94     initializes a register before the loop to the number of iterations.
95     Currently SMS relies on the do-loop pattern to recognize such loops,
96     where (1) the control part comprises of all insns defining and/or
97     using a certain 'count' register and (2) the loop count can be
98     adjusted by modifying this register prior to the loop.  
99     TODO: Rely on cfgloop analysis instead.  */
100 \f
101 /* This page defines partial-schedule structures and functions for
102    modulo scheduling.  */
103
104 typedef struct partial_schedule *partial_schedule_ptr;
105 typedef struct ps_insn *ps_insn_ptr;
106
107 /* The minimum (absolute) cycle that a node of ps was scheduled in.  */
108 #define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle)
109
110 /* The maximum (absolute) cycle that a node of ps was scheduled in.  */
111 #define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle)
112
113 /* Perform signed modulo, always returning a non-negative value.  */
114 #define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y))
115
116 /* The number of different iterations the nodes in ps span, assuming
117    the stage boundaries are placed efficiently.  */
118 #define PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
119                              + 1 + (ps)->ii - 1) / (ps)->ii)
120
121 /* A single instruction in the partial schedule.  */
122 struct ps_insn
123 {
124   /* The corresponding DDG_NODE.  */
125   ddg_node_ptr node;
126
127   /* The (absolute) cycle in which the PS instruction is scheduled.
128      Same as SCHED_TIME (node).  */
129   int cycle;
130
131   /* The next/prev PS_INSN in the same row.  */
132   ps_insn_ptr next_in_row,
133               prev_in_row;
134
135   /* The number of nodes in the same row that come after this node.  */
136   int row_rest_count;
137 };
138
139 /* Holds the partial schedule as an array of II rows.  Each entry of the
140    array points to a linked list of PS_INSNs, which represents the
141    instructions that are scheduled for that row.  */
142 struct partial_schedule
143 {
144   int ii;       /* Number of rows in the partial schedule.  */
145   int history;  /* Threshold for conflict checking using DFA.  */
146
147   /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii).  */
148   ps_insn_ptr *rows;
149
150   /* The earliest absolute cycle of an insn in the partial schedule.  */
151   int min_cycle;
152
153   /* The latest absolute cycle of an insn in the partial schedule.  */
154   int max_cycle;
155
156   ddg_ptr g;    /* The DDG of the insns in the partial schedule.  */
157 };
158
159 /* We use this to record all the register replacements we do in
160    the kernel so we can undo SMS if it is not profitable.  */
161 struct undo_replace_buff_elem
162 {
163   rtx insn;
164   rtx orig_reg;
165   rtx new_reg;
166   struct undo_replace_buff_elem *next;
167 };
168
169
170   
171 static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
172 static void free_partial_schedule (partial_schedule_ptr);
173 static void reset_partial_schedule (partial_schedule_ptr, int new_ii);
174 void print_partial_schedule (partial_schedule_ptr, FILE *);
175 static void verify_partial_schedule (partial_schedule_ptr, sbitmap);
176 static ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
177                                                 ddg_node_ptr node, int cycle,
178                                                 sbitmap must_precede,
179                                                 sbitmap must_follow);
180 static void rotate_partial_schedule (partial_schedule_ptr, int);
181 void set_row_column_for_ps (partial_schedule_ptr);
182 static void ps_insert_empty_row (partial_schedule_ptr, int, sbitmap);
183 static int compute_split_row (sbitmap, int, int, int, ddg_node_ptr);
184
185 \f
186 /* This page defines constants and structures for the modulo scheduling
187    driver.  */
188
189 /* As in haifa-sched.c:  */
190 /* issue_rate is the number of insns that can be scheduled in the same
191    machine cycle.  It can be defined in the config/mach/mach.h file,
192    otherwise we set it to 1.  */
193
194 static int issue_rate;
195
196 static int sms_order_nodes (ddg_ptr, int, int * result);
197 static void set_node_sched_params (ddg_ptr);
198 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *);
199 static void permute_partial_schedule (partial_schedule_ptr ps, rtx last);
200 static void generate_prolog_epilog (partial_schedule_ptr, struct loop *loop,
201                                     rtx, rtx);
202 static void duplicate_insns_of_cycles (partial_schedule_ptr ps,
203                                        int from_stage, int to_stage,
204                                        int is_prolog, rtx count_reg);
205
206 #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
207 #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
208 #define SCHED_FIRST_REG_MOVE(x) \
209         (((node_sched_params_ptr)(x)->aux.info)->first_reg_move)
210 #define SCHED_NREG_MOVES(x) \
211         (((node_sched_params_ptr)(x)->aux.info)->nreg_moves)
212 #define SCHED_ROW(x) (((node_sched_params_ptr)(x)->aux.info)->row)
213 #define SCHED_STAGE(x) (((node_sched_params_ptr)(x)->aux.info)->stage)
214 #define SCHED_COLUMN(x) (((node_sched_params_ptr)(x)->aux.info)->column)
215
216 /* The scheduling parameters held for each node.  */
217 typedef struct node_sched_params
218 {
219   int asap;     /* A lower-bound on the absolute scheduling cycle.  */
220   int time;     /* The absolute scheduling cycle (time >= asap).  */
221
222   /* The following field (first_reg_move) is a pointer to the first
223      register-move instruction added to handle the modulo-variable-expansion
224      of the register defined by this node.  This register-move copies the
225      original register defined by the node.  */
226   rtx first_reg_move;
227
228   /* The number of register-move instructions added, immediately preceding
229      first_reg_move.  */
230   int nreg_moves;
231
232   int row;    /* Holds time % ii.  */
233   int stage;  /* Holds time / ii.  */
234
235   /* The column of a node inside the ps.  If nodes u, v are on the same row,
236      u will precede v if column (u) < column (v).  */
237   int column;
238 } *node_sched_params_ptr;
239
240 \f
241 /* The following three functions are copied from the current scheduler
242    code in order to use sched_analyze() for computing the dependencies.
243    They are used when initializing the sched_info structure.  */
244 static const char *
245 sms_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
246 {
247   static char tmp[80];
248
249   sprintf (tmp, "i%4d", INSN_UID (insn));
250   return tmp;
251 }
252
253 static void
254 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
255                                regset cond_exec ATTRIBUTE_UNUSED,
256                                regset used ATTRIBUTE_UNUSED,
257                                regset set ATTRIBUTE_UNUSED)
258 {
259 }
260
261 static struct sched_info sms_sched_info =
262 {
263   NULL,
264   NULL,
265   NULL,
266   NULL,
267   NULL,
268   sms_print_insn,
269   NULL,
270   compute_jump_reg_dependencies,
271   NULL, NULL,
272   NULL, NULL,
273   0, 0, 0,
274
275   NULL, NULL, NULL, NULL, NULL,
276   0
277 };
278
279
280 /* Given HEAD and TAIL which are the first and last insns in a loop;
281    return the register which controls the loop.  Return zero if it has
282    more than one occurrence in the loop besides the control part or the
283    do-loop pattern is not of the form we expect.  */
284 static rtx
285 doloop_register_get (rtx head ATTRIBUTE_UNUSED, rtx tail ATTRIBUTE_UNUSED)
286 {
287 #ifdef HAVE_doloop_end
288   rtx reg, condition, insn;
289   bool found = false;
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   for (insn = head; insn != PREV_INSN (tail); insn = NEXT_INSN (insn))
312     if ((found = reg_mentioned_p (reg, insn)) == true)
313       break;
314   if (found)
315     {
316       if (dump_file)
317         fprintf (dump_file, "SMS count_reg found outside control\n");
318
319       return NULL_RTX;
320     }
321   /* One last check in case the do-loop pattern is parallel.  */
322   if (GET_CODE (PATTERN (tail)) == PARALLEL)
323     if (reg_mentioned_p (reg, PREV_INSN (tail)))
324       {
325         if (dump_file)
326           fprintf (dump_file, "SMS count_reg found outside control\n");
327
328         return NULL_RTX;
329       }
330   return reg;
331 #else
332   return NULL_RTX;
333 #endif
334 }
335
336 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
337    that the number of iterations is a compile-time constant.  If so,
338    return the rtx that sets COUNT_REG to a constant, and set COUNT to
339    this constant.  Otherwise return 0.  */
340 static rtx
341 const_iteration_count (rtx count_reg, basic_block pre_header,
342                        HOST_WIDEST_INT * count)
343 {
344   rtx insn;
345   rtx head, tail;
346
347   if (! pre_header)
348     return NULL_RTX;
349
350   get_ebb_head_tail (pre_header, pre_header, &head, &tail);
351
352   for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
353     if (INSN_P (insn) && single_set (insn) &&
354         rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
355       {
356         rtx pat = single_set (insn);
357
358         if (GET_CODE (SET_SRC (pat)) == CONST_INT)
359           {
360             *count = INTVAL (SET_SRC (pat));
361             return insn;
362           }
363
364         return NULL_RTX;
365       }
366
367   return NULL_RTX;
368 }
369
370 /* A very simple resource-based lower bound on the initiation interval.
371    ??? Improve the accuracy of this bound by considering the
372    utilization of various units.  */
373 static int
374 res_MII (ddg_ptr g)
375 {
376   return (g->num_nodes / issue_rate);
377 }
378
379
380 /* Points to the array that contains the sched data for each node.  */
381 static node_sched_params_ptr node_sched_params;
382
383 /* Allocate sched_params for each node and initialize it.  Assumes that
384    the aux field of each node contain the asap bound (computed earlier),
385    and copies it into the sched_params field.  */
386 static void
387 set_node_sched_params (ddg_ptr g)
388 {
389   int i;
390
391   /* Allocate for each node in the DDG a place to hold the "sched_data".  */
392   /* Initialize ASAP/ALAP/HIGHT to zero.  */
393   node_sched_params = (node_sched_params_ptr)
394                        xcalloc (g->num_nodes,
395                                 sizeof (struct node_sched_params));
396
397   /* Set the pointer of the general data of the node to point to the
398      appropriate sched_params structure.  */
399   for (i = 0; i < g->num_nodes; i++)
400     {
401       /* Watch out for aliasing problems?  */
402       node_sched_params[i].asap = g->nodes[i].aux.count;
403       g->nodes[i].aux.info = &node_sched_params[i];
404     }
405 }
406
407 static void
408 print_node_sched_params (FILE *file, int num_nodes, ddg_ptr g)
409 {
410   int i;
411
412   if (! file)
413     return;
414   for (i = 0; i < num_nodes; i++)
415     {
416       node_sched_params_ptr nsp = &node_sched_params[i];
417       rtx reg_move = nsp->first_reg_move;
418       int j;
419
420       fprintf (file, "Node = %d; INSN = %d\n", i,
421                (INSN_UID (g->nodes[i].insn)));
422       fprintf (file, " asap = %d:\n", nsp->asap);
423       fprintf (file, " time = %d:\n", nsp->time);
424       fprintf (file, " nreg_moves = %d:\n", nsp->nreg_moves);
425       for (j = 0; j < nsp->nreg_moves; j++)
426         {
427           fprintf (file, " reg_move = ");
428           print_rtl_single (file, reg_move);
429           reg_move = PREV_INSN (reg_move);
430         }
431     }
432 }
433
434 /*
435    Breaking intra-loop register anti-dependences:
436    Each intra-loop register anti-dependence implies a cross-iteration true
437    dependence of distance 1. Therefore, we can remove such false dependencies
438    and figure out if the partial schedule broke them by checking if (for a
439    true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
440    if so generate a register move.   The number of such moves is equal to:
441               SCHED_TIME (use) - SCHED_TIME (def)       { 0 broken
442    nreg_moves = ----------------------------------- + 1 - {   dependence.
443                             ii                          { 1 if not.
444 */
445 static struct undo_replace_buff_elem *
446 generate_reg_moves (partial_schedule_ptr ps, bool rescan)
447 {
448   ddg_ptr g = ps->g;
449   int ii = ps->ii;
450   int i;
451   struct undo_replace_buff_elem *reg_move_replaces = NULL;
452
453   for (i = 0; i < g->num_nodes; i++)
454     {
455       ddg_node_ptr u = &g->nodes[i];
456       ddg_edge_ptr e;
457       int nreg_moves = 0, i_reg_move;
458       sbitmap *uses_of_defs;
459       rtx last_reg_move;
460       rtx prev_reg, old_reg;
461
462       /* Compute the number of reg_moves needed for u, by looking at life
463          ranges started at u (excluding self-loops).  */
464       for (e = u->out; e; e = e->next_out)
465         if (e->type == TRUE_DEP && e->dest != e->src)
466           {
467             int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
468
469             if (e->distance == 1)
470               nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
471
472             /* If dest precedes src in the schedule of the kernel, then dest
473                will read before src writes and we can save one reg_copy.  */
474             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
475                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
476               nreg_moves4e--;
477
478             nreg_moves = MAX (nreg_moves, nreg_moves4e);
479           }
480
481       if (nreg_moves == 0)
482         continue;
483
484       /* Every use of the register defined by node may require a different
485          copy of this register, depending on the time the use is scheduled.
486          Set a bitmap vector, telling which nodes use each copy of this
487          register.  */
488       uses_of_defs = sbitmap_vector_alloc (nreg_moves, g->num_nodes);
489       sbitmap_vector_zero (uses_of_defs, nreg_moves);
490       for (e = u->out; e; e = e->next_out)
491         if (e->type == TRUE_DEP && e->dest != e->src)
492           {
493             int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
494
495             if (e->distance == 1)
496               dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src) + ii) / ii;
497
498             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
499                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
500               dest_copy--;
501
502             if (dest_copy)
503               SET_BIT (uses_of_defs[dest_copy - 1], e->dest->cuid);
504           }
505
506       /* Now generate the reg_moves, attaching relevant uses to them.  */
507       SCHED_NREG_MOVES (u) = nreg_moves;
508       old_reg = prev_reg = copy_rtx (SET_DEST (single_set (u->insn)));
509       last_reg_move = u->insn;
510
511       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
512         {
513           unsigned int i_use = 0;
514           rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
515           rtx reg_move = gen_move_insn (new_reg, prev_reg);
516           sbitmap_iterator sbi;
517
518           add_insn_before (reg_move, last_reg_move, NULL);
519           last_reg_move = reg_move;
520
521           if (!SCHED_FIRST_REG_MOVE (u))
522             SCHED_FIRST_REG_MOVE (u) = reg_move;
523
524           EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use, sbi)
525             {
526               struct undo_replace_buff_elem *rep;
527
528               rep = (struct undo_replace_buff_elem *)
529                     xcalloc (1, sizeof (struct undo_replace_buff_elem));
530               rep->insn = g->nodes[i_use].insn;
531               rep->orig_reg = old_reg;
532               rep->new_reg = new_reg;
533
534               if (! reg_move_replaces)
535                 reg_move_replaces = rep;
536               else
537                 {
538                   rep->next = reg_move_replaces;
539                   reg_move_replaces = rep;
540                 }
541
542               replace_rtx (g->nodes[i_use].insn, old_reg, new_reg);
543               if (rescan)
544                 df_insn_rescan (g->nodes[i_use].insn);
545             }
546
547           prev_reg = new_reg;
548         }
549       sbitmap_vector_free (uses_of_defs);
550     }
551   return reg_move_replaces;
552 }
553
554 /* Free memory allocated for the undo buffer.  */
555 static void
556 free_undo_replace_buff (struct undo_replace_buff_elem *reg_move_replaces)
557 {
558
559   while (reg_move_replaces)
560     {
561       struct undo_replace_buff_elem *rep = reg_move_replaces;
562
563       reg_move_replaces = reg_move_replaces->next;
564       free (rep);
565     }
566 }
567
568 /* Bump the SCHED_TIMEs of all nodes to start from zero.  Set the values
569    of SCHED_ROW and SCHED_STAGE.  */
570 static void
571 normalize_sched_times (partial_schedule_ptr ps)
572 {
573   int row;
574   int amount = PS_MIN_CYCLE (ps);
575   int ii = ps->ii;
576   ps_insn_ptr crr_insn;
577
578   for (row = 0; row < ii; row++)
579     for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
580       {
581         ddg_node_ptr u = crr_insn->node;
582         int normalized_time = SCHED_TIME (u) - amount;
583
584         if (dump_file)
585           fprintf (dump_file, "crr_insn->node=%d, crr_insn->cycle=%d,\
586                    min_cycle=%d\n", crr_insn->node->cuid, SCHED_TIME
587                    (u), ps->min_cycle);
588         gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
589         gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
590         SCHED_TIME (u) = normalized_time;
591         SCHED_ROW (u) = normalized_time % ii;
592         SCHED_STAGE (u) = normalized_time / ii;
593       }
594 }
595
596 /* Set SCHED_COLUMN of each node according to its position in PS.  */
597 static void
598 set_columns_for_ps (partial_schedule_ptr ps)
599 {
600   int row;
601
602   for (row = 0; row < ps->ii; row++)
603     {
604       ps_insn_ptr cur_insn = ps->rows[row];
605       int column = 0;
606
607       for (; cur_insn; cur_insn = cur_insn->next_in_row)
608         SCHED_COLUMN (cur_insn->node) = column++;
609     }
610 }
611
612 /* Permute the insns according to their order in PS, from row 0 to
613    row ii-1, and position them right before LAST.  This schedules
614    the insns of the loop kernel.  */
615 static void
616 permute_partial_schedule (partial_schedule_ptr ps, rtx last)
617 {
618   int ii = ps->ii;
619   int row;
620   ps_insn_ptr ps_ij;
621
622   for (row = 0; row < ii ; row++)
623     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
624       if (PREV_INSN (last) != ps_ij->node->insn)
625         reorder_insns_nobb (ps_ij->node->first_note, ps_ij->node->insn,
626                             PREV_INSN (last));
627 }
628
629 static void
630 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
631                            int to_stage, int for_prolog, rtx count_reg)
632 {
633   int row;
634   ps_insn_ptr ps_ij;
635
636   for (row = 0; row < ps->ii; row++)
637     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
638       {
639         ddg_node_ptr u_node = ps_ij->node;
640         int j, i_reg_moves;
641         rtx reg_move = NULL_RTX;
642
643         /* Do not duplicate any insn which refers to count_reg as it
644            belongs to the control part.
645            TODO: This should be done by analyzing the control part of
646            the loop.  */
647         if (reg_mentioned_p (count_reg, u_node->insn))
648           continue;
649
650         if (for_prolog)
651           {
652             /* SCHED_STAGE (u_node) >= from_stage == 0.  Generate increasing
653                number of reg_moves starting with the second occurrence of
654                u_node, which is generated if its SCHED_STAGE <= to_stage.  */
655             i_reg_moves = to_stage - SCHED_STAGE (u_node) + 1;
656             i_reg_moves = MAX (i_reg_moves, 0);
657             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
658
659             /* The reg_moves start from the *first* reg_move backwards.  */
660             if (i_reg_moves)
661               {
662                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
663                 for (j = 1; j < i_reg_moves; j++)
664                   reg_move = PREV_INSN (reg_move);
665               }
666           }
667         else /* It's for the epilog.  */
668           {
669             /* SCHED_STAGE (u_node) <= to_stage.  Generate all reg_moves,
670                starting to decrease one stage after u_node no longer occurs;
671                that is, generate all reg_moves until
672                SCHED_STAGE (u_node) == from_stage - 1.  */
673             i_reg_moves = SCHED_NREG_MOVES (u_node)
674                        - (from_stage - SCHED_STAGE (u_node) - 1);
675             i_reg_moves = MAX (i_reg_moves, 0);
676             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
677
678             /* The reg_moves start from the *last* reg_move forwards.  */
679             if (i_reg_moves)
680               {
681                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
682                 for (j = 1; j < SCHED_NREG_MOVES (u_node); j++)
683                   reg_move = PREV_INSN (reg_move);
684               }
685           }
686
687         for (j = 0; j < i_reg_moves; j++, reg_move = NEXT_INSN (reg_move))
688           emit_insn (copy_rtx (PATTERN (reg_move)));
689         if (SCHED_STAGE (u_node) >= from_stage
690             && SCHED_STAGE (u_node) <= to_stage)
691           duplicate_insn_chain (u_node->first_note, u_node->insn);
692       }
693 }
694
695
696 /* Generate the instructions (including reg_moves) for prolog & epilog.  */
697 static void
698 generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
699                         rtx count_reg, rtx count_init)
700 {
701   int i;
702   int last_stage = PS_STAGE_COUNT (ps) - 1;
703   edge e;
704   
705   /* Generate the prolog, inserting its insns on the loop-entry edge.  */
706   start_sequence ();
707
708   if (!count_init)
709     {
710       /* Generate instructions at the beginning of the prolog to
711          adjust the loop count by STAGE_COUNT.  If loop count is constant
712          (count_init), this constant is adjusted by STAGE_COUNT in
713          generate_prolog_epilog function.  */
714       rtx sub_reg = NULL_RTX;
715
716       sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS,
717                                      count_reg, GEN_INT (last_stage),
718                                      count_reg, 1, OPTAB_DIRECT);
719       gcc_assert (REG_P (sub_reg));
720       if (REGNO (sub_reg) != REGNO (count_reg))
721         emit_move_insn (count_reg, sub_reg);
722     }
723
724   for (i = 0; i < last_stage; i++)
725     duplicate_insns_of_cycles (ps, 0, i, 1, count_reg);
726   
727   /* Put the prolog on the entry edge.  */
728   e = loop_preheader_edge (loop);
729   split_edge_and_insert (e, get_insns ());
730
731   end_sequence ();
732
733   /* Generate the epilog, inserting its insns on the loop-exit edge.  */
734   start_sequence ();
735
736   for (i = 0; i < last_stage; i++)
737     duplicate_insns_of_cycles (ps, i + 1, last_stage, 0, count_reg);
738   
739   /* Put the epilogue on the exit edge.  */
740   gcc_assert (single_exit (loop));
741   e = single_exit (loop);
742   split_edge_and_insert (e, get_insns ());
743   end_sequence ();
744 }
745
746 /* Return true if all the BBs of the loop are empty except the
747    loop header.  */
748 static bool
749 loop_single_full_bb_p (struct loop *loop)
750 {
751   unsigned i;
752   basic_block *bbs = get_loop_body (loop);
753
754   for (i = 0; i < loop->num_nodes ; i++)
755     {
756       rtx head, tail;
757       bool empty_bb = true;
758
759       if (bbs[i] == loop->header)
760         continue;
761
762       /* Make sure that basic blocks other than the header
763          have only notes labels or jumps.  */
764       get_ebb_head_tail (bbs[i], bbs[i], &head, &tail);
765       for (; head != NEXT_INSN (tail); head = NEXT_INSN (head))
766         {
767           if (NOTE_P (head) || LABEL_P (head)
768               || (INSN_P (head) && JUMP_P (head)))
769             continue;
770           empty_bb = false;
771           break;
772         }
773
774       if (! empty_bb)
775         {
776           free (bbs);
777           return false;
778         }
779     }
780   free (bbs);
781   return true;
782 }
783
784 /* A simple loop from SMS point of view; it is a loop that is composed of
785    either a single basic block or two BBs - a header and a latch.  */
786 #define SIMPLE_SMS_LOOP_P(loop) ((loop->num_nodes < 3 )                     \
787                                   && (EDGE_COUNT (loop->latch->preds) == 1) \
788                                   && (EDGE_COUNT (loop->latch->succs) == 1))
789
790 /* Return true if the loop is in its canonical form and false if not.
791    i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit.  */
792 static bool
793 loop_canon_p (struct loop *loop)
794 {
795
796   if (loop->inner || !loop_outer (loop))
797     return false;
798
799   if (!single_exit (loop))
800     {
801       if (dump_file)
802         {
803           rtx insn = BB_END (loop->header);
804  
805           fprintf (dump_file, "SMS loop many exits ");
806                   fprintf (dump_file, " %s %d (file, line)\n",
807                            insn_file (insn), insn_line (insn));
808         }
809       return false;
810     }
811
812   if (! SIMPLE_SMS_LOOP_P (loop) && ! loop_single_full_bb_p (loop))
813     {
814       if (dump_file)
815         {
816           rtx insn = BB_END (loop->header);
817  
818           fprintf (dump_file, "SMS loop many BBs. ");
819           fprintf (dump_file, " %s %d (file, line)\n",
820                    insn_file (insn), insn_line (insn));
821         }
822       return false;
823     }
824
825     return true;
826 }
827
828 /* If there are more than one entry for the loop,
829    make it one by splitting the first entry edge and
830    redirecting the others to the new BB.  */
831 static void
832 canon_loop (struct loop *loop)
833 {
834   edge e;
835   edge_iterator i;
836
837   /* Avoid annoying special cases of edges going to exit
838      block.  */
839   FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
840     if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
841       split_edge (e);
842
843   if (loop->latch == loop->header
844       || EDGE_COUNT (loop->latch->succs) > 1)
845     {
846       FOR_EACH_EDGE (e, i, loop->header->preds)
847         if (e->src == loop->latch)
848           break;
849       split_edge (e);
850     }
851 }
852
853 /* Probability in % that the sms-ed loop rolls enough so that optimized
854    version may be entered.  Just a guess.  */
855 #define PROB_SMS_ENOUGH_ITERATIONS 80
856
857 /* Used to calculate the upper bound of ii.  */
858 #define MAXII_FACTOR 2
859
860 /* Main entry point, perform SMS scheduling on the loops of the function
861    that consist of single basic blocks.  */
862 static void
863 sms_schedule (void)
864 {
865   static int passes = 0;
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 ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
923         {
924           if (dump_file)
925             fprintf (dump_file, "SMS reached MAX_PASSES... \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 |
2657   TODO_dump_func |
2658   TODO_ggc_collect,                     /* todo_flags_finish */
2659   'm'                                   /* letter */
2660 };
2661