OSDN Git Service

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