OSDN Git Service

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