OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / modulo-sched.c
1 /* Swing Modulo Scheduling implementation.
2    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 3, 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 COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "diagnostic-core.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "hard-reg-set.h"
31 #include "regs.h"
32 #include "function.h"
33 #include "flags.h"
34 #include "insn-config.h"
35 #include "insn-attr.h"
36 #include "except.h"
37 #include "recog.h"
38 #include "sched-int.h"
39 #include "target.h"
40 #include "cfglayout.h"
41 #include "cfgloop.h"
42 #include "cfghooks.h"
43 #include "expr.h"
44 #include "params.h"
45 #include "gcov-io.h"
46 #include "ddg.h"
47 #include "timevar.h"
48 #include "tree-pass.h"
49 #include "dbgcnt.h"
50 #include "df.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     SMS works with countable loops (1) whose control part can be easily
88     decoupled from the rest of the loop and (2) whose loop count can
89     be easily adjusted.  This is because we peel a constant number of
90     iterations into a prologue and epilogue for which we want to avoid
91     emitting the control part, and a kernel which is to iterate that
92     constant number of iterations less than the original loop.  So the
93     control part should be a set of insns clearly identified and having
94     its own iv, not otherwise used in the loop (at-least for now), which
95     initializes a register before the loop to the number of iterations.
96     Currently SMS relies on the do-loop pattern to recognize such loops,
97     where (1) the control part comprises of all insns defining and/or
98     using a certain 'count' register and (2) the loop count can be
99     adjusted by modifying this register prior to the loop.
100     TODO: Rely on cfgloop analysis instead.  */
101 \f
102 /* This page defines partial-schedule structures and functions for
103    modulo scheduling.  */
104
105 typedef struct partial_schedule *partial_schedule_ptr;
106 typedef struct ps_insn *ps_insn_ptr;
107
108 /* The minimum (absolute) cycle that a node of ps was scheduled in.  */
109 #define PS_MIN_CYCLE(ps) (((partial_schedule_ptr)(ps))->min_cycle)
110
111 /* The maximum (absolute) cycle that a node of ps was scheduled in.  */
112 #define PS_MAX_CYCLE(ps) (((partial_schedule_ptr)(ps))->max_cycle)
113
114 /* Perform signed modulo, always returning a non-negative value.  */
115 #define SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y))
116
117 /* The number of different iterations the nodes in ps span, assuming
118    the stage boundaries are placed efficiently.  */
119 #define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \
120                          + 1 + ii - 1) / ii)
121 /* The stage count of ps.  */
122 #define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count)
123
124 /* A single instruction in the partial schedule.  */
125 struct ps_insn
126 {
127   /* Identifies the instruction to be scheduled.  Values smaller than
128      the ddg's num_nodes refer directly to ddg nodes.  A value of
129      X - num_nodes refers to register move X.  */
130   int id;
131
132   /* The (absolute) cycle in which the PS instruction is scheduled.
133      Same as SCHED_TIME (node).  */
134   int cycle;
135
136   /* The next/prev PS_INSN in the same row.  */
137   ps_insn_ptr next_in_row,
138               prev_in_row;
139
140 };
141
142 /* Information about a register move that has been added to a partial
143    schedule.  */
144 struct ps_reg_move_info
145 {
146   /* The source of the move is defined by the ps_insn with id DEF.
147      The destination is used by the ps_insns with the ids in USES.  */
148   int def;
149   sbitmap uses;
150
151   /* The original form of USES' instructions used OLD_REG, but they
152      should now use NEW_REG.  */
153   rtx old_reg;
154   rtx new_reg;
155
156   /* The number of consecutive stages that the move occupies.  */
157   int num_consecutive_stages;
158
159   /* An instruction that sets NEW_REG to the correct value.  The first
160      move associated with DEF will have an rhs of OLD_REG; later moves
161      use the result of the previous move.  */
162   rtx insn;
163 };
164
165 typedef struct ps_reg_move_info ps_reg_move_info;
166 DEF_VEC_O (ps_reg_move_info);
167 DEF_VEC_ALLOC_O (ps_reg_move_info, heap);
168
169 /* Holds the partial schedule as an array of II rows.  Each entry of the
170    array points to a linked list of PS_INSNs, which represents the
171    instructions that are scheduled for that row.  */
172 struct partial_schedule
173 {
174   int ii;       /* Number of rows in the partial schedule.  */
175   int history;  /* Threshold for conflict checking using DFA.  */
176
177   /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii).  */
178   ps_insn_ptr *rows;
179
180   /* All the moves added for this partial schedule.  Index X has
181      a ps_insn id of X + g->num_nodes.  */
182   VEC (ps_reg_move_info, heap) *reg_moves;
183
184   /*  rows_length[i] holds the number of instructions in the row.
185       It is used only (as an optimization) to back off quickly from
186       trying to schedule a node in a full row; that is, to avoid running
187       through futile DFA state transitions.  */
188   int *rows_length;
189   
190   /* The earliest absolute cycle of an insn in the partial schedule.  */
191   int min_cycle;
192
193   /* The latest absolute cycle of an insn in the partial schedule.  */
194   int max_cycle;
195
196   ddg_ptr g;    /* The DDG of the insns in the partial schedule.  */
197
198   int stage_count;  /* The stage count of the partial schedule.  */
199 };
200
201
202 static partial_schedule_ptr create_partial_schedule (int ii, ddg_ptr, int history);
203 static void free_partial_schedule (partial_schedule_ptr);
204 static void reset_partial_schedule (partial_schedule_ptr, int new_ii);
205 void print_partial_schedule (partial_schedule_ptr, FILE *);
206 static void verify_partial_schedule (partial_schedule_ptr, sbitmap);
207 static ps_insn_ptr ps_add_node_check_conflicts (partial_schedule_ptr,
208                                                 int, int, sbitmap, sbitmap);
209 static void rotate_partial_schedule (partial_schedule_ptr, int);
210 void set_row_column_for_ps (partial_schedule_ptr);
211 static void ps_insert_empty_row (partial_schedule_ptr, int, sbitmap);
212 static int compute_split_row (sbitmap, int, int, int, ddg_node_ptr);
213
214 \f
215 /* This page defines constants and structures for the modulo scheduling
216    driver.  */
217
218 static int sms_order_nodes (ddg_ptr, int, int *, int *);
219 static void set_node_sched_params (ddg_ptr);
220 static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *);
221 static void permute_partial_schedule (partial_schedule_ptr, rtx);
222 static void generate_prolog_epilog (partial_schedule_ptr, struct loop *,
223                                     rtx, rtx);
224 static int calculate_stage_count (partial_schedule_ptr, int);
225 static void calculate_must_precede_follow (ddg_node_ptr, int, int,
226                                            int, int, sbitmap, sbitmap, sbitmap);
227 static int get_sched_window (partial_schedule_ptr, ddg_node_ptr, 
228                              sbitmap, int, int *, int *, int *);
229 static bool try_scheduling_node_in_cycle (partial_schedule_ptr, int, int,
230                                           sbitmap, int *, sbitmap, sbitmap);
231 static void remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr);
232
233 #define NODE_ASAP(node) ((node)->aux.count)
234
235 #define SCHED_PARAMS(x) VEC_index (node_sched_params, node_sched_param_vec, x)
236 #define SCHED_TIME(x) (SCHED_PARAMS (x)->time)
237 #define SCHED_ROW(x) (SCHED_PARAMS (x)->row)
238 #define SCHED_STAGE(x) (SCHED_PARAMS (x)->stage)
239 #define SCHED_COLUMN(x) (SCHED_PARAMS (x)->column)
240
241 /* The scheduling parameters held for each node.  */
242 typedef struct node_sched_params
243 {
244   int time;     /* The absolute scheduling cycle.  */
245
246   int row;    /* Holds time % ii.  */
247   int stage;  /* Holds time / ii.  */
248
249   /* The column of a node inside the ps.  If nodes u, v are on the same row,
250      u will precede v if column (u) < column (v).  */
251   int column;
252 } *node_sched_params_ptr;
253
254 typedef struct node_sched_params node_sched_params;
255 DEF_VEC_O (node_sched_params);
256 DEF_VEC_ALLOC_O (node_sched_params, heap);
257 \f
258 /* The following three functions are copied from the current scheduler
259    code in order to use sched_analyze() for computing the dependencies.
260    They are used when initializing the sched_info structure.  */
261 static const char *
262 sms_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED)
263 {
264   static char tmp[80];
265
266   sprintf (tmp, "i%4d", INSN_UID (insn));
267   return tmp;
268 }
269
270 static void
271 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
272                                regset used ATTRIBUTE_UNUSED)
273 {
274 }
275
276 static struct common_sched_info_def sms_common_sched_info;
277
278 static struct sched_deps_info_def sms_sched_deps_info =
279   {
280     compute_jump_reg_dependencies,
281     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
282     NULL,
283     0, 0, 0
284   };
285
286 static struct haifa_sched_info sms_sched_info =
287 {
288   NULL,
289   NULL,
290   NULL,
291   NULL,
292   NULL,
293   sms_print_insn,
294   NULL,
295   NULL, /* insn_finishes_block_p */
296   NULL, NULL,
297   NULL, NULL,
298   0, 0,
299
300   NULL, NULL, NULL, NULL,
301   NULL, NULL,
302   0
303 };
304
305 /* Partial schedule instruction ID in PS is a register move.  Return
306    information about it.  */
307 static struct ps_reg_move_info *
308 ps_reg_move (partial_schedule_ptr ps, int id)
309 {
310   gcc_checking_assert (id >= ps->g->num_nodes);
311   return VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes);
312 }
313
314 /* Return the rtl instruction that is being scheduled by partial schedule
315    instruction ID, which belongs to schedule PS.  */
316 static rtx
317 ps_rtl_insn (partial_schedule_ptr ps, int id)
318 {
319   if (id < ps->g->num_nodes)
320     return ps->g->nodes[id].insn;
321   else
322     return ps_reg_move (ps, id)->insn;
323 }
324
325 /* Partial schedule instruction ID, which belongs to PS, occured in
326    the original (unscheduled) loop.  Return the first instruction
327    in the loop that was associated with ps_rtl_insn (PS, ID).
328    If the instruction had some notes before it, this is the first
329    of those notes.  */
330 static rtx
331 ps_first_note (partial_schedule_ptr ps, int id)
332 {
333   gcc_assert (id < ps->g->num_nodes);
334   return ps->g->nodes[id].first_note;
335 }
336
337 /* Return the number of consecutive stages that are occupied by
338    partial schedule instruction ID in PS.  */
339 static int
340 ps_num_consecutive_stages (partial_schedule_ptr ps, int id)
341 {
342   if (id < ps->g->num_nodes)
343     return 1;
344   else
345     return ps_reg_move (ps, id)->num_consecutive_stages;
346 }
347
348 /* Given HEAD and TAIL which are the first and last insns in a loop;
349    return the register which controls the loop.  Return zero if it has
350    more than one occurrence in the loop besides the control part or the
351    do-loop pattern is not of the form we expect.  */
352 static rtx
353 doloop_register_get (rtx head ATTRIBUTE_UNUSED, rtx tail ATTRIBUTE_UNUSED)
354 {
355 #ifdef HAVE_doloop_end
356   rtx reg, condition, insn, first_insn_not_to_check;
357
358   if (!JUMP_P (tail))
359     return NULL_RTX;
360
361   /* TODO: Free SMS's dependence on doloop_condition_get.  */
362   condition = doloop_condition_get (tail);
363   if (! condition)
364     return NULL_RTX;
365
366   if (REG_P (XEXP (condition, 0)))
367     reg = XEXP (condition, 0);
368   else if (GET_CODE (XEXP (condition, 0)) == PLUS
369            && REG_P (XEXP (XEXP (condition, 0), 0)))
370     reg = XEXP (XEXP (condition, 0), 0);
371   else
372     gcc_unreachable ();
373
374   /* Check that the COUNT_REG has no other occurrences in the loop
375      until the decrement.  We assume the control part consists of
376      either a single (parallel) branch-on-count or a (non-parallel)
377      branch immediately preceded by a single (decrement) insn.  */
378   first_insn_not_to_check = (GET_CODE (PATTERN (tail)) == PARALLEL ? tail
379                              : prev_nondebug_insn (tail));
380
381   for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
382     if (!DEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn))
383       {
384         if (dump_file)
385         {
386           fprintf (dump_file, "SMS count_reg found ");
387           print_rtl_single (dump_file, reg);
388           fprintf (dump_file, " outside control in insn:\n");
389           print_rtl_single (dump_file, insn);
390         }
391
392         return NULL_RTX;
393       }
394
395   return reg;
396 #else
397   return NULL_RTX;
398 #endif
399 }
400
401 /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
402    that the number of iterations is a compile-time constant.  If so,
403    return the rtx that sets COUNT_REG to a constant, and set COUNT to
404    this constant.  Otherwise return 0.  */
405 static rtx
406 const_iteration_count (rtx count_reg, basic_block pre_header,
407                        HOST_WIDEST_INT * count)
408 {
409   rtx insn;
410   rtx head, tail;
411
412   if (! pre_header)
413     return NULL_RTX;
414
415   get_ebb_head_tail (pre_header, pre_header, &head, &tail);
416
417   for (insn = tail; insn != PREV_INSN (head); insn = PREV_INSN (insn))
418     if (NONDEBUG_INSN_P (insn) && single_set (insn) &&
419         rtx_equal_p (count_reg, SET_DEST (single_set (insn))))
420       {
421         rtx pat = single_set (insn);
422
423         if (CONST_INT_P (SET_SRC (pat)))
424           {
425             *count = INTVAL (SET_SRC (pat));
426             return insn;
427           }
428
429         return NULL_RTX;
430       }
431
432   return NULL_RTX;
433 }
434
435 /* A very simple resource-based lower bound on the initiation interval.
436    ??? Improve the accuracy of this bound by considering the
437    utilization of various units.  */
438 static int
439 res_MII (ddg_ptr g)
440 {
441   if (targetm.sched.sms_res_mii)
442     return targetm.sched.sms_res_mii (g);
443
444   return ((g->num_nodes - g->num_debug) / issue_rate);
445 }
446
447
448 /* A vector that contains the sched data for each ps_insn.  */
449 static VEC (node_sched_params, heap) *node_sched_param_vec;
450
451 /* Allocate sched_params for each node and initialize it.  */
452 static void
453 set_node_sched_params (ddg_ptr g)
454 {
455   VEC_truncate (node_sched_params, node_sched_param_vec, 0);
456   VEC_safe_grow_cleared (node_sched_params, heap,
457                          node_sched_param_vec, g->num_nodes);
458 }
459
460 /* Make sure that node_sched_param_vec has an entry for every move in PS.  */
461 static void
462 extend_node_sched_params (partial_schedule_ptr ps)
463 {
464   VEC_safe_grow_cleared (node_sched_params, heap, node_sched_param_vec,
465                          ps->g->num_nodes + VEC_length (ps_reg_move_info,
466                                                         ps->reg_moves));
467 }
468
469 /* Update the sched_params (time, row and stage) for node U using the II,
470    the CYCLE of U and MIN_CYCLE.
471    We're not simply taking the following
472    SCHED_STAGE (u) = CALC_STAGE_COUNT (SCHED_TIME (u), min_cycle, ii);
473    because the stages may not be aligned on cycle 0.  */
474 static void
475 update_node_sched_params (int u, int ii, int cycle, int min_cycle)
476 {
477   int sc_until_cycle_zero;
478   int stage;
479
480   SCHED_TIME (u) = cycle;
481   SCHED_ROW (u) = SMODULO (cycle, ii);
482
483   /* The calculation of stage count is done adding the number
484      of stages before cycle zero and after cycle zero.  */
485   sc_until_cycle_zero = CALC_STAGE_COUNT (-1, min_cycle, ii);
486
487   if (SCHED_TIME (u) < 0)
488     {
489       stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii);
490       SCHED_STAGE (u) = sc_until_cycle_zero - stage;
491     }
492   else
493     {
494       stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii);
495       SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1;
496     }
497 }
498
499 static void
500 print_node_sched_params (FILE *file, int num_nodes, partial_schedule_ptr ps)
501 {
502   int i;
503
504   if (! file)
505     return;
506   for (i = 0; i < num_nodes; i++)
507     {
508       node_sched_params_ptr nsp = SCHED_PARAMS (i);
509
510       fprintf (file, "Node = %d; INSN = %d\n", i,
511                INSN_UID (ps_rtl_insn (ps, i)));
512       fprintf (file, " asap = %d:\n", NODE_ASAP (&ps->g->nodes[i]));
513       fprintf (file, " time = %d:\n", nsp->time);
514       fprintf (file, " stage = %d:\n", nsp->stage);
515     }
516 }
517
518 /* Set SCHED_COLUMN for each instruction in row ROW of PS.  */
519 static void
520 set_columns_for_row (partial_schedule_ptr ps, int row)
521 {
522   ps_insn_ptr cur_insn;
523   int column;
524
525   column = 0;
526   for (cur_insn = ps->rows[row]; cur_insn; cur_insn = cur_insn->next_in_row)
527     SCHED_COLUMN (cur_insn->id) = column++;
528 }
529
530 /* Set SCHED_COLUMN for each instruction in PS.  */
531 static void
532 set_columns_for_ps (partial_schedule_ptr ps)
533 {
534   int row;
535
536   for (row = 0; row < ps->ii; row++)
537     set_columns_for_row (ps, row);
538 }
539
540 /* Try to schedule the move with ps_insn identifier I_REG_MOVE in PS.
541    Its single predecessor has already been scheduled, as has its
542    ddg node successors.  (The move may have also another move as its
543    successor, in which case that successor will be scheduled later.)
544
545    The move is part of a chain that satisfies register dependencies
546    between a producing ddg node and various consuming ddg nodes.
547    If some of these dependencies have a distance of 1 (meaning that
548    the use is upward-exposoed) then DISTANCE1_USES is nonnull and
549    contains the set of uses with distance-1 dependencies.
550    DISTANCE1_USES is null otherwise.
551
552    MUST_FOLLOW is a scratch bitmap that is big enough to hold
553    all current ps_insn ids.
554
555    Return true on success.  */
556 static bool
557 schedule_reg_move (partial_schedule_ptr ps, int i_reg_move,
558                    sbitmap distance1_uses, sbitmap must_follow)
559 {
560   unsigned int u;
561   int this_time, this_distance, this_start, this_end, this_latency;
562   int start, end, c, ii;
563   sbitmap_iterator sbi;
564   ps_reg_move_info *move;
565   rtx this_insn;
566   ps_insn_ptr psi;
567
568   move = ps_reg_move (ps, i_reg_move);
569   ii = ps->ii;
570   if (dump_file)
571     {
572       fprintf (dump_file, "Scheduling register move INSN %d; ii = %d"
573                ", min cycle = %d\n\n", INSN_UID (move->insn), ii,
574                PS_MIN_CYCLE (ps));
575       print_rtl_single (dump_file, move->insn);
576       fprintf (dump_file, "\n%11s %11s %5s\n", "start", "end", "time");
577       fprintf (dump_file, "=========== =========== =====\n");
578     }
579
580   start = INT_MIN;
581   end = INT_MAX;
582
583   /* For dependencies of distance 1 between a producer ddg node A
584      and consumer ddg node B, we have a chain of dependencies:
585
586         A --(T,L1,1)--> M1 --(T,L2,0)--> M2 ... --(T,Ln,0)--> B
587
588      where Mi is the ith move.  For dependencies of distance 0 between
589      a producer ddg node A and consumer ddg node C, we have a chain of
590      dependencies:
591
592         A --(T,L1',0)--> M1' --(T,L2',0)--> M2' ... --(T,Ln',0)--> C
593
594      where Mi' occupies the same position as Mi but occurs a stage later.
595      We can only schedule each move once, so if we have both types of
596      chain, we model the second as:
597
598         A --(T,L1',1)--> M1 --(T,L2',0)--> M2 ... --(T,Ln',-1)--> C
599
600      First handle the dependencies between the previously-scheduled
601      predecessor and the move.  */
602   this_insn = ps_rtl_insn (ps, move->def);
603   this_latency = insn_latency (this_insn, move->insn);
604   this_distance = distance1_uses && move->def < ps->g->num_nodes ? 1 : 0;
605   this_time = SCHED_TIME (move->def) - this_distance * ii;
606   this_start = this_time + this_latency;
607   this_end = this_time + ii;
608   if (dump_file)
609     fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n",
610              this_start, this_end, SCHED_TIME (move->def),
611              INSN_UID (this_insn), this_latency, this_distance,
612              INSN_UID (move->insn));
613
614   if (start < this_start)
615     start = this_start;
616   if (end > this_end)
617     end = this_end;
618
619   /* Handle the dependencies between the move and previously-scheduled
620      successors.  */
621   EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, u, sbi)
622     {
623       this_insn = ps_rtl_insn (ps, u);
624       this_latency = insn_latency (move->insn, this_insn);
625       if (distance1_uses && !TEST_BIT (distance1_uses, u))
626         this_distance = -1;
627       else
628         this_distance = 0;
629       this_time = SCHED_TIME (u) + this_distance * ii;
630       this_start = this_time - ii;
631       this_end = this_time - this_latency;
632       if (dump_file)
633         fprintf (dump_file, "%11d %11d %5d %d --(T,%d,%d)--> %d\n",
634                  this_start, this_end, SCHED_TIME (u), INSN_UID (move->insn),
635                  this_latency, this_distance, INSN_UID (this_insn));
636
637       if (start < this_start)
638         start = this_start;
639       if (end > this_end)
640         end = this_end;
641     }
642
643   if (dump_file)
644     {
645       fprintf (dump_file, "----------- ----------- -----\n");
646       fprintf (dump_file, "%11d %11d %5s %s\n", start, end, "", "(max, min)");
647     }
648
649   sbitmap_zero (must_follow);
650   SET_BIT (must_follow, move->def);
651
652   start = MAX (start, end - (ii - 1));
653   for (c = end; c >= start; c--)
654     {
655       psi = ps_add_node_check_conflicts (ps, i_reg_move, c,
656                                          move->uses, must_follow);
657       if (psi)
658         {
659           update_node_sched_params (i_reg_move, ii, c, PS_MIN_CYCLE (ps));
660           if (dump_file)
661             fprintf (dump_file, "\nScheduled register move INSN %d at"
662                      " time %d, row %d\n\n", INSN_UID (move->insn), c,
663                      SCHED_ROW (i_reg_move));
664           return true;
665         }
666     }
667
668   if (dump_file)
669     fprintf (dump_file, "\nNo available slot\n\n");
670
671   return false;
672 }
673
674 /*
675    Breaking intra-loop register anti-dependences:
676    Each intra-loop register anti-dependence implies a cross-iteration true
677    dependence of distance 1. Therefore, we can remove such false dependencies
678    and figure out if the partial schedule broke them by checking if (for a
679    true-dependence of distance 1): SCHED_TIME (def) < SCHED_TIME (use) and
680    if so generate a register move.   The number of such moves is equal to:
681               SCHED_TIME (use) - SCHED_TIME (def)       { 0 broken
682    nreg_moves = ----------------------------------- + 1 - {   dependence.
683                             ii                          { 1 if not.
684 */
685 static bool
686 schedule_reg_moves (partial_schedule_ptr ps)
687 {
688   ddg_ptr g = ps->g;
689   int ii = ps->ii;
690   int i;
691
692   for (i = 0; i < g->num_nodes; i++)
693     {
694       ddg_node_ptr u = &g->nodes[i];
695       ddg_edge_ptr e;
696       int nreg_moves = 0, i_reg_move;
697       rtx prev_reg, old_reg;
698       int first_move;
699       int distances[2];
700       sbitmap must_follow;
701       sbitmap distance1_uses;
702       rtx set = single_set (u->insn);
703       
704       /* Skip instructions that do not set a register.  */
705       if ((set && !REG_P (SET_DEST (set))))
706         continue;
707  
708       /* Compute the number of reg_moves needed for u, by looking at life
709          ranges started at u (excluding self-loops).  */
710       distances[0] = distances[1] = false;
711       for (e = u->out; e; e = e->next_out)
712         if (e->type == TRUE_DEP && e->dest != e->src)
713           {
714             int nreg_moves4e = (SCHED_TIME (e->dest->cuid)
715                                 - SCHED_TIME (e->src->cuid)) / ii;
716
717             if (e->distance == 1)
718               nreg_moves4e = (SCHED_TIME (e->dest->cuid)
719                               - SCHED_TIME (e->src->cuid) + ii) / ii;
720
721             /* If dest precedes src in the schedule of the kernel, then dest
722                will read before src writes and we can save one reg_copy.  */
723             if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid)
724                 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid))
725               nreg_moves4e--;
726
727             if (nreg_moves4e >= 1)
728               {
729                 /* !single_set instructions are not supported yet and
730                    thus we do not except to encounter them in the loop
731                    except from the doloop part.  For the latter case
732                    we assume no regmoves are generated as the doloop
733                    instructions are tied to the branch with an edge.  */
734                 gcc_assert (set);
735                 /* If the instruction contains auto-inc register then
736                    validate that the regmov is being generated for the
737                    target regsiter rather then the inc'ed register.     */
738                 gcc_assert (!autoinc_var_is_used_p (u->insn, e->dest->insn));
739               }
740             
741             if (nreg_moves4e)
742               {
743                 gcc_assert (e->distance < 2);
744                 distances[e->distance] = true;
745               }
746             nreg_moves = MAX (nreg_moves, nreg_moves4e);
747           }
748
749       if (nreg_moves == 0)
750         continue;
751
752       /* Create NREG_MOVES register moves.  */
753       first_move = VEC_length (ps_reg_move_info, ps->reg_moves);
754       VEC_safe_grow_cleared (ps_reg_move_info, heap, ps->reg_moves,
755                              first_move + nreg_moves);
756       extend_node_sched_params (ps);
757
758       /* Record the moves associated with this node.  */
759       first_move += ps->g->num_nodes;
760
761       /* Generate each move.  */
762       old_reg = prev_reg = SET_DEST (single_set (u->insn));
763       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
764         {
765           ps_reg_move_info *move = ps_reg_move (ps, first_move + i_reg_move);
766
767           move->def = i_reg_move > 0 ? first_move + i_reg_move - 1 : i;
768           move->uses = sbitmap_alloc (first_move + nreg_moves);
769           move->old_reg = old_reg;
770           move->new_reg = gen_reg_rtx (GET_MODE (prev_reg));
771           move->num_consecutive_stages = distances[0] && distances[1] ? 2 : 1;
772           move->insn = gen_move_insn (move->new_reg, copy_rtx (prev_reg));
773           sbitmap_zero (move->uses);
774
775           prev_reg = move->new_reg;
776         }
777
778       distance1_uses = distances[1] ? sbitmap_alloc (g->num_nodes) : NULL;
779
780       /* Every use of the register defined by node may require a different
781          copy of this register, depending on the time the use is scheduled.
782          Record which uses require which move results.  */
783       for (e = u->out; e; e = e->next_out)
784         if (e->type == TRUE_DEP && e->dest != e->src)
785           {
786             int dest_copy = (SCHED_TIME (e->dest->cuid)
787                              - SCHED_TIME (e->src->cuid)) / ii;
788
789             if (e->distance == 1)
790               dest_copy = (SCHED_TIME (e->dest->cuid)
791                            - SCHED_TIME (e->src->cuid) + ii) / ii;
792
793             if (SCHED_ROW (e->dest->cuid) == SCHED_ROW (e->src->cuid)
794                 && SCHED_COLUMN (e->dest->cuid) < SCHED_COLUMN (e->src->cuid))
795               dest_copy--;
796
797             if (dest_copy)
798               {
799                 ps_reg_move_info *move;
800
801                 move = ps_reg_move (ps, first_move + dest_copy - 1);
802                 SET_BIT (move->uses, e->dest->cuid);
803                 if (e->distance == 1)
804                   SET_BIT (distance1_uses, e->dest->cuid);
805               }
806           }
807
808       must_follow = sbitmap_alloc (first_move + nreg_moves);
809       for (i_reg_move = 0; i_reg_move < nreg_moves; i_reg_move++)
810         if (!schedule_reg_move (ps, first_move + i_reg_move,
811                                 distance1_uses, must_follow))
812           break;
813       sbitmap_free (must_follow);
814       if (distance1_uses)
815         sbitmap_free (distance1_uses);
816       if (i_reg_move < nreg_moves)
817         return false;
818     }
819   return true;
820 }
821
822 /* Emit the moves associatied with PS.  Apply the substitutions
823    associated with them.  */
824 static void
825 apply_reg_moves (partial_schedule_ptr ps)
826 {
827   ps_reg_move_info *move;
828   int i;
829
830   FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
831     {
832       unsigned int i_use;
833       sbitmap_iterator sbi;
834
835       EXECUTE_IF_SET_IN_SBITMAP (move->uses, 0, i_use, sbi)
836         {
837           replace_rtx (ps->g->nodes[i_use].insn, move->old_reg, move->new_reg);
838           df_insn_rescan (ps->g->nodes[i_use].insn);
839         }
840     }
841 }
842
843 /* Bump the SCHED_TIMEs of all nodes by AMOUNT.  Set the values of
844    SCHED_ROW and SCHED_STAGE.  Instruction scheduled on cycle AMOUNT
845    will move to cycle zero.  */
846 static void
847 reset_sched_times (partial_schedule_ptr ps, int amount)
848 {
849   int row;
850   int ii = ps->ii;
851   ps_insn_ptr crr_insn;
852
853   for (row = 0; row < ii; row++)
854     for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
855       {
856         int u = crr_insn->id;
857         int normalized_time = SCHED_TIME (u) - amount;
858         int new_min_cycle = PS_MIN_CYCLE (ps) - amount;
859
860         if (dump_file)
861           {
862             /* Print the scheduling times after the rotation.  */
863             rtx insn = ps_rtl_insn (ps, u);
864
865             fprintf (dump_file, "crr_insn->node=%d (insn id %d), "
866                      "crr_insn->cycle=%d, min_cycle=%d", u,
867                      INSN_UID (insn), normalized_time, new_min_cycle);
868             if (JUMP_P (insn))
869               fprintf (dump_file, " (branch)");
870             fprintf (dump_file, "\n");
871           }
872         
873         gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
874         gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
875
876         crr_insn->cycle = normalized_time;
877         update_node_sched_params (u, ii, normalized_time, new_min_cycle);
878       }
879 }
880  
881 /* Permute the insns according to their order in PS, from row 0 to
882    row ii-1, and position them right before LAST.  This schedules
883    the insns of the loop kernel.  */
884 static void
885 permute_partial_schedule (partial_schedule_ptr ps, rtx last)
886 {
887   int ii = ps->ii;
888   int row;
889   ps_insn_ptr ps_ij;
890
891   for (row = 0; row < ii ; row++)
892     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
893       {
894         rtx insn = ps_rtl_insn (ps, ps_ij->id);
895
896         if (PREV_INSN (last) != insn)
897           {
898             if (ps_ij->id < ps->g->num_nodes)
899               reorder_insns_nobb (ps_first_note (ps, ps_ij->id), insn,
900                                   PREV_INSN (last));
901             else
902               add_insn_before (insn, last, NULL);
903           }
904       }
905 }
906
907 /* Set bitmaps TMP_FOLLOW and TMP_PRECEDE to MUST_FOLLOW and MUST_PRECEDE
908    respectively only if cycle C falls on the border of the scheduling
909    window boundaries marked by START and END cycles.  STEP is the
910    direction of the window.  */
911 static inline void
912 set_must_precede_follow (sbitmap *tmp_follow, sbitmap must_follow,
913                          sbitmap *tmp_precede, sbitmap must_precede, int c,
914                          int start, int end, int step)
915 {
916   *tmp_precede = NULL;
917   *tmp_follow = NULL;
918
919   if (c == start)
920     {
921       if (step == 1)
922         *tmp_precede = must_precede;
923       else                      /* step == -1.  */
924         *tmp_follow = must_follow;
925     }
926   if (c == end - step)
927     {
928       if (step == 1)
929         *tmp_follow = must_follow;
930       else                      /* step == -1.  */
931         *tmp_precede = must_precede;
932     }
933
934 }
935
936 /* Return True if the branch can be moved to row ii-1 while
937    normalizing the partial schedule PS to start from cycle zero and thus
938    optimize the SC.  Otherwise return False.  */
939 static bool
940 optimize_sc (partial_schedule_ptr ps, ddg_ptr g)
941 {
942   int amount = PS_MIN_CYCLE (ps);
943   sbitmap sched_nodes = sbitmap_alloc (g->num_nodes);
944   int start, end, step;
945   int ii = ps->ii;
946   bool ok = false;
947   int stage_count, stage_count_curr;
948
949   /* Compare the SC after normalization and SC after bringing the branch
950      to row ii-1.  If they are equal just bail out.  */
951   stage_count = calculate_stage_count (ps, amount);
952   stage_count_curr =
953     calculate_stage_count (ps, SCHED_TIME (g->closing_branch->cuid) - (ii - 1));
954
955   if (stage_count == stage_count_curr)
956     {
957       if (dump_file)
958         fprintf (dump_file, "SMS SC already optimized.\n");
959
960       ok = false;
961       goto clear;
962     }
963
964   if (dump_file)
965     {
966       fprintf (dump_file, "SMS Trying to optimize branch location\n");
967       fprintf (dump_file, "SMS partial schedule before trial:\n");
968       print_partial_schedule (ps, dump_file);
969     }
970
971   /* First, normalize the partial scheduling.  */
972   reset_sched_times (ps, amount);
973   rotate_partial_schedule (ps, amount);
974   if (dump_file)
975     {
976       fprintf (dump_file,
977                "SMS partial schedule after normalization (ii, %d, SC %d):\n",
978                ii, stage_count);
979       print_partial_schedule (ps, dump_file);
980     }
981
982   if (SMODULO (SCHED_TIME (g->closing_branch->cuid), ii) == ii - 1)
983     {
984       ok = true;
985       goto clear;
986     }
987
988   sbitmap_ones (sched_nodes);
989
990   /* Calculate the new placement of the branch.  It should be in row
991      ii-1 and fall into it's scheduling window.  */
992   if (get_sched_window (ps, g->closing_branch, sched_nodes, ii, &start,
993                         &step, &end) == 0)
994     {
995       bool success;
996       ps_insn_ptr next_ps_i;
997       int branch_cycle = SCHED_TIME (g->closing_branch->cuid);
998       int row = SMODULO (branch_cycle, ps->ii);
999       int num_splits = 0;
1000       sbitmap must_precede, must_follow, tmp_precede, tmp_follow;
1001       int c;
1002
1003       if (dump_file)
1004         fprintf (dump_file, "\nTrying to schedule node %d "
1005                  "INSN = %d  in (%d .. %d) step %d\n",
1006                  g->closing_branch->cuid,
1007                  (INSN_UID (g->closing_branch->insn)), start, end, step);
1008
1009       gcc_assert ((step > 0 && start < end) || (step < 0 && start > end));
1010       if (step == 1)
1011         {
1012           c = start + ii - SMODULO (start, ii) - 1;
1013           gcc_assert (c >= start);
1014           if (c >= end)
1015             {
1016               ok = false;
1017               if (dump_file)
1018                 fprintf (dump_file,
1019                          "SMS failed to schedule branch at cycle: %d\n", c);
1020               goto clear;
1021             }
1022         }
1023       else
1024         {
1025           c = start - SMODULO (start, ii) - 1;
1026           gcc_assert (c <= start);
1027
1028           if (c <= end)
1029             {
1030               if (dump_file)
1031                 fprintf (dump_file,
1032                          "SMS failed to schedule branch at cycle: %d\n", c);
1033               ok = false;
1034               goto clear;
1035             }
1036         }
1037
1038       must_precede = sbitmap_alloc (g->num_nodes);
1039       must_follow = sbitmap_alloc (g->num_nodes);
1040
1041       /* Try to schedule the branch is it's new cycle.  */
1042       calculate_must_precede_follow (g->closing_branch, start, end,
1043                                      step, ii, sched_nodes,
1044                                      must_precede, must_follow);
1045
1046       set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede,
1047                                must_precede, c, start, end, step);
1048
1049       /* Find the element in the partial schedule related to the closing
1050          branch so we can remove it from it's current cycle.  */
1051       for (next_ps_i = ps->rows[row];
1052            next_ps_i; next_ps_i = next_ps_i->next_in_row)
1053         if (next_ps_i->id == g->closing_branch->cuid)
1054           break;
1055
1056       remove_node_from_ps (ps, next_ps_i);
1057       success =
1058         try_scheduling_node_in_cycle (ps, g->closing_branch->cuid, c,
1059                                       sched_nodes, &num_splits,
1060                                       tmp_precede, tmp_follow);
1061       gcc_assert (num_splits == 0);
1062       if (!success)
1063         {
1064           if (dump_file)
1065             fprintf (dump_file,
1066                      "SMS failed to schedule branch at cycle: %d, "
1067                      "bringing it back to cycle %d\n", c, branch_cycle);
1068
1069           /* The branch was failed to be placed in row ii - 1.
1070              Put it back in it's original place in the partial
1071              schedualing.  */
1072           set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede,
1073                                    must_precede, branch_cycle, start, end,
1074                                    step);
1075           success =
1076             try_scheduling_node_in_cycle (ps, g->closing_branch->cuid,
1077                                           branch_cycle, sched_nodes,
1078                                           &num_splits, tmp_precede,
1079                                           tmp_follow);
1080           gcc_assert (success && (num_splits == 0));
1081           ok = false;
1082         }
1083       else
1084         {
1085           /* The branch is placed in row ii - 1.  */
1086           if (dump_file)
1087             fprintf (dump_file,
1088                      "SMS success in moving branch to cycle %d\n", c);
1089
1090           update_node_sched_params (g->closing_branch->cuid, ii, c,
1091                                     PS_MIN_CYCLE (ps));
1092           ok = true;
1093         }
1094
1095       free (must_precede);
1096       free (must_follow);
1097     }
1098
1099 clear:
1100   free (sched_nodes);
1101   return ok;
1102 }
1103
1104 static void
1105 duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
1106                            int to_stage, rtx count_reg)
1107 {
1108   int row;
1109   ps_insn_ptr ps_ij;
1110
1111   for (row = 0; row < ps->ii; row++)
1112     for (ps_ij = ps->rows[row]; ps_ij; ps_ij = ps_ij->next_in_row)
1113       {
1114         int u = ps_ij->id;
1115         int first_u, last_u;
1116         rtx u_insn;
1117
1118         /* Do not duplicate any insn which refers to count_reg as it
1119            belongs to the control part.
1120            The closing branch is scheduled as well and thus should
1121            be ignored.
1122            TODO: This should be done by analyzing the control part of
1123            the loop.  */
1124         u_insn = ps_rtl_insn (ps, u);
1125         if (reg_mentioned_p (count_reg, u_insn)
1126             || JUMP_P (u_insn))
1127           continue;
1128
1129         first_u = SCHED_STAGE (u);
1130         last_u = first_u + ps_num_consecutive_stages (ps, u) - 1;
1131         if (from_stage <= last_u && to_stage >= first_u)
1132           {
1133             if (u < ps->g->num_nodes)
1134               duplicate_insn_chain (ps_first_note (ps, u), u_insn);
1135             else
1136               emit_insn (copy_rtx (PATTERN (u_insn)));
1137           }
1138       }
1139 }
1140
1141
1142 /* Generate the instructions (including reg_moves) for prolog & epilog.  */
1143 static void
1144 generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
1145                         rtx count_reg, rtx count_init)
1146 {
1147   int i;
1148   int last_stage = PS_STAGE_COUNT (ps) - 1;
1149   edge e;
1150
1151   /* Generate the prolog, inserting its insns on the loop-entry edge.  */
1152   start_sequence ();
1153
1154   if (!count_init)
1155     {
1156       /* Generate instructions at the beginning of the prolog to
1157          adjust the loop count by STAGE_COUNT.  If loop count is constant
1158          (count_init), this constant is adjusted by STAGE_COUNT in
1159          generate_prolog_epilog function.  */
1160       rtx sub_reg = NULL_RTX;
1161
1162       sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS,
1163                                      count_reg, GEN_INT (last_stage),
1164                                      count_reg, 1, OPTAB_DIRECT);
1165       gcc_assert (REG_P (sub_reg));
1166       if (REGNO (sub_reg) != REGNO (count_reg))
1167         emit_move_insn (count_reg, sub_reg);
1168     }
1169
1170   for (i = 0; i < last_stage; i++)
1171     duplicate_insns_of_cycles (ps, 0, i, count_reg);
1172
1173   /* Put the prolog on the entry edge.  */
1174   e = loop_preheader_edge (loop);
1175   split_edge_and_insert (e, get_insns ());
1176
1177   end_sequence ();
1178
1179   /* Generate the epilog, inserting its insns on the loop-exit edge.  */
1180   start_sequence ();
1181
1182   for (i = 0; i < last_stage; i++)
1183     duplicate_insns_of_cycles (ps, i + 1, last_stage, count_reg);
1184
1185   /* Put the epilogue on the exit edge.  */
1186   gcc_assert (single_exit (loop));
1187   e = single_exit (loop);
1188   split_edge_and_insert (e, get_insns ());
1189   end_sequence ();
1190 }
1191
1192 /* Return true if all the BBs of the loop are empty except the
1193    loop header.  */
1194 static bool
1195 loop_single_full_bb_p (struct loop *loop)
1196 {
1197   unsigned i;
1198   basic_block *bbs = get_loop_body (loop);
1199
1200   for (i = 0; i < loop->num_nodes ; i++)
1201     {
1202       rtx head, tail;
1203       bool empty_bb = true;
1204
1205       if (bbs[i] == loop->header)
1206         continue;
1207
1208       /* Make sure that basic blocks other than the header
1209          have only notes labels or jumps.  */
1210       get_ebb_head_tail (bbs[i], bbs[i], &head, &tail);
1211       for (; head != NEXT_INSN (tail); head = NEXT_INSN (head))
1212         {
1213           if (NOTE_P (head) || LABEL_P (head)
1214               || (INSN_P (head) && (DEBUG_INSN_P (head) || JUMP_P (head))))
1215             continue;
1216           empty_bb = false;
1217           break;
1218         }
1219
1220       if (! empty_bb)
1221         {
1222           free (bbs);
1223           return false;
1224         }
1225     }
1226   free (bbs);
1227   return true;
1228 }
1229
1230 /* A simple loop from SMS point of view; it is a loop that is composed of
1231    either a single basic block or two BBs - a header and a latch.  */
1232 #define SIMPLE_SMS_LOOP_P(loop) ((loop->num_nodes < 3 )                     \
1233                                   && (EDGE_COUNT (loop->latch->preds) == 1) \
1234                                   && (EDGE_COUNT (loop->latch->succs) == 1))
1235
1236 /* Return true if the loop is in its canonical form and false if not.
1237    i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit.  */
1238 static bool
1239 loop_canon_p (struct loop *loop)
1240 {
1241
1242   if (loop->inner || !loop_outer (loop))
1243   {
1244     if (dump_file)
1245       fprintf (dump_file, "SMS loop inner or !loop_outer\n");
1246     return false;
1247   }
1248
1249   if (!single_exit (loop))
1250     {
1251       if (dump_file)
1252         {
1253           rtx insn = BB_END (loop->header);
1254
1255           fprintf (dump_file, "SMS loop many exits ");
1256                   fprintf (dump_file, " %s %d (file, line)\n",
1257                            insn_file (insn), insn_line (insn));
1258         }
1259       return false;
1260     }
1261
1262   if (! SIMPLE_SMS_LOOP_P (loop) && ! loop_single_full_bb_p (loop))
1263     {
1264       if (dump_file)
1265         {
1266           rtx insn = BB_END (loop->header);
1267
1268           fprintf (dump_file, "SMS loop many BBs. ");
1269           fprintf (dump_file, " %s %d (file, line)\n",
1270                    insn_file (insn), insn_line (insn));
1271         }
1272       return false;
1273     }
1274
1275     return true;
1276 }
1277
1278 /* If there are more than one entry for the loop,
1279    make it one by splitting the first entry edge and
1280    redirecting the others to the new BB.  */
1281 static void
1282 canon_loop (struct loop *loop)
1283 {
1284   edge e;
1285   edge_iterator i;
1286
1287   /* Avoid annoying special cases of edges going to exit
1288      block.  */
1289   FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
1290     if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
1291       split_edge (e);
1292
1293   if (loop->latch == loop->header
1294       || EDGE_COUNT (loop->latch->succs) > 1)
1295     {
1296       FOR_EACH_EDGE (e, i, loop->header->preds)
1297         if (e->src == loop->latch)
1298           break;
1299       split_edge (e);
1300     }
1301 }
1302
1303 /* Setup infos.  */
1304 static void
1305 setup_sched_infos (void)
1306 {
1307   memcpy (&sms_common_sched_info, &haifa_common_sched_info,
1308           sizeof (sms_common_sched_info));
1309   sms_common_sched_info.sched_pass_id = SCHED_SMS_PASS;
1310   common_sched_info = &sms_common_sched_info;
1311
1312   sched_deps_info = &sms_sched_deps_info;
1313   current_sched_info = &sms_sched_info;
1314 }
1315
1316 /* Probability in % that the sms-ed loop rolls enough so that optimized
1317    version may be entered.  Just a guess.  */
1318 #define PROB_SMS_ENOUGH_ITERATIONS 80
1319
1320 /* Used to calculate the upper bound of ii.  */
1321 #define MAXII_FACTOR 2
1322
1323 /* Main entry point, perform SMS scheduling on the loops of the function
1324    that consist of single basic blocks.  */
1325 static void
1326 sms_schedule (void)
1327 {
1328   rtx insn;
1329   ddg_ptr *g_arr, g;
1330   int * node_order;
1331   int maxii, max_asap;
1332   loop_iterator li;
1333   partial_schedule_ptr ps;
1334   basic_block bb = NULL;
1335   struct loop *loop;
1336   basic_block condition_bb = NULL;
1337   edge latch_edge;
1338   gcov_type trip_count = 0;
1339
1340   loop_optimizer_init (LOOPS_HAVE_PREHEADERS
1341                        | LOOPS_HAVE_RECORDED_EXITS);
1342   if (number_of_loops () <= 1)
1343     {
1344       loop_optimizer_finalize ();
1345       return;  /* There are no loops to schedule.  */
1346     }
1347
1348   /* Initialize issue_rate.  */
1349   if (targetm.sched.issue_rate)
1350     {
1351       int temp = reload_completed;
1352
1353       reload_completed = 1;
1354       issue_rate = targetm.sched.issue_rate ();
1355       reload_completed = temp;
1356     }
1357   else
1358     issue_rate = 1;
1359
1360   /* Initialize the scheduler.  */
1361   setup_sched_infos ();
1362   haifa_sched_init ();
1363
1364   /* Allocate memory to hold the DDG array one entry for each loop.
1365      We use loop->num as index into this array.  */
1366   g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
1367
1368   if (dump_file)
1369   {
1370     fprintf (dump_file, "\n\nSMS analysis phase\n");
1371     fprintf (dump_file, "===================\n\n");
1372   }
1373
1374   /* Build DDGs for all the relevant loops and hold them in G_ARR
1375      indexed by the loop index.  */
1376   FOR_EACH_LOOP (li, loop, 0)
1377     {
1378       rtx head, tail;
1379       rtx count_reg;
1380
1381       /* For debugging.  */
1382       if (dbg_cnt (sms_sched_loop) == false)
1383         {
1384           if (dump_file)
1385             fprintf (dump_file, "SMS reached max limit... \n");
1386
1387           break;
1388         }
1389
1390       if (dump_file)
1391       {
1392          rtx insn = BB_END (loop->header);
1393
1394          fprintf (dump_file, "SMS loop num: %d, file: %s, line: %d\n",
1395                   loop->num, insn_file (insn), insn_line (insn));
1396
1397       }
1398
1399       if (! loop_canon_p (loop))
1400         continue;
1401
1402       if (! loop_single_full_bb_p (loop))
1403       {
1404         if (dump_file)
1405           fprintf (dump_file, "SMS not loop_single_full_bb_p\n");
1406         continue;
1407       }
1408
1409       bb = loop->header;
1410
1411       get_ebb_head_tail (bb, bb, &head, &tail);
1412       latch_edge = loop_latch_edge (loop);
1413       gcc_assert (single_exit (loop));
1414       if (single_exit (loop)->count)
1415         trip_count = latch_edge->count / single_exit (loop)->count;
1416
1417       /* Perform SMS only on loops that their average count is above threshold.  */
1418
1419       if ( latch_edge->count
1420           && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
1421         {
1422           if (dump_file)
1423             {
1424               fprintf (dump_file, " %s %d (file, line)\n",
1425                        insn_file (tail), insn_line (tail));
1426               fprintf (dump_file, "SMS single-bb-loop\n");
1427               if (profile_info && flag_branch_probabilities)
1428                 {
1429                   fprintf (dump_file, "SMS loop-count ");
1430                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1431                            (HOST_WIDEST_INT) bb->count);
1432                   fprintf (dump_file, "\n");
1433                   fprintf (dump_file, "SMS trip-count ");
1434                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1435                            (HOST_WIDEST_INT) trip_count);
1436                   fprintf (dump_file, "\n");
1437                   fprintf (dump_file, "SMS profile-sum-max ");
1438                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1439                            (HOST_WIDEST_INT) profile_info->sum_max);
1440                   fprintf (dump_file, "\n");
1441                 }
1442             }
1443           continue;
1444         }
1445
1446       /* Make sure this is a doloop.  */
1447       if ( !(count_reg = doloop_register_get (head, tail)))
1448       {
1449         if (dump_file)
1450           fprintf (dump_file, "SMS doloop_register_get failed\n");
1451         continue;
1452       }
1453
1454       /* Don't handle BBs with calls or barriers
1455          or !single_set with the exception of instructions that include
1456          count_reg---these instructions are part of the control part
1457          that do-loop recognizes.
1458          ??? Should handle insns defining subregs.  */
1459      for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
1460       {
1461          rtx set;
1462
1463         if (CALL_P (insn)
1464             || BARRIER_P (insn)
1465             || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
1466                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE
1467                 && !reg_mentioned_p (count_reg, insn))
1468             || (INSN_P (insn) && (set = single_set (insn))
1469                 && GET_CODE (SET_DEST (set)) == SUBREG))
1470         break;
1471       }
1472
1473       if (insn != NEXT_INSN (tail))
1474         {
1475           if (dump_file)
1476             {
1477               if (CALL_P (insn))
1478                 fprintf (dump_file, "SMS loop-with-call\n");
1479               else if (BARRIER_P (insn))
1480                 fprintf (dump_file, "SMS loop-with-barrier\n");
1481               else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
1482                 && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
1483                 fprintf (dump_file, "SMS loop-with-not-single-set\n");
1484               else
1485                fprintf (dump_file, "SMS loop with subreg in lhs\n");
1486               print_rtl_single (dump_file, insn);
1487             }
1488
1489           continue;
1490         }
1491
1492       /* Always schedule the closing branch with the rest of the
1493          instructions. The branch is rotated to be in row ii-1 at the
1494          end of the scheduling procedure to make sure it's the last
1495          instruction in the iteration.  */
1496       if (! (g = create_ddg (bb, 1)))
1497         {
1498           if (dump_file)
1499             fprintf (dump_file, "SMS create_ddg failed\n");
1500           continue;
1501         }
1502
1503       g_arr[loop->num] = g;
1504       if (dump_file)
1505         fprintf (dump_file, "...OK\n");
1506
1507     }
1508   if (dump_file)
1509   {
1510     fprintf (dump_file, "\nSMS transformation phase\n");
1511     fprintf (dump_file, "=========================\n\n");
1512   }
1513
1514   /* We don't want to perform SMS on new loops - created by versioning.  */
1515   FOR_EACH_LOOP (li, loop, 0)
1516     {
1517       rtx head, tail;
1518       rtx count_reg, count_init;
1519       int mii, rec_mii, stage_count, min_cycle;
1520       HOST_WIDEST_INT loop_count = 0;
1521       bool opt_sc_p;
1522
1523       if (! (g = g_arr[loop->num]))
1524         continue;
1525
1526       if (dump_file)
1527       {
1528          rtx insn = BB_END (loop->header);
1529
1530          fprintf (dump_file, "SMS loop num: %d, file: %s, line: %d\n",
1531                   loop->num, insn_file (insn), insn_line (insn));
1532
1533          print_ddg (dump_file, g);
1534       }
1535
1536       get_ebb_head_tail (loop->header, loop->header, &head, &tail);
1537
1538       latch_edge = loop_latch_edge (loop);
1539       gcc_assert (single_exit (loop));
1540       if (single_exit (loop)->count)
1541         trip_count = latch_edge->count / single_exit (loop)->count;
1542
1543       if (dump_file)
1544         {
1545           fprintf (dump_file, " %s %d (file, line)\n",
1546                    insn_file (tail), insn_line (tail));
1547           fprintf (dump_file, "SMS single-bb-loop\n");
1548           if (profile_info && flag_branch_probabilities)
1549             {
1550               fprintf (dump_file, "SMS loop-count ");
1551               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1552                        (HOST_WIDEST_INT) bb->count);
1553               fprintf (dump_file, "\n");
1554               fprintf (dump_file, "SMS profile-sum-max ");
1555               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1556                        (HOST_WIDEST_INT) profile_info->sum_max);
1557               fprintf (dump_file, "\n");
1558             }
1559           fprintf (dump_file, "SMS doloop\n");
1560           fprintf (dump_file, "SMS built-ddg %d\n", g->num_nodes);
1561           fprintf (dump_file, "SMS num-loads %d\n", g->num_loads);
1562           fprintf (dump_file, "SMS num-stores %d\n", g->num_stores);
1563         }
1564
1565
1566       /* In case of th loop have doloop register it gets special
1567          handling.  */
1568       count_init = NULL_RTX;
1569       if ((count_reg = doloop_register_get (head, tail)))
1570         {
1571           basic_block pre_header;
1572
1573           pre_header = loop_preheader_edge (loop)->src;
1574           count_init = const_iteration_count (count_reg, pre_header,
1575                                               &loop_count);
1576         }
1577       gcc_assert (count_reg);
1578
1579       if (dump_file && count_init)
1580         {
1581           fprintf (dump_file, "SMS const-doloop ");
1582           fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
1583                      loop_count);
1584           fprintf (dump_file, "\n");
1585         }
1586
1587       node_order = XNEWVEC (int, g->num_nodes);
1588
1589       mii = 1; /* Need to pass some estimate of mii.  */
1590       rec_mii = sms_order_nodes (g, mii, node_order, &max_asap);
1591       mii = MAX (res_MII (g), rec_mii);
1592       maxii = MAX (max_asap, MAXII_FACTOR * mii);
1593
1594       if (dump_file)
1595         fprintf (dump_file, "SMS iis %d %d %d (rec_mii, mii, maxii)\n",
1596                  rec_mii, mii, maxii);
1597
1598       for (;;)
1599         {
1600           set_node_sched_params (g);
1601
1602           stage_count = 0;
1603           opt_sc_p = false;
1604           ps = sms_schedule_by_order (g, mii, maxii, node_order);
1605
1606           if (ps)
1607             {
1608               /* Try to achieve optimized SC by normalizing the partial
1609                  schedule (having the cycles start from cycle zero).
1610                  The branch location must be placed in row ii-1 in the
1611                  final scheduling.      If failed, shift all instructions to
1612                  position the branch in row ii-1.  */
1613               opt_sc_p = optimize_sc (ps, g);
1614               if (opt_sc_p)
1615                 stage_count = calculate_stage_count (ps, 0);
1616               else
1617                 {
1618                   /* Bring the branch to cycle ii-1.  */
1619                   int amount = (SCHED_TIME (g->closing_branch->cuid)
1620                                 - (ps->ii - 1));
1621
1622                   if (dump_file)
1623                     fprintf (dump_file, "SMS schedule branch at cycle ii-1\n");
1624
1625                   stage_count = calculate_stage_count (ps, amount);
1626                 }
1627
1628               gcc_assert (stage_count >= 1);
1629             }
1630
1631           /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of
1632              1 means that there is no interleaving between iterations thus
1633              we let the scheduling passes do the job in this case.  */
1634           if (stage_count < PARAM_VALUE (PARAM_SMS_MIN_SC)
1635               || (count_init && (loop_count <= stage_count))
1636               || (flag_branch_probabilities && (trip_count <= stage_count)))
1637             {
1638               if (dump_file)
1639                 {
1640                   fprintf (dump_file, "SMS failed... \n");
1641                   fprintf (dump_file, "SMS sched-failed (stage-count=%d,"
1642                            " loop-count=", stage_count);
1643                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, loop_count);
1644                   fprintf (dump_file, ", trip-count=");
1645                   fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, trip_count);
1646                   fprintf (dump_file, ")\n");
1647                 }
1648               break;
1649             }
1650
1651           if (!opt_sc_p)
1652             {
1653               /* Rotate the partial schedule to have the branch in row ii-1.  */
1654               int amount = SCHED_TIME (g->closing_branch->cuid) - (ps->ii - 1);
1655               
1656               reset_sched_times (ps, amount);
1657               rotate_partial_schedule (ps, amount);
1658             }
1659           
1660           set_columns_for_ps (ps);
1661
1662           min_cycle = PS_MIN_CYCLE (ps) - SMODULO (PS_MIN_CYCLE (ps), ps->ii);
1663           if (!schedule_reg_moves (ps))
1664             {
1665               mii = ps->ii + 1;
1666               free_partial_schedule (ps);
1667               continue;
1668             }
1669
1670           /* Moves that handle incoming values might have been added
1671              to a new first stage.  Bump the stage count if so.
1672
1673              ??? Perhaps we could consider rotating the schedule here
1674              instead?  */
1675           if (PS_MIN_CYCLE (ps) < min_cycle)
1676             {
1677               reset_sched_times (ps, 0);
1678               stage_count++;
1679             }
1680
1681           /* The stage count should now be correct without rotation.  */
1682           gcc_checking_assert (stage_count == calculate_stage_count (ps, 0));
1683           PS_STAGE_COUNT (ps) = stage_count;
1684
1685           canon_loop (loop);
1686
1687           if (dump_file)
1688             {
1689               fprintf (dump_file,
1690                        "%s:%d SMS succeeded %d %d (with ii, sc)\n",
1691                        insn_file (tail), insn_line (tail), ps->ii, stage_count);
1692               print_partial_schedule (ps, dump_file);
1693             }
1694  
1695           /* case the BCT count is not known , Do loop-versioning */
1696           if (count_reg && ! count_init)
1697             {
1698               rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
1699                                              GEN_INT(stage_count));
1700               unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS
1701                                * REG_BR_PROB_BASE) / 100;
1702
1703               loop_version (loop, comp_rtx, &condition_bb,
1704                             prob, prob, REG_BR_PROB_BASE - prob,
1705                             true);
1706              }
1707
1708           /* Set new iteration count of loop kernel.  */
1709           if (count_reg && count_init)
1710             SET_SRC (single_set (count_init)) = GEN_INT (loop_count
1711                                                      - stage_count + 1);
1712
1713           /* Now apply the scheduled kernel to the RTL of the loop.  */
1714           permute_partial_schedule (ps, g->closing_branch->first_note);
1715
1716           /* Mark this loop as software pipelined so the later
1717              scheduling passes doesn't touch it.  */
1718           if (! flag_resched_modulo_sched)
1719             g->bb->flags |= BB_DISABLE_SCHEDULE;
1720           /* The life-info is not valid any more.  */
1721           df_set_bb_dirty (g->bb);
1722
1723           apply_reg_moves (ps);
1724           if (dump_file)
1725             print_node_sched_params (dump_file, g->num_nodes, ps);
1726           /* Generate prolog and epilog.  */
1727           generate_prolog_epilog (ps, loop, count_reg, count_init);
1728           break;
1729         }
1730
1731       free_partial_schedule (ps);
1732       VEC_free (node_sched_params, heap, node_sched_param_vec);
1733       free (node_order);
1734       free_ddg (g);
1735     }
1736
1737   free (g_arr);
1738
1739   /* Release scheduler data, needed until now because of DFA.  */
1740   haifa_sched_finish ();
1741   loop_optimizer_finalize ();
1742 }
1743
1744 /* The SMS scheduling algorithm itself
1745    -----------------------------------
1746    Input: 'O' an ordered list of insns of a loop.
1747    Output: A scheduling of the loop - kernel, prolog, and epilogue.
1748
1749    'Q' is the empty Set
1750    'PS' is the partial schedule; it holds the currently scheduled nodes with
1751         their cycle/slot.
1752    'PSP' previously scheduled predecessors.
1753    'PSS' previously scheduled successors.
1754    't(u)' the cycle where u is scheduled.
1755    'l(u)' is the latency of u.
1756    'd(v,u)' is the dependence distance from v to u.
1757    'ASAP(u)' the earliest time at which u could be scheduled as computed in
1758              the node ordering phase.
1759    'check_hardware_resources_conflicts(u, PS, c)'
1760                              run a trace around cycle/slot through DFA model
1761                              to check resource conflicts involving instruction u
1762                              at cycle c given the partial schedule PS.
1763    'add_to_partial_schedule_at_time(u, PS, c)'
1764                              Add the node/instruction u to the partial schedule
1765                              PS at time c.
1766    'calculate_register_pressure(PS)'
1767                              Given a schedule of instructions, calculate the register
1768                              pressure it implies.  One implementation could be the
1769                              maximum number of overlapping live ranges.
1770    'maxRP' The maximum allowed register pressure, it is usually derived from the number
1771            registers available in the hardware.
1772
1773    1. II = MII.
1774    2. PS = empty list
1775    3. for each node u in O in pre-computed order
1776    4.   if (PSP(u) != Q && PSS(u) == Q) then
1777    5.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1778    6.     start = Early_start; end = Early_start + II - 1; step = 1
1779    11.  else if (PSP(u) == Q && PSS(u) != Q) then
1780    12.      Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1781    13.     start = Late_start; end = Late_start - II + 1; step = -1
1782    14.  else if (PSP(u) != Q && PSS(u) != Q) then
1783    15.     Early_start(u) = max ( t(v) + l(v) - d(v,u)*II ) over all every v in PSP(u).
1784    16.     Late_start(u) = min ( t(v) - l(v) + d(v,u)*II ) over all every v in PSS(u).
1785    17.     start = Early_start;
1786    18.     end = min(Early_start + II - 1 , Late_start);
1787    19.     step = 1
1788    20.     else "if (PSP(u) == Q && PSS(u) == Q)"
1789    21.    start = ASAP(u); end = start + II - 1; step = 1
1790    22.  endif
1791
1792    23.  success = false
1793    24.  for (c = start ; c != end ; c += step)
1794    25.     if check_hardware_resources_conflicts(u, PS, c) then
1795    26.       add_to_partial_schedule_at_time(u, PS, c)
1796    27.       success = true
1797    28.       break
1798    29.     endif
1799    30.  endfor
1800    31.  if (success == false) then
1801    32.    II = II + 1
1802    33.    if (II > maxII) then
1803    34.       finish - failed to schedule
1804    35.   endif
1805    36.    goto 2.
1806    37.  endif
1807    38. endfor
1808    39. if (calculate_register_pressure(PS) > maxRP) then
1809    40.    goto 32.
1810    41. endif
1811    42. compute epilogue & prologue
1812    43. finish - succeeded to schedule
1813 */
1814
1815 /* A limit on the number of cycles that resource conflicts can span.  ??? Should
1816    be provided by DFA, and be dependent on the type of insn scheduled.  Currently
1817    set to 0 to save compile time.  */
1818 #define DFA_HISTORY SMS_DFA_HISTORY
1819
1820 /* A threshold for the number of repeated unsuccessful attempts to insert
1821    an empty row, before we flush the partial schedule and start over.  */
1822 #define MAX_SPLIT_NUM 10
1823 /* Given the partial schedule PS, this function calculates and returns the
1824    cycles in which we can schedule the node with the given index I.
1825    NOTE: Here we do the backtracking in SMS, in some special cases. We have
1826    noticed that there are several cases in which we fail    to SMS the loop
1827    because the sched window of a node is empty    due to tight data-deps. In
1828    such cases we want to unschedule    some of the predecessors/successors
1829    until we get non-empty    scheduling window.  It returns -1 if the
1830    scheduling window is empty and zero otherwise.  */
1831
1832 static int
1833 get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
1834                   sbitmap sched_nodes, int ii, int *start_p, int *step_p,
1835                   int *end_p)
1836 {
1837   int start, step, end;
1838   int early_start, late_start;
1839   ddg_edge_ptr e;
1840   sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
1841   sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
1842   sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1843   sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1844   int psp_not_empty;
1845   int pss_not_empty;
1846   int count_preds;
1847   int count_succs;
1848
1849   /* 1. compute sched window for u (start, end, step).  */
1850   sbitmap_zero (psp);
1851   sbitmap_zero (pss);
1852   psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1853   pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1854
1855   /* We first compute a forward range (start <= end), then decide whether
1856      to reverse it.  */
1857   early_start = INT_MIN;
1858   late_start = INT_MAX;
1859   start = INT_MIN;
1860   end = INT_MAX;
1861   step = 1;
1862
1863   count_preds = 0;
1864   count_succs = 0;
1865
1866   if (dump_file && (psp_not_empty || pss_not_empty))
1867     {
1868       fprintf (dump_file, "\nAnalyzing dependencies for node %d (INSN %d)"
1869                "; ii = %d\n\n", u_node->cuid, INSN_UID (u_node->insn), ii);
1870       fprintf (dump_file, "%11s %11s %11s %11s %5s\n",
1871                "start", "early start", "late start", "end", "time");
1872       fprintf (dump_file, "=========== =========== =========== ==========="
1873                " =====\n");
1874     }
1875   /* Calculate early_start and limit end.  Both bounds are inclusive.  */
1876   if (psp_not_empty)
1877     for (e = u_node->in; e != 0; e = e->next_in)
1878       {
1879         int v = e->src->cuid;
1880
1881         if (TEST_BIT (sched_nodes, v))
1882           {
1883             int p_st = SCHED_TIME (v);
1884             int earliest = p_st + e->latency - (e->distance * ii);
1885             int latest = (e->data_type == MEM_DEP ? p_st + ii - 1 : INT_MAX);
1886
1887             if (dump_file)
1888               {
1889                 fprintf (dump_file, "%11s %11d %11s %11d %5d",
1890                          "", earliest, "", latest, p_st);
1891                 print_ddg_edge (dump_file, e);
1892                 fprintf (dump_file, "\n");
1893               }
1894
1895             early_start = MAX (early_start, earliest);
1896             end = MIN (end, latest);
1897
1898             if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1899               count_preds++;
1900           }
1901       }
1902
1903   /* Calculate late_start and limit start.  Both bounds are inclusive.  */
1904   if (pss_not_empty)
1905     for (e = u_node->out; e != 0; e = e->next_out)
1906       {
1907         int v = e->dest->cuid;
1908
1909         if (TEST_BIT (sched_nodes, v))
1910           {
1911             int s_st = SCHED_TIME (v);
1912             int earliest = (e->data_type == MEM_DEP ? s_st - ii + 1 : INT_MIN);
1913             int latest = s_st - e->latency + (e->distance * ii);
1914
1915             if (dump_file)
1916               {
1917                 fprintf (dump_file, "%11d %11s %11d %11s %5d",
1918                          earliest, "", latest, "", s_st);
1919                 print_ddg_edge (dump_file, e);
1920                 fprintf (dump_file, "\n");
1921               }
1922
1923             start = MAX (start, earliest);
1924             late_start = MIN (late_start, latest);
1925
1926             if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1927               count_succs++;
1928           }
1929       }
1930
1931   if (dump_file && (psp_not_empty || pss_not_empty))
1932     {
1933       fprintf (dump_file, "----------- ----------- ----------- -----------"
1934                " -----\n");
1935       fprintf (dump_file, "%11d %11d %11d %11d %5s %s\n",
1936                start, early_start, late_start, end, "",
1937                "(max, max, min, min)");
1938     }
1939
1940   /* Get a target scheduling window no bigger than ii.  */
1941   if (early_start == INT_MIN && late_start == INT_MAX)
1942     early_start = NODE_ASAP (u_node);
1943   else if (early_start == INT_MIN)
1944     early_start = late_start - (ii - 1);
1945   late_start = MIN (late_start, early_start + (ii - 1));
1946
1947   /* Apply memory dependence limits.  */
1948   start = MAX (start, early_start);
1949   end = MIN (end, late_start);
1950
1951   if (dump_file && (psp_not_empty || pss_not_empty))
1952     fprintf (dump_file, "%11s %11d %11d %11s %5s final window\n",
1953              "", start, end, "", "");
1954
1955   /* If there are at least as many successors as predecessors, schedule the
1956      node close to its successors.  */
1957   if (pss_not_empty && count_succs >= count_preds)
1958     {
1959       int tmp = end;
1960       end = start;
1961       start = tmp;
1962       step = -1;
1963     }
1964
1965   /* Now that we've finalized the window, make END an exclusive rather
1966      than an inclusive bound.  */
1967   end += step;
1968
1969   *start_p = start;
1970   *step_p = step;
1971   *end_p = end;
1972   sbitmap_free (psp);
1973   sbitmap_free (pss);
1974
1975   if ((start >= end && step == 1) || (start <= end && step == -1))
1976     {
1977       if (dump_file)
1978         fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
1979                  start, end, step);
1980       return -1;
1981     }
1982
1983   return 0;
1984 }
1985
1986 /* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the
1987    node currently been scheduled.  At the end of the calculation
1988    MUST_PRECEDE/MUST_FOLLOW contains all predecessors/successors of
1989    U_NODE which are (1) already scheduled in the first/last row of
1990    U_NODE's scheduling window, (2) whose dependence inequality with U
1991    becomes an equality when U is scheduled in this same row, and (3)
1992    whose dependence latency is zero.
1993
1994    The first and last rows are calculated using the following parameters:
1995    START/END rows - The cycles that begins/ends the traversal on the window;
1996    searching for an empty cycle to schedule U_NODE.
1997    STEP - The direction in which we traverse the window.
1998    II - The initiation interval.  */
1999
2000 static void
2001 calculate_must_precede_follow (ddg_node_ptr u_node, int start, int end,
2002                                int step, int ii, sbitmap sched_nodes,
2003                                sbitmap must_precede, sbitmap must_follow)
2004 {
2005   ddg_edge_ptr e;
2006   int first_cycle_in_window, last_cycle_in_window;
2007
2008   gcc_assert (must_precede && must_follow);
2009
2010   /* Consider the following scheduling window:
2011      {first_cycle_in_window, first_cycle_in_window+1, ...,
2012      last_cycle_in_window}.  If step is 1 then the following will be
2013      the order we traverse the window: {start=first_cycle_in_window,
2014      first_cycle_in_window+1, ..., end=last_cycle_in_window+1},
2015      or {start=last_cycle_in_window, last_cycle_in_window-1, ...,
2016      end=first_cycle_in_window-1} if step is -1.  */
2017   first_cycle_in_window = (step == 1) ? start : end - step;
2018   last_cycle_in_window = (step == 1) ? end - step : start;
2019
2020   sbitmap_zero (must_precede);
2021   sbitmap_zero (must_follow);
2022
2023   if (dump_file)
2024     fprintf (dump_file, "\nmust_precede: ");
2025
2026   /* Instead of checking if:
2027       (SMODULO (SCHED_TIME (e->src), ii) == first_row_in_window)
2028       && ((SCHED_TIME (e->src) + e->latency - (e->distance * ii)) ==
2029              first_cycle_in_window)
2030       && e->latency == 0
2031      we use the fact that latency is non-negative:
2032       SCHED_TIME (e->src) - (e->distance * ii) <=
2033       SCHED_TIME (e->src) + e->latency - (e->distance * ii)) <=
2034       first_cycle_in_window
2035      and check only if
2036       SCHED_TIME (e->src) - (e->distance * ii) == first_cycle_in_window  */
2037   for (e = u_node->in; e != 0; e = e->next_in)
2038     if (TEST_BIT (sched_nodes, e->src->cuid)
2039         && ((SCHED_TIME (e->src->cuid) - (e->distance * ii)) ==
2040              first_cycle_in_window))
2041       {
2042         if (dump_file)
2043           fprintf (dump_file, "%d ", e->src->cuid);
2044
2045         SET_BIT (must_precede, e->src->cuid);
2046       }
2047
2048   if (dump_file)
2049     fprintf (dump_file, "\nmust_follow: ");
2050
2051   /* Instead of checking if:
2052       (SMODULO (SCHED_TIME (e->dest), ii) == last_row_in_window)
2053       && ((SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) ==
2054              last_cycle_in_window)
2055       && e->latency == 0
2056      we use the fact that latency is non-negative:
2057       SCHED_TIME (e->dest) + (e->distance * ii) >=
2058       SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >=
2059       last_cycle_in_window
2060      and check only if
2061       SCHED_TIME (e->dest) + (e->distance * ii) == last_cycle_in_window  */
2062   for (e = u_node->out; e != 0; e = e->next_out)
2063     if (TEST_BIT (sched_nodes, e->dest->cuid)
2064         && ((SCHED_TIME (e->dest->cuid) + (e->distance * ii)) ==
2065              last_cycle_in_window))
2066       {
2067         if (dump_file)
2068           fprintf (dump_file, "%d ", e->dest->cuid);
2069
2070         SET_BIT (must_follow, e->dest->cuid);
2071       }
2072
2073   if (dump_file)
2074     fprintf (dump_file, "\n");
2075 }
2076
2077 /* Return 1 if U_NODE can be scheduled in CYCLE.  Use the following
2078    parameters to decide if that's possible:
2079    PS - The partial schedule.
2080    U - The serial number of U_NODE.
2081    NUM_SPLITS - The number of row splits made so far.
2082    MUST_PRECEDE - The nodes that must precede U_NODE. (only valid at
2083    the first row of the scheduling window)
2084    MUST_FOLLOW - The nodes that must follow U_NODE. (only valid at the
2085    last row of the scheduling window)  */
2086
2087 static bool
2088 try_scheduling_node_in_cycle (partial_schedule_ptr ps,
2089                               int u, int cycle, sbitmap sched_nodes,
2090                               int *num_splits, sbitmap must_precede,
2091                               sbitmap must_follow)
2092 {
2093   ps_insn_ptr psi;
2094   bool success = 0;
2095
2096   verify_partial_schedule (ps, sched_nodes);
2097   psi = ps_add_node_check_conflicts (ps, u, cycle, must_precede, must_follow);
2098   if (psi)
2099     {
2100       SCHED_TIME (u) = cycle;
2101       SET_BIT (sched_nodes, u);
2102       success = 1;
2103       *num_splits = 0;
2104       if (dump_file)
2105         fprintf (dump_file, "Scheduled w/o split in %d\n", cycle);
2106
2107     }
2108
2109   return success;
2110 }
2111
2112 /* This function implements the scheduling algorithm for SMS according to the
2113    above algorithm.  */
2114 static partial_schedule_ptr
2115 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
2116 {
2117   int ii = mii;
2118   int i, c, success, num_splits = 0;
2119   int flush_and_start_over = true;
2120   int num_nodes = g->num_nodes;
2121   int start, end, step; /* Place together into one struct?  */
2122   sbitmap sched_nodes = sbitmap_alloc (num_nodes);
2123   sbitmap must_precede = sbitmap_alloc (num_nodes);
2124   sbitmap must_follow = sbitmap_alloc (num_nodes);
2125   sbitmap tobe_scheduled = sbitmap_alloc (num_nodes);
2126
2127   partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
2128
2129   sbitmap_ones (tobe_scheduled);
2130   sbitmap_zero (sched_nodes);
2131
2132   while (flush_and_start_over && (ii < maxii))
2133     {
2134
2135       if (dump_file)
2136         fprintf (dump_file, "Starting with ii=%d\n", ii);
2137       flush_and_start_over = false;
2138       sbitmap_zero (sched_nodes);
2139
2140       for (i = 0; i < num_nodes; i++)
2141         {
2142           int u = nodes_order[i];
2143           ddg_node_ptr u_node = &ps->g->nodes[u];
2144           rtx insn = u_node->insn;
2145
2146           if (!NONDEBUG_INSN_P (insn))
2147             {
2148               RESET_BIT (tobe_scheduled, u);
2149               continue;
2150             }
2151
2152           if (TEST_BIT (sched_nodes, u))
2153             continue;
2154
2155           /* Try to get non-empty scheduling window.  */
2156          success = 0;
2157          if (get_sched_window (ps, u_node, sched_nodes, ii, &start,
2158                                 &step, &end) == 0)
2159             {
2160               if (dump_file)
2161                 fprintf (dump_file, "\nTrying to schedule node %d "
2162                          "INSN = %d  in (%d .. %d) step %d\n", u, (INSN_UID
2163                         (g->nodes[u].insn)), start, end, step);
2164
2165               gcc_assert ((step > 0 && start < end)
2166                           || (step < 0 && start > end));
2167
2168               calculate_must_precede_follow (u_node, start, end, step, ii,
2169                                              sched_nodes, must_precede,
2170                                              must_follow);
2171
2172               for (c = start; c != end; c += step)
2173                 {
2174                   sbitmap tmp_precede, tmp_follow;
2175
2176                   set_must_precede_follow (&tmp_follow, must_follow, 
2177                                            &tmp_precede, must_precede, 
2178                                            c, start, end, step);
2179                   success =
2180                     try_scheduling_node_in_cycle (ps, u, c,
2181                                                   sched_nodes,
2182                                                   &num_splits, tmp_precede,
2183                                                   tmp_follow);
2184                   if (success)
2185                     break;
2186                 }
2187
2188               verify_partial_schedule (ps, sched_nodes);
2189             }
2190             if (!success)
2191             {
2192               int split_row;
2193
2194               if (ii++ == maxii)
2195                 break;
2196
2197               if (num_splits >= MAX_SPLIT_NUM)
2198                 {
2199                   num_splits = 0;
2200                   flush_and_start_over = true;
2201                   verify_partial_schedule (ps, sched_nodes);
2202                   reset_partial_schedule (ps, ii);
2203                   verify_partial_schedule (ps, sched_nodes);
2204                   break;
2205                 }
2206
2207               num_splits++;
2208               /* The scheduling window is exclusive of 'end'
2209                  whereas compute_split_window() expects an inclusive,
2210                  ordered range.  */
2211               if (step == 1)
2212                 split_row = compute_split_row (sched_nodes, start, end - 1,
2213                                                ps->ii, u_node);
2214               else
2215                 split_row = compute_split_row (sched_nodes, end + 1, start,
2216                                                ps->ii, u_node);
2217
2218               ps_insert_empty_row (ps, split_row, sched_nodes);
2219               i--;              /* Go back and retry node i.  */
2220
2221               if (dump_file)
2222                 fprintf (dump_file, "num_splits=%d\n", num_splits);
2223             }
2224
2225           /* ??? If (success), check register pressure estimates.  */
2226         }                       /* Continue with next node.  */
2227     }                           /* While flush_and_start_over.  */
2228   if (ii >= maxii)
2229     {
2230       free_partial_schedule (ps);
2231       ps = NULL;
2232     }
2233   else
2234     gcc_assert (sbitmap_equal (tobe_scheduled, sched_nodes));
2235
2236   sbitmap_free (sched_nodes);
2237   sbitmap_free (must_precede);
2238   sbitmap_free (must_follow);
2239   sbitmap_free (tobe_scheduled);
2240
2241   return ps;
2242 }
2243
2244 /* This function inserts a new empty row into PS at the position
2245    according to SPLITROW, keeping all already scheduled instructions
2246    intact and updating their SCHED_TIME and cycle accordingly.  */
2247 static void
2248 ps_insert_empty_row (partial_schedule_ptr ps, int split_row,
2249                      sbitmap sched_nodes)
2250 {
2251   ps_insn_ptr crr_insn;
2252   ps_insn_ptr *rows_new;
2253   int ii = ps->ii;
2254   int new_ii = ii + 1;
2255   int row;
2256   int *rows_length_new;
2257
2258   verify_partial_schedule (ps, sched_nodes);
2259
2260   /* We normalize sched_time and rotate ps to have only non-negative sched
2261      times, for simplicity of updating cycles after inserting new row.  */
2262   split_row -= ps->min_cycle;
2263   split_row = SMODULO (split_row, ii);
2264   if (dump_file)
2265     fprintf (dump_file, "split_row=%d\n", split_row);
2266
2267   reset_sched_times (ps, PS_MIN_CYCLE (ps));
2268   rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
2269
2270   rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
2271   rows_length_new = (int *) xcalloc (new_ii, sizeof (int));
2272   for (row = 0; row < split_row; row++)
2273     {
2274       rows_new[row] = ps->rows[row];
2275       rows_length_new[row] = ps->rows_length[row];
2276       ps->rows[row] = NULL;
2277       for (crr_insn = rows_new[row];
2278            crr_insn; crr_insn = crr_insn->next_in_row)
2279         {
2280           int u = crr_insn->id;
2281           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii);
2282
2283           SCHED_TIME (u) = new_time;
2284           crr_insn->cycle = new_time;
2285           SCHED_ROW (u) = new_time % new_ii;
2286           SCHED_STAGE (u) = new_time / new_ii;
2287         }
2288
2289     }
2290
2291   rows_new[split_row] = NULL;
2292
2293   for (row = split_row; row < ii; row++)
2294     {
2295       rows_new[row + 1] = ps->rows[row];
2296       rows_length_new[row + 1] = ps->rows_length[row];
2297       ps->rows[row] = NULL;
2298       for (crr_insn = rows_new[row + 1];
2299            crr_insn; crr_insn = crr_insn->next_in_row)
2300         {
2301           int u = crr_insn->id;
2302           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii) + 1;
2303
2304           SCHED_TIME (u) = new_time;
2305           crr_insn->cycle = new_time;
2306           SCHED_ROW (u) = new_time % new_ii;
2307           SCHED_STAGE (u) = new_time / new_ii;
2308         }
2309     }
2310
2311   /* Updating ps.  */
2312   ps->min_cycle = ps->min_cycle + ps->min_cycle / ii
2313     + (SMODULO (ps->min_cycle, ii) >= split_row ? 1 : 0);
2314   ps->max_cycle = ps->max_cycle + ps->max_cycle / ii
2315     + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0);
2316   free (ps->rows);
2317   ps->rows = rows_new;
2318   free (ps->rows_length);
2319   ps->rows_length = rows_length_new;
2320   ps->ii = new_ii;
2321   gcc_assert (ps->min_cycle >= 0);
2322
2323   verify_partial_schedule (ps, sched_nodes);
2324
2325   if (dump_file)
2326     fprintf (dump_file, "min_cycle=%d, max_cycle=%d\n", ps->min_cycle,
2327              ps->max_cycle);
2328 }
2329
2330 /* Given U_NODE which is the node that failed to be scheduled; LOW and
2331    UP which are the boundaries of it's scheduling window; compute using
2332    SCHED_NODES and II a row in the partial schedule that can be split
2333    which will separate a critical predecessor from a critical successor
2334    thereby expanding the window, and return it.  */
2335 static int
2336 compute_split_row (sbitmap sched_nodes, int low, int up, int ii,
2337                    ddg_node_ptr u_node)
2338 {
2339   ddg_edge_ptr e;
2340   int lower = INT_MIN, upper = INT_MAX;
2341   int crit_pred = -1;
2342   int crit_succ = -1;
2343   int crit_cycle;
2344
2345   for (e = u_node->in; e != 0; e = e->next_in)
2346     {
2347       int v = e->src->cuid;
2348
2349       if (TEST_BIT (sched_nodes, v)
2350           && (low == SCHED_TIME (v) + e->latency - (e->distance * ii)))
2351         if (SCHED_TIME (v) > lower)
2352           {
2353             crit_pred = v;
2354             lower = SCHED_TIME (v);
2355           }
2356     }
2357
2358   if (crit_pred >= 0)
2359     {
2360       crit_cycle = SCHED_TIME (crit_pred) + 1;
2361       return SMODULO (crit_cycle, ii);
2362     }
2363
2364   for (e = u_node->out; e != 0; e = e->next_out)
2365     {
2366       int v = e->dest->cuid;
2367
2368       if (TEST_BIT (sched_nodes, v)
2369           && (up == SCHED_TIME (v) - e->latency + (e->distance * ii)))
2370         if (SCHED_TIME (v) < upper)
2371           {
2372             crit_succ = v;
2373             upper = SCHED_TIME (v);
2374           }
2375     }
2376
2377   if (crit_succ >= 0)
2378     {
2379       crit_cycle = SCHED_TIME (crit_succ);
2380       return SMODULO (crit_cycle, ii);
2381     }
2382
2383   if (dump_file)
2384     fprintf (dump_file, "Both crit_pred and crit_succ are NULL\n");
2385
2386   return SMODULO ((low + up + 1) / 2, ii);
2387 }
2388
2389 static void
2390 verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes)
2391 {
2392   int row;
2393   ps_insn_ptr crr_insn;
2394
2395   for (row = 0; row < ps->ii; row++)
2396     {
2397       int length = 0;
2398       
2399       for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
2400         {
2401           int u = crr_insn->id;
2402           
2403           length++;
2404           gcc_assert (TEST_BIT (sched_nodes, u));
2405           /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
2406              popcount (sched_nodes) == number of insns in ps.  */
2407           gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
2408           gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
2409         }
2410       
2411       gcc_assert (ps->rows_length[row] == length);
2412     }
2413 }
2414
2415 \f
2416 /* This page implements the algorithm for ordering the nodes of a DDG
2417    for modulo scheduling, activated through the
2418    "int sms_order_nodes (ddg_ptr, int mii, int * result)" API.  */
2419
2420 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
2421 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
2422 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
2423 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
2424 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
2425 #define DEPTH(x) (ASAP ((x)))
2426
2427 typedef struct node_order_params * nopa;
2428
2429 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
2430 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
2431 static nopa  calculate_order_params (ddg_ptr, int, int *);
2432 static int find_max_asap (ddg_ptr, sbitmap);
2433 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
2434 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
2435
2436 enum sms_direction {BOTTOMUP, TOPDOWN};
2437
2438 struct node_order_params
2439 {
2440   int asap;
2441   int alap;
2442   int height;
2443 };
2444
2445 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1.  */
2446 static void
2447 check_nodes_order (int *node_order, int num_nodes)
2448 {
2449   int i;
2450   sbitmap tmp = sbitmap_alloc (num_nodes);
2451
2452   sbitmap_zero (tmp);
2453
2454   if (dump_file)
2455     fprintf (dump_file, "SMS final nodes order: \n");
2456
2457   for (i = 0; i < num_nodes; i++)
2458     {
2459       int u = node_order[i];
2460
2461       if (dump_file)
2462         fprintf (dump_file, "%d ", u);
2463       gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u));
2464
2465       SET_BIT (tmp, u);
2466     }
2467
2468   if (dump_file)
2469     fprintf (dump_file, "\n");
2470
2471   sbitmap_free (tmp);
2472 }
2473
2474 /* Order the nodes of G for scheduling and pass the result in
2475    NODE_ORDER.  Also set aux.count of each node to ASAP.
2476    Put maximal ASAP to PMAX_ASAP.  Return the recMII for the given DDG.  */
2477 static int
2478 sms_order_nodes (ddg_ptr g, int mii, int * node_order, int *pmax_asap)
2479 {
2480   int i;
2481   int rec_mii = 0;
2482   ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
2483
2484   nopa nops = calculate_order_params (g, mii, pmax_asap);
2485
2486   if (dump_file)
2487     print_sccs (dump_file, sccs, g);
2488
2489   order_nodes_of_sccs (sccs, node_order);
2490
2491   if (sccs->num_sccs > 0)
2492     /* First SCC has the largest recurrence_length.  */
2493     rec_mii = sccs->sccs[0]->recurrence_length;
2494
2495   /* Save ASAP before destroying node_order_params.  */
2496   for (i = 0; i < g->num_nodes; i++)
2497     {
2498       ddg_node_ptr v = &g->nodes[i];
2499       v->aux.count = ASAP (v);
2500     }
2501
2502   free (nops);
2503   free_ddg_all_sccs (sccs);
2504   check_nodes_order (node_order, g->num_nodes);
2505
2506   return rec_mii;
2507 }
2508
2509 static void
2510 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
2511 {
2512   int i, pos = 0;
2513   ddg_ptr g = all_sccs->ddg;
2514   int num_nodes = g->num_nodes;
2515   sbitmap prev_sccs = sbitmap_alloc (num_nodes);
2516   sbitmap on_path = sbitmap_alloc (num_nodes);
2517   sbitmap tmp = sbitmap_alloc (num_nodes);
2518   sbitmap ones = sbitmap_alloc (num_nodes);
2519
2520   sbitmap_zero (prev_sccs);
2521   sbitmap_ones (ones);
2522
2523   /* Perform the node ordering starting from the SCC with the highest recMII.
2524      For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc.  */
2525   for (i = 0; i < all_sccs->num_sccs; i++)
2526     {
2527       ddg_scc_ptr scc = all_sccs->sccs[i];
2528
2529       /* Add nodes on paths from previous SCCs to the current SCC.  */
2530       find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
2531       sbitmap_a_or_b (tmp, scc->nodes, on_path);
2532
2533       /* Add nodes on paths from the current SCC to previous SCCs.  */
2534       find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
2535       sbitmap_a_or_b (tmp, tmp, on_path);
2536
2537       /* Remove nodes of previous SCCs from current extended SCC.  */
2538       sbitmap_difference (tmp, tmp, prev_sccs);
2539
2540       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2541       /* Above call to order_nodes_in_scc updated prev_sccs |= tmp.  */
2542     }
2543
2544   /* Handle the remaining nodes that do not belong to any scc.  Each call
2545      to order_nodes_in_scc handles a single connected component.  */
2546   while (pos < g->num_nodes)
2547     {
2548       sbitmap_difference (tmp, ones, prev_sccs);
2549       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2550     }
2551   sbitmap_free (prev_sccs);
2552   sbitmap_free (on_path);
2553   sbitmap_free (tmp);
2554   sbitmap_free (ones);
2555 }
2556
2557 /* MII is needed if we consider backarcs (that do not close recursive cycles).  */
2558 static struct node_order_params *
2559 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED, int *pmax_asap)
2560 {
2561   int u;
2562   int max_asap;
2563   int num_nodes = g->num_nodes;
2564   ddg_edge_ptr e;
2565   /* Allocate a place to hold ordering params for each node in the DDG.  */
2566   nopa node_order_params_arr;
2567
2568   /* Initialize of ASAP/ALAP/HEIGHT to zero.  */
2569   node_order_params_arr = (nopa) xcalloc (num_nodes,
2570                                           sizeof (struct node_order_params));
2571
2572   /* Set the aux pointer of each node to point to its order_params structure.  */
2573   for (u = 0; u < num_nodes; u++)
2574     g->nodes[u].aux.info = &node_order_params_arr[u];
2575
2576   /* Disregarding a backarc from each recursive cycle to obtain a DAG,
2577      calculate ASAP, ALAP, mobility, distance, and height for each node
2578      in the dependence (direct acyclic) graph.  */
2579
2580   /* We assume that the nodes in the array are in topological order.  */
2581
2582   max_asap = 0;
2583   for (u = 0; u < num_nodes; u++)
2584     {
2585       ddg_node_ptr u_node = &g->nodes[u];
2586
2587       ASAP (u_node) = 0;
2588       for (e = u_node->in; e; e = e->next_in)
2589         if (e->distance == 0)
2590           ASAP (u_node) = MAX (ASAP (u_node),
2591                                ASAP (e->src) + e->latency);
2592       max_asap = MAX (max_asap, ASAP (u_node));
2593     }
2594
2595   for (u = num_nodes - 1; u > -1; u--)
2596     {
2597       ddg_node_ptr u_node = &g->nodes[u];
2598
2599       ALAP (u_node) = max_asap;
2600       HEIGHT (u_node) = 0;
2601       for (e = u_node->out; e; e = e->next_out)
2602         if (e->distance == 0)
2603           {
2604             ALAP (u_node) = MIN (ALAP (u_node),
2605                                  ALAP (e->dest) - e->latency);
2606             HEIGHT (u_node) = MAX (HEIGHT (u_node),
2607                                    HEIGHT (e->dest) + e->latency);
2608           }
2609     }
2610   if (dump_file)
2611   {
2612     fprintf (dump_file, "\nOrder params\n");
2613     for (u = 0; u < num_nodes; u++)
2614       {
2615         ddg_node_ptr u_node = &g->nodes[u];
2616
2617         fprintf (dump_file, "node %d, ASAP: %d, ALAP: %d, HEIGHT: %d\n", u,
2618                  ASAP (u_node), ALAP (u_node), HEIGHT (u_node));
2619       }
2620   }
2621
2622   *pmax_asap = max_asap;
2623   return node_order_params_arr;
2624 }
2625
2626 static int
2627 find_max_asap (ddg_ptr g, sbitmap nodes)
2628 {
2629   unsigned int u = 0;
2630   int max_asap = -1;
2631   int result = -1;
2632   sbitmap_iterator sbi;
2633
2634   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2635     {
2636       ddg_node_ptr u_node = &g->nodes[u];
2637
2638       if (max_asap < ASAP (u_node))
2639         {
2640           max_asap = ASAP (u_node);
2641           result = u;
2642         }
2643     }
2644   return result;
2645 }
2646
2647 static int
2648 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
2649 {
2650   unsigned int u = 0;
2651   int max_hv = -1;
2652   int min_mob = INT_MAX;
2653   int result = -1;
2654   sbitmap_iterator sbi;
2655
2656   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2657     {
2658       ddg_node_ptr u_node = &g->nodes[u];
2659
2660       if (max_hv < HEIGHT (u_node))
2661         {
2662           max_hv = HEIGHT (u_node);
2663           min_mob = MOB (u_node);
2664           result = u;
2665         }
2666       else if ((max_hv == HEIGHT (u_node))
2667                && (min_mob > MOB (u_node)))
2668         {
2669           min_mob = MOB (u_node);
2670           result = u;
2671         }
2672     }
2673   return result;
2674 }
2675
2676 static int
2677 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
2678 {
2679   unsigned int u = 0;
2680   int max_dv = -1;
2681   int min_mob = INT_MAX;
2682   int result = -1;
2683   sbitmap_iterator sbi;
2684
2685   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2686     {
2687       ddg_node_ptr u_node = &g->nodes[u];
2688
2689       if (max_dv < DEPTH (u_node))
2690         {
2691           max_dv = DEPTH (u_node);
2692           min_mob = MOB (u_node);
2693           result = u;
2694         }
2695       else if ((max_dv == DEPTH (u_node))
2696                && (min_mob > MOB (u_node)))
2697         {
2698           min_mob = MOB (u_node);
2699           result = u;
2700         }
2701     }
2702   return result;
2703 }
2704
2705 /* Places the nodes of SCC into the NODE_ORDER array starting
2706    at position POS, according to the SMS ordering algorithm.
2707    NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
2708    the NODE_ORDER array, starting from position zero.  */
2709 static int
2710 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
2711                     int * node_order, int pos)
2712 {
2713   enum sms_direction dir;
2714   int num_nodes = g->num_nodes;
2715   sbitmap workset = sbitmap_alloc (num_nodes);
2716   sbitmap tmp = sbitmap_alloc (num_nodes);
2717   sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
2718   sbitmap predecessors = sbitmap_alloc (num_nodes);
2719   sbitmap successors = sbitmap_alloc (num_nodes);
2720
2721   sbitmap_zero (predecessors);
2722   find_predecessors (predecessors, g, nodes_ordered);
2723
2724   sbitmap_zero (successors);
2725   find_successors (successors, g, nodes_ordered);
2726
2727   sbitmap_zero (tmp);
2728   if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
2729     {
2730       sbitmap_copy (workset, tmp);
2731       dir = BOTTOMUP;
2732     }
2733   else if (sbitmap_a_and_b_cg (tmp, successors, scc))
2734     {
2735       sbitmap_copy (workset, tmp);
2736       dir = TOPDOWN;
2737     }
2738   else
2739     {
2740       int u;
2741
2742       sbitmap_zero (workset);
2743       if ((u = find_max_asap (g, scc)) >= 0)
2744         SET_BIT (workset, u);
2745       dir = BOTTOMUP;
2746     }
2747
2748   sbitmap_zero (zero_bitmap);
2749   while (!sbitmap_equal (workset, zero_bitmap))
2750     {
2751       int v;
2752       ddg_node_ptr v_node;
2753       sbitmap v_node_preds;
2754       sbitmap v_node_succs;
2755
2756       if (dir == TOPDOWN)
2757         {
2758           while (!sbitmap_equal (workset, zero_bitmap))
2759             {
2760               v = find_max_hv_min_mob (g, workset);
2761               v_node = &g->nodes[v];
2762               node_order[pos++] = v;
2763               v_node_succs = NODE_SUCCESSORS (v_node);
2764               sbitmap_a_and_b (tmp, v_node_succs, scc);
2765
2766               /* Don't consider the already ordered successors again.  */
2767               sbitmap_difference (tmp, tmp, nodes_ordered);
2768               sbitmap_a_or_b (workset, workset, tmp);
2769               RESET_BIT (workset, v);
2770               SET_BIT (nodes_ordered, v);
2771             }
2772           dir = BOTTOMUP;
2773           sbitmap_zero (predecessors);
2774           find_predecessors (predecessors, g, nodes_ordered);
2775           sbitmap_a_and_b (workset, predecessors, scc);
2776         }
2777       else
2778         {
2779           while (!sbitmap_equal (workset, zero_bitmap))
2780             {
2781               v = find_max_dv_min_mob (g, workset);
2782               v_node = &g->nodes[v];
2783               node_order[pos++] = v;
2784               v_node_preds = NODE_PREDECESSORS (v_node);
2785               sbitmap_a_and_b (tmp, v_node_preds, scc);
2786
2787               /* Don't consider the already ordered predecessors again.  */
2788               sbitmap_difference (tmp, tmp, nodes_ordered);
2789               sbitmap_a_or_b (workset, workset, tmp);
2790               RESET_BIT (workset, v);
2791               SET_BIT (nodes_ordered, v);
2792             }
2793           dir = TOPDOWN;
2794           sbitmap_zero (successors);
2795           find_successors (successors, g, nodes_ordered);
2796           sbitmap_a_and_b (workset, successors, scc);
2797         }
2798     }
2799   sbitmap_free (tmp);
2800   sbitmap_free (workset);
2801   sbitmap_free (zero_bitmap);
2802   sbitmap_free (predecessors);
2803   sbitmap_free (successors);
2804   return pos;
2805 }
2806
2807 \f
2808 /* This page contains functions for manipulating partial-schedules during
2809    modulo scheduling.  */
2810
2811 /* Create a partial schedule and allocate a memory to hold II rows.  */
2812
2813 static partial_schedule_ptr
2814 create_partial_schedule (int ii, ddg_ptr g, int history)
2815 {
2816   partial_schedule_ptr ps = XNEW (struct partial_schedule);
2817   ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
2818   ps->rows_length = (int *) xcalloc (ii, sizeof (int));
2819   ps->reg_moves = NULL;
2820   ps->ii = ii;
2821   ps->history = history;
2822   ps->min_cycle = INT_MAX;
2823   ps->max_cycle = INT_MIN;
2824   ps->g = g;
2825
2826   return ps;
2827 }
2828
2829 /* Free the PS_INSNs in rows array of the given partial schedule.
2830    ??? Consider caching the PS_INSN's.  */
2831 static void
2832 free_ps_insns (partial_schedule_ptr ps)
2833 {
2834   int i;
2835
2836   for (i = 0; i < ps->ii; i++)
2837     {
2838       while (ps->rows[i])
2839         {
2840           ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
2841
2842           free (ps->rows[i]);
2843           ps->rows[i] = ps_insn;
2844         }
2845       ps->rows[i] = NULL;
2846     }
2847 }
2848
2849 /* Free all the memory allocated to the partial schedule.  */
2850
2851 static void
2852 free_partial_schedule (partial_schedule_ptr ps)
2853 {
2854   ps_reg_move_info *move;
2855   unsigned int i;
2856
2857   if (!ps)
2858     return;
2859
2860   FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
2861     sbitmap_free (move->uses);
2862   VEC_free (ps_reg_move_info, heap, ps->reg_moves);
2863
2864   free_ps_insns (ps);
2865   free (ps->rows);
2866   free (ps->rows_length);
2867   free (ps);
2868 }
2869
2870 /* Clear the rows array with its PS_INSNs, and create a new one with
2871    NEW_II rows.  */
2872
2873 static void
2874 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
2875 {
2876   if (!ps)
2877     return;
2878   free_ps_insns (ps);
2879   if (new_ii == ps->ii)
2880     return;
2881   ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
2882                                                  * sizeof (ps_insn_ptr));
2883   memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
2884   ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int));
2885   memset (ps->rows_length, 0, new_ii * sizeof (int));
2886   ps->ii = new_ii;
2887   ps->min_cycle = INT_MAX;
2888   ps->max_cycle = INT_MIN;
2889 }
2890
2891 /* Prints the partial schedule as an ii rows array, for each rows
2892    print the ids of the insns in it.  */
2893 void
2894 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
2895 {
2896   int i;
2897
2898   for (i = 0; i < ps->ii; i++)
2899     {
2900       ps_insn_ptr ps_i = ps->rows[i];
2901
2902       fprintf (dump, "\n[ROW %d ]: ", i);
2903       while (ps_i)
2904         {
2905           rtx insn = ps_rtl_insn (ps, ps_i->id);
2906
2907           if (JUMP_P (insn))
2908             fprintf (dump, "%d (branch), ", INSN_UID (insn));
2909           else
2910             fprintf (dump, "%d, ", INSN_UID (insn));
2911         
2912           ps_i = ps_i->next_in_row;
2913         }
2914     }
2915 }
2916
2917 /* Creates an object of PS_INSN and initializes it to the given parameters.  */
2918 static ps_insn_ptr
2919 create_ps_insn (int id, int cycle)
2920 {
2921   ps_insn_ptr ps_i = XNEW (struct ps_insn);
2922
2923   ps_i->id = id;
2924   ps_i->next_in_row = NULL;
2925   ps_i->prev_in_row = NULL;
2926   ps_i->cycle = cycle;
2927
2928   return ps_i;
2929 }
2930
2931
2932 /* Removes the given PS_INSN from the partial schedule.  */  
2933 static void 
2934 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
2935 {
2936   int row;
2937
2938   gcc_assert (ps && ps_i);
2939   
2940   row = SMODULO (ps_i->cycle, ps->ii);
2941   if (! ps_i->prev_in_row)
2942     {
2943       gcc_assert (ps_i == ps->rows[row]);
2944       ps->rows[row] = ps_i->next_in_row;
2945       if (ps->rows[row])
2946         ps->rows[row]->prev_in_row = NULL;
2947     }
2948   else
2949     {
2950       ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
2951       if (ps_i->next_in_row)
2952         ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
2953     }
2954    
2955   ps->rows_length[row] -= 1; 
2956   free (ps_i);
2957   return;
2958 }
2959
2960 /* Unlike what literature describes for modulo scheduling (which focuses
2961    on VLIW machines) the order of the instructions inside a cycle is
2962    important.  Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
2963    where the current instruction should go relative to the already
2964    scheduled instructions in the given cycle.  Go over these
2965    instructions and find the first possible column to put it in.  */
2966 static bool
2967 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
2968                      sbitmap must_precede, sbitmap must_follow)
2969 {
2970   ps_insn_ptr next_ps_i;
2971   ps_insn_ptr first_must_follow = NULL;
2972   ps_insn_ptr last_must_precede = NULL;
2973   ps_insn_ptr last_in_row = NULL;
2974   int row;
2975
2976   if (! ps_i)
2977     return false;
2978
2979   row = SMODULO (ps_i->cycle, ps->ii);
2980
2981   /* Find the first must follow and the last must precede
2982      and insert the node immediately after the must precede
2983      but make sure that it there is no must follow after it.  */
2984   for (next_ps_i = ps->rows[row];
2985        next_ps_i;
2986        next_ps_i = next_ps_i->next_in_row)
2987     {
2988       if (must_follow
2989           && TEST_BIT (must_follow, next_ps_i->id)
2990           && ! first_must_follow)
2991         first_must_follow = next_ps_i;
2992       if (must_precede && TEST_BIT (must_precede, next_ps_i->id))
2993         {
2994           /* If we have already met a node that must follow, then
2995              there is no possible column.  */
2996           if (first_must_follow)
2997             return false;
2998           else
2999             last_must_precede = next_ps_i;
3000         }
3001       /* The closing branch must be the last in the row.  */
3002       if (must_precede 
3003           && TEST_BIT (must_precede, next_ps_i->id)
3004           && JUMP_P (ps_rtl_insn (ps, next_ps_i->id)))
3005         return false;
3006              
3007        last_in_row = next_ps_i;
3008     }
3009
3010   /* The closing branch is scheduled as well.  Make sure there is no
3011      dependent instruction after it as the branch should be the last
3012      instruction in the row.  */
3013   if (JUMP_P (ps_rtl_insn (ps, ps_i->id)))
3014     {
3015       if (first_must_follow)
3016         return false;
3017       if (last_in_row)
3018         {
3019           /* Make the branch the last in the row.  New instructions
3020              will be inserted at the beginning of the row or after the
3021              last must_precede instruction thus the branch is guaranteed
3022              to remain the last instruction in the row.  */
3023           last_in_row->next_in_row = ps_i;
3024           ps_i->prev_in_row = last_in_row;
3025           ps_i->next_in_row = NULL;
3026         }
3027       else
3028         ps->rows[row] = ps_i;
3029       return true;
3030     }
3031   
3032   /* Now insert the node after INSERT_AFTER_PSI.  */
3033
3034   if (! last_must_precede)
3035     {
3036       ps_i->next_in_row = ps->rows[row];
3037       ps_i->prev_in_row = NULL;
3038       if (ps_i->next_in_row)
3039         ps_i->next_in_row->prev_in_row = ps_i;
3040       ps->rows[row] = ps_i;
3041     }
3042   else
3043     {
3044       ps_i->next_in_row = last_must_precede->next_in_row;
3045       last_must_precede->next_in_row = ps_i;
3046       ps_i->prev_in_row = last_must_precede;
3047       if (ps_i->next_in_row)
3048         ps_i->next_in_row->prev_in_row = ps_i;
3049     }
3050
3051   return true;
3052 }
3053
3054 /* Advances the PS_INSN one column in its current row; returns false
3055    in failure and true in success.  Bit N is set in MUST_FOLLOW if
3056    the node with cuid N must be come after the node pointed to by
3057    PS_I when scheduled in the same cycle.  */
3058 static int
3059 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
3060                         sbitmap must_follow)
3061 {
3062   ps_insn_ptr prev, next;
3063   int row;
3064
3065   if (!ps || !ps_i)
3066     return false;
3067
3068   row = SMODULO (ps_i->cycle, ps->ii);
3069
3070   if (! ps_i->next_in_row)
3071     return false;
3072
3073   /* Check if next_in_row is dependent on ps_i, both having same sched
3074      times (typically ANTI_DEP).  If so, ps_i cannot skip over it.  */
3075   if (must_follow && TEST_BIT (must_follow, ps_i->next_in_row->id))
3076     return false;
3077
3078   /* Advance PS_I over its next_in_row in the doubly linked list.  */
3079   prev = ps_i->prev_in_row;
3080   next = ps_i->next_in_row;
3081
3082   if (ps_i == ps->rows[row])
3083     ps->rows[row] = next;
3084
3085   ps_i->next_in_row = next->next_in_row;
3086
3087   if (next->next_in_row)
3088     next->next_in_row->prev_in_row = ps_i;
3089
3090   next->next_in_row = ps_i;
3091   ps_i->prev_in_row = next;
3092
3093   next->prev_in_row = prev;
3094   if (prev)
3095     prev->next_in_row = next;
3096
3097   return true;
3098 }
3099
3100 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
3101    Returns 0 if this is not possible and a PS_INSN otherwise.  Bit N is
3102    set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come
3103    before/after (respectively) the node pointed to by PS_I when scheduled
3104    in the same cycle.  */
3105 static ps_insn_ptr
3106 add_node_to_ps (partial_schedule_ptr ps, int id, int cycle,
3107                 sbitmap must_precede, sbitmap must_follow)
3108 {
3109   ps_insn_ptr ps_i;
3110   int row = SMODULO (cycle, ps->ii);
3111
3112   if (ps->rows_length[row] >= issue_rate)
3113     return NULL;
3114
3115   ps_i = create_ps_insn (id, cycle);
3116
3117   /* Finds and inserts PS_I according to MUST_FOLLOW and
3118      MUST_PRECEDE.  */
3119   if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
3120     {
3121       free (ps_i);
3122       return NULL;
3123     }
3124
3125   ps->rows_length[row] += 1;
3126   return ps_i;
3127 }
3128
3129 /* Advance time one cycle.  Assumes DFA is being used.  */
3130 static void
3131 advance_one_cycle (void)
3132 {
3133   if (targetm.sched.dfa_pre_cycle_insn)
3134     state_transition (curr_state,
3135                       targetm.sched.dfa_pre_cycle_insn ());
3136
3137   state_transition (curr_state, NULL);
3138
3139   if (targetm.sched.dfa_post_cycle_insn)
3140     state_transition (curr_state,
3141                       targetm.sched.dfa_post_cycle_insn ());
3142 }
3143
3144
3145
3146 /* Checks if PS has resource conflicts according to DFA, starting from
3147    FROM cycle to TO cycle; returns true if there are conflicts and false
3148    if there are no conflicts.  Assumes DFA is being used.  */
3149 static int
3150 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
3151 {
3152   int cycle;
3153
3154   state_reset (curr_state);
3155
3156   for (cycle = from; cycle <= to; cycle++)
3157     {
3158       ps_insn_ptr crr_insn;
3159       /* Holds the remaining issue slots in the current row.  */
3160       int can_issue_more = issue_rate;
3161
3162       /* Walk through the DFA for the current row.  */
3163       for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
3164            crr_insn;
3165            crr_insn = crr_insn->next_in_row)
3166         {
3167           rtx insn = ps_rtl_insn (ps, crr_insn->id);
3168
3169           if (!NONDEBUG_INSN_P (insn))
3170             continue;
3171
3172           /* Check if there is room for the current insn.  */
3173           if (!can_issue_more || state_dead_lock_p (curr_state))
3174             return true;
3175
3176           /* Update the DFA state and return with failure if the DFA found
3177              resource conflicts.  */
3178           if (state_transition (curr_state, insn) >= 0)
3179             return true;
3180
3181           if (targetm.sched.variable_issue)
3182             can_issue_more =
3183               targetm.sched.variable_issue (sched_dump, sched_verbose,
3184                                             insn, can_issue_more);
3185           /* A naked CLOBBER or USE generates no instruction, so don't
3186              let them consume issue slots.  */
3187           else if (GET_CODE (PATTERN (insn)) != USE
3188                    && GET_CODE (PATTERN (insn)) != CLOBBER)
3189             can_issue_more--;
3190         }
3191
3192       /* Advance the DFA to the next cycle.  */
3193       advance_one_cycle ();
3194     }
3195   return false;
3196 }
3197
3198 /* Checks if the given node causes resource conflicts when added to PS at
3199    cycle C.  If not the node is added to PS and returned; otherwise zero
3200    is returned.  Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with
3201    cuid N must be come before/after (respectively) the node pointed to by
3202    PS_I when scheduled in the same cycle.  */
3203 ps_insn_ptr
3204 ps_add_node_check_conflicts (partial_schedule_ptr ps, int n,
3205                              int c, sbitmap must_precede,
3206                              sbitmap must_follow)
3207 {
3208   int has_conflicts = 0;
3209   ps_insn_ptr ps_i;
3210
3211   /* First add the node to the PS, if this succeeds check for
3212      conflicts, trying different issue slots in the same row.  */
3213   if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
3214     return NULL; /* Failed to insert the node at the given cycle.  */
3215
3216   has_conflicts = ps_has_conflicts (ps, c, c)
3217                   || (ps->history > 0
3218                       && ps_has_conflicts (ps,
3219                                            c - ps->history,
3220                                            c + ps->history));
3221
3222   /* Try different issue slots to find one that the given node can be
3223      scheduled in without conflicts.  */
3224   while (has_conflicts)
3225     {
3226       if (! ps_insn_advance_column (ps, ps_i, must_follow))
3227         break;
3228       has_conflicts = ps_has_conflicts (ps, c, c)
3229                       || (ps->history > 0
3230                           && ps_has_conflicts (ps,
3231                                                c - ps->history,
3232                                                c + ps->history));
3233     }
3234
3235   if (has_conflicts)
3236     {
3237       remove_node_from_ps (ps, ps_i);
3238       return NULL;
3239     }
3240
3241   ps->min_cycle = MIN (ps->min_cycle, c);
3242   ps->max_cycle = MAX (ps->max_cycle, c);
3243   return ps_i;
3244 }
3245
3246 /* Calculate the stage count of the partial schedule PS.  The calculation
3247    takes into account the rotation amount passed in ROTATION_AMOUNT.  */
3248 int
3249 calculate_stage_count (partial_schedule_ptr ps, int rotation_amount)
3250 {
3251   int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount;
3252   int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount;
3253   int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii);
3254
3255   /* The calculation of stage count is done adding the number of stages
3256      before cycle zero and after cycle zero.  */ 
3257   stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii);
3258
3259   return stage_count;
3260 }
3261
3262 /* Rotate the rows of PS such that insns scheduled at time
3263    START_CYCLE will appear in row 0.  Updates max/min_cycles.  */
3264 void
3265 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
3266 {
3267   int i, row, backward_rotates;
3268   int last_row = ps->ii - 1;
3269
3270   if (start_cycle == 0)
3271     return;
3272
3273   backward_rotates = SMODULO (start_cycle, ps->ii);
3274
3275   /* Revisit later and optimize this into a single loop.  */
3276   for (i = 0; i < backward_rotates; i++)
3277     {
3278       ps_insn_ptr first_row = ps->rows[0];
3279       int first_row_length = ps->rows_length[0];
3280
3281       for (row = 0; row < last_row; row++)
3282         {
3283           ps->rows[row] = ps->rows[row + 1];
3284           ps->rows_length[row] = ps->rows_length[row + 1]; 
3285         }
3286
3287       ps->rows[last_row] = first_row;
3288       ps->rows_length[last_row] = first_row_length;
3289     }
3290
3291   ps->max_cycle -= start_cycle;
3292   ps->min_cycle -= start_cycle;
3293 }
3294
3295 #endif /* INSN_SCHEDULING */
3296 \f
3297 static bool
3298 gate_handle_sms (void)
3299 {
3300   return (optimize > 0 && flag_modulo_sched);
3301 }
3302
3303
3304 /* Run instruction scheduler.  */
3305 /* Perform SMS module scheduling.  */
3306 static unsigned int
3307 rest_of_handle_sms (void)
3308 {
3309 #ifdef INSN_SCHEDULING
3310   basic_block bb;
3311
3312   /* Collect loop information to be used in SMS.  */
3313   cfg_layout_initialize (0);
3314   sms_schedule ();
3315
3316   /* Update the life information, because we add pseudos.  */
3317   max_regno = max_reg_num ();
3318
3319   /* Finalize layout changes.  */
3320   FOR_EACH_BB (bb)
3321     if (bb->next_bb != EXIT_BLOCK_PTR)
3322       bb->aux = bb->next_bb;
3323   free_dominance_info (CDI_DOMINATORS);
3324   cfg_layout_finalize ();
3325 #endif /* INSN_SCHEDULING */
3326   return 0;
3327 }
3328
3329 struct rtl_opt_pass pass_sms =
3330 {
3331  {
3332   RTL_PASS,
3333   "sms",                                /* name */
3334   gate_handle_sms,                      /* gate */
3335   rest_of_handle_sms,                   /* execute */
3336   NULL,                                 /* sub */
3337   NULL,                                 /* next */
3338   0,                                    /* static_pass_number */
3339   TV_SMS,                               /* tv_id */
3340   0,                                    /* properties_required */
3341   0,                                    /* properties_provided */
3342   0,                                    /* properties_destroyed */
3343   0,                                    /* todo_flags_start */
3344   TODO_df_finish
3345     | TODO_verify_flow
3346     | TODO_verify_rtl_sharing
3347     | TODO_ggc_collect                  /* todo_flags_finish */
3348  }
3349 };