Merge lp:~eres/gcc-linaro/sms_opt_sc-4.6 into lp:gcc-linaro/4.6
- sms_opt_sc-4.6
- Merge into 4.6
Status: | Merged |
---|---|
Approved by: | Richard Sandiford |
Approved revision: | no longer in the source branch. |
Merged at revision: | 106784 |
Proposed branch: | lp:~eres/gcc-linaro/sms_opt_sc-4.6 |
Merge into: | lp:gcc-linaro/4.6 |
Diff against target: |
463 lines (+303/-58) 2 files modified
ChangeLog.linaro (+15/-0) gcc/modulo-sched.c (+288/-58) |
To merge this branch: | bzr merge lp:~eres/gcc-linaro/sms_opt_sc-4.6 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Richard Sandiford | Approve | ||
Review via email:
|
Commit message
Description of the change
Backport from trunk -r177235
http://
http://

Linaro Toolchain Builder (cbuild) wrote : | # |

Michael Hope (michaelh1) wrote : | # |
cbuild successfully built this on armv7l-
The build results are available at:
http://
The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106782
The full testsuite results are at:
http://
cbuild-checked: armv7l-

Michael Hope (michaelh1) wrote : | # |
cbuild successfully built this on armv7l-
The build results are available at:
http://
The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106782
The full testsuite results are at:
http://
cbuild-checked: armv7l-

Michael Hope (michaelh1) wrote : | # |
cbuild successfully built this on x86_64-
The build results are available at:
http://
The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106782
The full testsuite results are at:
http://
cbuild-checked: x86_64-

Richard Sandiford (rsandifo) wrote : | # |
Looks good.

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