OSDN Git Service

2004-09-28 Paolo Carlini <pcarlini@suse.de>
[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 = EDGE_PRED (ps->g->bb, 0);
675   if (e->src == ps->g->bb)
676     e = EDGE_PRED (ps->g->bb, 1);
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 = EDGE_SUCC (ps->g->bb, 0);
730   if (e->dest == ps->g->bb)
731     e = EDGE_SUCC (ps->g->bb, 1);
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 = EDGE_SUCC (epilog_bb, 0);
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       if (EDGE_COUNT (bb->succs) != 2)
855         continue;
856
857       if (EDGE_SUCC (bb, 0)->dest != bb && EDGE_SUCC (bb, 1)->dest != bb)
858         continue;
859
860       if ((EDGE_SUCC (bb, 0)->flags & EDGE_COMPLEX)
861           || (EDGE_SUCC (bb, 1)->flags & EDGE_COMPLEX))
862         continue;
863
864       /* Check if bb has two predecessors, one being itself.  */
865       if (EDGE_COUNT (bb->preds) != 2)
866         continue;
867
868       if (EDGE_PRED (bb, 0)->src != bb && EDGE_PRED (bb, 1)->src != bb)
869         continue;
870
871       if ((EDGE_PRED (bb, 0)->flags & EDGE_COMPLEX)
872           || (EDGE_PRED (bb, 1)->flags & EDGE_COMPLEX))
873         continue;
874
875       /* For debugging.  */
876       if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
877         {
878           if (dump_file)
879             fprintf (dump_file, "SMS reached MAX_PASSES... \n");
880           break;
881         }
882
883       get_block_head_tail (bb->index, &head, &tail);
884       pre_header_edge = EDGE_PRED (bb, 0);
885       if (EDGE_PRED (bb, 0)->src != bb)
886         pre_header_edge = EDGE_PRED (bb, 1);
887
888       /* Perfrom SMS only on loops that their average count is above threshold.  */
889       if (bb->count < pre_header_edge->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD)
890         {
891           if (stats_file)
892             {
893               rtx line_note = find_line_note (tail);
894
895               if (line_note)
896                 {
897                   expanded_location xloc;
898                   NOTE_EXPANDED_LOCATION (xloc, line_note);
899                   fprintf (stats_file, "SMS bb %s %d (file, line)\n",
900                            xloc.file, xloc.line);
901                 }
902               fprintf (stats_file, "SMS single-bb-loop\n");
903               if (profile_info && flag_branch_probabilities)
904                 {
905                   fprintf (stats_file, "SMS loop-count ");
906                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
907                            (HOST_WIDEST_INT) bb->count);
908                   fprintf (stats_file, "\n");
909                   fprintf (stats_file, "SMS preheader-count ");
910                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
911                            (HOST_WIDEST_INT) pre_header_edge->count);
912                   fprintf (stats_file, "\n");
913                   fprintf (stats_file, "SMS profile-sum-max ");
914                   fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
915                            (HOST_WIDEST_INT) profile_info->sum_max);
916                   fprintf (stats_file, "\n");
917                 }
918             }
919           continue;
920         }
921
922       /* Make sure this is a doloop.  */
923       if ( !(count_reg = doloop_register_get (tail, &comp)))
924         continue;
925
926       e = EDGE_PRED (bb, 0);
927       if (e->src == bb)
928         pre_header = EDGE_PRED (bb, 1)->src;
929       else
930         pre_header = e->src;
931
932       /* Don't handle BBs with calls or barriers, or !single_set insns.  */
933       for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
934         if (CALL_P (insn)
935             || BARRIER_P (insn)
936             || (INSN_P (insn) && !JUMP_P (insn)
937                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
938           break;
939
940       if (insn != NEXT_INSN (tail))
941         {
942           if (stats_file)
943             {
944               if (CALL_P (insn))
945                 fprintf (stats_file, "SMS loop-with-call\n");
946               else if (BARRIER_P (insn))
947                 fprintf (stats_file, "SMS loop-with-barrier\n");
948               else
949                 fprintf (stats_file, "SMS loop-with-not-single-set\n");
950               print_rtl_single (stats_file, insn);
951             }
952
953           continue;
954         }
955
956       if (! (g = create_ddg (bb, df, 0)))
957         {
958           if (stats_file)
959             fprintf (stats_file, "SMS doloop\n");
960           continue;
961         }
962
963       g_arr[bb->index] = g;
964     }
965
966   /* Release Data Flow analysis data structures.  */
967   df_finish (df);
968
969   /* Go over the built DDGs and perfrom SMS for each one of them.  */
970   for (i = 0; i < max_bb_index; i++)
971     {
972       rtx head, tail;
973       rtx count_reg, count_init, comp;
974       edge pre_header_edge;
975       int mii, rec_mii;
976       int stage_count = 0;
977       HOST_WIDEST_INT loop_count = 0;
978
979       if (! (g = g_arr[i]))
980         continue;
981
982       if (dump_file)
983         print_ddg (dump_file, g);
984
985       get_block_head_tail (g->bb->index, &head, &tail);
986
987       pre_header_edge = EDGE_PRED (g->bb, 0);
988       if (EDGE_PRED (g->bb, 0)->src != g->bb)
989         pre_header_edge = EDGE_PRED (g->bb, 1);
990
991       if (stats_file)
992         {
993           rtx line_note = find_line_note (tail);
994
995           if (line_note)
996             {
997               expanded_location xloc;
998               NOTE_EXPANDED_LOCATION (xloc, line_note);
999               fprintf (stats_file, "SMS bb %s %d (file, line)\n",
1000                        xloc.file, xloc.line);
1001             }
1002           fprintf (stats_file, "SMS single-bb-loop\n");
1003           if (profile_info && flag_branch_probabilities)
1004             {
1005               fprintf (stats_file, "SMS loop-count ");
1006               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1007                        (HOST_WIDEST_INT) bb->count);
1008               fprintf (stats_file, "\n");
1009               fprintf (stats_file, "SMS preheader-count ");
1010               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1011                        (HOST_WIDEST_INT) pre_header_edge->count);
1012               fprintf (stats_file, "\n");
1013               fprintf (stats_file, "SMS profile-sum-max ");
1014               fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC,
1015                        (HOST_WIDEST_INT) profile_info->sum_max);
1016               fprintf (stats_file, "\n");
1017             }
1018           fprintf (stats_file, "SMS doloop\n");
1019           fprintf (stats_file, "SMS built-ddg %d\n", g->num_nodes);
1020           fprintf (stats_file, "SMS num-loads %d\n", g->num_loads);
1021           fprintf (stats_file, "SMS num-stores %d\n", g->num_stores);
1022         }
1023
1024       /* Make sure this is a doloop.  */
1025       if ( !(count_reg = doloop_register_get (tail, &comp)))
1026         abort ();
1027
1028       /* This should be NULL_RTX if the count is unknown at compile time.  */
1029       count_init = const_iteration_count (count_reg, pre_header, &loop_count);
1030
1031       if (stats_file && count_init)
1032         {
1033           fprintf (stats_file, "SMS const-doloop ");
1034           fprintf (stats_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
1035           fprintf (stats_file, "\n");
1036         }
1037
1038       node_order = (int *) xmalloc (sizeof (int) * g->num_nodes);
1039
1040       mii = 1; /* Need to pass some estimate of mii.  */
1041       rec_mii = sms_order_nodes (g, mii, node_order);
1042       mii = MAX (res_MII (g), rec_mii);
1043       maxii = (calculate_maxii (g) * SMS_MAX_II_FACTOR) / 100;
1044
1045       if (stats_file)
1046         fprintf (stats_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
1047                  rec_mii, mii, maxii);
1048
1049       /* After sms_order_nodes and before sms_schedule_by_order, to copy over
1050          ASAP.  */
1051       set_node_sched_params (g);
1052
1053       ps = sms_schedule_by_order (g, mii, maxii, node_order, dump_file);
1054
1055       if (ps)
1056         stage_count = PS_STAGE_COUNT (ps);
1057
1058       if (stage_count == 0 || (count_init && (stage_count > loop_count)))
1059         {
1060           if (dump_file)
1061             fprintf (dump_file, "SMS failed... \n");
1062           if (stats_file)
1063             fprintf (stats_file, "SMS sched-failed %d\n", stage_count);
1064         }
1065       else
1066         {
1067           rtx orig_loop_beg = NULL_RTX;
1068           rtx orig_loop_end = NULL_RTX;
1069
1070           if (stats_file)
1071             {
1072               fprintf (stats_file,
1073                        "SMS succeeded %d %d (with ii, sc)\n", ps->ii,
1074                        stage_count);
1075               print_partial_schedule (ps, dump_file);
1076               fprintf (dump_file,
1077                        "SMS Branch (%d) will later be scheduled at cycle %d.\n",
1078                        g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1);
1079             }
1080
1081           /* Save the original loop if we want to do loop preconditioning in
1082              case the BCT count is not known.  */
1083           if (! count_init)
1084             {
1085               int i;
1086
1087               start_sequence ();
1088               /* Copy the original loop code before modifying it -
1089                  so we can use it later.  */
1090               for (i = 0; i < ps->g->num_nodes; i++)
1091                 duplicate_insn_chain (ps->g->nodes[i].first_note,
1092                                       ps->g->nodes[i].insn);
1093
1094               orig_loop_beg = get_insns ();
1095               orig_loop_end = get_last_insn ();
1096               end_sequence ();
1097             }
1098           /* Set the stage boundaries.  If the DDG is built with closing_branch_deps,
1099              the closing_branch was scheduled and should appear in the last (ii-1)
1100              row.  Otherwise, we are free to schedule the branch, and we let nodes
1101              that were scheduled at the first PS_MIN_CYCLE cycle appear in the first
1102              row; this should reduce stage_count to minimum.  */
1103           normalize_sched_times (ps);
1104           rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
1105           set_columns_for_ps (ps);
1106
1107           permute_partial_schedule (ps, g->closing_branch->first_note);
1108
1109           /* Mark this loop as software pipelined so the later
1110              scheduling passes doesn't touch it.  */
1111           if (! flag_resched_modulo_sched)
1112             g->bb->flags |= BB_DISABLE_SCHEDULE;
1113
1114           generate_reg_moves (ps);
1115           if (dump_file)
1116             print_node_sched_params (dump_file, g->num_nodes);
1117
1118           /* Set new iteration count of loop kernel.  */
1119           if (count_init)
1120             SET_SRC (single_set (count_init)) = GEN_INT (loop_count
1121                                                          - stage_count + 1);
1122
1123           /* Generate prolog and epilog.  */
1124           generate_prolog_epilog (ps, orig_loop_beg, orig_loop_end,
1125                                   count_init ? 0 : 1);
1126         }
1127       free_partial_schedule (ps);
1128       free (node_sched_params);
1129       free (node_order);
1130       free_ddg (g);
1131     }
1132
1133   /* Release scheduler data, needed until now because of DFA.  */
1134   sched_finish ();
1135 }
1136
1137 /* The SMS scheduling algorithm itself
1138    -----------------------------------
1139    Input: 'O' an ordered list of insns of a loop.
1140    Output: A scheduling of the loop - kernel, prolog, and epilogue.
1141
1142    'Q' is the empty Set
1143    'PS' is the partial schedule; it holds the currently scheduled nodes with
1144         their cycle/slot.
1145    'PSP' previously scheduled predecessors.
1146    'PSS' previously scheduled successors.
1147    't(u)' the cycle where u is scheduled.
1148    'l(u)' is the latency of u.
1149    'd(v,u)' is the dependence distance from v to u.
1150    'ASAP(u)' the earliest time at which u could be scheduled as computed in
1151              the node ordering phase.
1152    'check_hardware_resources_conflicts(u, PS, c)'
1153                              run a trace around cycle/slot through DFA model
1154                              to check resource conflicts involving instruction u
1155                              at cycle c given the partial schedule PS.
1156    'add_to_partial_schedule_at_time(u, PS, c)'
1157                              Add the node/instruction u to the partial schedule
1158                              PS at time c.
1159    'calculate_register_pressure(PS)'
1160                              Given a schedule of instructions, calculate the register
1161                              pressure it implies.  One implementation could be the
1162                              maximum number of overlapping live ranges.
1163    'maxRP' The maximum allowed register pressure, it is usually derived from the number
1164            registers available in the hardware.
1165
1166    1. II = MII.
1167    2. PS = empty list
1168    3. for each node u in O in pre-computed order
1169    4.   if (PSP(u) != Q && PSS(u) == Q) then
1170    5.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1171    6.     start = Early_start; end = Early_start + II - 1; step = 1
1172    11.  else if (PSP(u) == Q && PSS(u) != Q) then
1173    12.      Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1174    13.     start = Late_start; end = Late_start - II + 1; step = -1
1175    14.  else if (PSP(u) != Q && PSS(u) != Q) then
1176    15.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1177    16.     Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1178    17.     start = Early_start;
1179    18.     end = min(Early_start + II - 1 , Late_start);
1180    19.     step = 1
1181    20.     else "if (PSP(u) == Q && PSS(u) == Q)"
1182    21.    start = ASAP(u); end = start + II - 1; step = 1
1183    22.  endif
1184
1185    23.  success = false
1186    24.  for (c = start ; c != end ; c += step)
1187    25.     if check_hardware_resources_conflicts(u, PS, c) then
1188    26.       add_to_partial_schedule_at_time(u, PS, c)
1189    27.       success = true
1190    28.       break
1191    29.     endif
1192    30.  endfor
1193    31.  if (success == false) then
1194    32.    II = II + 1
1195    33.    if (II > maxII) then
1196    34.       finish - failed to schedule
1197    35.   endif
1198    36.    goto 2.
1199    37.  endif
1200    38. endfor
1201    39. if (calculate_register_pressure(PS) > maxRP) then
1202    40.    goto 32.
1203    41. endif
1204    42. compute epilogue & prologue
1205    43. finish - succeeded to schedule
1206 */
1207
1208 /* A limit on the number of cycles that resource conflicts can span.  ??? Should
1209    be provided by DFA, and be dependent on the type of insn scheduled.  Currently
1210    set to 0 to save compile time.  */
1211 #define DFA_HISTORY SMS_DFA_HISTORY
1212
1213 static partial_schedule_ptr
1214 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order, FILE *dump_file)
1215 {
1216   int ii = mii;
1217   int i, c, success;
1218   int try_again_with_larger_ii = true;
1219   int num_nodes = g->num_nodes;
1220   ddg_edge_ptr e;
1221   int start, end, step; /* Place together into one struct?  */
1222   sbitmap sched_nodes = sbitmap_alloc (num_nodes);
1223   sbitmap psp = sbitmap_alloc (num_nodes);
1224   sbitmap pss = sbitmap_alloc (num_nodes);
1225   sbitmap must_precede = sbitmap_alloc (num_nodes);
1226   sbitmap must_follow = sbitmap_alloc (num_nodes);
1227
1228   partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
1229
1230   while (try_again_with_larger_ii && ii < maxii)
1231     {
1232       if (dump_file)
1233         fprintf(dump_file, "Starting with ii=%d\n", ii);
1234       try_again_with_larger_ii = false;
1235       sbitmap_zero (sched_nodes);
1236
1237       for (i = 0; i < num_nodes; i++)
1238         {
1239           int u = nodes_order[i];
1240           ddg_node_ptr u_node = &g->nodes[u];
1241           sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1242           sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1243           int psp_not_empty;
1244           int pss_not_empty;
1245           rtx insn = u_node->insn;
1246
1247           if (!INSN_P (insn))
1248             continue;
1249
1250           if (JUMP_P (insn)) /* Closing branch handled later.  */
1251             continue;
1252
1253           /* 1. compute sched window for u (start, end, step).  */
1254           sbitmap_zero (psp);
1255           sbitmap_zero (pss);
1256           psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1257           pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1258
1259           if (psp_not_empty && !pss_not_empty)
1260             {
1261               int early_start = 0;
1262
1263               end = INT_MAX;
1264               for (e = u_node->in; e != 0; e = e->next_in)
1265                 {
1266                   ddg_node_ptr v_node = e->src;
1267                   if (TEST_BIT (sched_nodes, v_node->cuid))
1268                     {
1269                       int node_st = SCHED_TIME (v_node)
1270                                     + e->latency - (e->distance * ii);
1271
1272                       early_start = MAX (early_start, node_st);
1273
1274                       if (e->data_type == MEM_DEP)
1275                         end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1276                     }
1277                 }
1278               start = early_start;
1279               end = MIN (end, early_start + ii);
1280               step = 1;
1281             }
1282
1283           else if (!psp_not_empty && pss_not_empty)
1284             {
1285               int late_start = INT_MAX;
1286
1287               end = INT_MIN;
1288               for (e = u_node->out; e != 0; e = e->next_out)
1289                 {
1290                   ddg_node_ptr v_node = e->dest;
1291                   if (TEST_BIT (sched_nodes, v_node->cuid))
1292                     {
1293                       late_start = MIN (late_start,
1294                                         SCHED_TIME (v_node) - e->latency
1295                                         + (e->distance * ii));
1296                       if (e->data_type == MEM_DEP)
1297                         end = MAX (end, SCHED_TIME (v_node) - ii + 1);
1298                     }
1299                 }
1300               start = late_start;
1301               end = MAX (end, late_start - ii);
1302               step = -1;
1303             }
1304
1305           else if (psp_not_empty && pss_not_empty)
1306             {
1307               int early_start = 0;
1308               int late_start = INT_MAX;
1309
1310               start = INT_MIN;
1311               end = INT_MAX;
1312               for (e = u_node->in; e != 0; e = e->next_in)
1313                 {
1314                   ddg_node_ptr v_node = e->src;
1315
1316                   if (TEST_BIT (sched_nodes, v_node->cuid))
1317                     {
1318                       early_start = MAX (early_start,
1319                                          SCHED_TIME (v_node) + e->latency
1320                                          - (e->distance * ii));
1321                       if (e->data_type == MEM_DEP)
1322                         end = MIN (end, SCHED_TIME (v_node) + ii - 1);
1323                     }
1324                 }
1325               for (e = u_node->out; e != 0; e = e->next_out)
1326                 {
1327                   ddg_node_ptr v_node = e->dest;
1328
1329                   if (TEST_BIT (sched_nodes, v_node->cuid))
1330                     {
1331                       late_start = MIN (late_start,
1332                                         SCHED_TIME (v_node) - e->latency
1333                                         + (e->distance * ii));
1334                       if (e->data_type == MEM_DEP)
1335                         start = MAX (start, SCHED_TIME (v_node) - ii + 1);
1336                     }
1337                 }
1338               start = MAX (start, early_start);
1339               end = MIN (end, MIN (early_start + ii, late_start + 1));
1340               step = 1;
1341             }
1342           else /* psp is empty && pss is empty.  */
1343             {
1344               start = SCHED_ASAP (u_node);
1345               end = start + ii;
1346               step = 1;
1347             }
1348
1349           /* 2. Try scheduling u in window.  */
1350           if (dump_file)
1351             fprintf(dump_file, "Trying to schedule node %d in (%d .. %d) step %d\n",
1352                     u, start, end, step);
1353
1354           /* use must_follow & must_precede bitmaps to determine order
1355              of nodes within the cycle.  */
1356           sbitmap_zero (must_precede);
1357           sbitmap_zero (must_follow);
1358           for (e = u_node->in; e != 0; e = e->next_in)
1359             if (TEST_BIT (sched_nodes, e->src->cuid)
1360                 && e->latency == (ii * e->distance)
1361                 && start == SCHED_TIME (e->src))
1362              SET_BIT (must_precede, e->src->cuid);
1363
1364           for (e = u_node->out; e != 0; e = e->next_out)
1365             if (TEST_BIT (sched_nodes, e->dest->cuid)
1366                 && e->latency == (ii * e->distance)
1367                 && end == SCHED_TIME (e->dest))
1368              SET_BIT (must_follow, e->dest->cuid);
1369
1370           success = 0;
1371           if ((step > 0 && start < end) ||  (step < 0 && start > end))
1372             for (c = start; c != end; c += step)
1373               {
1374                 ps_insn_ptr psi;
1375
1376                 psi = ps_add_node_check_conflicts (ps, u_node, c,
1377                                                    must_precede,
1378                                                    must_follow);
1379
1380                 if (psi)
1381                   {
1382                     SCHED_TIME (u_node) = c;
1383                     SET_BIT (sched_nodes, u);
1384                     success = 1;
1385                     if (dump_file)
1386                       fprintf(dump_file, "Schedule in %d\n", c);
1387                     break;
1388                   }
1389               }
1390           if (!success)
1391             {
1392               /* ??? Try backtracking instead of immediately ii++?  */
1393               ii++;
1394               try_again_with_larger_ii = true;
1395               reset_partial_schedule (ps, ii);
1396               break;
1397             }
1398           /* ??? If (success), check register pressure estimates.  */
1399         } /* Continue with next node.  */
1400     } /* While try_again_with_larger_ii.  */
1401
1402   sbitmap_free (sched_nodes);
1403   sbitmap_free (psp);
1404   sbitmap_free (pss);
1405
1406   if (ii >= maxii)
1407     {
1408       free_partial_schedule (ps);
1409       ps = NULL;
1410     }
1411   return ps;
1412 }
1413
1414 \f
1415 /* This page implements the algorithm for ordering the nodes of a DDG
1416    for modulo scheduling, activated through the
1417    "int sms_order_nodes (ddg_ptr, int mii, int * result)" API.  */
1418
1419 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
1420 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
1421 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
1422 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
1423 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
1424 #define DEPTH(x) (ASAP ((x)))
1425
1426 typedef struct node_order_params * nopa;
1427
1428 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
1429 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
1430 static nopa  calculate_order_params (ddg_ptr, int mii);
1431 static int find_max_asap (ddg_ptr, sbitmap);
1432 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
1433 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
1434
1435 enum sms_direction {BOTTOMUP, TOPDOWN};
1436
1437 struct node_order_params
1438 {
1439   int asap;
1440   int alap;
1441   int height;
1442 };
1443
1444 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1.  */
1445 static void
1446 check_nodes_order (int *node_order, int num_nodes)
1447 {
1448   int i;
1449   sbitmap tmp = sbitmap_alloc (num_nodes);
1450
1451   sbitmap_zero (tmp);
1452
1453   for (i = 0; i < num_nodes; i++)
1454     {
1455       int u = node_order[i];
1456
1457       if (u >= num_nodes || u < 0 || TEST_BIT (tmp, u))
1458         abort ();
1459
1460       SET_BIT (tmp, u);
1461     }
1462
1463   sbitmap_free (tmp);
1464 }
1465
1466 /* Order the nodes of G for scheduling and pass the result in
1467    NODE_ORDER.  Also set aux.count of each node to ASAP.
1468    Return the recMII for the given DDG.  */
1469 static int
1470 sms_order_nodes (ddg_ptr g, int mii, int * node_order)
1471 {
1472   int i;
1473   int rec_mii = 0;
1474   ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
1475
1476   nopa nops = calculate_order_params (g, mii);
1477
1478   order_nodes_of_sccs (sccs, node_order);
1479
1480   if (sccs->num_sccs > 0)
1481     /* First SCC has the largest recurrence_length.  */
1482     rec_mii = sccs->sccs[0]->recurrence_length;
1483
1484   /* Save ASAP before destroying node_order_params.  */
1485   for (i = 0; i < g->num_nodes; i++)
1486     {
1487       ddg_node_ptr v = &g->nodes[i];
1488       v->aux.count = ASAP (v);
1489     }
1490
1491   free (nops);
1492   free_ddg_all_sccs (sccs);
1493   check_nodes_order (node_order, g->num_nodes);
1494
1495   return rec_mii;
1496 }
1497
1498 static void
1499 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
1500 {
1501   int i, pos = 0;
1502   ddg_ptr g = all_sccs->ddg;
1503   int num_nodes = g->num_nodes;
1504   sbitmap prev_sccs = sbitmap_alloc (num_nodes);
1505   sbitmap on_path = sbitmap_alloc (num_nodes);
1506   sbitmap tmp = sbitmap_alloc (num_nodes);
1507   sbitmap ones = sbitmap_alloc (num_nodes);
1508
1509   sbitmap_zero (prev_sccs);
1510   sbitmap_ones (ones);
1511
1512   /* Perfrom the node ordering starting from the SCC with the highest recMII.
1513      For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc.  */
1514   for (i = 0; i < all_sccs->num_sccs; i++)
1515     {
1516       ddg_scc_ptr scc = all_sccs->sccs[i];
1517
1518       /* Add nodes on paths from previous SCCs to the current SCC.  */
1519       find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
1520       sbitmap_a_or_b (tmp, scc->nodes, on_path);
1521
1522       /* Add nodes on paths from the current SCC to previous SCCs.  */
1523       find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
1524       sbitmap_a_or_b (tmp, tmp, on_path);
1525
1526       /* Remove nodes of previous SCCs from current extended SCC.  */
1527       sbitmap_difference (tmp, tmp, prev_sccs);
1528
1529       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1530       /* Above call to order_nodes_in_scc updated prev_sccs |= tmp.  */
1531     }
1532
1533   /* Handle the remaining nodes that do not belong to any scc.  Each call
1534      to order_nodes_in_scc handles a single connected component.  */
1535   while (pos < g->num_nodes)
1536     {
1537       sbitmap_difference (tmp, ones, prev_sccs);
1538       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
1539     }
1540   sbitmap_free (prev_sccs);
1541   sbitmap_free (on_path);
1542   sbitmap_free (tmp);
1543   sbitmap_free (ones);
1544 }
1545
1546 /* MII is needed if we consider backarcs (that do not close recursive cycles).  */
1547 static struct node_order_params *
1548 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED)
1549 {
1550   int u;
1551   int max_asap;
1552   int num_nodes = g->num_nodes;
1553   ddg_edge_ptr e;
1554   /* Allocate a place to hold ordering params for each node in the DDG.  */
1555   nopa node_order_params_arr;
1556
1557   /* Initialize of ASAP/ALAP/HEIGHT to zero.  */
1558   node_order_params_arr = (nopa) xcalloc (num_nodes,
1559                                           sizeof (struct node_order_params));
1560
1561   /* Set the aux pointer of each node to point to its order_params structure.  */
1562   for (u = 0; u < num_nodes; u++)
1563     g->nodes[u].aux.info = &node_order_params_arr[u];
1564
1565   /* Disregarding a backarc from each recursive cycle to obtain a DAG,
1566      calculate ASAP, ALAP, mobility, distance, and height for each node
1567      in the dependence (direct acyclic) graph.  */
1568
1569   /* We assume that the nodes in the array are in topological order.  */
1570
1571   max_asap = 0;
1572   for (u = 0; u < num_nodes; u++)
1573     {
1574       ddg_node_ptr u_node = &g->nodes[u];
1575
1576       ASAP (u_node) = 0;
1577       for (e = u_node->in; e; e = e->next_in)
1578         if (e->distance == 0)
1579           ASAP (u_node) = MAX (ASAP (u_node),
1580                                ASAP (e->src) + e->latency);
1581       max_asap = MAX (max_asap, ASAP (u_node));
1582     }
1583
1584   for (u = num_nodes - 1; u > -1; u--)
1585     {
1586       ddg_node_ptr u_node = &g->nodes[u];
1587
1588       ALAP (u_node) = max_asap;
1589       HEIGHT (u_node) = 0;
1590       for (e = u_node->out; e; e = e->next_out)
1591         if (e->distance == 0)
1592           {
1593             ALAP (u_node) = MIN (ALAP (u_node),
1594                                  ALAP (e->dest) - e->latency);
1595             HEIGHT (u_node) = MAX (HEIGHT (u_node),
1596                                    HEIGHT (e->dest) + e->latency);
1597           }
1598     }
1599
1600   return node_order_params_arr;
1601 }
1602
1603 static int
1604 find_max_asap (ddg_ptr g, sbitmap nodes)
1605 {
1606   int u;
1607   int max_asap = -1;
1608   int result = -1;
1609
1610   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1611     {
1612       ddg_node_ptr u_node = &g->nodes[u];
1613
1614       if (max_asap < ASAP (u_node))
1615         {
1616           max_asap = ASAP (u_node);
1617           result = u;
1618         }
1619     });
1620   return result;
1621 }
1622
1623 static int
1624 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
1625 {
1626   int u;
1627   int max_hv = -1;
1628   int min_mob = INT_MAX;
1629   int result = -1;
1630
1631   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1632     {
1633       ddg_node_ptr u_node = &g->nodes[u];
1634
1635       if (max_hv < HEIGHT (u_node))
1636         {
1637           max_hv = HEIGHT (u_node);
1638           min_mob = MOB (u_node);
1639           result = u;
1640         }
1641       else if ((max_hv == HEIGHT (u_node))
1642                && (min_mob > MOB (u_node)))
1643         {
1644           min_mob = MOB (u_node);
1645           result = u;
1646         }
1647     });
1648   return result;
1649 }
1650
1651 static int
1652 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
1653 {
1654   int u;
1655   int max_dv = -1;
1656   int min_mob = INT_MAX;
1657   int result = -1;
1658
1659   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u,
1660     {
1661       ddg_node_ptr u_node = &g->nodes[u];
1662
1663       if (max_dv < DEPTH (u_node))
1664         {
1665           max_dv = DEPTH (u_node);
1666           min_mob = MOB (u_node);
1667           result = u;
1668         }
1669       else if ((max_dv == DEPTH (u_node))
1670                && (min_mob > MOB (u_node)))
1671         {
1672           min_mob = MOB (u_node);
1673           result = u;
1674         }
1675     });
1676   return result;
1677 }
1678
1679 /* Places the nodes of SCC into the NODE_ORDER array starting
1680    at position POS, according to the SMS ordering algorithm.
1681    NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
1682    the NODE_ORDER array, starting from position zero.  */
1683 static int
1684 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
1685                     int * node_order, int pos)
1686 {
1687   enum sms_direction dir;
1688   int num_nodes = g->num_nodes;
1689   sbitmap workset = sbitmap_alloc (num_nodes);
1690   sbitmap tmp = sbitmap_alloc (num_nodes);
1691   sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
1692   sbitmap predecessors = sbitmap_alloc (num_nodes);
1693   sbitmap successors = sbitmap_alloc (num_nodes);
1694
1695   sbitmap_zero (predecessors);
1696   find_predecessors (predecessors, g, nodes_ordered);
1697
1698   sbitmap_zero (successors);
1699   find_successors (successors, g, nodes_ordered);
1700
1701   sbitmap_zero (tmp);
1702   if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
1703     {
1704       sbitmap_copy (workset, tmp);
1705       dir = BOTTOMUP;
1706     }
1707   else if (sbitmap_a_and_b_cg (tmp, successors, scc))
1708     {
1709       sbitmap_copy (workset, tmp);
1710       dir = TOPDOWN;
1711     }
1712   else
1713     {
1714       int u;
1715
1716       sbitmap_zero (workset);
1717       if ((u = find_max_asap (g, scc)) >= 0)
1718         SET_BIT (workset, u);
1719       dir = BOTTOMUP;
1720     }
1721
1722   sbitmap_zero (zero_bitmap);
1723   while (!sbitmap_equal (workset, zero_bitmap))
1724     {
1725       int v;
1726       ddg_node_ptr v_node;
1727       sbitmap v_node_preds;
1728       sbitmap v_node_succs;
1729
1730       if (dir == TOPDOWN)
1731         {
1732           while (!sbitmap_equal (workset, zero_bitmap))
1733             {
1734               v = find_max_hv_min_mob (g, workset);
1735               v_node = &g->nodes[v];
1736               node_order[pos++] = v;
1737               v_node_succs = NODE_SUCCESSORS (v_node);
1738               sbitmap_a_and_b (tmp, v_node_succs, scc);
1739
1740               /* Don't consider the already ordered successors again.  */
1741               sbitmap_difference (tmp, tmp, nodes_ordered);
1742               sbitmap_a_or_b (workset, workset, tmp);
1743               RESET_BIT (workset, v);
1744               SET_BIT (nodes_ordered, v);
1745             }
1746           dir = BOTTOMUP;
1747           sbitmap_zero (predecessors);
1748           find_predecessors (predecessors, g, nodes_ordered);
1749           sbitmap_a_and_b (workset, predecessors, scc);
1750         }
1751       else
1752         {
1753           while (!sbitmap_equal (workset, zero_bitmap))
1754             {
1755               v = find_max_dv_min_mob (g, workset);
1756               v_node = &g->nodes[v];
1757               node_order[pos++] = v;
1758               v_node_preds = NODE_PREDECESSORS (v_node);
1759               sbitmap_a_and_b (tmp, v_node_preds, scc);
1760
1761               /* Don't consider the already ordered predecessors again.  */
1762               sbitmap_difference (tmp, tmp, nodes_ordered);
1763               sbitmap_a_or_b (workset, workset, tmp);
1764               RESET_BIT (workset, v);
1765               SET_BIT (nodes_ordered, v);
1766             }
1767           dir = TOPDOWN;
1768           sbitmap_zero (successors);
1769           find_successors (successors, g, nodes_ordered);
1770           sbitmap_a_and_b (workset, successors, scc);
1771         }
1772     }
1773   sbitmap_free (tmp);
1774   sbitmap_free (workset);
1775   sbitmap_free (zero_bitmap);
1776   sbitmap_free (predecessors);
1777   sbitmap_free (successors);
1778   return pos;
1779 }
1780
1781 \f
1782 /* This page contains functions for manipulating partial-schedules during
1783    modulo scheduling.  */
1784
1785 /* Create a partial schedule and allocate a memory to hold II rows.  */
1786 partial_schedule_ptr
1787 create_partial_schedule (int ii, ddg_ptr g, int history)
1788 {
1789   partial_schedule_ptr ps = (partial_schedule_ptr)
1790                              xmalloc (sizeof (struct partial_schedule));
1791   ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
1792   ps->ii = ii;
1793   ps->history = history;
1794   ps->min_cycle = INT_MAX;
1795   ps->max_cycle = INT_MIN;
1796   ps->g = g;
1797
1798   return ps;
1799 }
1800
1801 /* Free the PS_INSNs in rows array of the given partial schedule.
1802    ??? Consider caching the PS_INSN's.  */
1803 static void
1804 free_ps_insns (partial_schedule_ptr ps)
1805 {
1806   int i;
1807
1808   for (i = 0; i < ps->ii; i++)
1809     {
1810       while (ps->rows[i])
1811         {
1812           ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
1813
1814           free (ps->rows[i]);
1815           ps->rows[i] = ps_insn;
1816         }
1817       ps->rows[i] = NULL;
1818     }
1819 }
1820
1821 /* Free all the memory allocated to the partial schedule.  */
1822 void
1823 free_partial_schedule (partial_schedule_ptr ps)
1824 {
1825   if (!ps)
1826     return;
1827   free_ps_insns (ps);
1828   free (ps->rows);
1829   free (ps);
1830 }
1831
1832 /* Clear the rows array with its PS_INSNs, and create a new one with
1833    NEW_II rows.  */
1834 void
1835 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
1836 {
1837   if (!ps)
1838     return;
1839   free_ps_insns (ps);
1840   if (new_ii == ps->ii)
1841     return;
1842   ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
1843                                                  * sizeof (ps_insn_ptr));
1844   memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
1845   ps->ii = new_ii;
1846   ps->min_cycle = INT_MAX;
1847   ps->max_cycle = INT_MIN;
1848 }
1849
1850 /* Prints the partial schedule as an ii rows array, for each rows
1851    print the ids of the insns in it.  */
1852 void
1853 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
1854 {
1855   int i;
1856
1857   for (i = 0; i < ps->ii; i++)
1858     {
1859       ps_insn_ptr ps_i = ps->rows[i];
1860
1861       fprintf (dump, "\n[CYCLE %d ]: ", i);
1862       while (ps_i)
1863         {
1864           fprintf (dump, "%d, ",
1865                    INSN_UID (ps_i->node->insn));
1866           ps_i = ps_i->next_in_row;
1867         }
1868     }
1869 }
1870
1871 /* Creates an object of PS_INSN and initializes it to the given parameters.  */
1872 static ps_insn_ptr
1873 create_ps_insn (ddg_node_ptr node, int rest_count, int cycle)
1874 {
1875   ps_insn_ptr ps_i = xmalloc (sizeof (struct ps_insn));
1876
1877   ps_i->node = node;
1878   ps_i->next_in_row = NULL;
1879   ps_i->prev_in_row = NULL;
1880   ps_i->row_rest_count = rest_count;
1881   ps_i->cycle = cycle;
1882
1883   return ps_i;
1884 }
1885
1886
1887 /* Removes the given PS_INSN from the partial schedule.  Returns false if the
1888    node is not found in the partial schedule, else returns true.  */
1889 static int
1890 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
1891 {
1892   int row;
1893
1894   if (!ps || !ps_i)
1895     return false;
1896
1897   row = SMODULO (ps_i->cycle, ps->ii);
1898   if (! ps_i->prev_in_row)
1899     {
1900       if (ps_i != ps->rows[row])
1901         return false;
1902
1903       ps->rows[row] = ps_i->next_in_row;
1904       if (ps->rows[row])
1905         ps->rows[row]->prev_in_row = NULL;
1906     }
1907   else
1908     {
1909       ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
1910       if (ps_i->next_in_row)
1911         ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
1912     }
1913   free (ps_i);
1914   return true;
1915 }
1916
1917 /* Unlike what literature describes for modulo scheduling (which focuses
1918    on VLIW machines) the order of the instructions inside a cycle is
1919    important.  Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
1920    where the current instruction should go relative to the already
1921    scheduled instructions in the given cycle.  Go over these
1922    instructions and find the first possible column to put it in.  */
1923 static bool
1924 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
1925                      sbitmap must_precede, sbitmap must_follow)
1926 {
1927   ps_insn_ptr next_ps_i;
1928   ps_insn_ptr first_must_follow = NULL;
1929   ps_insn_ptr last_must_precede = NULL;
1930   int row;
1931
1932   if (! ps_i)
1933     return false;
1934
1935   row = SMODULO (ps_i->cycle, ps->ii);
1936
1937   /* Find the first must follow and the last must precede
1938      and insert the node immediately after the must precede
1939      but make sure that it there is no must follow after it.   */
1940   for (next_ps_i = ps->rows[row];
1941        next_ps_i;
1942        next_ps_i = next_ps_i->next_in_row)
1943     {
1944       if (TEST_BIT (must_follow, next_ps_i->node->cuid)
1945           && ! first_must_follow)
1946         first_must_follow = next_ps_i;
1947       if (TEST_BIT (must_precede, next_ps_i->node->cuid))
1948         {
1949           /* If we have already met a node that must follow, then
1950              there is no possible column.  */
1951           if (first_must_follow)
1952             return false;
1953           else
1954             last_must_precede = next_ps_i;
1955         }
1956     }
1957
1958   /* Now insert the node after INSERT_AFTER_PSI.  */
1959
1960   if (! last_must_precede)
1961     {
1962       ps_i->next_in_row = ps->rows[row];
1963       ps_i->prev_in_row = NULL;
1964       if (ps_i->next_in_row)
1965         ps_i->next_in_row->prev_in_row = ps_i;
1966       ps->rows[row] = ps_i;
1967     }
1968   else
1969     {
1970       ps_i->next_in_row = last_must_precede->next_in_row;
1971       last_must_precede->next_in_row = ps_i;
1972       ps_i->prev_in_row = last_must_precede;
1973       if (ps_i->next_in_row)
1974         ps_i->next_in_row->prev_in_row = ps_i;
1975     }
1976
1977   return true;
1978 }
1979
1980 /* Advances the PS_INSN one column in its current row; returns false
1981    in failure and true in success.  Bit N is set in MUST_FOLLOW if 
1982    the node with cuid N must be come after the node pointed to by 
1983    PS_I when scheduled in the same cycle.  */
1984 static int
1985 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
1986                         sbitmap must_follow)
1987 {
1988   ps_insn_ptr prev, next;
1989   int row;
1990   ddg_node_ptr next_node;
1991
1992   if (!ps || !ps_i)
1993     return false;
1994
1995   row = SMODULO (ps_i->cycle, ps->ii);
1996
1997   if (! ps_i->next_in_row)
1998     return false;
1999
2000   next_node = ps_i->next_in_row->node;
2001
2002   /* Check if next_in_row is dependent on ps_i, both having same sched
2003      times (typically ANTI_DEP).  If so, ps_i cannot skip over it.  */
2004   if (TEST_BIT (must_follow, next_node->cuid))
2005     return false;
2006
2007   /* Advance PS_I over its next_in_row in the doubly linked list.  */
2008   prev = ps_i->prev_in_row;
2009   next = ps_i->next_in_row;
2010
2011   if (ps_i == ps->rows[row])
2012     ps->rows[row] = next;
2013
2014   ps_i->next_in_row = next->next_in_row;
2015
2016   if (next->next_in_row)
2017     next->next_in_row->prev_in_row = ps_i;
2018
2019   next->next_in_row = ps_i;
2020   ps_i->prev_in_row = next;
2021
2022   next->prev_in_row = prev;
2023   if (prev)
2024     prev->next_in_row = next;
2025
2026   return true;
2027 }
2028
2029 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
2030    Returns 0 if this is not possible and a PS_INSN otherwise.  Bit N is 
2031    set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come 
2032    before/after (respectively) the node pointed to by PS_I when scheduled 
2033    in the same cycle.  */
2034 static ps_insn_ptr
2035 add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle,
2036                 sbitmap must_precede, sbitmap must_follow)
2037 {
2038   ps_insn_ptr ps_i;
2039   int rest_count = 1;
2040   int row = SMODULO (cycle, ps->ii);
2041
2042   if (ps->rows[row]
2043       && ps->rows[row]->row_rest_count >= issue_rate)
2044     return NULL;
2045
2046   if (ps->rows[row])
2047     rest_count += ps->rows[row]->row_rest_count;
2048
2049   ps_i = create_ps_insn (node, rest_count, cycle);
2050
2051   /* Finds and inserts PS_I according to MUST_FOLLOW and
2052      MUST_PRECEDE.  */
2053   if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
2054     {
2055       free (ps_i);
2056       return NULL;
2057     }
2058
2059   return ps_i;
2060 }
2061
2062 /* Advance time one cycle.  Assumes DFA is being used.  */
2063 static void
2064 advance_one_cycle (void)
2065 {
2066   if (targetm.sched.dfa_pre_cycle_insn)
2067     state_transition (curr_state,
2068                       (*targetm.sched.dfa_pre_cycle_insn) ());
2069
2070   state_transition (curr_state, NULL);
2071
2072   if (targetm.sched.dfa_post_cycle_insn)
2073     state_transition (curr_state,
2074                       (*targetm.sched.dfa_post_cycle_insn) ());
2075 }
2076
2077 /* Checks if PS has resource conflicts according to DFA, starting from
2078    FROM cycle to TO cycle; returns true if there are conflicts and false
2079    if there are no conflicts.  Assumes DFA is being used.  */
2080 static int
2081 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
2082 {
2083   int cycle;
2084
2085   state_reset (curr_state);
2086
2087   for (cycle = from; cycle <= to; cycle++)
2088     {
2089       ps_insn_ptr crr_insn;
2090       /* Holds the remaining issue slots in the current row.  */
2091       int can_issue_more = issue_rate;
2092
2093       /* Walk through the DFA for the current row.  */
2094       for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
2095            crr_insn;
2096            crr_insn = crr_insn->next_in_row)
2097         {
2098           rtx insn = crr_insn->node->insn;
2099
2100           if (!INSN_P (insn))
2101             continue;
2102
2103           /* Check if there is room for the current insn.  */
2104           if (!can_issue_more || state_dead_lock_p (curr_state))
2105             return true;
2106
2107           /* Update the DFA state and return with failure if the DFA found
2108              recource conflicts.  */
2109           if (state_transition (curr_state, insn) >= 0)
2110             return true;
2111
2112           if (targetm.sched.variable_issue)
2113             can_issue_more =
2114               (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
2115                                                insn, can_issue_more);
2116           /* A naked CLOBBER or USE generates no instruction, so don't
2117              let them consume issue slots.  */
2118           else if (GET_CODE (PATTERN (insn)) != USE
2119                    && GET_CODE (PATTERN (insn)) != CLOBBER)
2120             can_issue_more--;
2121         }
2122
2123       /* Advance the DFA to the next cycle.  */
2124       advance_one_cycle ();
2125     }
2126   return false;
2127 }
2128
2129 /* Checks if the given node causes resource conflicts when added to PS at
2130    cycle C.  If not the node is added to PS and returned; otherwise zero
2131    is returned.  Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with 
2132    cuid N must be come before/after (respectively) the node pointed to by 
2133    PS_I when scheduled in the same cycle.  */
2134 ps_insn_ptr
2135 ps_add_node_check_conflicts (partial_schedule_ptr ps, ddg_node_ptr n,
2136                              int c, sbitmap must_precede,
2137                              sbitmap must_follow)
2138 {
2139   int has_conflicts = 0;
2140   ps_insn_ptr ps_i;
2141
2142   /* First add the node to the PS, if this succeeds check for
2143      conflicts, trying different issue slots in the same row.  */
2144   if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
2145     return NULL; /* Failed to insert the node at the given cycle.  */
2146
2147   has_conflicts = ps_has_conflicts (ps, c, c)
2148                   || (ps->history > 0
2149                       && ps_has_conflicts (ps,
2150                                            c - ps->history,
2151                                            c + ps->history));
2152
2153   /* Try different issue slots to find one that the given node can be
2154      scheduled in without conflicts.  */
2155   while (has_conflicts)
2156     {
2157       if (! ps_insn_advance_column (ps, ps_i, must_follow))
2158         break;
2159       has_conflicts = ps_has_conflicts (ps, c, c)
2160                       || (ps->history > 0
2161                           && ps_has_conflicts (ps,
2162                                                c - ps->history,
2163                                                c + ps->history));
2164     }
2165
2166   if (has_conflicts)
2167     {
2168       remove_node_from_ps (ps, ps_i);
2169       return NULL;
2170     }
2171
2172   ps->min_cycle = MIN (ps->min_cycle, c);
2173   ps->max_cycle = MAX (ps->max_cycle, c);
2174   return ps_i;
2175 }
2176
2177 /* Rotate the rows of PS such that insns scheduled at time
2178    START_CYCLE will appear in row 0.  Updates max/min_cycles.  */
2179 void
2180 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
2181 {
2182   int i, row, backward_rotates;
2183   int last_row = ps->ii - 1;
2184
2185   if (start_cycle == 0)
2186     return;
2187
2188   backward_rotates = SMODULO (start_cycle, ps->ii);
2189
2190   /* Revisit later and optimize this into a single loop.  */
2191   for (i = 0; i < backward_rotates; i++)
2192     {
2193       ps_insn_ptr first_row = ps->rows[0];
2194
2195       for (row = 0; row < last_row; row++)
2196         ps->rows[row] = ps->rows[row+1];
2197
2198       ps->rows[last_row] = first_row;
2199     }
2200
2201   ps->max_cycle -= start_cycle;
2202   ps->min_cycle -= start_cycle;
2203 }
2204
2205 #endif /* INSN_SCHEDULING*/