OSDN Git Service

Oops, old revision of patch..
[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-exposed) 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    ??? The algorithm restricts the scheduling window to II cycles.
1815    In rare cases, it may be better to allow windows of II+1 cycles.
1816    The window would then start and end on the same row, but with
1817    different "must precede" and "must follow" requirements.  */
1818
1819 /* A limit on the number of cycles that resource conflicts can span.  ??? Should
1820    be provided by DFA, and be dependent on the type of insn scheduled.  Currently
1821    set to 0 to save compile time.  */
1822 #define DFA_HISTORY SMS_DFA_HISTORY
1823
1824 /* A threshold for the number of repeated unsuccessful attempts to insert
1825    an empty row, before we flush the partial schedule and start over.  */
1826 #define MAX_SPLIT_NUM 10
1827 /* Given the partial schedule PS, this function calculates and returns the
1828    cycles in which we can schedule the node with the given index I.
1829    NOTE: Here we do the backtracking in SMS, in some special cases. We have
1830    noticed that there are several cases in which we fail    to SMS the loop
1831    because the sched window of a node is empty    due to tight data-deps. In
1832    such cases we want to unschedule    some of the predecessors/successors
1833    until we get non-empty    scheduling window.  It returns -1 if the
1834    scheduling window is empty and zero otherwise.  */
1835
1836 static int
1837 get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node,
1838                   sbitmap sched_nodes, int ii, int *start_p, int *step_p,
1839                   int *end_p)
1840 {
1841   int start, step, end;
1842   int early_start, late_start;
1843   ddg_edge_ptr e;
1844   sbitmap psp = sbitmap_alloc (ps->g->num_nodes);
1845   sbitmap pss = sbitmap_alloc (ps->g->num_nodes);
1846   sbitmap u_node_preds = NODE_PREDECESSORS (u_node);
1847   sbitmap u_node_succs = NODE_SUCCESSORS (u_node);
1848   int psp_not_empty;
1849   int pss_not_empty;
1850   int count_preds;
1851   int count_succs;
1852
1853   /* 1. compute sched window for u (start, end, step).  */
1854   sbitmap_zero (psp);
1855   sbitmap_zero (pss);
1856   psp_not_empty = sbitmap_a_and_b_cg (psp, u_node_preds, sched_nodes);
1857   pss_not_empty = sbitmap_a_and_b_cg (pss, u_node_succs, sched_nodes);
1858
1859   /* We first compute a forward range (start <= end), then decide whether
1860      to reverse it.  */
1861   early_start = INT_MIN;
1862   late_start = INT_MAX;
1863   start = INT_MIN;
1864   end = INT_MAX;
1865   step = 1;
1866
1867   count_preds = 0;
1868   count_succs = 0;
1869
1870   if (dump_file && (psp_not_empty || pss_not_empty))
1871     {
1872       fprintf (dump_file, "\nAnalyzing dependencies for node %d (INSN %d)"
1873                "; ii = %d\n\n", u_node->cuid, INSN_UID (u_node->insn), ii);
1874       fprintf (dump_file, "%11s %11s %11s %11s %5s\n",
1875                "start", "early start", "late start", "end", "time");
1876       fprintf (dump_file, "=========== =========== =========== ==========="
1877                " =====\n");
1878     }
1879   /* Calculate early_start and limit end.  Both bounds are inclusive.  */
1880   if (psp_not_empty)
1881     for (e = u_node->in; e != 0; e = e->next_in)
1882       {
1883         int v = e->src->cuid;
1884
1885         if (TEST_BIT (sched_nodes, v))
1886           {
1887             int p_st = SCHED_TIME (v);
1888             int earliest = p_st + e->latency - (e->distance * ii);
1889             int latest = (e->data_type == MEM_DEP ? p_st + ii - 1 : INT_MAX);
1890
1891             if (dump_file)
1892               {
1893                 fprintf (dump_file, "%11s %11d %11s %11d %5d",
1894                          "", earliest, "", latest, p_st);
1895                 print_ddg_edge (dump_file, e);
1896                 fprintf (dump_file, "\n");
1897               }
1898
1899             early_start = MAX (early_start, earliest);
1900             end = MIN (end, latest);
1901
1902             if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1903               count_preds++;
1904           }
1905       }
1906
1907   /* Calculate late_start and limit start.  Both bounds are inclusive.  */
1908   if (pss_not_empty)
1909     for (e = u_node->out; e != 0; e = e->next_out)
1910       {
1911         int v = e->dest->cuid;
1912
1913         if (TEST_BIT (sched_nodes, v))
1914           {
1915             int s_st = SCHED_TIME (v);
1916             int earliest = (e->data_type == MEM_DEP ? s_st - ii + 1 : INT_MIN);
1917             int latest = s_st - e->latency + (e->distance * ii);
1918
1919             if (dump_file)
1920               {
1921                 fprintf (dump_file, "%11d %11s %11d %11s %5d",
1922                          earliest, "", latest, "", s_st);
1923                 print_ddg_edge (dump_file, e);
1924                 fprintf (dump_file, "\n");
1925               }
1926
1927             start = MAX (start, earliest);
1928             late_start = MIN (late_start, latest);
1929
1930             if (e->type == TRUE_DEP && e->data_type == REG_DEP)
1931               count_succs++;
1932           }
1933       }
1934
1935   if (dump_file && (psp_not_empty || pss_not_empty))
1936     {
1937       fprintf (dump_file, "----------- ----------- ----------- -----------"
1938                " -----\n");
1939       fprintf (dump_file, "%11d %11d %11d %11d %5s %s\n",
1940                start, early_start, late_start, end, "",
1941                "(max, max, min, min)");
1942     }
1943
1944   /* Get a target scheduling window no bigger than ii.  */
1945   if (early_start == INT_MIN && late_start == INT_MAX)
1946     early_start = NODE_ASAP (u_node);
1947   else if (early_start == INT_MIN)
1948     early_start = late_start - (ii - 1);
1949   late_start = MIN (late_start, early_start + (ii - 1));
1950
1951   /* Apply memory dependence limits.  */
1952   start = MAX (start, early_start);
1953   end = MIN (end, late_start);
1954
1955   if (dump_file && (psp_not_empty || pss_not_empty))
1956     fprintf (dump_file, "%11s %11d %11d %11s %5s final window\n",
1957              "", start, end, "", "");
1958
1959   /* If there are at least as many successors as predecessors, schedule the
1960      node close to its successors.  */
1961   if (pss_not_empty && count_succs >= count_preds)
1962     {
1963       int tmp = end;
1964       end = start;
1965       start = tmp;
1966       step = -1;
1967     }
1968
1969   /* Now that we've finalized the window, make END an exclusive rather
1970      than an inclusive bound.  */
1971   end += step;
1972
1973   *start_p = start;
1974   *step_p = step;
1975   *end_p = end;
1976   sbitmap_free (psp);
1977   sbitmap_free (pss);
1978
1979   if ((start >= end && step == 1) || (start <= end && step == -1))
1980     {
1981       if (dump_file)
1982         fprintf (dump_file, "\nEmpty window: start=%d, end=%d, step=%d\n",
1983                  start, end, step);
1984       return -1;
1985     }
1986
1987   return 0;
1988 }
1989
1990 /* Calculate MUST_PRECEDE/MUST_FOLLOW bitmaps of U_NODE; which is the
1991    node currently been scheduled.  At the end of the calculation
1992    MUST_PRECEDE/MUST_FOLLOW contains all predecessors/successors of
1993    U_NODE which are (1) already scheduled in the first/last row of
1994    U_NODE's scheduling window, (2) whose dependence inequality with U
1995    becomes an equality when U is scheduled in this same row, and (3)
1996    whose dependence latency is zero.
1997
1998    The first and last rows are calculated using the following parameters:
1999    START/END rows - The cycles that begins/ends the traversal on the window;
2000    searching for an empty cycle to schedule U_NODE.
2001    STEP - The direction in which we traverse the window.
2002    II - The initiation interval.  */
2003
2004 static void
2005 calculate_must_precede_follow (ddg_node_ptr u_node, int start, int end,
2006                                int step, int ii, sbitmap sched_nodes,
2007                                sbitmap must_precede, sbitmap must_follow)
2008 {
2009   ddg_edge_ptr e;
2010   int first_cycle_in_window, last_cycle_in_window;
2011
2012   gcc_assert (must_precede && must_follow);
2013
2014   /* Consider the following scheduling window:
2015      {first_cycle_in_window, first_cycle_in_window+1, ...,
2016      last_cycle_in_window}.  If step is 1 then the following will be
2017      the order we traverse the window: {start=first_cycle_in_window,
2018      first_cycle_in_window+1, ..., end=last_cycle_in_window+1},
2019      or {start=last_cycle_in_window, last_cycle_in_window-1, ...,
2020      end=first_cycle_in_window-1} if step is -1.  */
2021   first_cycle_in_window = (step == 1) ? start : end - step;
2022   last_cycle_in_window = (step == 1) ? end - step : start;
2023
2024   sbitmap_zero (must_precede);
2025   sbitmap_zero (must_follow);
2026
2027   if (dump_file)
2028     fprintf (dump_file, "\nmust_precede: ");
2029
2030   /* Instead of checking if:
2031       (SMODULO (SCHED_TIME (e->src), ii) == first_row_in_window)
2032       && ((SCHED_TIME (e->src) + e->latency - (e->distance * ii)) ==
2033              first_cycle_in_window)
2034       && e->latency == 0
2035      we use the fact that latency is non-negative:
2036       SCHED_TIME (e->src) - (e->distance * ii) <=
2037       SCHED_TIME (e->src) + e->latency - (e->distance * ii)) <=
2038       first_cycle_in_window
2039      and check only if
2040       SCHED_TIME (e->src) - (e->distance * ii) == first_cycle_in_window  */
2041   for (e = u_node->in; e != 0; e = e->next_in)
2042     if (TEST_BIT (sched_nodes, e->src->cuid)
2043         && ((SCHED_TIME (e->src->cuid) - (e->distance * ii)) ==
2044              first_cycle_in_window))
2045       {
2046         if (dump_file)
2047           fprintf (dump_file, "%d ", e->src->cuid);
2048
2049         SET_BIT (must_precede, e->src->cuid);
2050       }
2051
2052   if (dump_file)
2053     fprintf (dump_file, "\nmust_follow: ");
2054
2055   /* Instead of checking if:
2056       (SMODULO (SCHED_TIME (e->dest), ii) == last_row_in_window)
2057       && ((SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) ==
2058              last_cycle_in_window)
2059       && e->latency == 0
2060      we use the fact that latency is non-negative:
2061       SCHED_TIME (e->dest) + (e->distance * ii) >=
2062       SCHED_TIME (e->dest) - e->latency + (e->distance * ii)) >=
2063       last_cycle_in_window
2064      and check only if
2065       SCHED_TIME (e->dest) + (e->distance * ii) == last_cycle_in_window  */
2066   for (e = u_node->out; e != 0; e = e->next_out)
2067     if (TEST_BIT (sched_nodes, e->dest->cuid)
2068         && ((SCHED_TIME (e->dest->cuid) + (e->distance * ii)) ==
2069              last_cycle_in_window))
2070       {
2071         if (dump_file)
2072           fprintf (dump_file, "%d ", e->dest->cuid);
2073
2074         SET_BIT (must_follow, e->dest->cuid);
2075       }
2076
2077   if (dump_file)
2078     fprintf (dump_file, "\n");
2079 }
2080
2081 /* Return 1 if U_NODE can be scheduled in CYCLE.  Use the following
2082    parameters to decide if that's possible:
2083    PS - The partial schedule.
2084    U - The serial number of U_NODE.
2085    NUM_SPLITS - The number of row splits made so far.
2086    MUST_PRECEDE - The nodes that must precede U_NODE. (only valid at
2087    the first row of the scheduling window)
2088    MUST_FOLLOW - The nodes that must follow U_NODE. (only valid at the
2089    last row of the scheduling window)  */
2090
2091 static bool
2092 try_scheduling_node_in_cycle (partial_schedule_ptr ps,
2093                               int u, int cycle, sbitmap sched_nodes,
2094                               int *num_splits, sbitmap must_precede,
2095                               sbitmap must_follow)
2096 {
2097   ps_insn_ptr psi;
2098   bool success = 0;
2099
2100   verify_partial_schedule (ps, sched_nodes);
2101   psi = ps_add_node_check_conflicts (ps, u, cycle, must_precede, must_follow);
2102   if (psi)
2103     {
2104       SCHED_TIME (u) = cycle;
2105       SET_BIT (sched_nodes, u);
2106       success = 1;
2107       *num_splits = 0;
2108       if (dump_file)
2109         fprintf (dump_file, "Scheduled w/o split in %d\n", cycle);
2110
2111     }
2112
2113   return success;
2114 }
2115
2116 /* This function implements the scheduling algorithm for SMS according to the
2117    above algorithm.  */
2118 static partial_schedule_ptr
2119 sms_schedule_by_order (ddg_ptr g, int mii, int maxii, int *nodes_order)
2120 {
2121   int ii = mii;
2122   int i, c, success, num_splits = 0;
2123   int flush_and_start_over = true;
2124   int num_nodes = g->num_nodes;
2125   int start, end, step; /* Place together into one struct?  */
2126   sbitmap sched_nodes = sbitmap_alloc (num_nodes);
2127   sbitmap must_precede = sbitmap_alloc (num_nodes);
2128   sbitmap must_follow = sbitmap_alloc (num_nodes);
2129   sbitmap tobe_scheduled = sbitmap_alloc (num_nodes);
2130
2131   partial_schedule_ptr ps = create_partial_schedule (ii, g, DFA_HISTORY);
2132
2133   sbitmap_ones (tobe_scheduled);
2134   sbitmap_zero (sched_nodes);
2135
2136   while (flush_and_start_over && (ii < maxii))
2137     {
2138
2139       if (dump_file)
2140         fprintf (dump_file, "Starting with ii=%d\n", ii);
2141       flush_and_start_over = false;
2142       sbitmap_zero (sched_nodes);
2143
2144       for (i = 0; i < num_nodes; i++)
2145         {
2146           int u = nodes_order[i];
2147           ddg_node_ptr u_node = &ps->g->nodes[u];
2148           rtx insn = u_node->insn;
2149
2150           if (!NONDEBUG_INSN_P (insn))
2151             {
2152               RESET_BIT (tobe_scheduled, u);
2153               continue;
2154             }
2155
2156           if (TEST_BIT (sched_nodes, u))
2157             continue;
2158
2159           /* Try to get non-empty scheduling window.  */
2160          success = 0;
2161          if (get_sched_window (ps, u_node, sched_nodes, ii, &start,
2162                                 &step, &end) == 0)
2163             {
2164               if (dump_file)
2165                 fprintf (dump_file, "\nTrying to schedule node %d "
2166                          "INSN = %d  in (%d .. %d) step %d\n", u, (INSN_UID
2167                         (g->nodes[u].insn)), start, end, step);
2168
2169               gcc_assert ((step > 0 && start < end)
2170                           || (step < 0 && start > end));
2171
2172               calculate_must_precede_follow (u_node, start, end, step, ii,
2173                                              sched_nodes, must_precede,
2174                                              must_follow);
2175
2176               for (c = start; c != end; c += step)
2177                 {
2178                   sbitmap tmp_precede, tmp_follow;
2179
2180                   set_must_precede_follow (&tmp_follow, must_follow, 
2181                                            &tmp_precede, must_precede, 
2182                                            c, start, end, step);
2183                   success =
2184                     try_scheduling_node_in_cycle (ps, u, c,
2185                                                   sched_nodes,
2186                                                   &num_splits, tmp_precede,
2187                                                   tmp_follow);
2188                   if (success)
2189                     break;
2190                 }
2191
2192               verify_partial_schedule (ps, sched_nodes);
2193             }
2194             if (!success)
2195             {
2196               int split_row;
2197
2198               if (ii++ == maxii)
2199                 break;
2200
2201               if (num_splits >= MAX_SPLIT_NUM)
2202                 {
2203                   num_splits = 0;
2204                   flush_and_start_over = true;
2205                   verify_partial_schedule (ps, sched_nodes);
2206                   reset_partial_schedule (ps, ii);
2207                   verify_partial_schedule (ps, sched_nodes);
2208                   break;
2209                 }
2210
2211               num_splits++;
2212               /* The scheduling window is exclusive of 'end'
2213                  whereas compute_split_window() expects an inclusive,
2214                  ordered range.  */
2215               if (step == 1)
2216                 split_row = compute_split_row (sched_nodes, start, end - 1,
2217                                                ps->ii, u_node);
2218               else
2219                 split_row = compute_split_row (sched_nodes, end + 1, start,
2220                                                ps->ii, u_node);
2221
2222               ps_insert_empty_row (ps, split_row, sched_nodes);
2223               i--;              /* Go back and retry node i.  */
2224
2225               if (dump_file)
2226                 fprintf (dump_file, "num_splits=%d\n", num_splits);
2227             }
2228
2229           /* ??? If (success), check register pressure estimates.  */
2230         }                       /* Continue with next node.  */
2231     }                           /* While flush_and_start_over.  */
2232   if (ii >= maxii)
2233     {
2234       free_partial_schedule (ps);
2235       ps = NULL;
2236     }
2237   else
2238     gcc_assert (sbitmap_equal (tobe_scheduled, sched_nodes));
2239
2240   sbitmap_free (sched_nodes);
2241   sbitmap_free (must_precede);
2242   sbitmap_free (must_follow);
2243   sbitmap_free (tobe_scheduled);
2244
2245   return ps;
2246 }
2247
2248 /* This function inserts a new empty row into PS at the position
2249    according to SPLITROW, keeping all already scheduled instructions
2250    intact and updating their SCHED_TIME and cycle accordingly.  */
2251 static void
2252 ps_insert_empty_row (partial_schedule_ptr ps, int split_row,
2253                      sbitmap sched_nodes)
2254 {
2255   ps_insn_ptr crr_insn;
2256   ps_insn_ptr *rows_new;
2257   int ii = ps->ii;
2258   int new_ii = ii + 1;
2259   int row;
2260   int *rows_length_new;
2261
2262   verify_partial_schedule (ps, sched_nodes);
2263
2264   /* We normalize sched_time and rotate ps to have only non-negative sched
2265      times, for simplicity of updating cycles after inserting new row.  */
2266   split_row -= ps->min_cycle;
2267   split_row = SMODULO (split_row, ii);
2268   if (dump_file)
2269     fprintf (dump_file, "split_row=%d\n", split_row);
2270
2271   reset_sched_times (ps, PS_MIN_CYCLE (ps));
2272   rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
2273
2274   rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
2275   rows_length_new = (int *) xcalloc (new_ii, sizeof (int));
2276   for (row = 0; row < split_row; row++)
2277     {
2278       rows_new[row] = ps->rows[row];
2279       rows_length_new[row] = ps->rows_length[row];
2280       ps->rows[row] = NULL;
2281       for (crr_insn = rows_new[row];
2282            crr_insn; crr_insn = crr_insn->next_in_row)
2283         {
2284           int u = crr_insn->id;
2285           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii);
2286
2287           SCHED_TIME (u) = new_time;
2288           crr_insn->cycle = new_time;
2289           SCHED_ROW (u) = new_time % new_ii;
2290           SCHED_STAGE (u) = new_time / new_ii;
2291         }
2292
2293     }
2294
2295   rows_new[split_row] = NULL;
2296
2297   for (row = split_row; row < ii; row++)
2298     {
2299       rows_new[row + 1] = ps->rows[row];
2300       rows_length_new[row + 1] = ps->rows_length[row];
2301       ps->rows[row] = NULL;
2302       for (crr_insn = rows_new[row + 1];
2303            crr_insn; crr_insn = crr_insn->next_in_row)
2304         {
2305           int u = crr_insn->id;
2306           int new_time = SCHED_TIME (u) + (SCHED_TIME (u) / ii) + 1;
2307
2308           SCHED_TIME (u) = new_time;
2309           crr_insn->cycle = new_time;
2310           SCHED_ROW (u) = new_time % new_ii;
2311           SCHED_STAGE (u) = new_time / new_ii;
2312         }
2313     }
2314
2315   /* Updating ps.  */
2316   ps->min_cycle = ps->min_cycle + ps->min_cycle / ii
2317     + (SMODULO (ps->min_cycle, ii) >= split_row ? 1 : 0);
2318   ps->max_cycle = ps->max_cycle + ps->max_cycle / ii
2319     + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0);
2320   free (ps->rows);
2321   ps->rows = rows_new;
2322   free (ps->rows_length);
2323   ps->rows_length = rows_length_new;
2324   ps->ii = new_ii;
2325   gcc_assert (ps->min_cycle >= 0);
2326
2327   verify_partial_schedule (ps, sched_nodes);
2328
2329   if (dump_file)
2330     fprintf (dump_file, "min_cycle=%d, max_cycle=%d\n", ps->min_cycle,
2331              ps->max_cycle);
2332 }
2333
2334 /* Given U_NODE which is the node that failed to be scheduled; LOW and
2335    UP which are the boundaries of it's scheduling window; compute using
2336    SCHED_NODES and II a row in the partial schedule that can be split
2337    which will separate a critical predecessor from a critical successor
2338    thereby expanding the window, and return it.  */
2339 static int
2340 compute_split_row (sbitmap sched_nodes, int low, int up, int ii,
2341                    ddg_node_ptr u_node)
2342 {
2343   ddg_edge_ptr e;
2344   int lower = INT_MIN, upper = INT_MAX;
2345   int crit_pred = -1;
2346   int crit_succ = -1;
2347   int crit_cycle;
2348
2349   for (e = u_node->in; e != 0; e = e->next_in)
2350     {
2351       int v = e->src->cuid;
2352
2353       if (TEST_BIT (sched_nodes, v)
2354           && (low == SCHED_TIME (v) + e->latency - (e->distance * ii)))
2355         if (SCHED_TIME (v) > lower)
2356           {
2357             crit_pred = v;
2358             lower = SCHED_TIME (v);
2359           }
2360     }
2361
2362   if (crit_pred >= 0)
2363     {
2364       crit_cycle = SCHED_TIME (crit_pred) + 1;
2365       return SMODULO (crit_cycle, ii);
2366     }
2367
2368   for (e = u_node->out; e != 0; e = e->next_out)
2369     {
2370       int v = e->dest->cuid;
2371
2372       if (TEST_BIT (sched_nodes, v)
2373           && (up == SCHED_TIME (v) - e->latency + (e->distance * ii)))
2374         if (SCHED_TIME (v) < upper)
2375           {
2376             crit_succ = v;
2377             upper = SCHED_TIME (v);
2378           }
2379     }
2380
2381   if (crit_succ >= 0)
2382     {
2383       crit_cycle = SCHED_TIME (crit_succ);
2384       return SMODULO (crit_cycle, ii);
2385     }
2386
2387   if (dump_file)
2388     fprintf (dump_file, "Both crit_pred and crit_succ are NULL\n");
2389
2390   return SMODULO ((low + up + 1) / 2, ii);
2391 }
2392
2393 static void
2394 verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes)
2395 {
2396   int row;
2397   ps_insn_ptr crr_insn;
2398
2399   for (row = 0; row < ps->ii; row++)
2400     {
2401       int length = 0;
2402       
2403       for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row)
2404         {
2405           int u = crr_insn->id;
2406           
2407           length++;
2408           gcc_assert (TEST_BIT (sched_nodes, u));
2409           /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by
2410              popcount (sched_nodes) == number of insns in ps.  */
2411           gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
2412           gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
2413         }
2414       
2415       gcc_assert (ps->rows_length[row] == length);
2416     }
2417 }
2418
2419 \f
2420 /* This page implements the algorithm for ordering the nodes of a DDG
2421    for modulo scheduling, activated through the
2422    "int sms_order_nodes (ddg_ptr, int mii, int * result)" API.  */
2423
2424 #define ORDER_PARAMS(x) ((struct node_order_params *) (x)->aux.info)
2425 #define ASAP(x) (ORDER_PARAMS ((x))->asap)
2426 #define ALAP(x) (ORDER_PARAMS ((x))->alap)
2427 #define HEIGHT(x) (ORDER_PARAMS ((x))->height)
2428 #define MOB(x) (ALAP ((x)) - ASAP ((x)))
2429 #define DEPTH(x) (ASAP ((x)))
2430
2431 typedef struct node_order_params * nopa;
2432
2433 static void order_nodes_of_sccs (ddg_all_sccs_ptr, int * result);
2434 static int order_nodes_in_scc (ddg_ptr, sbitmap, sbitmap, int*, int);
2435 static nopa  calculate_order_params (ddg_ptr, int, int *);
2436 static int find_max_asap (ddg_ptr, sbitmap);
2437 static int find_max_hv_min_mob (ddg_ptr, sbitmap);
2438 static int find_max_dv_min_mob (ddg_ptr, sbitmap);
2439
2440 enum sms_direction {BOTTOMUP, TOPDOWN};
2441
2442 struct node_order_params
2443 {
2444   int asap;
2445   int alap;
2446   int height;
2447 };
2448
2449 /* Check if NODE_ORDER contains a permutation of 0 .. NUM_NODES-1.  */
2450 static void
2451 check_nodes_order (int *node_order, int num_nodes)
2452 {
2453   int i;
2454   sbitmap tmp = sbitmap_alloc (num_nodes);
2455
2456   sbitmap_zero (tmp);
2457
2458   if (dump_file)
2459     fprintf (dump_file, "SMS final nodes order: \n");
2460
2461   for (i = 0; i < num_nodes; i++)
2462     {
2463       int u = node_order[i];
2464
2465       if (dump_file)
2466         fprintf (dump_file, "%d ", u);
2467       gcc_assert (u < num_nodes && u >= 0 && !TEST_BIT (tmp, u));
2468
2469       SET_BIT (tmp, u);
2470     }
2471
2472   if (dump_file)
2473     fprintf (dump_file, "\n");
2474
2475   sbitmap_free (tmp);
2476 }
2477
2478 /* Order the nodes of G for scheduling and pass the result in
2479    NODE_ORDER.  Also set aux.count of each node to ASAP.
2480    Put maximal ASAP to PMAX_ASAP.  Return the recMII for the given DDG.  */
2481 static int
2482 sms_order_nodes (ddg_ptr g, int mii, int * node_order, int *pmax_asap)
2483 {
2484   int i;
2485   int rec_mii = 0;
2486   ddg_all_sccs_ptr sccs = create_ddg_all_sccs (g);
2487
2488   nopa nops = calculate_order_params (g, mii, pmax_asap);
2489
2490   if (dump_file)
2491     print_sccs (dump_file, sccs, g);
2492
2493   order_nodes_of_sccs (sccs, node_order);
2494
2495   if (sccs->num_sccs > 0)
2496     /* First SCC has the largest recurrence_length.  */
2497     rec_mii = sccs->sccs[0]->recurrence_length;
2498
2499   /* Save ASAP before destroying node_order_params.  */
2500   for (i = 0; i < g->num_nodes; i++)
2501     {
2502       ddg_node_ptr v = &g->nodes[i];
2503       v->aux.count = ASAP (v);
2504     }
2505
2506   free (nops);
2507   free_ddg_all_sccs (sccs);
2508   check_nodes_order (node_order, g->num_nodes);
2509
2510   return rec_mii;
2511 }
2512
2513 static void
2514 order_nodes_of_sccs (ddg_all_sccs_ptr all_sccs, int * node_order)
2515 {
2516   int i, pos = 0;
2517   ddg_ptr g = all_sccs->ddg;
2518   int num_nodes = g->num_nodes;
2519   sbitmap prev_sccs = sbitmap_alloc (num_nodes);
2520   sbitmap on_path = sbitmap_alloc (num_nodes);
2521   sbitmap tmp = sbitmap_alloc (num_nodes);
2522   sbitmap ones = sbitmap_alloc (num_nodes);
2523
2524   sbitmap_zero (prev_sccs);
2525   sbitmap_ones (ones);
2526
2527   /* Perform the node ordering starting from the SCC with the highest recMII.
2528      For each SCC order the nodes according to their ASAP/ALAP/HEIGHT etc.  */
2529   for (i = 0; i < all_sccs->num_sccs; i++)
2530     {
2531       ddg_scc_ptr scc = all_sccs->sccs[i];
2532
2533       /* Add nodes on paths from previous SCCs to the current SCC.  */
2534       find_nodes_on_paths (on_path, g, prev_sccs, scc->nodes);
2535       sbitmap_a_or_b (tmp, scc->nodes, on_path);
2536
2537       /* Add nodes on paths from the current SCC to previous SCCs.  */
2538       find_nodes_on_paths (on_path, g, scc->nodes, prev_sccs);
2539       sbitmap_a_or_b (tmp, tmp, on_path);
2540
2541       /* Remove nodes of previous SCCs from current extended SCC.  */
2542       sbitmap_difference (tmp, tmp, prev_sccs);
2543
2544       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2545       /* Above call to order_nodes_in_scc updated prev_sccs |= tmp.  */
2546     }
2547
2548   /* Handle the remaining nodes that do not belong to any scc.  Each call
2549      to order_nodes_in_scc handles a single connected component.  */
2550   while (pos < g->num_nodes)
2551     {
2552       sbitmap_difference (tmp, ones, prev_sccs);
2553       pos = order_nodes_in_scc (g, prev_sccs, tmp, node_order, pos);
2554     }
2555   sbitmap_free (prev_sccs);
2556   sbitmap_free (on_path);
2557   sbitmap_free (tmp);
2558   sbitmap_free (ones);
2559 }
2560
2561 /* MII is needed if we consider backarcs (that do not close recursive cycles).  */
2562 static struct node_order_params *
2563 calculate_order_params (ddg_ptr g, int mii ATTRIBUTE_UNUSED, int *pmax_asap)
2564 {
2565   int u;
2566   int max_asap;
2567   int num_nodes = g->num_nodes;
2568   ddg_edge_ptr e;
2569   /* Allocate a place to hold ordering params for each node in the DDG.  */
2570   nopa node_order_params_arr;
2571
2572   /* Initialize of ASAP/ALAP/HEIGHT to zero.  */
2573   node_order_params_arr = (nopa) xcalloc (num_nodes,
2574                                           sizeof (struct node_order_params));
2575
2576   /* Set the aux pointer of each node to point to its order_params structure.  */
2577   for (u = 0; u < num_nodes; u++)
2578     g->nodes[u].aux.info = &node_order_params_arr[u];
2579
2580   /* Disregarding a backarc from each recursive cycle to obtain a DAG,
2581      calculate ASAP, ALAP, mobility, distance, and height for each node
2582      in the dependence (direct acyclic) graph.  */
2583
2584   /* We assume that the nodes in the array are in topological order.  */
2585
2586   max_asap = 0;
2587   for (u = 0; u < num_nodes; u++)
2588     {
2589       ddg_node_ptr u_node = &g->nodes[u];
2590
2591       ASAP (u_node) = 0;
2592       for (e = u_node->in; e; e = e->next_in)
2593         if (e->distance == 0)
2594           ASAP (u_node) = MAX (ASAP (u_node),
2595                                ASAP (e->src) + e->latency);
2596       max_asap = MAX (max_asap, ASAP (u_node));
2597     }
2598
2599   for (u = num_nodes - 1; u > -1; u--)
2600     {
2601       ddg_node_ptr u_node = &g->nodes[u];
2602
2603       ALAP (u_node) = max_asap;
2604       HEIGHT (u_node) = 0;
2605       for (e = u_node->out; e; e = e->next_out)
2606         if (e->distance == 0)
2607           {
2608             ALAP (u_node) = MIN (ALAP (u_node),
2609                                  ALAP (e->dest) - e->latency);
2610             HEIGHT (u_node) = MAX (HEIGHT (u_node),
2611                                    HEIGHT (e->dest) + e->latency);
2612           }
2613     }
2614   if (dump_file)
2615   {
2616     fprintf (dump_file, "\nOrder params\n");
2617     for (u = 0; u < num_nodes; u++)
2618       {
2619         ddg_node_ptr u_node = &g->nodes[u];
2620
2621         fprintf (dump_file, "node %d, ASAP: %d, ALAP: %d, HEIGHT: %d\n", u,
2622                  ASAP (u_node), ALAP (u_node), HEIGHT (u_node));
2623       }
2624   }
2625
2626   *pmax_asap = max_asap;
2627   return node_order_params_arr;
2628 }
2629
2630 static int
2631 find_max_asap (ddg_ptr g, sbitmap nodes)
2632 {
2633   unsigned int u = 0;
2634   int max_asap = -1;
2635   int result = -1;
2636   sbitmap_iterator sbi;
2637
2638   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2639     {
2640       ddg_node_ptr u_node = &g->nodes[u];
2641
2642       if (max_asap < ASAP (u_node))
2643         {
2644           max_asap = ASAP (u_node);
2645           result = u;
2646         }
2647     }
2648   return result;
2649 }
2650
2651 static int
2652 find_max_hv_min_mob (ddg_ptr g, sbitmap nodes)
2653 {
2654   unsigned int u = 0;
2655   int max_hv = -1;
2656   int min_mob = INT_MAX;
2657   int result = -1;
2658   sbitmap_iterator sbi;
2659
2660   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2661     {
2662       ddg_node_ptr u_node = &g->nodes[u];
2663
2664       if (max_hv < HEIGHT (u_node))
2665         {
2666           max_hv = HEIGHT (u_node);
2667           min_mob = MOB (u_node);
2668           result = u;
2669         }
2670       else if ((max_hv == HEIGHT (u_node))
2671                && (min_mob > MOB (u_node)))
2672         {
2673           min_mob = MOB (u_node);
2674           result = u;
2675         }
2676     }
2677   return result;
2678 }
2679
2680 static int
2681 find_max_dv_min_mob (ddg_ptr g, sbitmap nodes)
2682 {
2683   unsigned int u = 0;
2684   int max_dv = -1;
2685   int min_mob = INT_MAX;
2686   int result = -1;
2687   sbitmap_iterator sbi;
2688
2689   EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, u, sbi)
2690     {
2691       ddg_node_ptr u_node = &g->nodes[u];
2692
2693       if (max_dv < DEPTH (u_node))
2694         {
2695           max_dv = DEPTH (u_node);
2696           min_mob = MOB (u_node);
2697           result = u;
2698         }
2699       else if ((max_dv == DEPTH (u_node))
2700                && (min_mob > MOB (u_node)))
2701         {
2702           min_mob = MOB (u_node);
2703           result = u;
2704         }
2705     }
2706   return result;
2707 }
2708
2709 /* Places the nodes of SCC into the NODE_ORDER array starting
2710    at position POS, according to the SMS ordering algorithm.
2711    NODES_ORDERED (in&out parameter) holds the bitset of all nodes in
2712    the NODE_ORDER array, starting from position zero.  */
2713 static int
2714 order_nodes_in_scc (ddg_ptr g, sbitmap nodes_ordered, sbitmap scc,
2715                     int * node_order, int pos)
2716 {
2717   enum sms_direction dir;
2718   int num_nodes = g->num_nodes;
2719   sbitmap workset = sbitmap_alloc (num_nodes);
2720   sbitmap tmp = sbitmap_alloc (num_nodes);
2721   sbitmap zero_bitmap = sbitmap_alloc (num_nodes);
2722   sbitmap predecessors = sbitmap_alloc (num_nodes);
2723   sbitmap successors = sbitmap_alloc (num_nodes);
2724
2725   sbitmap_zero (predecessors);
2726   find_predecessors (predecessors, g, nodes_ordered);
2727
2728   sbitmap_zero (successors);
2729   find_successors (successors, g, nodes_ordered);
2730
2731   sbitmap_zero (tmp);
2732   if (sbitmap_a_and_b_cg (tmp, predecessors, scc))
2733     {
2734       sbitmap_copy (workset, tmp);
2735       dir = BOTTOMUP;
2736     }
2737   else if (sbitmap_a_and_b_cg (tmp, successors, scc))
2738     {
2739       sbitmap_copy (workset, tmp);
2740       dir = TOPDOWN;
2741     }
2742   else
2743     {
2744       int u;
2745
2746       sbitmap_zero (workset);
2747       if ((u = find_max_asap (g, scc)) >= 0)
2748         SET_BIT (workset, u);
2749       dir = BOTTOMUP;
2750     }
2751
2752   sbitmap_zero (zero_bitmap);
2753   while (!sbitmap_equal (workset, zero_bitmap))
2754     {
2755       int v;
2756       ddg_node_ptr v_node;
2757       sbitmap v_node_preds;
2758       sbitmap v_node_succs;
2759
2760       if (dir == TOPDOWN)
2761         {
2762           while (!sbitmap_equal (workset, zero_bitmap))
2763             {
2764               v = find_max_hv_min_mob (g, workset);
2765               v_node = &g->nodes[v];
2766               node_order[pos++] = v;
2767               v_node_succs = NODE_SUCCESSORS (v_node);
2768               sbitmap_a_and_b (tmp, v_node_succs, scc);
2769
2770               /* Don't consider the already ordered successors again.  */
2771               sbitmap_difference (tmp, tmp, nodes_ordered);
2772               sbitmap_a_or_b (workset, workset, tmp);
2773               RESET_BIT (workset, v);
2774               SET_BIT (nodes_ordered, v);
2775             }
2776           dir = BOTTOMUP;
2777           sbitmap_zero (predecessors);
2778           find_predecessors (predecessors, g, nodes_ordered);
2779           sbitmap_a_and_b (workset, predecessors, scc);
2780         }
2781       else
2782         {
2783           while (!sbitmap_equal (workset, zero_bitmap))
2784             {
2785               v = find_max_dv_min_mob (g, workset);
2786               v_node = &g->nodes[v];
2787               node_order[pos++] = v;
2788               v_node_preds = NODE_PREDECESSORS (v_node);
2789               sbitmap_a_and_b (tmp, v_node_preds, scc);
2790
2791               /* Don't consider the already ordered predecessors again.  */
2792               sbitmap_difference (tmp, tmp, nodes_ordered);
2793               sbitmap_a_or_b (workset, workset, tmp);
2794               RESET_BIT (workset, v);
2795               SET_BIT (nodes_ordered, v);
2796             }
2797           dir = TOPDOWN;
2798           sbitmap_zero (successors);
2799           find_successors (successors, g, nodes_ordered);
2800           sbitmap_a_and_b (workset, successors, scc);
2801         }
2802     }
2803   sbitmap_free (tmp);
2804   sbitmap_free (workset);
2805   sbitmap_free (zero_bitmap);
2806   sbitmap_free (predecessors);
2807   sbitmap_free (successors);
2808   return pos;
2809 }
2810
2811 \f
2812 /* This page contains functions for manipulating partial-schedules during
2813    modulo scheduling.  */
2814
2815 /* Create a partial schedule and allocate a memory to hold II rows.  */
2816
2817 static partial_schedule_ptr
2818 create_partial_schedule (int ii, ddg_ptr g, int history)
2819 {
2820   partial_schedule_ptr ps = XNEW (struct partial_schedule);
2821   ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr));
2822   ps->rows_length = (int *) xcalloc (ii, sizeof (int));
2823   ps->reg_moves = NULL;
2824   ps->ii = ii;
2825   ps->history = history;
2826   ps->min_cycle = INT_MAX;
2827   ps->max_cycle = INT_MIN;
2828   ps->g = g;
2829
2830   return ps;
2831 }
2832
2833 /* Free the PS_INSNs in rows array of the given partial schedule.
2834    ??? Consider caching the PS_INSN's.  */
2835 static void
2836 free_ps_insns (partial_schedule_ptr ps)
2837 {
2838   int i;
2839
2840   for (i = 0; i < ps->ii; i++)
2841     {
2842       while (ps->rows[i])
2843         {
2844           ps_insn_ptr ps_insn = ps->rows[i]->next_in_row;
2845
2846           free (ps->rows[i]);
2847           ps->rows[i] = ps_insn;
2848         }
2849       ps->rows[i] = NULL;
2850     }
2851 }
2852
2853 /* Free all the memory allocated to the partial schedule.  */
2854
2855 static void
2856 free_partial_schedule (partial_schedule_ptr ps)
2857 {
2858   ps_reg_move_info *move;
2859   unsigned int i;
2860
2861   if (!ps)
2862     return;
2863
2864   FOR_EACH_VEC_ELT (ps_reg_move_info, ps->reg_moves, i, move)
2865     sbitmap_free (move->uses);
2866   VEC_free (ps_reg_move_info, heap, ps->reg_moves);
2867
2868   free_ps_insns (ps);
2869   free (ps->rows);
2870   free (ps->rows_length);
2871   free (ps);
2872 }
2873
2874 /* Clear the rows array with its PS_INSNs, and create a new one with
2875    NEW_II rows.  */
2876
2877 static void
2878 reset_partial_schedule (partial_schedule_ptr ps, int new_ii)
2879 {
2880   if (!ps)
2881     return;
2882   free_ps_insns (ps);
2883   if (new_ii == ps->ii)
2884     return;
2885   ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii
2886                                                  * sizeof (ps_insn_ptr));
2887   memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr));
2888   ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int));
2889   memset (ps->rows_length, 0, new_ii * sizeof (int));
2890   ps->ii = new_ii;
2891   ps->min_cycle = INT_MAX;
2892   ps->max_cycle = INT_MIN;
2893 }
2894
2895 /* Prints the partial schedule as an ii rows array, for each rows
2896    print the ids of the insns in it.  */
2897 void
2898 print_partial_schedule (partial_schedule_ptr ps, FILE *dump)
2899 {
2900   int i;
2901
2902   for (i = 0; i < ps->ii; i++)
2903     {
2904       ps_insn_ptr ps_i = ps->rows[i];
2905
2906       fprintf (dump, "\n[ROW %d ]: ", i);
2907       while (ps_i)
2908         {
2909           rtx insn = ps_rtl_insn (ps, ps_i->id);
2910
2911           if (JUMP_P (insn))
2912             fprintf (dump, "%d (branch), ", INSN_UID (insn));
2913           else
2914             fprintf (dump, "%d, ", INSN_UID (insn));
2915         
2916           ps_i = ps_i->next_in_row;
2917         }
2918     }
2919 }
2920
2921 /* Creates an object of PS_INSN and initializes it to the given parameters.  */
2922 static ps_insn_ptr
2923 create_ps_insn (int id, int cycle)
2924 {
2925   ps_insn_ptr ps_i = XNEW (struct ps_insn);
2926
2927   ps_i->id = id;
2928   ps_i->next_in_row = NULL;
2929   ps_i->prev_in_row = NULL;
2930   ps_i->cycle = cycle;
2931
2932   return ps_i;
2933 }
2934
2935
2936 /* Removes the given PS_INSN from the partial schedule.  */  
2937 static void 
2938 remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i)
2939 {
2940   int row;
2941
2942   gcc_assert (ps && ps_i);
2943   
2944   row = SMODULO (ps_i->cycle, ps->ii);
2945   if (! ps_i->prev_in_row)
2946     {
2947       gcc_assert (ps_i == ps->rows[row]);
2948       ps->rows[row] = ps_i->next_in_row;
2949       if (ps->rows[row])
2950         ps->rows[row]->prev_in_row = NULL;
2951     }
2952   else
2953     {
2954       ps_i->prev_in_row->next_in_row = ps_i->next_in_row;
2955       if (ps_i->next_in_row)
2956         ps_i->next_in_row->prev_in_row = ps_i->prev_in_row;
2957     }
2958    
2959   ps->rows_length[row] -= 1; 
2960   free (ps_i);
2961   return;
2962 }
2963
2964 /* Unlike what literature describes for modulo scheduling (which focuses
2965    on VLIW machines) the order of the instructions inside a cycle is
2966    important.  Given the bitmaps MUST_FOLLOW and MUST_PRECEDE we know
2967    where the current instruction should go relative to the already
2968    scheduled instructions in the given cycle.  Go over these
2969    instructions and find the first possible column to put it in.  */
2970 static bool
2971 ps_insn_find_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
2972                      sbitmap must_precede, sbitmap must_follow)
2973 {
2974   ps_insn_ptr next_ps_i;
2975   ps_insn_ptr first_must_follow = NULL;
2976   ps_insn_ptr last_must_precede = NULL;
2977   ps_insn_ptr last_in_row = NULL;
2978   int row;
2979
2980   if (! ps_i)
2981     return false;
2982
2983   row = SMODULO (ps_i->cycle, ps->ii);
2984
2985   /* Find the first must follow and the last must precede
2986      and insert the node immediately after the must precede
2987      but make sure that it there is no must follow after it.  */
2988   for (next_ps_i = ps->rows[row];
2989        next_ps_i;
2990        next_ps_i = next_ps_i->next_in_row)
2991     {
2992       if (must_follow
2993           && TEST_BIT (must_follow, next_ps_i->id)
2994           && ! first_must_follow)
2995         first_must_follow = next_ps_i;
2996       if (must_precede && TEST_BIT (must_precede, next_ps_i->id))
2997         {
2998           /* If we have already met a node that must follow, then
2999              there is no possible column.  */
3000           if (first_must_follow)
3001             return false;
3002           else
3003             last_must_precede = next_ps_i;
3004         }
3005       /* The closing branch must be the last in the row.  */
3006       if (must_precede 
3007           && TEST_BIT (must_precede, next_ps_i->id)
3008           && JUMP_P (ps_rtl_insn (ps, next_ps_i->id)))
3009         return false;
3010              
3011        last_in_row = next_ps_i;
3012     }
3013
3014   /* The closing branch is scheduled as well.  Make sure there is no
3015      dependent instruction after it as the branch should be the last
3016      instruction in the row.  */
3017   if (JUMP_P (ps_rtl_insn (ps, ps_i->id)))
3018     {
3019       if (first_must_follow)
3020         return false;
3021       if (last_in_row)
3022         {
3023           /* Make the branch the last in the row.  New instructions
3024              will be inserted at the beginning of the row or after the
3025              last must_precede instruction thus the branch is guaranteed
3026              to remain the last instruction in the row.  */
3027           last_in_row->next_in_row = ps_i;
3028           ps_i->prev_in_row = last_in_row;
3029           ps_i->next_in_row = NULL;
3030         }
3031       else
3032         ps->rows[row] = ps_i;
3033       return true;
3034     }
3035   
3036   /* Now insert the node after INSERT_AFTER_PSI.  */
3037
3038   if (! last_must_precede)
3039     {
3040       ps_i->next_in_row = ps->rows[row];
3041       ps_i->prev_in_row = NULL;
3042       if (ps_i->next_in_row)
3043         ps_i->next_in_row->prev_in_row = ps_i;
3044       ps->rows[row] = ps_i;
3045     }
3046   else
3047     {
3048       ps_i->next_in_row = last_must_precede->next_in_row;
3049       last_must_precede->next_in_row = ps_i;
3050       ps_i->prev_in_row = last_must_precede;
3051       if (ps_i->next_in_row)
3052         ps_i->next_in_row->prev_in_row = ps_i;
3053     }
3054
3055   return true;
3056 }
3057
3058 /* Advances the PS_INSN one column in its current row; returns false
3059    in failure and true in success.  Bit N is set in MUST_FOLLOW if
3060    the node with cuid N must be come after the node pointed to by
3061    PS_I when scheduled in the same cycle.  */
3062 static int
3063 ps_insn_advance_column (partial_schedule_ptr ps, ps_insn_ptr ps_i,
3064                         sbitmap must_follow)
3065 {
3066   ps_insn_ptr prev, next;
3067   int row;
3068
3069   if (!ps || !ps_i)
3070     return false;
3071
3072   row = SMODULO (ps_i->cycle, ps->ii);
3073
3074   if (! ps_i->next_in_row)
3075     return false;
3076
3077   /* Check if next_in_row is dependent on ps_i, both having same sched
3078      times (typically ANTI_DEP).  If so, ps_i cannot skip over it.  */
3079   if (must_follow && TEST_BIT (must_follow, ps_i->next_in_row->id))
3080     return false;
3081
3082   /* Advance PS_I over its next_in_row in the doubly linked list.  */
3083   prev = ps_i->prev_in_row;
3084   next = ps_i->next_in_row;
3085
3086   if (ps_i == ps->rows[row])
3087     ps->rows[row] = next;
3088
3089   ps_i->next_in_row = next->next_in_row;
3090
3091   if (next->next_in_row)
3092     next->next_in_row->prev_in_row = ps_i;
3093
3094   next->next_in_row = ps_i;
3095   ps_i->prev_in_row = next;
3096
3097   next->prev_in_row = prev;
3098   if (prev)
3099     prev->next_in_row = next;
3100
3101   return true;
3102 }
3103
3104 /* Inserts a DDG_NODE to the given partial schedule at the given cycle.
3105    Returns 0 if this is not possible and a PS_INSN otherwise.  Bit N is
3106    set in MUST_PRECEDE/MUST_FOLLOW if the node with cuid N must be come
3107    before/after (respectively) the node pointed to by PS_I when scheduled
3108    in the same cycle.  */
3109 static ps_insn_ptr
3110 add_node_to_ps (partial_schedule_ptr ps, int id, int cycle,
3111                 sbitmap must_precede, sbitmap must_follow)
3112 {
3113   ps_insn_ptr ps_i;
3114   int row = SMODULO (cycle, ps->ii);
3115
3116   if (ps->rows_length[row] >= issue_rate)
3117     return NULL;
3118
3119   ps_i = create_ps_insn (id, cycle);
3120
3121   /* Finds and inserts PS_I according to MUST_FOLLOW and
3122      MUST_PRECEDE.  */
3123   if (! ps_insn_find_column (ps, ps_i, must_precede, must_follow))
3124     {
3125       free (ps_i);
3126       return NULL;
3127     }
3128
3129   ps->rows_length[row] += 1;
3130   return ps_i;
3131 }
3132
3133 /* Advance time one cycle.  Assumes DFA is being used.  */
3134 static void
3135 advance_one_cycle (void)
3136 {
3137   if (targetm.sched.dfa_pre_cycle_insn)
3138     state_transition (curr_state,
3139                       targetm.sched.dfa_pre_cycle_insn ());
3140
3141   state_transition (curr_state, NULL);
3142
3143   if (targetm.sched.dfa_post_cycle_insn)
3144     state_transition (curr_state,
3145                       targetm.sched.dfa_post_cycle_insn ());
3146 }
3147
3148
3149
3150 /* Checks if PS has resource conflicts according to DFA, starting from
3151    FROM cycle to TO cycle; returns true if there are conflicts and false
3152    if there are no conflicts.  Assumes DFA is being used.  */
3153 static int
3154 ps_has_conflicts (partial_schedule_ptr ps, int from, int to)
3155 {
3156   int cycle;
3157
3158   state_reset (curr_state);
3159
3160   for (cycle = from; cycle <= to; cycle++)
3161     {
3162       ps_insn_ptr crr_insn;
3163       /* Holds the remaining issue slots in the current row.  */
3164       int can_issue_more = issue_rate;
3165
3166       /* Walk through the DFA for the current row.  */
3167       for (crr_insn = ps->rows[SMODULO (cycle, ps->ii)];
3168            crr_insn;
3169            crr_insn = crr_insn->next_in_row)
3170         {
3171           rtx insn = ps_rtl_insn (ps, crr_insn->id);
3172
3173           if (!NONDEBUG_INSN_P (insn))
3174             continue;
3175
3176           /* Check if there is room for the current insn.  */
3177           if (!can_issue_more || state_dead_lock_p (curr_state))
3178             return true;
3179
3180           /* Update the DFA state and return with failure if the DFA found
3181              resource conflicts.  */
3182           if (state_transition (curr_state, insn) >= 0)
3183             return true;
3184
3185           if (targetm.sched.variable_issue)
3186             can_issue_more =
3187               targetm.sched.variable_issue (sched_dump, sched_verbose,
3188                                             insn, can_issue_more);
3189           /* A naked CLOBBER or USE generates no instruction, so don't
3190              let them consume issue slots.  */
3191           else if (GET_CODE (PATTERN (insn)) != USE
3192                    && GET_CODE (PATTERN (insn)) != CLOBBER)
3193             can_issue_more--;
3194         }
3195
3196       /* Advance the DFA to the next cycle.  */
3197       advance_one_cycle ();
3198     }
3199   return false;
3200 }
3201
3202 /* Checks if the given node causes resource conflicts when added to PS at
3203    cycle C.  If not the node is added to PS and returned; otherwise zero
3204    is returned.  Bit N is set in MUST_PRECEDE/MUST_FOLLOW if the node with
3205    cuid N must be come before/after (respectively) the node pointed to by
3206    PS_I when scheduled in the same cycle.  */
3207 ps_insn_ptr
3208 ps_add_node_check_conflicts (partial_schedule_ptr ps, int n,
3209                              int c, sbitmap must_precede,
3210                              sbitmap must_follow)
3211 {
3212   int has_conflicts = 0;
3213   ps_insn_ptr ps_i;
3214
3215   /* First add the node to the PS, if this succeeds check for
3216      conflicts, trying different issue slots in the same row.  */
3217   if (! (ps_i = add_node_to_ps (ps, n, c, must_precede, must_follow)))
3218     return NULL; /* Failed to insert the node at the given cycle.  */
3219
3220   has_conflicts = ps_has_conflicts (ps, c, c)
3221                   || (ps->history > 0
3222                       && ps_has_conflicts (ps,
3223                                            c - ps->history,
3224                                            c + ps->history));
3225
3226   /* Try different issue slots to find one that the given node can be
3227      scheduled in without conflicts.  */
3228   while (has_conflicts)
3229     {
3230       if (! ps_insn_advance_column (ps, ps_i, must_follow))
3231         break;
3232       has_conflicts = ps_has_conflicts (ps, c, c)
3233                       || (ps->history > 0
3234                           && ps_has_conflicts (ps,
3235                                                c - ps->history,
3236                                                c + ps->history));
3237     }
3238
3239   if (has_conflicts)
3240     {
3241       remove_node_from_ps (ps, ps_i);
3242       return NULL;
3243     }
3244
3245   ps->min_cycle = MIN (ps->min_cycle, c);
3246   ps->max_cycle = MAX (ps->max_cycle, c);
3247   return ps_i;
3248 }
3249
3250 /* Calculate the stage count of the partial schedule PS.  The calculation
3251    takes into account the rotation amount passed in ROTATION_AMOUNT.  */
3252 int
3253 calculate_stage_count (partial_schedule_ptr ps, int rotation_amount)
3254 {
3255   int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount;
3256   int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount;
3257   int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii);
3258
3259   /* The calculation of stage count is done adding the number of stages
3260      before cycle zero and after cycle zero.  */ 
3261   stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii);
3262
3263   return stage_count;
3264 }
3265
3266 /* Rotate the rows of PS such that insns scheduled at time
3267    START_CYCLE will appear in row 0.  Updates max/min_cycles.  */
3268 void
3269 rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
3270 {
3271   int i, row, backward_rotates;
3272   int last_row = ps->ii - 1;
3273
3274   if (start_cycle == 0)
3275     return;
3276
3277   backward_rotates = SMODULO (start_cycle, ps->ii);
3278
3279   /* Revisit later and optimize this into a single loop.  */
3280   for (i = 0; i < backward_rotates; i++)
3281     {
3282       ps_insn_ptr first_row = ps->rows[0];
3283       int first_row_length = ps->rows_length[0];
3284
3285       for (row = 0; row < last_row; row++)
3286         {
3287           ps->rows[row] = ps->rows[row + 1];
3288           ps->rows_length[row] = ps->rows_length[row + 1]; 
3289         }
3290
3291       ps->rows[last_row] = first_row;
3292       ps->rows_length[last_row] = first_row_length;
3293     }
3294
3295   ps->max_cycle -= start_cycle;
3296   ps->min_cycle -= start_cycle;
3297 }
3298
3299 #endif /* INSN_SCHEDULING */
3300 \f
3301 static bool
3302 gate_handle_sms (void)
3303 {
3304   return (optimize > 0 && flag_modulo_sched);
3305 }
3306
3307
3308 /* Run instruction scheduler.  */
3309 /* Perform SMS module scheduling.  */
3310 static unsigned int
3311 rest_of_handle_sms (void)
3312 {
3313 #ifdef INSN_SCHEDULING
3314   basic_block bb;
3315
3316   /* Collect loop information to be used in SMS.  */
3317   cfg_layout_initialize (0);
3318   sms_schedule ();
3319
3320   /* Update the life information, because we add pseudos.  */
3321   max_regno = max_reg_num ();
3322
3323   /* Finalize layout changes.  */
3324   FOR_EACH_BB (bb)
3325     if (bb->next_bb != EXIT_BLOCK_PTR)
3326       bb->aux = bb->next_bb;
3327   free_dominance_info (CDI_DOMINATORS);
3328   cfg_layout_finalize ();
3329 #endif /* INSN_SCHEDULING */
3330   return 0;
3331 }
3332
3333 struct rtl_opt_pass pass_sms =
3334 {
3335  {
3336   RTL_PASS,
3337   "sms",                                /* name */
3338   gate_handle_sms,                      /* gate */
3339   rest_of_handle_sms,                   /* execute */
3340   NULL,                                 /* sub */
3341   NULL,                                 /* next */
3342   0,                                    /* static_pass_number */
3343   TV_SMS,                               /* tv_id */
3344   0,                                    /* properties_required */
3345   0,                                    /* properties_provided */
3346   0,                                    /* properties_destroyed */
3347   0,                                    /* todo_flags_start */
3348   TODO_df_finish
3349     | TODO_verify_flow
3350     | TODO_verify_rtl_sharing
3351     | TODO_ggc_collect                  /* todo_flags_finish */
3352  }
3353 };