summaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch640
1 files changed, 0 insertions, 640 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch
deleted file mode 100644
index 7885b7af4..000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch
+++ /dev/null
@@ -1,640 +0,0 @@
12011-05-13 Revital Eres <revital.eres@linaro.org>
2
3 gcc/
4 * loop-doloop.c (doloop_condition_get): Support new form of
5 doloop pattern and use prev_nondebug_insn instead of PREV_INSN.
6 * config/arm/thumb2.md (*thumb2_addsi3_compare0): Remove "*".
7 (doloop_end): New.
8 * config/arm/arm.md (*addsi3_compare0): Remove "*".
9 * params.def (sms-min-sc): New param flag.
10 * doc/invoke.texi (sms-min-sc): Document it.
11 * ddg.c (create_ddg_dep_from_intra_loop_link): If a true dep edge
12 enters the branch create an anti edge in the opposite direction
13 to prevent the creation of reg-moves.
14 * modulo-sched.c: Adjust comment to reflect the fact we are
15 scheduling closing branch.
16 (PS_STAGE_COUNT): Rename to CALC_STAGE_COUNT and redefine.
17 (stage_count): New field in struct partial_schedule.
18 (calculate_stage_count): New function.
19 (normalize_sched_times): Rename to reset_sched_times and handle
20 incrementing the sched time of the nodes by a constant value
21 passed as parameter.
22 (duplicate_insns_of_cycles): Skip closing branch.
23 (sms_schedule_by_order): Schedule closing branch.
24 (ps_insn_find_column): Handle closing branch.
25 (sms_schedule): Call reset_sched_times and adjust the code to
26 support scheduling of the closing branch. Use sms-min-sc.
27 Support new form of doloop pattern.
28 (ps_insert_empty_row): Update calls to normalize_sched_times
29 and rotate_partial_schedule functions.
30
31=== modified file 'gcc/config/arm/arm.md'
32--- old/gcc/config/arm/arm.md 2011-05-06 11:28:27 +0000
33+++ new/gcc/config/arm/arm.md 2011-05-13 13:42:39 +0000
34@@ -791,7 +791,7 @@
35 ""
36 )
37
38-(define_insn "*addsi3_compare0"
39+(define_insn "addsi3_compare0"
40 [(set (reg:CC_NOOV CC_REGNUM)
41 (compare:CC_NOOV
42 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
43
44=== modified file 'gcc/config/arm/thumb2.md'
45--- old/gcc/config/arm/thumb2.md 2011-01-03 20:52:22 +0000
46+++ new/gcc/config/arm/thumb2.md 2011-05-11 07:15:47 +0000
47@@ -836,7 +836,7 @@
48 "operands[4] = GEN_INT (- INTVAL (operands[2]));"
49 )
50
51-(define_insn "*thumb2_addsi3_compare0"
52+(define_insn "thumb2_addsi3_compare0"
53 [(set (reg:CC_NOOV CC_REGNUM)
54 (compare:CC_NOOV
55 (plus:SI (match_operand:SI 1 "s_register_operand" "l, 0, r")
56@@ -1118,3 +1118,54 @@
57 "
58 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
59 ")
60+
61+;; Define the subtract-one-and-jump insns so loop.c
62+;; knows what to generate.
63+(define_expand "doloop_end"
64+ [(use (match_operand 0 "" "")) ; loop pseudo
65+ (use (match_operand 1 "" "")) ; iterations; zero if unknown
66+ (use (match_operand 2 "" "")) ; max iterations
67+ (use (match_operand 3 "" "")) ; loop level
68+ (use (match_operand 4 "" ""))] ; label
69+ "TARGET_32BIT"
70+ "
71+ {
72+ /* Currently SMS relies on the do-loop pattern to recognize loops
73+ where (1) the control part consists of all insns defining and/or
74+ using a certain 'count' register and (2) the loop count can be
75+ adjusted by modifying this register prior to the loop.
76+ ??? The possible introduction of a new block to initialize the
77+ new IV can potentially affect branch optimizations. */
78+ if (optimize > 0 && flag_modulo_sched)
79+ {
80+ rtx s0;
81+ rtx bcomp;
82+ rtx loc_ref;
83+ rtx cc_reg;
84+ rtx insn;
85+ rtx cmp;
86+
87+ /* Only use this on innermost loops. */
88+ if (INTVAL (operands[3]) > 1)
89+ FAIL;
90+ if (GET_MODE (operands[0]) != SImode)
91+ FAIL;
92+
93+ s0 = operands [0];
94+ if (TARGET_THUMB2)
95+ insn = emit_insn (gen_thumb2_addsi3_compare0 (s0, s0, GEN_INT (-1)));
96+ else
97+ insn = emit_insn (gen_addsi3_compare0 (s0, s0, GEN_INT (-1)));
98+
99+ cmp = XVECEXP (PATTERN (insn), 0, 0);
100+ cc_reg = SET_DEST (cmp);
101+ bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
102+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
103+ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
104+ gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
105+ loc_ref, pc_rtx)));
106+ DONE;
107+ }else
108+ FAIL;
109+}")
110+
111
112=== modified file 'gcc/ddg.c'
113--- old/gcc/ddg.c 2010-11-30 11:41:24 +0000
114+++ new/gcc/ddg.c 2011-05-11 07:15:47 +0000
115@@ -197,6 +197,11 @@
116 }
117 }
118
119+ /* If a true dep edge enters the branch create an anti edge in the
120+ opposite direction to prevent the creation of reg-moves. */
121+ if ((DEP_TYPE (link) == REG_DEP_TRUE) && JUMP_P (dest_node->insn))
122+ create_ddg_dep_no_link (g, dest_node, src_node, ANTI_DEP, REG_DEP, 1);
123+
124 latency = dep_cost (link);
125 e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
126 add_edge_to_ddg (g, e);
127
128=== modified file 'gcc/doc/invoke.texi'
129--- old/gcc/doc/invoke.texi 2011-04-18 11:31:29 +0000
130+++ new/gcc/doc/invoke.texi 2011-05-11 07:15:47 +0000
131@@ -8730,6 +8730,10 @@
132 The maximum number of best instructions in the ready list that are considered
133 for renaming in the selective scheduler. The default value is 2.
134
135+@item sms-min-sc
136+The minimum value of stage count that swing modulo scheduler will
137+generate. The default value is 2.
138+
139 @item max-last-value-rtl
140 The maximum size measured as number of RTLs that can be recorded in an expression
141 in combiner for a pseudo register as last known value of that register. The default
142
143=== modified file 'gcc/loop-doloop.c'
144--- old/gcc/loop-doloop.c 2010-11-30 11:41:24 +0000
145+++ new/gcc/loop-doloop.c 2011-05-11 07:15:47 +0000
146@@ -78,6 +78,8 @@
147 rtx inc_src;
148 rtx condition;
149 rtx pattern;
150+ rtx cc_reg = NULL_RTX;
151+ rtx reg_orig = NULL_RTX;
152
153 /* The canonical doloop pattern we expect has one of the following
154 forms:
155@@ -96,7 +98,16 @@
156 2) (set (reg) (plus (reg) (const_int -1))
157 (set (pc) (if_then_else (reg != 0)
158 (label_ref (label))
159- (pc))). */
160+ (pc))).
161+
162+ Some targets (ARM) do the comparison before the branch, as in the
163+ following form:
164+
165+ 3) (parallel [(set (cc) (compare ((plus (reg) (const_int -1), 0)))
166+ (set (reg) (plus (reg) (const_int -1)))])
167+ (set (pc) (if_then_else (cc == NE)
168+ (label_ref (label))
169+ (pc))) */
170
171 pattern = PATTERN (doloop_pat);
172
173@@ -104,19 +115,47 @@
174 {
175 rtx cond;
176 rtx prev_insn = prev_nondebug_insn (doloop_pat);
177+ rtx cmp_arg1, cmp_arg2;
178+ rtx cmp_orig;
179
180- /* We expect the decrement to immediately precede the branch. */
181+ /* In case the pattern is not PARALLEL we expect two forms
182+ of doloop which are cases 2) and 3) above: in case 2) the
183+ decrement immediately precedes the branch, while in case 3)
184+ the compare and decrement instructions immediately precede
185+ the branch. */
186
187 if (prev_insn == NULL_RTX || !INSN_P (prev_insn))
188 return 0;
189
190 cmp = pattern;
191- inc = PATTERN (PREV_INSN (doloop_pat));
192+ if (GET_CODE (PATTERN (prev_insn)) == PARALLEL)
193+ {
194+ /* The third case: the compare and decrement instructions
195+ immediately precede the branch. */
196+ cmp_orig = XVECEXP (PATTERN (prev_insn), 0, 0);
197+ if (GET_CODE (cmp_orig) != SET)
198+ return 0;
199+ if (GET_CODE (SET_SRC (cmp_orig)) != COMPARE)
200+ return 0;
201+ cmp_arg1 = XEXP (SET_SRC (cmp_orig), 0);
202+ cmp_arg2 = XEXP (SET_SRC (cmp_orig), 1);
203+ if (cmp_arg2 != const0_rtx
204+ || GET_CODE (cmp_arg1) != PLUS)
205+ return 0;
206+ reg_orig = XEXP (cmp_arg1, 0);
207+ if (XEXP (cmp_arg1, 1) != GEN_INT (-1)
208+ || !REG_P (reg_orig))
209+ return 0;
210+ cc_reg = SET_DEST (cmp_orig);
211+
212+ inc = XVECEXP (PATTERN (prev_insn), 0, 1);
213+ }
214+ else
215+ inc = PATTERN (prev_insn);
216 /* We expect the condition to be of the form (reg != 0) */
217 cond = XEXP (SET_SRC (cmp), 0);
218 if (GET_CODE (cond) != NE || XEXP (cond, 1) != const0_rtx)
219 return 0;
220-
221 }
222 else
223 {
224@@ -162,11 +201,15 @@
225 return 0;
226
227 if ((XEXP (condition, 0) == reg)
228+ /* For the third case: */
229+ || ((cc_reg != NULL_RTX)
230+ && (XEXP (condition, 0) == cc_reg)
231+ && (reg_orig == reg))
232 || (GET_CODE (XEXP (condition, 0)) == PLUS
233- && XEXP (XEXP (condition, 0), 0) == reg))
234+ && XEXP (XEXP (condition, 0), 0) == reg))
235 {
236 if (GET_CODE (pattern) != PARALLEL)
237- /* The second form we expect:
238+ /* For the second form we expect:
239
240 (set (reg) (plus (reg) (const_int -1))
241 (set (pc) (if_then_else (reg != 0)
242@@ -181,7 +224,24 @@
243 (set (reg) (plus (reg) (const_int -1)))
244 (additional clobbers and uses)])
245
246- So we return that form instead.
247+ For the third form we expect:
248+
249+ (parallel [(set (cc) (compare ((plus (reg) (const_int -1)), 0))
250+ (set (reg) (plus (reg) (const_int -1)))])
251+ (set (pc) (if_then_else (cc == NE)
252+ (label_ref (label))
253+ (pc)))
254+
255+ which is equivalent to the following:
256+
257+ (parallel [(set (cc) (compare (reg, 1))
258+ (set (reg) (plus (reg) (const_int -1)))
259+ (set (pc) (if_then_else (NE == cc)
260+ (label_ref (label))
261+ (pc))))])
262+
263+ So we return the second form instead for the two cases.
264+
265 */
266 condition = gen_rtx_fmt_ee (NE, VOIDmode, inc_src, const1_rtx);
267
268
269=== modified file 'gcc/modulo-sched.c'
270--- old/gcc/modulo-sched.c 2011-02-14 17:59:10 +0000
271+++ new/gcc/modulo-sched.c 2011-05-11 07:15:47 +0000
272@@ -84,14 +84,13 @@
273 II cycles (i.e. use register copies to prevent a def from overwriting
274 itself before reaching the use).
275
276- SMS works with countable loops (1) whose control part can be easily
277- decoupled from the rest of the loop and (2) whose loop count can
278- be easily adjusted. This is because we peel a constant number of
279- iterations into a prologue and epilogue for which we want to avoid
280- emitting the control part, and a kernel which is to iterate that
281- constant number of iterations less than the original loop. So the
282- control part should be a set of insns clearly identified and having
283- its own iv, not otherwise used in the loop (at-least for now), which
284+ SMS works with countable loops whose loop count can be easily
285+ adjusted. This is because we peel a constant number of iterations
286+ into a prologue and epilogue for which we want to avoid emitting
287+ the control part, and a kernel which is to iterate that constant
288+ number of iterations less than the original loop. So the control
289+ part should be a set of insns clearly identified and having its
290+ own iv, not otherwise used in the loop (at-least for now), which
291 initializes a register before the loop to the number of iterations.
292 Currently SMS relies on the do-loop pattern to recognize such loops,
293 where (1) the control part comprises of all insns defining and/or
294@@ -116,8 +115,10 @@
295
296 /* The number of different iterations the nodes in ps span, assuming
297 the stage boundaries are placed efficiently. */
298-#define PS_STAGE_COUNT(ps) ((PS_MAX_CYCLE (ps) - PS_MIN_CYCLE (ps) \
299- + 1 + (ps)->ii - 1) / (ps)->ii)
300+#define CALC_STAGE_COUNT(max_cycle,min_cycle,ii) ((max_cycle - min_cycle \
301+ + 1 + ii - 1) / ii)
302+/* The stage count of ps. */
303+#define PS_STAGE_COUNT(ps) (((partial_schedule_ptr)(ps))->stage_count)
304
305 /* A single instruction in the partial schedule. */
306 struct ps_insn
307@@ -155,6 +156,8 @@
308 int max_cycle;
309
310 ddg_ptr g; /* The DDG of the insns in the partial schedule. */
311+
312+ int stage_count; /* The stage count of the partial schedule. */
313 };
314
315 /* We use this to record all the register replacements we do in
316@@ -195,7 +198,7 @@
317 rtx, rtx);
318 static void duplicate_insns_of_cycles (partial_schedule_ptr,
319 int, int, int, rtx);
320-
321+static int calculate_stage_count (partial_schedule_ptr ps);
322 #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
323 #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
324 #define SCHED_FIRST_REG_MOVE(x) \
325@@ -310,10 +313,10 @@
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_INSN (tail));
330+ : prev_nondebug_insn (tail));
331
332 for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
333- if (reg_mentioned_p (reg, insn))
334+ if (reg_mentioned_p (reg, insn) && !DEBUG_INSN_P (insn))
335 {
336 if (dump_file)
337 {
338@@ -569,13 +572,12 @@
339 }
340 }
341
342-/* Bump the SCHED_TIMEs of all nodes to start from zero. Set the values
343- of SCHED_ROW and SCHED_STAGE. */
344+/* Bump the SCHED_TIMEs of all nodes by AMOUNT. Set the values of
345+ SCHED_ROW and SCHED_STAGE. */
346 static void
347-normalize_sched_times (partial_schedule_ptr ps)
348+reset_sched_times (partial_schedule_ptr ps, int amount)
349 {
350 int row;
351- int amount = PS_MIN_CYCLE (ps);
352 int ii = ps->ii;
353 ps_insn_ptr crr_insn;
354
355@@ -584,19 +586,43 @@
356 {
357 ddg_node_ptr u = crr_insn->node;
358 int normalized_time = SCHED_TIME (u) - amount;
359+ int new_min_cycle = PS_MIN_CYCLE (ps) - amount;
360+ int sc_until_cycle_zero, stage;
361
362- if (dump_file)
363- fprintf (dump_file, "crr_insn->node=%d, crr_insn->cycle=%d,\
364- min_cycle=%d\n", crr_insn->node->cuid, SCHED_TIME
365- (u), ps->min_cycle);
366+ if (dump_file)
367+ {
368+ /* Print the scheduling times after the rotation. */
369+ fprintf (dump_file, "crr_insn->node=%d (insn id %d), "
370+ "crr_insn->cycle=%d, min_cycle=%d", crr_insn->node->cuid,
371+ INSN_UID (crr_insn->node->insn), SCHED_TIME (u),
372+ normalized_time);
373+ if (JUMP_P (crr_insn->node->insn))
374+ fprintf (dump_file, " (branch)");
375+ fprintf (dump_file, "\n");
376+ }
377+
378 gcc_assert (SCHED_TIME (u) >= ps->min_cycle);
379 gcc_assert (SCHED_TIME (u) <= ps->max_cycle);
380 SCHED_TIME (u) = normalized_time;
381- SCHED_ROW (u) = normalized_time % ii;
382- SCHED_STAGE (u) = normalized_time / ii;
383+ SCHED_ROW (u) = SMODULO (normalized_time, ii);
384+
385+ /* The calculation of stage count is done adding the number
386+ of stages before cycle zero and after cycle zero. */
387+ sc_until_cycle_zero = CALC_STAGE_COUNT (-1, new_min_cycle, ii);
388+
389+ if (SCHED_TIME (u) < 0)
390+ {
391+ stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii);
392+ SCHED_STAGE (u) = sc_until_cycle_zero - stage;
393+ }
394+ else
395+ {
396+ stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii);
397+ SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1;
398+ }
399 }
400 }
401-
402+
403 /* Set SCHED_COLUMN of each node according to its position in PS. */
404 static void
405 set_columns_for_ps (partial_schedule_ptr ps)
406@@ -646,9 +672,12 @@
407
408 /* Do not duplicate any insn which refers to count_reg as it
409 belongs to the control part.
410+ The closing branch is scheduled as well and thus should
411+ be ignored.
412 TODO: This should be done by analyzing the control part of
413 the loop. */
414- if (reg_mentioned_p (count_reg, u_node->insn))
415+ if (reg_mentioned_p (count_reg, u_node->insn)
416+ || JUMP_P (ps_ij->node->insn))
417 continue;
418
419 if (for_prolog)
420@@ -1009,9 +1038,11 @@
421 continue;
422 }
423
424- /* Don't handle BBs with calls or barriers, or !single_set insns,
425- or auto-increment insns (to avoid creating invalid reg-moves
426- for the auto-increment insns).
427+ /* Don't handle BBs with calls or barriers or auto-increment insns
428+ (to avoid creating invalid reg-moves for the auto-increment insns),
429+ or !single_set with the exception of instructions that include
430+ count_reg---these instructions are part of the control part
431+ that do-loop recognizes.
432 ??? Should handle auto-increment insns.
433 ??? Should handle insns defining subregs. */
434 for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
435@@ -1021,7 +1052,8 @@
436 if (CALL_P (insn)
437 || BARRIER_P (insn)
438 || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
439- && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE)
440+ && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE
441+ && !reg_mentioned_p (count_reg, insn))
442 || (FIND_REG_INC_NOTE (insn, NULL_RTX) != 0)
443 || (INSN_P (insn) && (set = single_set (insn))
444 && GET_CODE (SET_DEST (set)) == SUBREG))
445@@ -1049,7 +1081,11 @@
446 continue;
447 }
448
449- if (! (g = create_ddg (bb, 0)))
450+ /* Always schedule the closing branch with the rest of the
451+ instructions. The branch is rotated to be in row ii-1 at the
452+ end of the scheduling procedure to make sure it's the last
453+ instruction in the iteration. */
454+ if (! (g = create_ddg (bb, 1)))
455 {
456 if (dump_file)
457 fprintf (dump_file, "SMS create_ddg failed\n");
458@@ -1157,14 +1193,17 @@
459
460 ps = sms_schedule_by_order (g, mii, maxii, node_order);
461
462- if (ps){
463- stage_count = PS_STAGE_COUNT (ps);
464- gcc_assert(stage_count >= 1);
465- }
466+ if (ps)
467+ {
468+ stage_count = calculate_stage_count (ps);
469+ gcc_assert(stage_count >= 1);
470+ PS_STAGE_COUNT(ps) = stage_count;
471+ }
472
473- /* Stage count of 1 means that there is no interleaving between
474- iterations, let the scheduling passes do the job. */
475- if (stage_count <= 1
476+ /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of
477+ 1 means that there is no interleaving between iterations thus
478+ we let the scheduling passes do the job in this case. */
479+ if (stage_count < (unsigned) PARAM_VALUE (PARAM_SMS_MIN_SC)
480 || (count_init && (loop_count <= stage_count))
481 || (flag_branch_probabilities && (trip_count <= stage_count)))
482 {
483@@ -1182,32 +1221,24 @@
484 else
485 {
486 struct undo_replace_buff_elem *reg_move_replaces;
487-
488- if (dump_file)
489- {
490+ int amount = SCHED_TIME (g->closing_branch) + 1;
491+
492+ /* Set the stage boundaries. The closing_branch was scheduled
493+ and should appear in the last (ii-1) row. */
494+ reset_sched_times (ps, amount);
495+ rotate_partial_schedule (ps, amount);
496+ set_columns_for_ps (ps);
497+
498+ canon_loop (loop);
499+
500+ if (dump_file)
501+ {
502 fprintf (dump_file,
503 "SMS succeeded %d %d (with ii, sc)\n", ps->ii,
504 stage_count);
505 print_partial_schedule (ps, dump_file);
506- fprintf (dump_file,
507- "SMS Branch (%d) will later be scheduled at cycle %d.\n",
508- g->closing_branch->cuid, PS_MIN_CYCLE (ps) - 1);
509 }
510-
511- /* Set the stage boundaries. If the DDG is built with closing_branch_deps,
512- the closing_branch was scheduled and should appear in the last (ii-1)
513- row. Otherwise, we are free to schedule the branch, and we let nodes
514- that were scheduled at the first PS_MIN_CYCLE cycle appear in the first
515- row; this should reduce stage_count to minimum.
516- TODO: Revisit the issue of scheduling the insns of the
517- control part relative to the branch when the control part
518- has more than one insn. */
519- normalize_sched_times (ps);
520- rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
521- set_columns_for_ps (ps);
522-
523- canon_loop (loop);
524-
525+
526 /* case the BCT count is not known , Do loop-versioning */
527 if (count_reg && ! count_init)
528 {
529@@ -1760,12 +1791,6 @@
530 continue;
531 }
532
533- if (JUMP_P (insn)) /* Closing branch handled later. */
534- {
535- RESET_BIT (tobe_scheduled, u);
536- continue;
537- }
538-
539 if (TEST_BIT (sched_nodes, u))
540 continue;
541
542@@ -1893,8 +1918,8 @@
543 if (dump_file)
544 fprintf (dump_file, "split_row=%d\n", split_row);
545
546- normalize_sched_times (ps);
547- rotate_partial_schedule (ps, ps->min_cycle);
548+ reset_sched_times (ps, PS_MIN_CYCLE (ps));
549+ rotate_partial_schedule (ps, PS_MIN_CYCLE (ps));
550
551 rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr));
552 for (row = 0; row < split_row; row++)
553@@ -2571,6 +2596,7 @@
554 ps_insn_ptr next_ps_i;
555 ps_insn_ptr first_must_follow = NULL;
556 ps_insn_ptr last_must_precede = NULL;
557+ ps_insn_ptr last_in_row = NULL;
558 int row;
559
560 if (! ps_i)
561@@ -2597,8 +2623,37 @@
562 else
563 last_must_precede = next_ps_i;
564 }
565+ /* The closing branch must be the last in the row. */
566+ if (must_precede
567+ && TEST_BIT (must_precede, next_ps_i->node->cuid)
568+ && JUMP_P (next_ps_i->node->insn))
569+ return false;
570+
571+ last_in_row = next_ps_i;
572 }
573
574+ /* The closing branch is scheduled as well. Make sure there is no
575+ dependent instruction after it as the branch should be the last
576+ instruction in the row. */
577+ if (JUMP_P (ps_i->node->insn))
578+ {
579+ if (first_must_follow)
580+ return false;
581+ if (last_in_row)
582+ {
583+ /* Make the branch the last in the row. New instructions
584+ will be inserted at the beginning of the row or after the
585+ last must_precede instruction thus the branch is guaranteed
586+ to remain the last instruction in the row. */
587+ last_in_row->next_in_row = ps_i;
588+ ps_i->prev_in_row = last_in_row;
589+ ps_i->next_in_row = NULL;
590+ }
591+ else
592+ ps->rows[row] = ps_i;
593+ return true;
594+ }
595+
596 /* Now insert the node after INSERT_AFTER_PSI. */
597
598 if (! last_must_precede)
599@@ -2820,6 +2875,24 @@
600 return ps_i;
601 }
602
603+/* Calculate the stage count of the partial schedule PS. The calculation
604+ takes into account the rotation to bring the closing branch to row
605+ ii-1. */
606+int
607+calculate_stage_count (partial_schedule_ptr ps)
608+{
609+ int rotation_amount = (SCHED_TIME (ps->g->closing_branch)) + 1;
610+ int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount;
611+ int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount;
612+ int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii);
613+
614+ /* The calculation of stage count is done adding the number of stages
615+ before cycle zero and after cycle zero. */
616+ stage_count += CALC_STAGE_COUNT (new_max_cycle, 0, ps->ii);
617+
618+ return stage_count;
619+}
620+
621 /* Rotate the rows of PS such that insns scheduled at time
622 START_CYCLE will appear in row 0. Updates max/min_cycles. */
623 void
624
625=== modified file 'gcc/params.def'
626--- old/gcc/params.def 2011-04-18 11:31:29 +0000
627+++ new/gcc/params.def 2011-05-11 07:15:47 +0000
628@@ -344,6 +344,11 @@
629 "sms-max-ii-factor",
630 "A factor for tuning the upper bound that swing modulo scheduler uses for scheduling a loop",
631 100, 0, 0)
632+/* The minimum value of stage count that swing modulo scheduler will generate. */
633+DEFPARAM(PARAM_SMS_MIN_SC,
634+ "sms-min-sc",
635+ "The minimum value of stage count that swing modulo scheduler will generate.",
636+ 2, 1, 1)
637 DEFPARAM(PARAM_SMS_DFA_HISTORY,
638 "sms-dfa-history",
639 "The number of cycles the swing modulo scheduler considers when checking conflicts using DFA",
640