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