diff options
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch')
-rw-r--r-- | meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch new file mode 100644 index 0000000000..b82fe76d41 --- /dev/null +++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch | |||
@@ -0,0 +1,458 @@ | |||
1 | 2011-08-09 Revital Eres <revital.eres@linaro.org> | ||
2 | |||
3 | gcc/ | ||
4 | Backport from trunk -r177235. | ||
5 | * modulo-sched.c (calculate_stage_count, | ||
6 | calculate_must_precede_follow, get_sched_window, | ||
7 | try_scheduling_node_in_cycle, remove_node_from_ps): | ||
8 | Add declaration. | ||
9 | (update_node_sched_params, set_must_precede_follow, optimize_sc): | ||
10 | New functions. | ||
11 | (reset_sched_times): Call update_node_sched_params. | ||
12 | (sms_schedule): Call optimize_sc. | ||
13 | (get_sched_window): Change function arguments. | ||
14 | (sms_schedule_by_order): Update call to get_sched_window. | ||
15 | Call set_must_precede_follow. | ||
16 | (calculate_stage_count): Add function argument. | ||
17 | |||
18 | === modified file 'gcc/modulo-sched.c' | ||
19 | --- old/gcc/modulo-sched.c 2011-07-31 10:58:46 +0000 | ||
20 | +++ new/gcc/modulo-sched.c 2011-08-09 04:51:48 +0000 | ||
21 | @@ -203,7 +203,16 @@ | ||
22 | rtx, rtx); | ||
23 | static void duplicate_insns_of_cycles (partial_schedule_ptr, | ||
24 | int, int, int, rtx); | ||
25 | -static int calculate_stage_count (partial_schedule_ptr ps); | ||
26 | +static int calculate_stage_count (partial_schedule_ptr, int); | ||
27 | +static void calculate_must_precede_follow (ddg_node_ptr, int, int, | ||
28 | + int, int, sbitmap, sbitmap, sbitmap); | ||
29 | +static int get_sched_window (partial_schedule_ptr, ddg_node_ptr, | ||
30 | + sbitmap, int, int *, int *, int *); | ||
31 | +static bool try_scheduling_node_in_cycle (partial_schedule_ptr, ddg_node_ptr, | ||
32 | + int, int, sbitmap, int *, sbitmap, | ||
33 | + sbitmap); | ||
34 | +static bool remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr); | ||
35 | + | ||
36 | #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap) | ||
37 | #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time) | ||
38 | #define SCHED_FIRST_REG_MOVE(x) \ | ||
39 | @@ -577,6 +586,36 @@ | ||
40 | } | ||
41 | } | ||
42 | |||
43 | +/* Update the sched_params (time, row and stage) for node U using the II, | ||
44 | + the CYCLE of U and MIN_CYCLE. | ||
45 | + We're not simply taking the following | ||
46 | + SCHED_STAGE (u) = CALC_STAGE_COUNT (SCHED_TIME (u), min_cycle, ii); | ||
47 | + because the stages may not be aligned on cycle 0. */ | ||
48 | +static void | ||
49 | +update_node_sched_params (ddg_node_ptr u, int ii, int cycle, int min_cycle) | ||
50 | +{ | ||
51 | + int sc_until_cycle_zero; | ||
52 | + int stage; | ||
53 | + | ||
54 | + SCHED_TIME (u) = cycle; | ||
55 | + SCHED_ROW (u) = SMODULO (cycle, ii); | ||
56 | + | ||
57 | + /* The calculation of stage count is done adding the number | ||
58 | + of stages before cycle zero and after cycle zero. */ | ||
59 | + sc_until_cycle_zero = CALC_STAGE_COUNT (-1, min_cycle, ii); | ||
60 | + | ||
61 | + if (SCHED_TIME (u) < 0) | ||
62 | + { | ||
63 | + stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii); | ||
64 | + SCHED_STAGE (u) = sc_until_cycle_zero - stage; | ||
65 | + } | ||
66 | + else | ||
67 | + { | ||
68 | + stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii); | ||
69 | + SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1; | ||
70 | + } | ||
71 | +} | ||
72 | + | ||
73 | /* Bump the SCHED_TIMEs of all nodes by AMOUNT. Set the values of | ||
74 | SCHED_ROW and SCHED_STAGE. */ | ||
75 | static void | ||
76 | @@ -592,7 +631,6 @@ | ||
77 | ddg_node_ptr u = crr_insn->node; | ||
78 | int normalized_time = SCHED_TIME (u) - amount; | ||
79 | int new_min_cycle = PS_MIN_CYCLE (ps) - amount; | ||
80 | - int sc_until_cycle_zero, stage; | ||
81 | |||
82 | if (dump_file) | ||
83 | { | ||
84 | @@ -608,23 +646,9 @@ | ||
85 | |||
86 | gcc_assert (SCHED_TIME (u) >= ps->min_cycle); | ||
87 | gcc_assert (SCHED_TIME (u) <= ps->max_cycle); | ||
88 | - SCHED_TIME (u) = normalized_time; | ||
89 | - SCHED_ROW (u) = SMODULO (normalized_time, ii); | ||
90 | - | ||
91 | - /* The calculation of stage count is done adding the number | ||
92 | - of stages before cycle zero and after cycle zero. */ | ||
93 | - sc_until_cycle_zero = CALC_STAGE_COUNT (-1, new_min_cycle, ii); | ||
94 | - | ||
95 | - if (SCHED_TIME (u) < 0) | ||
96 | - { | ||
97 | - stage = CALC_STAGE_COUNT (-1, SCHED_TIME (u), ii); | ||
98 | - SCHED_STAGE (u) = sc_until_cycle_zero - stage; | ||
99 | - } | ||
100 | - else | ||
101 | - { | ||
102 | - stage = CALC_STAGE_COUNT (SCHED_TIME (u), 0, ii); | ||
103 | - SCHED_STAGE (u) = sc_until_cycle_zero + stage - 1; | ||
104 | - } | ||
105 | + | ||
106 | + crr_insn->cycle = normalized_time; | ||
107 | + update_node_sched_params (u, ii, normalized_time, new_min_cycle); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | @@ -661,6 +685,206 @@ | ||
112 | PREV_INSN (last)); | ||
113 | } | ||
114 | |||
115 | +/* Set bitmaps TMP_FOLLOW and TMP_PRECEDE to MUST_FOLLOW and MUST_PRECEDE | ||
116 | + respectively only if cycle C falls on the border of the scheduling | ||
117 | + window boundaries marked by START and END cycles. STEP is the | ||
118 | + direction of the window. */ | ||
119 | +static inline void | ||
120 | +set_must_precede_follow (sbitmap *tmp_follow, sbitmap must_follow, | ||
121 | + sbitmap *tmp_precede, sbitmap must_precede, int c, | ||
122 | + int start, int end, int step) | ||
123 | +{ | ||
124 | + *tmp_precede = NULL; | ||
125 | + *tmp_follow = NULL; | ||
126 | + | ||
127 | + if (c == start) | ||
128 | + { | ||
129 | + if (step == 1) | ||
130 | + *tmp_precede = must_precede; | ||
131 | + else /* step == -1. */ | ||
132 | + *tmp_follow = must_follow; | ||
133 | + } | ||
134 | + if (c == end - step) | ||
135 | + { | ||
136 | + if (step == 1) | ||
137 | + *tmp_follow = must_follow; | ||
138 | + else /* step == -1. */ | ||
139 | + *tmp_precede = must_precede; | ||
140 | + } | ||
141 | + | ||
142 | +} | ||
143 | + | ||
144 | +/* Return True if the branch can be moved to row ii-1 while | ||
145 | + normalizing the partial schedule PS to start from cycle zero and thus | ||
146 | + optimize the SC. Otherwise return False. */ | ||
147 | +static bool | ||
148 | +optimize_sc (partial_schedule_ptr ps, ddg_ptr g) | ||
149 | +{ | ||
150 | + int amount = PS_MIN_CYCLE (ps); | ||
151 | + sbitmap sched_nodes = sbitmap_alloc (g->num_nodes); | ||
152 | + int start, end, step; | ||
153 | + int ii = ps->ii; | ||
154 | + bool ok = false; | ||
155 | + int stage_count, stage_count_curr; | ||
156 | + | ||
157 | + /* Compare the SC after normalization and SC after bringing the branch | ||
158 | + to row ii-1. If they are equal just bail out. */ | ||
159 | + stage_count = calculate_stage_count (ps, amount); | ||
160 | + stage_count_curr = | ||
161 | + calculate_stage_count (ps, SCHED_TIME (g->closing_branch) - (ii - 1)); | ||
162 | + | ||
163 | + if (stage_count == stage_count_curr) | ||
164 | + { | ||
165 | + if (dump_file) | ||
166 | + fprintf (dump_file, "SMS SC already optimized.\n"); | ||
167 | + | ||
168 | + ok = false; | ||
169 | + goto clear; | ||
170 | + } | ||
171 | + | ||
172 | + if (dump_file) | ||
173 | + { | ||
174 | + fprintf (dump_file, "SMS Trying to optimize branch location\n"); | ||
175 | + fprintf (dump_file, "SMS partial schedule before trial:\n"); | ||
176 | + print_partial_schedule (ps, dump_file); | ||
177 | + } | ||
178 | + | ||
179 | + /* First, normalize the partial scheduling. */ | ||
180 | + reset_sched_times (ps, amount); | ||
181 | + rotate_partial_schedule (ps, amount); | ||
182 | + if (dump_file) | ||
183 | + { | ||
184 | + fprintf (dump_file, | ||
185 | + "SMS partial schedule after normalization (ii, %d, SC %d):\n", | ||
186 | + ii, stage_count); | ||
187 | + print_partial_schedule (ps, dump_file); | ||
188 | + } | ||
189 | + | ||
190 | + if (SMODULO (SCHED_TIME (g->closing_branch), ii) == ii - 1) | ||
191 | + { | ||
192 | + ok = true; | ||
193 | + goto clear; | ||
194 | + } | ||
195 | + | ||
196 | + sbitmap_ones (sched_nodes); | ||
197 | + | ||
198 | + /* Calculate the new placement of the branch. It should be in row | ||
199 | + ii-1 and fall into it's scheduling window. */ | ||
200 | + if (get_sched_window (ps, g->closing_branch, sched_nodes, ii, &start, | ||
201 | + &step, &end) == 0) | ||
202 | + { | ||
203 | + bool success; | ||
204 | + ps_insn_ptr next_ps_i; | ||
205 | + int branch_cycle = SCHED_TIME (g->closing_branch); | ||
206 | + int row = SMODULO (branch_cycle, ps->ii); | ||
207 | + int num_splits = 0; | ||
208 | + sbitmap must_precede, must_follow, tmp_precede, tmp_follow; | ||
209 | + int c; | ||
210 | + | ||
211 | + if (dump_file) | ||
212 | + fprintf (dump_file, "\nTrying to schedule node %d " | ||
213 | + "INSN = %d in (%d .. %d) step %d\n", | ||
214 | + g->closing_branch->cuid, | ||
215 | + (INSN_UID (g->closing_branch->insn)), start, end, step); | ||
216 | + | ||
217 | + gcc_assert ((step > 0 && start < end) || (step < 0 && start > end)); | ||
218 | + if (step == 1) | ||
219 | + { | ||
220 | + c = start + ii - SMODULO (start, ii) - 1; | ||
221 | + gcc_assert (c >= start); | ||
222 | + if (c >= end) | ||
223 | + { | ||
224 | + ok = false; | ||
225 | + if (dump_file) | ||
226 | + fprintf (dump_file, | ||
227 | + "SMS failed to schedule branch at cycle: %d\n", c); | ||
228 | + goto clear; | ||
229 | + } | ||
230 | + } | ||
231 | + else | ||
232 | + { | ||
233 | + c = start - SMODULO (start, ii) - 1; | ||
234 | + gcc_assert (c <= start); | ||
235 | + | ||
236 | + if (c <= end) | ||
237 | + { | ||
238 | + if (dump_file) | ||
239 | + fprintf (dump_file, | ||
240 | + "SMS failed to schedule branch at cycle: %d\n", c); | ||
241 | + ok = false; | ||
242 | + goto clear; | ||
243 | + } | ||
244 | + } | ||
245 | + | ||
246 | + must_precede = sbitmap_alloc (g->num_nodes); | ||
247 | + must_follow = sbitmap_alloc (g->num_nodes); | ||
248 | + | ||
249 | + /* Try to schedule the branch is it's new cycle. */ | ||
250 | + calculate_must_precede_follow (g->closing_branch, start, end, | ||
251 | + step, ii, sched_nodes, | ||
252 | + must_precede, must_follow); | ||
253 | + | ||
254 | + set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede, | ||
255 | + must_precede, c, start, end, step); | ||
256 | + | ||
257 | + /* Find the element in the partial schedule related to the closing | ||
258 | + branch so we can remove it from it's current cycle. */ | ||
259 | + for (next_ps_i = ps->rows[row]; | ||
260 | + next_ps_i; next_ps_i = next_ps_i->next_in_row) | ||
261 | + if (next_ps_i->node->cuid == g->closing_branch->cuid) | ||
262 | + break; | ||
263 | + | ||
264 | + gcc_assert (next_ps_i); | ||
265 | + gcc_assert (remove_node_from_ps (ps, next_ps_i)); | ||
266 | + success = | ||
267 | + try_scheduling_node_in_cycle (ps, g->closing_branch, | ||
268 | + g->closing_branch->cuid, c, | ||
269 | + sched_nodes, &num_splits, | ||
270 | + tmp_precede, tmp_follow); | ||
271 | + gcc_assert (num_splits == 0); | ||
272 | + if (!success) | ||
273 | + { | ||
274 | + if (dump_file) | ||
275 | + fprintf (dump_file, | ||
276 | + "SMS failed to schedule branch at cycle: %d, " | ||
277 | + "bringing it back to cycle %d\n", c, branch_cycle); | ||
278 | + | ||
279 | + /* The branch was failed to be placed in row ii - 1. | ||
280 | + Put it back in it's original place in the partial | ||
281 | + schedualing. */ | ||
282 | + set_must_precede_follow (&tmp_follow, must_follow, &tmp_precede, | ||
283 | + must_precede, branch_cycle, start, end, | ||
284 | + step); | ||
285 | + success = | ||
286 | + try_scheduling_node_in_cycle (ps, g->closing_branch, | ||
287 | + g->closing_branch->cuid, | ||
288 | + branch_cycle, sched_nodes, | ||
289 | + &num_splits, tmp_precede, | ||
290 | + tmp_follow); | ||
291 | + gcc_assert (success && (num_splits == 0)); | ||
292 | + ok = false; | ||
293 | + } | ||
294 | + else | ||
295 | + { | ||
296 | + /* The branch is placed in row ii - 1. */ | ||
297 | + if (dump_file) | ||
298 | + fprintf (dump_file, | ||
299 | + "SMS success in moving branch to cycle %d\n", c); | ||
300 | + | ||
301 | + update_node_sched_params (g->closing_branch, ii, c, | ||
302 | + PS_MIN_CYCLE (ps)); | ||
303 | + ok = true; | ||
304 | + } | ||
305 | + | ||
306 | + free (must_precede); | ||
307 | + free (must_follow); | ||
308 | + } | ||
309 | + | ||
310 | +clear: | ||
311 | + free (sched_nodes); | ||
312 | + return ok; | ||
313 | +} | ||
314 | + | ||
315 | static void | ||
316 | duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage, | ||
317 | int to_stage, int for_prolog, rtx count_reg) | ||
318 | @@ -1116,6 +1340,7 @@ | ||
319 | int mii, rec_mii; | ||
320 | unsigned stage_count = 0; | ||
321 | HOST_WIDEST_INT loop_count = 0; | ||
322 | + bool opt_sc_p = false; | ||
323 | |||
324 | if (! (g = g_arr[loop->num])) | ||
325 | continue; | ||
326 | @@ -1197,14 +1422,32 @@ | ||
327 | set_node_sched_params (g); | ||
328 | |||
329 | ps = sms_schedule_by_order (g, mii, maxii, node_order); | ||
330 | - | ||
331 | - if (ps) | ||
332 | - { | ||
333 | - stage_count = calculate_stage_count (ps); | ||
334 | - gcc_assert(stage_count >= 1); | ||
335 | - PS_STAGE_COUNT(ps) = stage_count; | ||
336 | - } | ||
337 | - | ||
338 | + | ||
339 | + if (ps) | ||
340 | + { | ||
341 | + /* Try to achieve optimized SC by normalizing the partial | ||
342 | + schedule (having the cycles start from cycle zero). | ||
343 | + The branch location must be placed in row ii-1 in the | ||
344 | + final scheduling. If failed, shift all instructions to | ||
345 | + position the branch in row ii-1. */ | ||
346 | + opt_sc_p = optimize_sc (ps, g); | ||
347 | + if (opt_sc_p) | ||
348 | + stage_count = calculate_stage_count (ps, 0); | ||
349 | + else | ||
350 | + { | ||
351 | + /* Bring the branch to cycle ii-1. */ | ||
352 | + int amount = SCHED_TIME (g->closing_branch) - (ps->ii - 1); | ||
353 | + | ||
354 | + if (dump_file) | ||
355 | + fprintf (dump_file, "SMS schedule branch at cycle ii-1\n"); | ||
356 | + | ||
357 | + stage_count = calculate_stage_count (ps, amount); | ||
358 | + } | ||
359 | + | ||
360 | + gcc_assert (stage_count >= 1); | ||
361 | + PS_STAGE_COUNT (ps) = stage_count; | ||
362 | + } | ||
363 | + | ||
364 | /* The default value of PARAM_SMS_MIN_SC is 2 as stage count of | ||
365 | 1 means that there is no interleaving between iterations thus | ||
366 | we let the scheduling passes do the job in this case. */ | ||
367 | @@ -1225,12 +1468,16 @@ | ||
368 | else | ||
369 | { | ||
370 | struct undo_replace_buff_elem *reg_move_replaces; | ||
371 | - int amount = SCHED_TIME (g->closing_branch) + 1; | ||
372 | + | ||
373 | + if (!opt_sc_p) | ||
374 | + { | ||
375 | + /* Rotate the partial schedule to have the branch in row ii-1. */ | ||
376 | + int amount = SCHED_TIME (g->closing_branch) - (ps->ii - 1); | ||
377 | + | ||
378 | + reset_sched_times (ps, amount); | ||
379 | + rotate_partial_schedule (ps, amount); | ||
380 | + } | ||
381 | |||
382 | - /* Set the stage boundaries. The closing_branch was scheduled | ||
383 | - and should appear in the last (ii-1) row. */ | ||
384 | - reset_sched_times (ps, amount); | ||
385 | - rotate_partial_schedule (ps, amount); | ||
386 | set_columns_for_ps (ps); | ||
387 | |||
388 | canon_loop (loop); | ||
389 | @@ -1382,13 +1629,11 @@ | ||
390 | scheduling window is empty and zero otherwise. */ | ||
391 | |||
392 | static int | ||
393 | -get_sched_window (partial_schedule_ptr ps, int *nodes_order, int i, | ||
394 | +get_sched_window (partial_schedule_ptr ps, ddg_node_ptr u_node, | ||
395 | sbitmap sched_nodes, int ii, int *start_p, int *step_p, int *end_p) | ||
396 | { | ||
397 | int start, step, end; | ||
398 | ddg_edge_ptr e; | ||
399 | - int u = nodes_order [i]; | ||
400 | - ddg_node_ptr u_node = &ps->g->nodes[u]; | ||
401 | sbitmap psp = sbitmap_alloc (ps->g->num_nodes); | ||
402 | sbitmap pss = sbitmap_alloc (ps->g->num_nodes); | ||
403 | sbitmap u_node_preds = NODE_PREDECESSORS (u_node); | ||
404 | @@ -1800,7 +2045,7 @@ | ||
405 | |||
406 | /* Try to get non-empty scheduling window. */ | ||
407 | success = 0; | ||
408 | - if (get_sched_window (ps, nodes_order, i, sched_nodes, ii, &start, | ||
409 | + if (get_sched_window (ps, u_node, sched_nodes, ii, &start, | ||
410 | &step, &end) == 0) | ||
411 | { | ||
412 | if (dump_file) | ||
413 | @@ -1817,24 +2062,11 @@ | ||
414 | |||
415 | for (c = start; c != end; c += step) | ||
416 | { | ||
417 | - sbitmap tmp_precede = NULL; | ||
418 | - sbitmap tmp_follow = NULL; | ||
419 | - | ||
420 | - if (c == start) | ||
421 | - { | ||
422 | - if (step == 1) | ||
423 | - tmp_precede = must_precede; | ||
424 | - else /* step == -1. */ | ||
425 | - tmp_follow = must_follow; | ||
426 | - } | ||
427 | - if (c == end - step) | ||
428 | - { | ||
429 | - if (step == 1) | ||
430 | - tmp_follow = must_follow; | ||
431 | - else /* step == -1. */ | ||
432 | - tmp_precede = must_precede; | ||
433 | - } | ||
434 | - | ||
435 | + sbitmap tmp_precede, tmp_follow; | ||
436 | + | ||
437 | + set_must_precede_follow (&tmp_follow, must_follow, | ||
438 | + &tmp_precede, must_precede, | ||
439 | + c, start, end, step); | ||
440 | success = | ||
441 | try_scheduling_node_in_cycle (ps, u_node, u, c, | ||
442 | sched_nodes, | ||
443 | @@ -2899,12 +3131,10 @@ | ||
444 | } | ||
445 | |||
446 | /* Calculate the stage count of the partial schedule PS. The calculation | ||
447 | - takes into account the rotation to bring the closing branch to row | ||
448 | - ii-1. */ | ||
449 | + takes into account the rotation amount passed in ROTATION_AMOUNT. */ | ||
450 | int | ||
451 | -calculate_stage_count (partial_schedule_ptr ps) | ||
452 | +calculate_stage_count (partial_schedule_ptr ps, int rotation_amount) | ||
453 | { | ||
454 | - int rotation_amount = (SCHED_TIME (ps->g->closing_branch)) + 1; | ||
455 | int new_min_cycle = PS_MIN_CYCLE (ps) - rotation_amount; | ||
456 | int new_max_cycle = PS_MAX_CYCLE (ps) - rotation_amount; | ||
457 | int stage_count = CALC_STAGE_COUNT (-1, new_min_cycle, ps->ii); | ||
458 | |||