summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106784.patch
diff options
context:
space:
mode:
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.patch458
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 @@
12011-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