OSDN Git Service

2004-08-08 Mostafa Hagog <mustafa@il.ibm.com>
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
1 /* Swing Modulo Scheduling implementation.
2    Copyright (C) 2004
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 2, 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 COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "toplev.h"
29 #include "rtl.h"
30 #include "tm_p.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "regs.h"
34 #include "function.h"
35 #include "flags.h"
36 #include "insn-config.h"
37 #include "insn-attr.h"
38 #include "except.h"
39 #include "toplev.h"
40 #include "recog.h"
41 #include "sched-int.h"
42 #include "target.h"
43 #include "cfglayout.h"
44 #include "cfgloop.h"
45 #include "cfghooks.h"
46 #include "expr.h"
47 #include "params.h"
48 #include "gcov-io.h"
49 #include "df.h"
50 #include "ddg.h"
51
52 #ifdef INSN_SCHEDULING
53
54 /* This file contains the implementation of the Swing Modulo Scheduler,
55    described in the following references:
56    [1] J. Llosa, A. Gonzalez, E. Ayguade, M. Valero., and J. Eckhardt.
57        Lifetime--sensitive modulo scheduling in a production environment.
58        IEEE Trans. on Comps., 50(3), March 2001
59    [2] J. Llosa, A. Gonzalez, E. Ayguade, and M. Valero.
60        Swing Modulo Scheduling: A Lifetime Sensitive Approach.
61        PACT '96 , pages 80-87, October 1996 (Boston - Massachusetts - USA).
62
63    The basic structure is:
64    1. Build a data-dependence graph (DDG) for each loop.
65    2. Use the DDG to order the insns of a loop (not in topological order
66       necessarily, but rather) trying to place each insn after all its
67       predecessors _or_ after all its successors.
68    3. Compute MII: a lower bound on the number of cycles to schedule the loop.
69    4. Use the ordering to perform list-scheduling of the loop:
70       1. Set II = MII.  We will try to schedule the loop within II cycles.
71       2. Try to schedule the insns one by one according to the ordering.
72          For each insn compute an interval of cycles by considering already-
73          scheduled preds and succs (and associated latencies); try to place
74          the insn in the cycles of this window checking for potential
75          resource conflicts (using the DFA interface).
76          Note: this is different from the cycle-scheduling of schedule_insns;
77          here the insns are not scheduled monotonically top-down (nor bottom-
78          up).
79       3. If failed in scheduling all insns - bump II++ and try again, unless
80          II reaches an upper bound MaxII, in which case report failure.
81    5. If we succeeded in scheduling the loop within II cycles, we now
82       generate prolog and epilog, decrease the counter of the loop, and
83       perform modulo variable expansion for live ranges that span more than
84       II cycles (i.e. use register copies to prevent a def from overwriting
85       itself before reaching the use).
86 */
87
88 \f
89 /* This page defines partial-schedule structures and functions for
90    modulo scheduling.  */
91
92 typedef struct partial_schedule *partial_schedule_ptr;
93 typedef struct ps_insn *ps_insn_ptr;
94
95 /* The minimum (absolute) cycle that a node of ps was scheduled in.  */
96 #define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle)
97
98 /* The maximum (absolute) cycle that a node of ps was scheduled in.  */
99 #define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle)
100
101 /* Perform signed modulo, always returning a non-negative value.  */
102 #define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y))
103
104 /* The number of different iterations the nodes in ps span, assuming
105    the stage boundaries are placed efficiently.  */
106 #define PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
107                              + 1 + (ps)->ii - 1) / (ps)->ii)
108
109 #define CFG_HOOKS cfg_layout_rtl_cfg_hooks
110
111 /* A single instruction in the partial schedule.  */
112 struct ps_insn
113 {
114   /* The corresponding DDG_NODE.  */
115   ddg_node_ptr node;
116
117   /* The (absolute) cycle in which the PS instruction is scheduled.
118      Same as SCHED_TIME (node).  */
119   int cycle;
120
121   /* The next/prev PS_INSN in the same row.  */
122   ps_insn_ptr next_in_row,
123               prev_in_row;
124
125   /* The number of nodes in the same row that come after this node.  */
126   int row_rest_count;
127 };
128
129 /* Holds the partial schedule as an array of II rows.  Each entry of the
130    array points to a linked list of PS_INSNs, which represents the
131    instructions that are scheduled for that row.  */
132 struct partial_schedule
133 {
134   int ii;       /* Number of rows in the partial schedule.  */
135   int history;  /* Threshold for conflict checking using DFA.  */
136
137   /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii).  */
138   ps_insn_ptr *rows;
139
140   /* The earliest absolute cycle of an insn in the partial schedule.  */
141   int min_cycle;
142
143   /* The latest absolute cycle of an insn in the partial schedule.  */
144   int max_cycle;
145
146   ddg_ptr g;    /* The DDG of the insns in the partial schedule.  */
147 };
148
149
150 partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
151 void free_partial_schedule (partial_schedule_ptr);
152 void reset_partial_schedule (partial_schedule_ptr, int new_ii);
153 void print_partial_schedule (partial_schedule_ptr, FILE *);
154 ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
155                                          ddg_node_ptr node, int cycle,
156                                          sbitmap must_precede,
157                                          sbitmap must_follow);
158 void rotate_partial_schedule (partial_schedule_ptr, int);
159 void set_row_column_for_ps (partial_schedule_ptr);
160
161 \f
162 /* This page defines constants and structures for the modulo scheduling
163    driver.  */
164
165 /* As in haifa-sched.c:  */
166 /* issue_rate is the number of insns that can be scheduled in the same
167    machine cycle.  It can be defined in the config/mach/mach.h file,
168    otherwise we set it to 1.  */
169
170 static int issue_rate;
171
172 /* For printing statistics.  */
173 static FILE *stats_file;
174
175 static int sms_order_nodes (ddg_ptr, int, int * result);
176 static void set_node_sched_params (ddg_ptr);
177 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int,
178                                                    int *, FILE*);
179 static void permute_partial_schedule (partial_schedule_ptr ps, rtx last);
180 static void generate_prolog_epilog (partial_schedule_ptr, rtx, rtx, int);
181 static void duplicate_insns_of_cycles (partial_schedule_ptr ps,
182                                        int from_stage, int to_stage,
183                                        int is_prolog);
184
185
186 #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
187 #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
188 #define SCHED_FIRST_REG_MOVE(x) \
189         (((node_sched_params_ptr)(x)->aux.info)->first_reg_move)
190 #define SCHED_NREG_MOVES(x) \
191         (((node_sched_params_ptr)(x)->aux.info)->nreg_moves)
192 #define SCHED_ROW(x) (((node_sched_params_ptr)(x)->aux.info)->row)
193 #define SCHED_STAGE(x) (((node_sched_params_ptr)(x)->aux.info)->stage)
194 #define SCHED_COLUMN(x) (((node_sched_params_ptr)(x)->aux.info)->column)
195
196 /* The scheduling parameters held for each node.  */
197 typedef struct node_sched_params
198 {
199   int asap;     /* A lower-bound on the absolute scheduling cycle.  */
200   int time;     /* The absolute scheduling cycle (time >= asap).  */
201
202   /* The following field (first_reg_move) is a pointer to the first
203      register-move instruction added to handle the modulo-variable-expansion
204      of the register defined by this node.  This register-move copies the
205      original register defined by the node.  */
206   rtx first_reg_move;
207
208   /* The number of register-move instructions added, immediately preceding
209      first_reg_move.  */
210   int nreg_moves;
211
212   int row;    /* Holds time % ii.  */
213   int stage;  /* Holds time / ii.  */
214
215   /* The column of a node inside the ps.  If nodes u, v are on the same row,
216      u will precede v if column (u) < column (v).  */
217   int column;
218 } *node_sched_params_ptr;
219
220 \f
221 /* The following three functions are copied from the current scheduler
222    code in order to use sched_analyze() for computing the dependencies.
223    They are used when initializing the sched_info structure.  */
224 static const char *
225 sms_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
226 {
227   static char tmp[80];
228
229   sprintf (tmp, "i%4d", INSN_UID (insn));
230   return tmp;
231 }
232
233 static int
234 contributes_to_priority (rtx next, rtx insn)
235 {
236   return BLOCK_NUM (next) == BLOCK_NUM (insn);
237 }
238
239 static void
240 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
241                                regset cond_exec ATTRIBUTE_UNUSED,
242                                regset used ATTRIBUTE_UNUSED,
243                                regset set ATTRIBUTE_UNUSED)
244 {
245 }
246
247 static struct sched_info sms_sched_info =
248 {
249   NULL,
250   NULL,
251   NULL,
252   NULL,
253   NULL,
254   sms_print_insn,
255   contributes_to_priority,
256   compute_jump_reg_dependencies,
257   NULL, NULL,
258   NULL, NULL,
259   0, 0, 0
260 };
261
262
263 /* Return the register decremented and tested or zero if it is not a decrement
264    and branch jump insn (similar to doloop_condition_get).  */
265 static rtx
266 doloop_register_get (rtx insn, rtx *comp)
267 {
268   rtx pattern, cmp, inc, reg, condition;
269
270   if (!JUMP_P (insn))
271     return NULL_RTX;
272   pattern = PATTERN (insn);
273
274   /* The canonical doloop pattern we expect is:
275
276      (parallel [(set (pc) (if_then_else (condition)
277                                         (label_ref (label))
278                                         (pc)))
279                 (set (reg) (plus (reg) (const_int -1)))
280                 (additional clobbers and uses)])
281
282     where condition is further restricted to be
283       (ne (reg) (const_int 1)).  */
284
285   if (GET_CODE (pattern) != PARALLEL)
286     return NULL_RTX;
287
288   cmp = XVECEXP (pattern, 0, 0);
289   inc = XVECEXP (pattern, 0, 1);
290   /* Return the compare rtx.  */
291   *comp = cmp;
292
293   /* Check for (set (reg) (something)).  */
294   if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
295     return NULL_RTX;
296
297   /* Extract loop counter register.  */
298   reg = SET_DEST (inc);
299
300   /* Check if something = (plus (reg) (const_int -1)).  */
301   if (GET_CODE (SET_SRC (inc)) != PLUS
302       || XEXP (SET_SRC (inc), 0) != reg
303       || XEXP (SET_SRC (inc), 1) != constm1_rtx)
304     return NULL_RTX;
305
306   /* Check for (set (pc) (if_then_else (condition)
307                                        (label_ref (label))
308                                        (pc))).  */
309   if (GET_CODE (cmp) != SET
310       || SET_DEST (cmp) != pc_rtx
311       || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
312       || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
313       || XEXP (SET_SRC (cmp), 2) != pc_rtx)
314     return NULL_RTX;
315
316   /* Extract loop termination condition.  */
317   condition = XEXP (SET_SRC (cmp), 0);
318
319   /* Check if condition = (ne (reg) (const_int 1)), which is more
320      restrictive than the check in doloop_condition_get:
321      if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
322          || GET_CODE (XEXP (condition, 1)) != CONST_INT).  */
323   if (GET_CODE (condition) != NE
324       || XEXP (condition, 1) != const1_rtx)
325     return NULL_RTX;
326
327   if (XEXP (condition, 0) == reg)
328     return reg;
329
330   return NULL_RTX;
331 }
332
333 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
334    that the number of iterations is a compile-time constant.  If so,
335    return the rtx that sets COUNT_REG to a constant, and set COUNT to
336    this constant.  Otherwise return 0.  */
337 static rtx
338 const_iteration_count (rtx count_reg, basic_block pre_header,
339                        HOST_WIDEST_INT * count)
340 {
341   rtx insn;
342   rtx head, tail;
343   get_block_head_tail (pre_header->index, &head, &tail);
344
345   for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
346     if (INSN_P (insn) && single_set (insn) &&
347         rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
348       {
349         rtx pat = single_set (insn);
350
351         if (GET_CODE (SET_SRC (pat)) == CONST_INT)
352           {
353             *count = INTVAL (SET_SRC (pat));
354             return insn;
355           }
356
357         return NULL_RTX;
358       }
359
360   return NULL_RTX;
361 }
362
363 /* A very simple resource-based lower bound on the initiation interval.
364    ??? Improve the accuracy of this bound by considering the
365    utilization of various units.  */
366 static int
367 res_MII (ddg_ptr g)
368 {
369   return (g->num_nodes / issue_rate);
370 }
371
372
373 /* Points to the array that contains the sched data for each node.  */
374 static node_sched_params_ptr node_sched_params;
375
376 /* Allocate sched_params for each node and initialize it.  Assumes that
377    the aux field of each node contain the asap bound (computed earlier),
378    and copies it into the sched_params field.  */
379 static void
380 set_node_sched_params (ddg_ptr g)
381 {
382   int i;
383
384   /* Allocate for each node in the DDG a place to hold the "sched_data".  */
385   /* Initialize ASAP/ALAP/HIGHT to zero.  */
386   node_sched_params = (node_sched_params_ptr)
387                        xcalloc (g->num_nodes,
388                                 sizeof (struct node_sched_params));
389
390   /* Set the pointer of the general data of the node to point to the
391      appropriate sched_params structure.  */
392   for (i = 0; i < g->num_nodes; i++)
393     {
394       /* Watch out for aliasing problems?  */
395       node_sched_params[i].asap = g->nodes[i].aux.count;
396       g->nodes[i].aux.info = &node_sched_params[i];
397     }
398 }
399
400 static void
401 print_node_sched_params (FILE * dump_file, int num_nodes)
402 {
403   int i;
404
405   for (i = 0; i < num_nodes; i++)
406     {
407       node_sched_params_ptr nsp = &node_sched_params[i];
408       rtx reg_move = nsp->first_reg_move;
409       int j;
410
411       fprintf (dump_file, "Node %d:\n", i);
412       fprintf (dump_file, " asap = %d:\n", nsp->asap);
413       fprintf (dump_file, " time = %d:\n", nsp->time);
414       fprintf (dump_file, " nreg_moves = %d:\n", nsp->nreg_moves);
415       for (j = 0; j < nsp->nreg_moves; j++)
416         {
417           fprintf (dump_file, " reg_move = ");
418           print_rtl_single (dump_file, reg_move);
419           reg_move = PREV_INSN (reg_move);
420         }
421     }
422 }
423
424 /* Calculate an upper bound for II.  SMS should not schedule the loop if it
425    requires more cycles than this bound.  Currently set to the sum of the
426    longest latency edge for each node.  Reset based on experiments.  */
427 static int
428 calculate_maxii (ddg_ptr g)
429 {
430   int i;
431   int maxii = 0;
432
433   for (i = 0; i < g->num_nodes; i++)
434     {
435       ddg_node_ptr u = &g->nodes[i];
436       ddg_edge_ptr e;
437       int max_edge_latency = 0;
438
439       for (e = u->out; e; e = e->next_out)
440         max_edge_latency = MAX (max_edge_latency, e->latency);
441
442       maxii += max_edge_latency;
443     }
444   return maxii;
445 }
446
447
448 /* Given the partial schedule, generate register moves when the length
449    of the register live range is more than ii; the number of moves is
450    determined according to the following equation:
451                 SCHED_TIME (use) - SCHED_TIME (def)   { 1 broken loop-carried
452    nreg_moves = ----------------------------------- - {   dependence.
453                               ii                      { 0 if not.
454    This handles the modulo-variable-expansions (mve's) needed for the ps.  */
455 static void
456 generate_reg_moves (partial_schedule_ptr ps)
457 {
458   ddg_ptr g = ps->g;
459   int ii = ps->ii;
460   int i;
461
462   for (i = 0; i < g->num_nodes; i++)
463     {
464       ddg_node_ptr u = &g->nodes[i];
465       ddg_edge_ptr e;
466       int nreg_moves = 0, i_reg_move;
467       sbitmap *uses_of_defs;
468       rtx last_reg_move;
469       rtx prev_reg, old_reg;
470
471       /* Compute the number of reg_moves needed for u, by looking at life
472          ranges started at u (excluding self-loops).  */
473       for (e = u->out; e; e = e->next_out)
474         if (e->type == TRUE_DEP && e->dest != e->src)
475           {
476             int nreg_moves4e = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
477
478             /* If dest precedes src in the schedule of the kernel, then dest
479                will read before src writes and we can save one reg_copy.  */
480             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
481                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
482               nreg_moves4e--;
483
484             nreg_moves = MAX (nreg_moves, nreg_moves4e);
485           }
486
487       if (nreg_moves == 0)
488         continue;
489
490       /* Every use of the register defined by node may require a different
491          copy of this register, depending on the time the use is scheduled.
492          Set a bitmap vector, telling which nodes use each copy of this
493          register.  */
494       uses_of_defs = sbitmap_vector_alloc (nreg_moves, g->num_nodes);
495       sbitmap_vector_zero (uses_of_defs, nreg_moves);
496       for (e = u->out; e; e = e->next_out)
497         if (e->type == TRUE_DEP && e->dest != e->src)
498           {
499             int dest_copy = (SCHED_TIME (e->dest) - SCHED_TIME (e->src)) / ii;
500
501             if (SCHED_ROW (e->dest) == SCHED_ROW (e->src)
502                 && SCHED_COLUMN (e->dest) < SCHED_COLUMN (e->src))
503               dest_copy--;
504
505             if (dest_copy)
506               SET_BIT (uses_of_defs[dest_copy - 1], e->dest->cuid);
507           }
508
509       /* Now generate the reg_moves, attaching relevant uses to them.  */
510       SCHED_NREG_MOVES (u) = nreg_moves;
511       old_reg = prev_reg = copy_rtx (SET_DEST (single_set (u->insn)));
512       last_reg_move = u->insn;
513
514       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
515         {
516           int i_use;
517           rtx new_reg = gen_reg_rtx (GET_MODE (prev_reg));
518           rtx reg_move = gen_move_insn (new_reg, prev_reg);
519
520           add_insn_before (reg_move, last_reg_move);
521           last_reg_move = reg_move;
522
523           if (!SCHED_FIRST_REG_MOVE (u))
524             SCHED_FIRST_REG_MOVE (u) = reg_move;
525
526           EXECUTE_IF_SET_IN_SBITMAP (uses_of_defs[i_reg_move], 0, i_use,
527             replace_rtx (g->nodes[i_use].insn, old_reg, new_reg));
528
529           prev_reg = new_reg;
530         }
531     }
532 }
533
534 /* Bump the SCHED_TIMEs of all nodes to start from zero.  Set the values
535    of SCHED_ROW and SCHED_STAGE.  */
536 static void
537 normalize_sched_times (partial_schedule_ptr ps)
538 {
539   int i;
540   ddg_ptr g = ps->g;
541   int amount = PS_MIN_CYCLE (ps);
542   int ii = ps->ii;
543
544   for (i = 0; i < g->num_nodes; i++)
545     {
546       ddg_node_ptr u = &g->nodes[i];
547       int normalized_time = SCHED_TIME (u) - amount;
548
549       if (normalized_time < 0)
550         abort ();
551
552       SCHED_TIME (u) = normalized_time;
553       SCHED_ROW (u) = normalized_time % ii;
554       SCHED_STAGE (u) = normalized_time / ii;
555     }
556 }
557
558 /* Set SCHED_COLUMN of each node according to its position in PS.  */
559 static void
560 set_columns_for_ps (partial_schedule_ptr ps)
561 {
562   int row;
563
564   for (row = 0; row < ps->ii; row++)
565     {
566       ps_insn_ptr cur_insn = ps->rows[row];
567       int column = 0;
568
569       for (; cur_insn; cur_insn = cur_insn->next_in_row)
570         SCHED_COLUMN (cur_insn->node) = column++;
571     }
572 }
573
574 /* Permute the insns according to their order in PS, from row 0 to
575    row ii-1, and position them right before LAST.  This schedules
576    the insns of the loop kernel.  */
577 static void
578 permute_partial_schedule (partial_schedule_ptr ps, rtx last)
579 {
580   int ii = ps->ii;
581   int row;
582   ps_insn_ptr ps_ij;
583
584   for (row = 0; row < ii ; row++)
585     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
586       if (PREV_INSN (last) != ps_ij->node->insn)
587         reorder_insns_nobb (ps_ij->node->first_note, ps_ij->node->insn,
588                             PREV_INSN (last));
589 }
590
591 /* Used to generate the prologue & epilogue.  Duplicate the subset of
592    nodes whose stages are between FROM_STAGE and TO_STAGE (inclusive
593    of both), together with a prefix/suffix of their reg_moves.  */
594 static void
595 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
596                            int to_stage, int for_prolog)
597 {
598   int row;
599   ps_insn_ptr ps_ij;
600
601   for (row = 0; row < ps->ii; row++)
602     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
603       {
604         ddg_node_ptr u_node = ps_ij->node;
605         int j, i_reg_moves;
606         rtx reg_move = NULL_RTX;
607
608         if (for_prolog)
609           {
610             /* SCHED_STAGE (u_node) >= from_stage == 0.  Generate increasing
611                number of reg_moves starting with the second occurrence of
612                u_node, which is generated if its SCHED_STAGE <= to_stage.  */
613             i_reg_moves = to_stage - SCHED_STAGE (u_node);
614             i_reg_moves = MAX (i_reg_moves, 0);
615             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
616
617             /* The reg_moves start from the *first* reg_move backwards.  */
618             if (i_reg_moves)
619               {
620                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
621                 for (j = 1; j < i_reg_moves; j++)
622                   reg_move = PREV_INSN (reg_move);
623               }
624           }
625         else /* It's for the epilog.  */
626           {
627             /* SCHED_STAGE (u_node) <= to_stage.  Generate all reg_moves,
628                starting to decrease one stage after u_node no longer occurs;
629                that is, generate all reg_moves until
630                SCHED_STAGE (u_node) == from_stage - 1.  */
631             i_reg_moves = SCHED_NREG_MOVES (u_node)
632                        - (from_stage - SCHED_STAGE (u_node) - 1);
633             i_reg_moves = MAX (i_reg_moves, 0);
634             i_reg_moves = MIN (i_reg_moves, SCHED_NREG_MOVES (u_node));
635
636             /* The reg_moves start from the *last* reg_move forwards.  */
637             if (i_reg_moves)
638               {
639                 reg_move = SCHED_FIRST_REG_MOVE (u_node);
640                 for (j = 1; j < SCHED_NREG_MOVES (u_node); j++)
641                   reg_move = PREV_INSN (reg_move);
642               }
643           }
644
645         for (j = 0; j < i_reg_moves; j++, reg_move = NEXT_INSN (reg_move))
646           emit_insn (copy_rtx (PATTERN (reg_move)));
647
648         if (SCHED_STAGE (u_node) >= from_stage
649             && SCHED_STAGE (u_node) <= to_stage)
650           duplicate_insn_chain (u_node->first_note, u_node->insn);
651       }
652 }
653
654
655 /* Generate the instructions (including reg_moves) for prolog & epilog.  */
656 static void
657 generate_prolog_epilog (partial_schedule_ptr ps, rtx orig_loop_beg,
658                         rtx orig_loop_end, int unknown_count)
659 {
660   int i;
661   int last_stage = PS_STAGE_COUNT (ps) - 1;
662   edge e;
663   rtx c_reg = NULL_RTX;
664   rtx cmp = NULL_RTX;
665   rtx precond_jump = NULL_RTX;
666   rtx precond_exit_label = NULL_RTX;
667   rtx precond_exit_label_insn = NULL_RTX;
668   rtx last_epilog_insn = NULL_RTX;
669   rtx loop_exit_label = NULL_RTX;
670   rtx loop_exit_label_insn = NULL_RTX;
671   rtx orig_loop_bct = NULL_RTX;
672
673   /* Loop header edge.  */
674   e = ps->g->bb->pred;
675   if (e->src == ps->g->bb)
676     e = e->pred_next;
677
678   /* Generate the prolog, inserting its insns on the loop-entry edge.  */
679   start_sequence ();
680
681   /* This is the place where we want to insert the precondition.  */
682   if (unknown_count)
683     precond_jump = emit_note (NOTE_INSN_DELETED);
684
685   for (i = 0; i < last_stage; i++)
686     duplicate_insns_of_cycles (ps, 0, i, 1);
687
688   /* No need to call insert_insn_on_edge; we prepared the sequence.  */
689   e->insns.r = get_insns ();
690   end_sequence ();
691
692   /* Generate the epilog, inserting its insns on the loop-exit edge.  */
693   start_sequence ();
694
695   for (i = 0; i < last_stage; i++)
696     duplicate_insns_of_cycles (ps, i + 1, last_stage, 0);
697
698   last_epilog_insn = emit_note (NOTE_INSN_DELETED);
699
700   /* Emit the label where to put the original loop code.  */
701   if (unknown_count)
702     {
703       rtx label, cond;
704
705       precond_exit_label = gen_label_rtx ();
706       precond_exit_label_insn = emit_label (precond_exit_label);
707
708       /* Put the original loop code.  */
709       reorder_insns_nobb (orig_loop_beg, orig_loop_end, precond_exit_label_insn);
710
711       /* Change the label of the BCT to be the PRECOND_EXIT_LABEL.  */
712       orig_loop_bct = get_last_insn ();
713       c_reg = doloop_register_get (orig_loop_bct, &cmp);
714       label = XEXP (SET_SRC (cmp), 1);
715       cond = XEXP (SET_SRC (cmp), 0);
716
717       if (! c_reg || GET_CODE (cond) != NE)
718         abort ();
719
720       XEXP (label, 0) = precond_exit_label;
721       JUMP_LABEL (orig_loop_bct) = precond_exit_label_insn;
722       LABEL_NUSES (precond_exit_label_insn)++;
723
724       /* Generate the loop exit label.  */
725       loop_exit_label = gen_label_rtx ();
726       loop_exit_label_insn = emit_label (loop_exit_label);
727     }
728
729   e = ps->g->bb->succ;
730   if (e->dest == ps->g->bb)
731     e = e->succ_next;
732
733   e->insns.r = get_insns ();
734   end_sequence ();
735
736   commit_edge_insertions ();
737
738   if (unknown_count)
739     {
740       rtx precond_insns, epilog_jump, insert_after_insn;
741       basic_block loop_exit_bb = BLOCK_FOR_INSN (loop_exit_label_insn);
742       basic_block epilog_bb = BLOCK_FOR_INSN (last_epilog_insn);
743       basic_block precond_bb = BLOCK_FOR_INSN (precond_jump);
744       basic_block orig_loop_bb = BLOCK_FOR_INSN (precond_exit_label_insn);
745       edge epilog_exit_edge = epilog_bb->succ;
746
747       /* Do loop preconditioning to take care of cases were the loop count is
748          less than the stage count.  Update the CFG properly.  */
749       insert_after_insn = precond_jump;
750       start_sequence ();
751       c_reg = doloop_register_get (ps->g->closing_branch->insn, &cmp);
752       emit_cmp_and_jump_insns (c_reg, GEN_INT (PS_STAGE_COUNT (ps)), LT, NULL,
753                                GET_MODE (c_reg), 1, precond_exit_label);
754       precond_insns = get_insns ();
755       precond_jump = get_last_insn ();
756       end_sequence ();
757       reorder_insns (precond_insns, precond_jump, insert_after_insn);
758
759       /* Generate a subtract instruction at the beginning of the prolog to
760          adjust the loop count by STAGE_COUNT.  */
761       emit_insn_after (gen_sub2_insn (c_reg, GEN_INT (PS_STAGE_COUNT (ps) - 1)),
762                        precond_jump);
763       update_bb_for_insn (precond_bb);
764       delete_insn (insert_after_insn);
765
766       /* Update label info for the precondition jump.  */
767       JUMP_LABEL (precond_jump) = precond_exit_label_insn;
768       LABEL_NUSES (precond_exit_label_insn)++;
769
770       /* Update the CFG.  */
771       split_block (precond_bb, precond_jump);
772       make_edge (precond_bb, orig_loop_bb, 0);
773
774       /* Add a jump at end of the epilog to the LOOP_EXIT_LABEL to jump over the
775          original loop copy and update the CFG.  */
776       epilog_jump = emit_jump_insn_after (gen_jump (loop_exit_label),
777                                           last_epilog_insn);
778       delete_insn (last_epilog_insn);
779       JUMP_LABEL (epilog_jump) = loop_exit_label_insn;
780       LABEL_NUSES (loop_exit_label_insn)++;
781
782       redirect_edge_succ (epilog_exit_edge, loop_exit_bb);
783       epilog_exit_edge->flags &= ~EDGE_FALLTHRU;
784       emit_barrier_after (BB_END (epilog_bb));
785     }
786 }
787
788 /* Return the line note insn preceding INSN, for debugging.  Taken from
789    emit-rtl.c.  */
790 static rtx
791 find_line_note (rtx insn)
792 {
793   for (; insn; insn = PREV_INSN (insn))
794     if (NOTE_P (insn)
795         && NOTE_LINE_NUMBER (insn) >= 0)
796       break;
797
798   return insn;
799 }
800
801 /* Main entry point, perform SMS scheduling on the loops of the function
802    that consist of single basic blocks.  */
803 void
804 sms_schedule (FILE *dump_file)
805 {
806   static int passes = 0;
807   rtx insn;
808   ddg_ptr *g_arr, g;
809   basic_block bb, pre_header = NULL;
810   int * node_order;
811   int maxii;
812   int i;
813   partial_schedule_ptr ps;
814   int max_bb_index = last_basic_block;
815   struct df *df;
816
817   stats_file = dump_file;
818
819   /* Initialize issue_rate.  */
820   if (targetm.sched.issue_rate)
821     {
822       int temp = reload_completed;
823
824       reload_completed = 1;
825       issue_rate = (*targetm.sched.issue_rate) ();
826       reload_completed = temp;
827     }
828   else
829     issue_rate = 1;
830
831   /* Initialize the scheduler.  */
832   current_sched_info = &sms_sched_info;
833   sched_init (NULL);
834
835   /* Init Data Flow analysis, to be used in interloop dep calculation.  */
836   df = df_init ();
837   df_analyze (df, 0, DF_ALL);
838
839   /* Allocate memory to hold the DDG array.  */
840   g_arr = xcalloc (max_bb_index, sizeof (ddg_ptr));
841
842   /* Build DDGs for all the relevant loops and hold them in G_ARR
843      indexed by the loop BB index.  */
844   FOR_EACH_BB (bb)
845     {
846       rtx head, tail;
847       rtx count_reg, comp;
848       edge e, pre_header_edge;
849
850       if (bb->index < 0)
851         continue;
852
853       /* Check if bb has two successors, one being itself.  */
854       e = bb->succ;
855       if (!e || !e->succ_next || e->succ_next->succ_next)
856         continue;
857
858       if (e->dest != bb && e->succ_next->dest != bb)
859         continue;
860
861       if ((e->flags & EDGE_COMPLEX)
862           || (e->succ_next->flags & EDGE_COMPLEX))
863         continue;
864
865       /* Check if bb has two predecessors, one being itself.  */
866       /* In view of above tests, suffices to check e->pred_next->pred_next?  */
867       e = bb->pred;
868       if (!e || !e->pred_next || e->pred_next->pred_next)
869         continue;
870
871       if (e->src != bb && e->pred_next->src != bb)
872         continue;
873
874       if ((e->flags & EDGE_COMPLEX)
875           || (e->pred_next->flags & EDGE_COMPLEX))
876         continue;
877
878       /* For debugging.  */
879       if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
880         {
881           if (dump_file)
882             fprintf (dump_file, "SMS reached MAX_PASSES... \n");
883           break;
884         }
885
886       get_block_head_tail (bb->index, &head, &tail);
887       pre_header_edge = bb->pred;
888       if (bb->pred->src != bb)
889         pre_header_edge = bb->pred->pred_next;
890
891       /* Perfrom SMS only on loops that their average count is above threshold.  */
892       if (bb->count < pre_header_edge->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD)
893         {
894           if (stats_file)
895             {
896               rtx line_note = find_line_note (tail);
897
898               if (line_note)
899                 {
900                   expanded_location xloc;
901                   NOTE_EXPANDED_LOCATION (xloc, line_note);
902                   fprintf (stats_file, "SMS bb %s %d (file, line)\n",
903                            xloc.file, xloc.line);
904                 }
905               fprintf (stats_file, "SMS single-bb-loop\n");
906               if (profile_info && flag_branch_probabilities)
907                 {
908                   fprintf (stats_file, "SMS loop-count ");
909                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
910                            (HOST_WIDEST_INT) bb->count);
911                   fprintf (stats_file, "\n");
912                   fprintf (stats_file, "SMS preheader-count ");
913                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
914                            (HOST_WIDEST_INT) pre_header_edge->count);
915                   fprintf (stats_file, "\n");
916                   fprintf (stats_file, "SMS profile-sum-max ");
917                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
918                            (HOST_WIDEST_INT) profile_info->sum_max);
919                   fprintf (stats_file, "\n");
920                 }
921             }
922           continue;
923         }
924
925       /* Make sure this is a doloop.  */
926       if ( !(count_reg = doloop_register_get (tail, &comp)))
927         continue;
928
929       e = bb->pred;
930       if (e->src == bb)
931         pre_header = e->pred_next->src;
932       else
933         pre_header = e->src;
934
935       /* Don't handle BBs with calls or barriers, or !single_set insns.  */
936       for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
937         if (CALL_P (insn)
938             || BARRIER_P (insn)
939             || (INSN_P (insn) && !JUMP_P (insn)
940                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
941           break;
942
943       if (insn != NEXT_INSN (tail))
944         {
945           if (stats_file)
946             {
947               if (CALL_P (insn))
948                 fprintf (stats_file, "SMS loop-with-call\n");
949               else if (BARRIER_P (insn))
950                 fprintf (stats_file, "SMS loop-with-barrier\n");
951               else
952                 fprintf (stats_file, "SMS loop-with-not-single-set\n");
953               print_rtl_single (stats_file, insn);
954             }
955
956           continue;
957         }
958
959       if (! (g = create_ddg (bb, df, 0)))
960         {
961           if (stats_file)
962             fprintf (stats_file, "SMS doloop\n");
963           continue;
964         }
965
966       g_arr[bb->index] = g;
967     }
968
969   /* Release Data Flow analysis data structures.  */
970   df_finish (df);
971
972   /* Go over the built DDGs and perfrom SMS for each one of them.  */
973   for (i = 0; i < max_bb_index; i++)
974     {
975       rtx head, tail;
976       rtx count_reg, count_init, comp;
977       edge pre_header_edge;
978       int mii, rec_mii;
979       int stage_count = 0;
980       HOST_WIDEST_INT loop_count = 0;
981
982       if (! (g = g_arr[i]))
983         continue;
984
985       if (dump_file)
986         print_ddg (dump_file, g);
987
988       get_block_head_tail (g->bb->index, &head, &tail);
989
990       pre_header_edge = g->bb->pred;
991       if (g->bb->pred->src != g->bb)
992         pre_header_edge = g->bb->pred->pred_next;
993
994       if (stats_file)
995         {
996           rtx line_note = find_line_note (tail);
997
998           if (line_note)
999             {
1000               expanded_location xloc;
1001               NOTE_EXPANDED_LOCATION (xloc, line_note);
1002               fprintf (stats_file, "SMS bb %s %d (file, line)\n",
1003                        xloc.file, xloc.line);
1004             }
1005           fprintf (stats_file, "SMS single-bb-loop\n");
1006           if (profile_info && flag_branch_probabilities)
1007             {
1008               fprintf (stats_file, "SMS loop-count ");
1009               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1010                        (HOST_WIDEST_INT) bb->count);
1011               fprintf (stats_file, "\n");
1012               fprintf (stats_file, "SMS preheader-count ");
1013               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1014                        (HOST_WIDEST_INT) pre_header_edge->count);
1015               fprintf (stats_file, "\n");
1016               fprintf (stats_file, "SMS profile-sum-max ");
1017               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1018                        (HOST_WIDEST_INT) profile_info->sum_max);
1019               fprintf (stats_file, "\n");
1020             }
1021           fprintf (stats_file, "SMS doloop\n");
1022           fprintf (stats_file, "SMS built-ddg %d\n", g->num_nodes);
1023           fprintf (stats_file, "SMS num-loads %d\n", g->num_loads);
1024           fprintf (stats_file, "SMS num-stores %d\n", g->num_stores);
1025         }
1026
1027       /* Make sure this is a doloop.  */
1028       if ( !(count_reg = doloop_register_get (tail, &comp)))
1029         abort ();
1030
1031       /* This should be NULL_RTX if the count is unknown at compile time.  */
1032       count_init = const_iteration_count (count_reg, pre_header, &loop_count);
1033
1034       if (stats_file && count_init)
1035         {
1036           fprintf (stats_file, "SMS const-doloop ");
1037           fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
1038           fprintf (stats_file, "\n");
1039         }
1040
1041       node_order = (int *) xmalloc (sizeof (int) * g->num_nodes);
1042
1043       mii = 1; /* Need to pass some estimate of mii.  */
1044       rec_mii = sms_order_nodes (g, mii, node_order);
1045       mii = MAX (res_MII (g), rec_mii);
1046       maxii = (calculate_maxii (g) * SMS_MAX_II_FACTOR) / 100;
1047
1048       if (stats_file)
1049         fprintf (stats_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
1050                  rec_mii, mii, maxii);
1051
1052       /* After sms_order_nodes and before sms_schedule_by_order, to copy over
1053          ASAP.  */
1054       set_node_sched_params (g);
1055
1056       ps = sms_schedule_by_order (g, mii, maxii, node_order, dump_file);
1057
1058       if (ps)
1059         stage_count = PS_STAGE_COUNT (ps);
1060
1061       if (stage_count == 0 || (count_init && (stage_count > loop_count)))
1062         {
1063           if (dump_file)
1064             fprintf (dump_file, "SMS failed... \n");
1065           if (stats_file)
1066             fprintf (stats_file, "SMS sched-failed %d\n", stage_count);
1067         }
1068       else
1069         {
1070           rtx orig_loop_beg = NULL_RTX;
1071           rtx orig_loop_end = NULL_RTX;
1072
1073           if (stats_file)
1074             {
1075               fprintf (stats_file,
1076                        "SMS succeeded %d %d (with ii, sc)\n", ps->ii,
1077                        stage_count);
1078               print_partial_schedule (ps, dump_file);
1079               fprintf (dump_file,
1080                        "SMS Branch (%d) will later be scheduled at cycle %d.\n",
1081                        g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1);
1082             }
1083
1084           /* Save the original loop if we want to do loop preconditioning in
1085              case the BCT count is not known.  */
1086           if (! count_init)
1087             {
1088               int i;
1089
1090               start_sequence ();
1091               /* Copy the original loop code before modifying it -
1092                  so we can use it later.  */
1093               for (i = 0; i < ps->g->num_nodes; i++)
1094                 duplicate_insn_chain (ps->g->nodes[i].first_note,
1095                                       ps->g->nodes[i].insn);
1096
1097               orig_loop_beg = get_insns ();
1098               orig_loop_end = get_last_insn ();
1099               end_sequence ();
1100             }
1101           /* Set the stage boundaries.  If the DDG is built with closing_branch_deps,
1102              the closing_branch was scheduled and should appear in the last (ii-1)
1103              row.  Otherwise, we are free to schedule the branch, and we let nodes
1104              that were scheduled at the first PS_MIN_CYCLE cycle appear in the first
1105              row; this should reduce stage_count to minimum.  */
1106           normalize_sched_times (ps);
1107           rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
1108           set_columns_for_ps (ps);
1109
1110           permute_partial_schedule (ps, g->closing_branch->first_note);
1111
1112           /* Mark this loop as software pipelined so the later
1113              scheduling passes doesn't touch it.  */
1114           if (! flag_resched_modulo_sched)
1115             emit_note_before (NOTE_DISABLE_SCHED_OF_BLOCK,
1116                               g->closing_branch->insn);
1117
1118           generate_reg_moves (ps);
1119           if (dump_file)
1120             print_node_sched_params (dump_file, g->num_nodes);
1121
1122           /* Set new iteration count of loop kernel.  */
1123           if (count_init)
1124             SET_SRC (single_set (count_init)) = GEN_INT (loop_count
1125                                                          - stage_count + 1);
1126
1127           /* Generate prolog and epilog.  */
1128           generate_prolog_epilog (ps, orig_loop_beg, orig_loop_end,
1129                                   count_init ? 0 : 1);
1130         }
1131       free_partial_schedule (ps);
1132       free (node_sched_params);
1133       free (node_order);
1134       free_ddg (g);
1135     }
1136
1137   /* Release scheduler data, needed until now because of DFA.  */
1138   sched_finish ();
1139 }
1140
1141 /* The SMS scheduling algorithm itself
1142    -----------------------------------
1143    Input: 'O' an ordered list of insns of a loop.
1144    Output: A scheduling of the loop - kernel, prolog, and epilogue.
1145
1146    'Q' is the empty Set
1147    'PS' is the partial schedule; it holds the currently scheduled nodes with
1148         their cycle/slot.
1149    'PSP' previously scheduled predecessors.
1150    'PSS' previously scheduled successors.
1151    't(u)' the cycle where u is scheduled.
1152    'l(u)' is the latency of u.
1153    'd(v,u)' is the dependence distance from v to u.
1154    'ASAP(u)' the earliest time at which u could be scheduled as computed in
1155              the node ordering phase.
1156    'check_hardware_resources_conflicts(u, PS, c)'
1157                              run a trace around cycle/slot through DFA model
1158                              to check resource conflicts involving instruction u
1159                              at cycle c given the partial schedule PS.
1160    'add_to_partial_schedule_at_time(u, PS, c)'
1161                              Add the node/instruction u to the partial schedule
1162                              PS at time c.
1163    'calculate_register_pressure(PS)'
1164                              Given a schedule of instructions, calculate the register
1165                              pressure it implies.  One implementation could be the
1166                              maximum number of overlapping live ranges.
1167    'maxRP' The maximum allowed register pressure, it is usually derived from the number
1168            registers available in the hardware.
1169
1170    1. II = MII.
1171    2. PS = empty list
1172    3. for each node u in O in pre-computed order
1173    4.   if (PSP(u) != Q && PSS(u) == Q) then
1174    5.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1175    6.     start = Early_start; end = Early_start + II - 1; step = 1
1176    11.  else if (PSP(u) == Q && PSS(u) != Q) then
1177    12.      Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1178    13.     start = Late_start; end = Late_start - II + 1; step = -1
1179    14.  else if (PSP(u) != Q && PSS(u) != Q) then
1180    15.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1181    16.     Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1182    17.     start = Early_start;
1183    18.     end = min(Early_start + II - 1 , Late_start);
1184    19.     step = 1
1185    20.     else "if (PSP(u) == Q && PSS(u) == Q)"
1186    21.    start = ASAP(u); end = start + II - 1; step = 1
1187    22.  endif
1188
1189    23.  success = false
1190    24.  for (c = start ; c != end ; c += step)
1191    25.     if check_hardware_resources_conflicts(u, PS, c) then
1192    26.       add_to_partial_schedule_at_time(u, PS, c)
1193    27.       success = true
1194    28.       break
1195    29.     endif
1196    30.  endfor
1197    31.  if (success == false) then
1198    32.    II = II + 1
1199    33.    if (II > maxII) then
1200    34.       finish - failed to schedule
1201    35.   endif
1202    36.    goto 2.
1203    37.  endif
1204    38. endfor
1205    39. if (calculate_register_pressure(PS) > maxRP) then
1206    40.    goto 32.
1207    41. endif
1208    42. compute epilogue & prologue
1209    43. finish - succeeded to schedule
1210 */
1211
1212 /* A limit on the number of cycles that resource conflicts can span.  ??? Should
1213    be provided by DFA, and be dependent on the type of insn scheduled.  Currently
1214    set to 0 to save compile time.  */
1215 #define DFA_HISTORY SMS_DFA_HISTORY
1216
1217 static partial_schedule_ptr
1218 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *dump_file)
1219 {
1220   int ii = mii;
1221   int i, c, success;
1222   int try_again_with_larger_ii = true;
1223   int num_nodes = g->num_nodes;
1224   ddg_edge_ptr e;
1225   int start, end, step; /* Place together into one struct?  */
1226   sbitmap sched_nodes = sbitmap_alloc (num_nodes);
1227   sbitmap psp = sbitmap_alloc (num_nodes);
1228   sbitmap pss = sbitmap_alloc (num_nodes);
1229   sbitmap must_precede = sbitmap_alloc (num_nodes);
1230   sbitmap must_follow = sbitmap_alloc (num_nodes);
1231
1232   partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
1233
1234   while (try_again_with_larger_ii && ii < maxii)
1235     {
1236       if (dump_file)
1237         fprintf(dump_file, "Starting with ii=%d\n", ii);
1238       try_again_with_larger_ii = false;
1239       sbitmap_zero (sched_nodes);
1240
1241       for (i = 0; i < num_nodes; i++)
1242         {
1243           int u = nodes_order[i];
1244           ddg_node_ptr u_node = &g->nodes[u];
1245           sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1246           sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1247           int psp_not_empty;
1248           int pss_not_empty;
1249           rtx insn = u_node->insn;
1250
1251           if (!INSN_P (insn))
1252             continue;
1253
1254           if (JUMP_P (insn)) /* Closing branch handled later.  */
1255             continue;
1256
1257           /* 1. compute sched window for u (start, end, step).  */
1258           sbitmap_zero (psp);
1259           sbitmap_zero (pss);
1260           psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1261           pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1262
1263           if (psp_not_empty && !pss_not_empty)
1264             {
1265               int early_start = 0;
1266
1267               end = INT_MAX;
1268               for (e = u_node->in; e != 0; e = e->next_in)
1269                 {
1270                   ddg_node_ptr v_node = e->src;
1271                   if (TEST_BIT (sched_nodes, v_node->cuid))
1272                     {
1273                       int node_st = SCHED_TIME (v_node)
1274                                     + e->latency - (e->distance * ii);
1275
1276                       early_start = MAX (early_start, node_st);
1277
1278                       if (e->data_type == MEM_DEP)
1279                         end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1280                     }
1281                 }
1282               start = early_start;
1283               end = MIN (end, early_start + ii);
1284               step = 1;
1285             }
1286
1287           else if (!psp_not_empty && pss_not_empty)
1288             {
1289               int late_start = INT_MAX;
1290
1291               end = INT_MIN;
1292               for (e = u_node->out; e != 0; e = e->next_out)
1293                 {
1294                   ddg_node_ptr v_node = e->dest;
1295                   if (TEST_BIT (sched_nodes, v_node->cuid))
1296                     {
1297                       late_start = MIN (late_start,
1298                                         SCHED_TIME (v_node) - e->latency
1299                                         + (e->distance * ii));
1300                       if (e->data_type == MEM_DEP)
1301                         end = MAX (end, SCHED_TIME (v_node) - ii + 1);
1302                     }
1303                 }
1304               start = late_start;
1305               end = MAX (end, late_start - ii);
1306               step = -1;
1307             }
1308
1309           else if (psp_not_empty && pss_not_empty)
1310             {
1311               int early_start = 0;
1312               int late_start = INT_MAX;
1313
1314               start = INT_MIN;
1315               end = INT_MAX;
1316               for (e = u_node->in; e != 0; e = e->next_in)
1317                 {
1318                   ddg_node_ptr v_node = e->src;
1319
1320                   if (TEST_BIT (sched_nodes, v_node->cuid))
1321                     {
1322                       early_start = MAX (early_start,
1323                                          SCHED_TIME (v_node) + e->latency
1324                                          - (e->distance * ii));
1325                       if (e->data_type == MEM_DEP)
1326                         end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1327                     }
1328                 }
1329               for (e = u_node->out; e != 0; e = e->next_out)
1330                 {
1331                   ddg_node_ptr v_node = e->dest;
1332
1333                   if (TEST_BIT (sched_nodes, v_node->cuid))
1334                     {
1335                       late_start = MIN (late_start,
1336                                         SCHED_TIME (v_node) - e->latency
1337                                         + (e->distance * ii));
1338                       if (e->data_type == MEM_DEP)
1339                         start = MAX (start, SCHED_TIME (v_node) - ii + 1);
1340                     }
1341                 }
1342               start = MAX (start, early_start);
1343               end = MIN (end, MIN (early_start + ii, late_start + 1));
1344               step = 1;
1345             }
1346           else /* psp is empty && pss is empty.  */
1347             {
1348               start = SCHED_ASAP (u_node);
1349               end = start + ii;
1350               step = 1;
1351             }
1352
1353           /* 2. Try scheduling u in window.  */
1354           if (dump_file)
1355             fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
1356                     u, start, end, step);
1357
1358           /* use must_follow & must_precede bitmaps to determine order
1359              of nodes within the cycle.  */
1360           sbitmap_zero (must_precede);
1361           sbitmap_zero (must_follow);
1362           for (e = u_node->in; e != 0; e = e->next_in)
1363             if (TEST_BIT (sched_nodes, e->src->cuid)
1364                 && e->latency == (ii * e->distance)
1365                 && start == SCHED_TIME (e->src))
1366              SET_BIT (must_precede, e->src->cuid);
1367
1368           for (e = u_node->out; e != 0; e = e->next_out)
1369             if (TEST_BIT (sched_nodes, e->dest->cuid)
1370                 && e->latency == (ii * e->distance)
1371                 && end == SCHED_TIME (e->dest))
1372              SET_BIT (must_follow, e->dest->cuid);
1373
1374           success = 0;
1375           if ((step > 0 && start < end) ||  (step < 0 && start > end))
1376             for (c = start; c != end; c += step)
1377               {
1378                 ps_insn_ptr psi;
1379
1380                 psi = ps_add_node_check_conflicts (ps, u_node, c,
1381                                                    must_precede,
1382                                                    must_follow);
1383
1384                 if (psi)
1385                   {
1386                     SCHED_TIME (u_node) = c;
1387                     SET_BIT (sched_nodes, u);
1388                     success = 1;
1389                     if (dump_file)
1390                       fprintf(dump_file, "Schedule in %d\n", c);
1391                     break;
1392                   }
1393               }
1394           if (!success)
1395             {
1396               /* ??? Try backtracking instead of immediately ii++?  */
1397               ii++;
1398               try_again_with_larger_ii = true;
1399               reset_partial_schedule (ps, ii);
1400               break;
1401             }
1402           /* ??? If (success), check register pressure estimates.  */
1403         } /* Continue with next node.  */
1404     } /* While try_again_with_larger_ii.  */
1405
1406   sbitmap_free (sched_nodes);
1407   sbitmap_free (psp);
1408   sbitmap_free (pss);
1409
1410   if (ii >= maxii)
1411     {
1412       free_partial_schedule (ps);
1413       ps = NULL;
1414     }
1415   return ps;
1416 }
1417
1418 \f
1419 /* This page implements the algorithm for ordering the nodes of a DDG
1420    for modulo scheduling, activated through the
1421    "int sms_order_nodes (ddg_ptr, int mii, int * result)" API.  */
1422
1423 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
1424 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
1425 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
1426 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
1427 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
1428 #define DEPTH(x) (ASAP ((x)))
1429
1430 typedef struct node_order_params * nopa;
1431
1432 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
1433 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
1434 static nopa  calculate_order_params (ddg_ptr, int mii);
1435 static int find_max_asap (ddg_ptr, sbitmap);
1436 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
1437 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
1438
1439 enum sms_direction {BOTTOMUP, TOPDOWN};
1440
1441 struct node_order_params
1442 {
1443   int asap;
1444   int alap;
1445   int height;
1446 };
1447
1448 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1.  */
1449 static void
1450 check_nodes_order (int *node_order, int num_nodes)
1451 {
1452   int i;
1453   sbitmap tmp = sbitmap_alloc (num_nodes);
1454
1455   sbitmap_zero (tmp);
1456
1457   for (i = 0; i < num_nodes; i++)
1458     {
1459       int u = node_order[i];
1460
1461       if (u >= num_nodes || u < 0 || TEST_BIT (tmp, u))
1462         abort ();
1463
1464       SET_BIT (tmp, u);
1465     }
1466
1467   sbitmap_free (tmp);
1468 }
1469
1470 /* Order the nodes of G for scheduling and pass the result in
1471    NODE_ORDER.  Also set aux.count of each node to ASAP.
1472    Return the recMII for the given DDG.  */
1473 static int
1474 sms_order_nodes (ddg_ptr g, int mii, int * node_order)
1475 {
1476   int i;
1477   int rec_mii = 0;
1478   ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
1479
1480   nopa nops = calculate_order_params (g, mii);
1481
1482   order_nodes_of_sccs (sccs, node_order);
1483
1484   if (sccs->num_sccs > 0)
1485     /* First SCC has the largest recurrence_length.  */
1486     rec_mii = sccs->sccs[0]->recurrence_length;
1487
1488   /* Save ASAP before destroying node_order_params.  */
1489   for (i = 0; i < g->num_nodes; i++)
1490     {
1491       ddg_node_ptr v = &g->nodes[i];
1492       v->aux.count = ASAP (v);
1493     }
1494
1495   free (nops);
1496   free_ddg_all_sccs (sccs);
1497   check_nodes_order (node_order, g->num_nodes);
1498
1499   return rec_mii;
1500 }
1501
1502 static void
1503 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
1504 {
1505   int i, pos = 0;
1506   ddg_ptr g = all_sccs->ddg;
1507   int num_nodes = g->num_nodes;
1508   sbitmap prev_sccs = sbitmap_alloc (num_nodes);
1509   sbitmap on_path = sbitmap_alloc (num_nodes);
1510   sbitmap tmp = sbitmap_alloc (num_nodes);
1511   sbitmap ones = sbitmap_alloc (num_nodes);
1512
1513   sbitmap_zero (prev_sccs);
1514   sbitmap_ones (ones);
1515
1516   /* Perfrom the node ordering starting from the SCC with the highest recMII.
1517      For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc.  */
1518   for (i = 0; i < all_sccs->num_sccs; i++)
1519     {
1520       ddg_scc_ptr scc = all_sccs->sccs[i];
1521
1522       /* Add nodes on paths from previous SCCs to the current SCC.  */
1523       find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
1524       sbitmap_a_or_b (tmp, scc->nodes, on_path);
1525
1526       /* Add nodes on paths from the current SCC to previous SCCs.  */
1527       find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
1528       sbitmap_a_or_b (tmp, tmp, on_path);
1529
1530       /* Remove nodes of previous SCCs from current extended SCC.  */
1531       sbitmap_difference (tmp, tmp, prev_sccs);
1532
1533       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1534       /* Above call to order_nodes_in_scc updated prev_sccs |= tmp.  */
1535     }
1536
1537   /* Handle the remaining nodes that do not belong to any scc.  Each call
1538      to order_nodes_in_scc handles a single connected component.  */
1539   while (pos < g->num_nodes)
1540     {
1541       sbitmap_difference (tmp, ones, prev_sccs);
1542       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1543     }
1544   sbitmap_free (prev_sccs);
1545   sbitmap_free (on_path);
1546   sbitmap_free (tmp);
1547   sbitmap_free (ones);
1548 }
1549
1550 /* MII is needed if we consider backarcs (that do not close recursive cycles).  */
1551 static struct node_order_params *
1552 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
1553 {
1554   int u;
1555   int max_asap;
1556   int num_nodes = g->num_nodes;
1557   ddg_edge_ptr e;
1558   /* Allocate a place to hold ordering params for each node in the DDG.  */
1559   nopa node_order_params_arr;
1560
1561   /* Initialize of ASAP/ALAP/HEIGHT to zero.  */
1562   node_order_params_arr = (nopa) xcalloc (num_nodes,
1563                                           sizeof (struct node_order_params));
1564
1565   /* Set the aux pointer of each node to point to its order_params structure.  */
1566   for (u = 0; u < num_nodes; u++)
1567     g->nodes[u].aux.info = &node_order_params_arr[u];
1568
1569   /* Disregarding a backarc from each recursive cycle to obtain a DAG,
1570      calculate ASAP, ALAP, mobility, distance, and height for each node
1571      in the dependence (direct acyclic) graph.  */
1572
1573   /* We assume that the nodes in the array are in topological order.  */
1574
1575   max_asap = 0;
1576   for (u = 0; u < num_nodes; u++)
1577     {
1578       ddg_node_ptr u_node = &g->nodes[u];
1579
1580       ASAP (u_node) = 0;
1581       for (e = u_node->in; e; e = e->next_in)
1582         if (e->distance == 0)
1583           ASAP (u_node) = MAX (ASAP (u_node),
1584                                ASAP (e->src) + e->latency);
1585       max_asap = MAX (max_asap, ASAP (u_node));
1586     }
1587
1588   for (u = num_nodes - 1; u > -1; u--)
1589     {
1590       ddg_node_ptr u_node = &g->nodes[u];
1591
1592       ALAP (u_node) = max_asap;
1593       HEIGHT (u_node) = 0;
1594       for (e = u_node->out; e; e = e->next_out)
1595         if (e->distance == 0)
1596           {
1597             ALAP (u_node) = MIN (ALAP (u_node),
1598                                  ALAP (e->dest) - e->latency);
1599             HEIGHT (u_node) = MAX (HEIGHT (u_node),
1600                                    HEIGHT (e->dest) + e->latency);
1601           }
1602     }
1603
1604   return node_order_params_arr;
1605 }
1606
1607 static int
1608 find_max_asap (ddg_ptr g, sbitmap nodes)
1609 {
1610   int u;
1611   int max_asap = -1;
1612   int result = -1;
1613
1614   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1615     {
1616       ddg_node_ptr u_node = &g->nodes[u];
1617
1618       if (max_asap < ASAP (u_node))
1619         {
1620           max_asap = ASAP (u_node);
1621           result = u;
1622         }
1623     });
1624   return result;
1625 }
1626
1627 static int
1628 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
1629 {
1630   int u;
1631   int max_hv = -1;
1632   int min_mob = INT_MAX;
1633   int result = -1;
1634
1635   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1636     {
1637       ddg_node_ptr u_node = &g->nodes[u];
1638
1639       if (max_hv < HEIGHT (u_node))
1640         {
1641           max_hv = HEIGHT (u_node);
1642           min_mob = MOB (u_node);
1643           result = u;
1644         }
1645       else if ((max_hv == HEIGHT (u_node))
1646                && (min_mob > MOB (u_node)))
1647         {
1648           min_mob = MOB (u_node);
1649           result = u;
1650         }
1651     });
1652   return result;
1653 }
1654
1655 static int
1656 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
1657 {
1658   int u;
1659   int max_dv = -1;
1660   int min_mob = INT_MAX;
1661   int result = -1;
1662
1663   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1664     {
1665       ddg_node_ptr u_node = &g->nodes[u];
1666
1667       if (max_dv < DEPTH (u_node))
1668         {
1669           max_dv = DEPTH (u_node);
1670           min_mob = MOB (u_node);
1671           result = u;
1672         }
1673       else if ((max_dv == DEPTH (u_node))
1674                && (min_mob > MOB (u_node)))
1675         {
1676           min_mob = MOB (u_node);
1677           result = u;
1678         }
1679     });
1680   return result;
1681 }
1682
1683 /* Places the nodes of SCC into the NODE_ORDER array starting
1684    at position POS, according to the SMS ordering algorithm.
1685    NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
1686    the NODE_ORDER array, starting from position zero.  */
1687 static int
1688 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
1689                     int * node_order, int pos)
1690 {
1691   enum sms_direction dir;
1692   int num_nodes = g->num_nodes;
1693   sbitmap workset = sbitmap_alloc (num_nodes);
1694   sbitmap tmp = sbitmap_alloc (num_nodes);
1695   sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
1696   sbitmap predecessors = sbitmap_alloc (num_nodes);
1697   sbitmap successors = sbitmap_alloc (num_nodes);
1698
1699   sbitmap_zero (predecessors);
1700   find_predecessors (predecessors, g, nodes_ordered);
1701
1702   sbitmap_zero (successors);
1703   find_successors (successors, g, nodes_ordered);
1704
1705   sbitmap_zero (tmp);
1706   if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
1707     {
1708       sbitmap_copy (workset, tmp);
1709       dir = BOTTOMUP;
1710     }
1711   else if (sbitmap_a_and_b_cg (tmp, successors, scc))
1712     {
1713       sbitmap_copy (workset, tmp);
1714       dir = TOPDOWN;
1715     }
1716   else
1717     {
1718       int u;
1719
1720       sbitmap_zero (workset);
1721       if ((u = find_max_asap (g, scc)) >= 0)
1722         SET_BIT (workset, u);
1723       dir = BOTTOMUP;
1724     }
1725
1726   sbitmap_zero (zero_bitmap);
1727   while (!sbitmap_equal (workset, zero_bitmap))
1728     {
1729       int v;
1730       ddg_node_ptr v_node;
1731       sbitmap v_node_preds;
1732       sbitmap v_node_succs;
1733
1734       if (dir == TOPDOWN)
1735         {
1736           while (!sbitmap_equal (workset, zero_bitmap))
1737             {
1738               v = find_max_hv_min_mob (g, workset);
1739               v_node = &g->nodes[v];
1740               node_order[pos++] = v;
1741               v_node_succs = NODE_SUCCESSORS (v_node);
1742               sbitmap_a_and_b (tmp, v_node_succs, scc);
1743
1744               /* Don't consider the already ordered successors again.  */
1745               sbitmap_difference (tmp, tmp, nodes_ordered);
1746               sbitmap_a_or_b (workset, workset, tmp);
1747               RESET_BIT (workset, v);
1748               SET_BIT (nodes_ordered, v);
1749             }
1750           dir = BOTTOMUP;
1751           sbitmap_zero (predecessors);
1752           find_predecessors (predecessors, g, nodes_ordered);
1753           sbitmap_a_and_b (workset, predecessors, scc);
1754         }
1755       else
1756         {
1757           while (!sbitmap_equal (workset, zero_bitmap))
1758             {
1759               v = find_max_dv_min_mob (g, workset);
1760               v_node = &g->nodes[v];
1761               node_order[pos++] = v;
1762               v_node_preds = NODE_PREDECESSORS (v_node);
1763               sbitmap_a_and_b (tmp, v_node_preds, scc);
1764
1765               /* Don't consider the already ordered predecessors again.  */
1766               sbitmap_difference (tmp, tmp, nodes_ordered);
1767               sbitmap_a_or_b (workset, workset, tmp);
1768               RESET_BIT (workset, v);
1769               SET_BIT (nodes_ordered, v);
1770             }
1771           dir = TOPDOWN;
1772           sbitmap_zero (successors);
1773           find_successors (successors, g, nodes_ordered);
1774           sbitmap_a_and_b (workset, successors, scc);
1775         }
1776     }
1777   sbitmap_free (tmp);
1778   sbitmap_free (workset);
1779   sbitmap_free (zero_bitmap);
1780   sbitmap_free (predecessors);
1781   sbitmap_free (successors);
1782   return pos;
1783 }
1784
1785 \f
1786 /* This page contains functions for manipulating partial-schedules during
1787    modulo scheduling.  */
1788
1789 /* Create a partial schedule and allocate a memory to hold II rows.  */
1790 partial_schedule_ptr
1791 create_partial_schedule (int ii, ddg_ptr g, int history)
1792 {
1793   partial_schedule_ptr ps = (partial_schedule_ptr)
1794                              xmalloc (sizeof (struct partial_schedule));
1795   ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
1796   ps->ii = ii;
1797   ps->history = history;
1798   ps->min_cycle = INT_MAX;
1799   ps->max_cycle = INT_MIN;
1800   ps->g = g;
1801
1802   return ps;
1803 }
1804
1805 /* Free the PS_INSNs in rows array of the given partial schedule.
1806    ??? Consider caching the PS_INSN's.  */
1807 static void
1808 free_ps_insns (partial_schedule_ptr ps)
1809 {
1810   int i;
1811
1812   for (i = 0; i < ps->ii; i++)
1813     {
1814       while (ps->rows[i])
1815         {
1816           ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
1817
1818           free (ps->rows[i]);
1819           ps->rows[i] = ps_insn;
1820         }
1821       ps->rows[i] = NULL;
1822     }
1823 }
1824
1825 /* Free all the memory allocated to the partial schedule.  */
1826 void
1827 free_partial_schedule (partial_schedule_ptr ps)
1828 {
1829   if (!ps)
1830     return;
1831   free_ps_insns (ps);
1832   free (ps->rows);
1833   free (ps);
1834 }
1835
1836 /* Clear the rows array with its PS_INSNs, and create a new one with
1837    NEW_II rows.  */
1838 void
1839 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
1840 {
1841   if (!ps)
1842     return;
1843   free_ps_insns (ps);
1844   if (new_ii == ps->ii)
1845     return;
1846   ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
1847                                                  * sizeof (ps_insn_ptr));
1848   memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
1849   ps->ii = new_ii;
1850   ps->min_cycle = INT_MAX;
1851   ps->max_cycle = INT_MIN;
1852 }
1853
1854 /* Prints the partial schedule as an ii rows array, for each rows
1855    print the ids of the insns in it.  */
1856 void
1857 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
1858 {
1859   int i;
1860
1861   for (i = 0; i < ps->ii; i++)
1862     {
1863       ps_insn_ptr ps_i = ps->rows[i];
1864
1865       fprintf (dump, "\n[CYCLE %d ]: ", i);
1866       while (ps_i)
1867         {
1868           fprintf (dump, "%d, ",
1869                    INSN_UID (ps_i->node->insn));
1870           ps_i = ps_i->next_in_row;
1871         }
1872     }
1873 }
1874
1875 /* Creates an object of PS_INSN and initializes it to the given parameters.  */
1876 static ps_insn_ptr
1877 create_ps_insn (ddg_node_ptr node, int rest_count, int cycle)
1878 {
1879   ps_insn_ptr ps_i = xmalloc (sizeof (struct ps_insn));
1880
1881   ps_i->node = node;
1882   ps_i->next_in_row = NULL;
1883   ps_i->prev_in_row = NULL;
1884   ps_i->row_rest_count = rest_count;
1885   ps_i->cycle = cycle;
1886
1887   return ps_i;
1888 }
1889
1890
1891 /* Removes the given PS_INSN from the partial schedule.  Returns false if the
1892    node is not found in the partial schedule, else returns true.  */
1893 static int
1894 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
1895 {
1896   int row;
1897
1898   if (!ps || !ps_i)
1899     return false;
1900
1901   row = SMODULO (ps_i->cycle, ps->ii);
1902   if (! ps_i->prev_in_row)
1903     {
1904       if (ps_i != ps->rows[row])
1905         return false;
1906
1907       ps->rows[row] = ps_i->next_in_row;
1908       if (ps->rows[row])
1909         ps->rows[row]->prev_in_row = NULL;
1910     }
1911   else
1912     {
1913       ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
1914       if (ps_i->next_in_row)
1915         ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
1916     }
1917   free (ps_i);
1918   return true;
1919 }
1920
1921 /* Unlike what literature describes for modulo scheduling (which focuses
1922    on VLIW machines) the order of the instructions inside a cycle is
1923    important.  Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
1924    where the current instruction should go relative to the already
1925    scheduled instructions in the given cycle.  Go over these
1926    instructions and find the first possible column to put it in.  */
1927 static bool
1928 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
1929                      sbitmap must_precede, sbitmap must_follow)
1930 {
1931   ps_insn_ptr next_ps_i;
1932   ps_insn_ptr first_must_follow = NULL;
1933   ps_insn_ptr last_must_precede = NULL;
1934   int row;
1935
1936   if (! ps_i)
1937     return false;
1938
1939   row = SMODULO (ps_i->cycle, ps->ii);
1940
1941   /* Find the first must follow and the last must precede
1942      and insert the node immediatly after the must precede
1943      but make sure that it there is no must follow after it.   */
1944   for (next_ps_i = ps->rows[row];
1945        next_ps_i;
1946        next_ps_i = next_ps_i->next_in_row)
1947     {
1948       if (TEST_BIT (must_follow, next_ps_i->node->cuid)
1949           && ! first_must_follow)
1950         first_must_follow = next_ps_i;
1951       if (TEST_BIT (must_precede, next_ps_i->node->cuid))
1952         {
1953           /* If we have already met a node that must follow, then
1954              there is no possible column.  */
1955           if (first_must_follow)
1956             return false;
1957           else
1958             last_must_precede = next_ps_i;
1959         }
1960     }
1961
1962   /* Now insert the node after INSERT_AFTER_PSI.  */
1963
1964   if (! last_must_precede)
1965     {
1966       ps_i->next_in_row = ps->rows[row];
1967       ps_i->prev_in_row = NULL;
1968       if (ps_i->next_in_row)
1969         ps_i->next_in_row->prev_in_row = ps_i;
1970       ps->rows[row] = ps_i;
1971     }
1972   else
1973     {
1974       ps_i->next_in_row = last_must_precede->next_in_row;
1975       last_must_precede->next_in_row = ps_i;
1976       ps_i->prev_in_row = last_must_precede;
1977       if (ps_i->next_in_row)
1978         ps_i->next_in_row->prev_in_row = ps_i;
1979     }
1980
1981   return true;
1982 }
1983
1984 /* Advances the PS_INSN one column in its current row; returns false
1985    in failure and true in success.  Bit N is set in MUST_FOLLOW if 
1986    the node with cuid N must be come after the node pointed to by 
1987    PS_I when scheduled in the same cycle.  */
1988 static int
1989 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
1990                         sbitmap must_follow)
1991 {
1992   ps_insn_ptr prev, next;
1993   int row;
1994   ddg_node_ptr next_node;
1995
1996   if (!ps || !ps_i)
1997     return false;
1998
1999   row = SMODULO (ps_i->cycle, ps->ii);
2000
2001   if (! ps_i->next_in_row)
2002     return false;
2003
2004   next_node = ps_i->next_in_row->node;
2005
2006   /* Check if next_in_row is dependent on ps_i, both having same sched
2007      times (typically ANTI_DEP).  If so, ps_i cannot skip over it.  */
2008   if (TEST_BIT (must_follow, next_node->cuid))
2009     return false;
2010
2011   /* Advace PS_I over its next_in_row in the doubly linked list.  */
2012   prev = ps_i->prev_in_row;
2013   next = ps_i->next_in_row;
2014
2015   if (ps_i == ps->rows[row])
2016     ps->rows[row] = next;
2017
2018   ps_i->next_in_row = next->next_in_row;
2019
2020   if (next->next_in_row)
2021     next->next_in_row->prev_in_row = ps_i;
2022
2023   next->next_in_row = ps_i;
2024   ps_i->prev_in_row = next;
2025
2026   next->prev_in_row = prev;
2027   if (prev)
2028     prev->next_in_row = next;
2029
2030   return true;
2031 }
2032
2033 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
2034    Returns 0 if this is not possible and a PS_INSN otherwise.  Bit N is 
2035    set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come 
2036    before/after (respectively) the node pointed to by PS_I when scheduled 
2037    in the same cycle.  */
2038 static ps_insn_ptr
2039 add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle,
2040                 sbitmap must_precede, sbitmap must_follow)
2041 {
2042   ps_insn_ptr ps_i;
2043   int rest_count = 1;
2044   int row = SMODULO (cycle, ps->ii);
2045
2046   if (ps->rows[row]
2047       && ps->rows[row]->row_rest_count >= issue_rate)
2048     return NULL;
2049
2050   if (ps->rows[row])
2051     rest_count += ps->rows[row]->row_rest_count;
2052
2053   ps_i = create_ps_insn (node, rest_count, cycle);
2054
2055   /* Finds and inserts PS_I according to MUST_FOLLOW and
2056      MUST_PRECEDE.  */
2057   if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
2058     {
2059       free (ps_i);
2060       return NULL;
2061     }
2062
2063   return ps_i;
2064 }
2065
2066 /* Advance time one cycle.  Assumes DFA is being used.  */
2067 static void
2068 advance_one_cycle (void)
2069 {
2070   if (targetm.sched.dfa_pre_cycle_insn)
2071     state_transition (curr_state,
2072                       (*targetm.sched.dfa_pre_cycle_insn) ());
2073
2074   state_transition (curr_state, NULL);
2075
2076   if (targetm.sched.dfa_post_cycle_insn)
2077     state_transition (curr_state,
2078                       (*targetm.sched.dfa_post_cycle_insn) ());
2079 }
2080
2081 /* Checks if PS has resource conflicts according to DFA, starting from
2082    FROM cycle to TO cycle; returns true if there are conflicts and false
2083    if there are no conflicts.  Assumes DFA is being used.  */
2084 static int
2085 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
2086 {
2087   int cycle;
2088
2089   state_reset (curr_state);
2090
2091   for (cycle = from; cycle <= to; cycle++)
2092     {
2093       ps_insn_ptr crr_insn;
2094       /* Holds the remaining issue slots in the current row.  */
2095       int can_issue_more = issue_rate;
2096
2097       /* Walk through the DFA for the current row.  */
2098       for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
2099            crr_insn;
2100            crr_insn = crr_insn->next_in_row)
2101         {
2102           rtx insn = crr_insn->node->insn;
2103
2104           if (!INSN_P (insn))
2105             continue;
2106
2107           /* Check if there is room for the current insn.  */
2108           if (!can_issue_more || state_dead_lock_p (curr_state))
2109             return true;
2110
2111           /* Update the DFA state and return with failure if the DFA found
2112              recource conflicts.  */
2113           if (state_transition (curr_state, insn) >= 0)
2114             return true;
2115
2116           if (targetm.sched.variable_issue)
2117             can_issue_more =
2118               (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
2119                                                insn, can_issue_more);
2120           /* A naked CLOBBER or USE generates no instruction, so don't
2121              let them consume issue slots.  */
2122           else if (GET_CODE (PATTERN (insn)) != USE
2123                    && GET_CODE (PATTERN (insn)) != CLOBBER)
2124             can_issue_more--;
2125         }
2126
2127       /* Advance the DFA to the next cycle.  */
2128       advance_one_cycle ();
2129     }
2130   return false;
2131 }
2132
2133 /* Checks if the given node causes resource conflicts when added to PS at
2134    cycle C.  If not the node is added to PS and returned; otherwise zero
2135    is returned.  Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with 
2136    cuid N must be come before/after (respectively) the node pointed to by 
2137    PS_I when scheduled in the same cycle.  */
2138 ps_insn_ptr
2139 ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n,
2140                              int c, sbitmap must_precede,
2141                              sbitmap must_follow)
2142 {
2143   int has_conflicts = 0;
2144   ps_insn_ptr ps_i;
2145
2146   /* First add the node to the PS, if this succeeds check for
2147      conflicts, trying different issue slots in the same row.  */
2148   if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
2149     return NULL; /* Failed to insert the node at the given cycle.  */
2150
2151   has_conflicts = ps_has_conflicts (ps, c, c)
2152                   || (ps->history > 0
2153                       && ps_has_conflicts (ps,
2154                                            c - ps->history,
2155                                            c + ps->history));
2156
2157   /* Try different issue slots to find one that the given node can be
2158      scheduled in without conflicts.  */
2159   while (has_conflicts)
2160     {
2161       if (! ps_insn_advance_column (ps, ps_i, must_follow))
2162         break;
2163       has_conflicts = ps_has_conflicts (ps, c, c)
2164                       || (ps->history > 0
2165                           && ps_has_conflicts (ps,
2166                                                c - ps->history,
2167                                                c + ps->history));
2168     }
2169
2170   if (has_conflicts)
2171     {
2172       remove_node_from_ps (ps, ps_i);
2173       return NULL;
2174     }
2175
2176   ps->min_cycle = MIN (ps->min_cycle, c);
2177   ps->max_cycle = MAX (ps->max_cycle, c);
2178   return ps_i;
2179 }
2180
2181 /* Rotate the rows of PS such that insns scheduled at time
2182    START_CYCLE will appear in row 0.  Updates max/min_cycles.  */
2183 void
2184 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
2185 {
2186   int i, row, backward_rotates;
2187   int last_row = ps->ii - 1;
2188
2189   if (start_cycle == 0)
2190     return;
2191
2192   backward_rotates = SMODULO (start_cycle, ps->ii);
2193
2194   /* Revisit later and optimize this into a single loop.  */
2195   for (i = 0; i < backward_rotates; i++)
2196     {
2197       ps_insn_ptr first_row = ps->rows[0];
2198
2199       for (row = 0; row < last_row; row++)
2200         ps->rows[row] = ps->rows[row+1];
2201
2202       ps->rows[last_row] = first_row;
2203     }
2204
2205   ps->max_cycle -= start_cycle;
2206   ps->min_cycle -= start_cycle;
2207 }
2208
2209 #endif /* INSN_SCHEDULING*/