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