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