diff options
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.patch | 640 |
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 7885b7af49..0000000000 --- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106747.patch +++ /dev/null | |||
@@ -1,640 +0,0 @@ | |||
1 | 2011-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 | |||