OSDN Git Service

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