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