OSDN Git Service

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