Mercurial > hg > CbC > CbC_gcc
annotate gcc/sched-ebb.c @ 108:7ad14f446135
add CbC-example/rectypeTest/
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 14 Jun 2012 20:30:24 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Instruction scheduling pass. |
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
0 | 4 Free Software Foundation, Inc. |
5 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by, | |
6 and currently maintained by, Jim Wilson (wilson@cygnus.com) | |
7 | |
8 This file is part of GCC. | |
9 | |
10 GCC is free software; you can redistribute it and/or modify it under | |
11 the terms of the GNU General Public License as published by the Free | |
12 Software Foundation; either version 3, or (at your option) any later | |
13 version. | |
14 | |
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with GCC; see the file COPYING3. If not see | |
22 <http://www.gnu.org/licenses/>. */ | |
23 | |
24 #include "config.h" | |
25 #include "system.h" | |
26 #include "coretypes.h" | |
27 #include "tm.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
28 #include "diagnostic-core.h" |
0 | 29 #include "rtl.h" |
30 #include "tm_p.h" | |
31 #include "hard-reg-set.h" | |
32 #include "regs.h" | |
33 #include "function.h" | |
34 #include "flags.h" | |
35 #include "insn-config.h" | |
36 #include "insn-attr.h" | |
37 #include "except.h" | |
38 #include "recog.h" | |
39 #include "cfglayout.h" | |
40 #include "params.h" | |
41 #include "sched-int.h" | |
42 #include "target.h" | |
43 #include "output.h" | |
44 | |
45 | |
46 #ifdef INSN_SCHEDULING | |
47 | |
48 /* The number of insns to be scheduled in total. */ | |
49 static int rgn_n_insns; | |
50 | |
51 /* The number of insns scheduled so far. */ | |
52 static int sched_rgn_n_insns; | |
53 | |
54 /* Set of blocks, that already have their dependencies calculated. */ | |
55 static bitmap_head dont_calc_deps; | |
56 | |
57 /* Last basic block in current ebb. */ | |
58 static basic_block last_bb; | |
59 | |
60 /* Implementations of the sched_info functions for region scheduling. */ | |
61 static void init_ready_list (void); | |
62 static void begin_schedule_ready (rtx, rtx); | |
63 static int schedule_more_p (void); | |
64 static const char *ebb_print_insn (const_rtx, int); | |
65 static int rank (rtx, rtx); | |
66 static int ebb_contributes_to_priority (rtx, rtx); | |
67 static basic_block earliest_block_with_similiar_load (basic_block, rtx); | |
68 static void add_deps_for_risky_insns (rtx, rtx); | |
69 static basic_block schedule_ebb (rtx, rtx); | |
70 static void debug_ebb_dependencies (rtx, rtx); | |
71 | |
72 static void ebb_add_remove_insn (rtx, int); | |
73 static void ebb_add_block (basic_block, basic_block); | |
74 static basic_block advance_target_bb (basic_block, rtx); | |
75 static void ebb_fix_recovery_cfg (int, int, int); | |
76 | |
77 /* Return nonzero if there are more insns that should be scheduled. */ | |
78 | |
79 static int | |
80 schedule_more_p (void) | |
81 { | |
82 return sched_rgn_n_insns < rgn_n_insns; | |
83 } | |
84 | |
85 /* Print dependency information about ebb between HEAD and TAIL. */ | |
86 static void | |
87 debug_ebb_dependencies (rtx head, rtx tail) | |
88 { | |
89 fprintf (sched_dump, | |
90 ";; --------------- forward dependences: ------------ \n"); | |
91 | |
92 fprintf (sched_dump, "\n;; --- EBB Dependences --- from bb%d to bb%d \n", | |
93 BLOCK_NUM (head), BLOCK_NUM (tail)); | |
94 | |
95 debug_dependencies (head, tail); | |
96 } | |
97 | |
98 /* Add all insns that are initially ready to the ready list READY. Called | |
99 once before scheduling a set of insns. */ | |
100 | |
101 static void | |
102 init_ready_list (void) | |
103 { | |
104 int n = 0; | |
105 rtx prev_head = current_sched_info->prev_head; | |
106 rtx next_tail = current_sched_info->next_tail; | |
107 rtx insn; | |
108 | |
109 sched_rgn_n_insns = 0; | |
110 | |
111 /* Print debugging information. */ | |
112 if (sched_verbose >= 5) | |
113 debug_ebb_dependencies (NEXT_INSN (prev_head), PREV_INSN (next_tail)); | |
114 | |
115 /* Initialize ready list with all 'ready' insns in target block. | |
116 Count number of insns in the target block being scheduled. */ | |
117 for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn)) | |
118 { | |
119 try_ready (insn); | |
120 n++; | |
121 } | |
122 | |
123 gcc_assert (n == rgn_n_insns); | |
124 } | |
125 | |
126 /* INSN is being scheduled after LAST. Update counters. */ | |
127 static void | |
128 begin_schedule_ready (rtx insn, rtx last) | |
129 { | |
130 sched_rgn_n_insns++; | |
131 | |
132 if (BLOCK_FOR_INSN (insn) == last_bb | |
133 /* INSN is a jump in the last block, ... */ | |
134 && control_flow_insn_p (insn) | |
135 /* that is going to be moved over some instructions. */ | |
136 && last != PREV_INSN (insn)) | |
137 { | |
138 edge e; | |
139 basic_block bb; | |
140 | |
141 /* An obscure special case, where we do have partially dead | |
142 instruction scheduled after last control flow instruction. | |
143 In this case we can create new basic block. It is | |
144 always exactly one basic block last in the sequence. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
146 e = find_fallthru_edge (last_bb->succs); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
147 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
148 gcc_checking_assert (!e || !(e->flags & EDGE_COMPLEX)); |
0 | 149 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
150 gcc_checking_assert (BLOCK_FOR_INSN (insn) == last_bb |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
151 && !IS_SPECULATION_CHECK_P (insn) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
152 && BB_HEAD (last_bb) != insn |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
153 && BB_END (last_bb) == insn); |
0 | 154 |
155 { | |
156 rtx x; | |
157 | |
158 x = NEXT_INSN (insn); | |
159 if (e) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
160 gcc_checking_assert (NOTE_P (x) || LABEL_P (x)); |
0 | 161 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
162 gcc_checking_assert (BARRIER_P (x)); |
0 | 163 } |
164 | |
165 if (e) | |
166 { | |
167 bb = split_edge (e); | |
168 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_END (bb))); | |
169 } | |
170 else | |
171 /* Create an empty unreachable block after the INSN. */ | |
172 bb = create_basic_block (NEXT_INSN (insn), NULL_RTX, last_bb); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
173 |
0 | 174 /* split_edge () creates BB before E->DEST. Keep in mind, that |
175 this operation extends scheduling region till the end of BB. | |
176 Hence, we need to shift NEXT_TAIL, so haifa-sched.c won't go out | |
177 of the scheduling region. */ | |
178 current_sched_info->next_tail = NEXT_INSN (BB_END (bb)); | |
179 gcc_assert (current_sched_info->next_tail); | |
180 | |
181 /* Append new basic block to the end of the ebb. */ | |
182 sched_init_only_bb (bb, last_bb); | |
183 gcc_assert (last_bb == bb); | |
184 } | |
185 } | |
186 | |
187 /* Return a string that contains the insn uid and optionally anything else | |
188 necessary to identify this insn in an output. It's valid to use a | |
189 static buffer for this. The ALIGNED parameter should cause the string | |
190 to be formatted so that multiple output lines will line up nicely. */ | |
191 | |
192 static const char * | |
193 ebb_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED) | |
194 { | |
195 static char tmp[80]; | |
196 | |
197 /* '+' before insn means it is a new cycle start. */ | |
198 if (GET_MODE (insn) == TImode) | |
199 sprintf (tmp, "+ %4d", INSN_UID (insn)); | |
200 else | |
201 sprintf (tmp, " %4d", INSN_UID (insn)); | |
202 | |
203 return tmp; | |
204 } | |
205 | |
206 /* Compare priority of two insns. Return a positive number if the second | |
207 insn is to be preferred for scheduling, and a negative one if the first | |
208 is to be preferred. Zero if they are equally good. */ | |
209 | |
210 static int | |
211 rank (rtx insn1, rtx insn2) | |
212 { | |
213 basic_block bb1 = BLOCK_FOR_INSN (insn1); | |
214 basic_block bb2 = BLOCK_FOR_INSN (insn2); | |
215 | |
216 if (bb1->count > bb2->count | |
217 || bb1->frequency > bb2->frequency) | |
218 return -1; | |
219 if (bb1->count < bb2->count | |
220 || bb1->frequency < bb2->frequency) | |
221 return 1; | |
222 return 0; | |
223 } | |
224 | |
225 /* NEXT is an instruction that depends on INSN (a backward dependence); | |
226 return nonzero if we should include this dependence in priority | |
227 calculations. */ | |
228 | |
229 static int | |
230 ebb_contributes_to_priority (rtx next ATTRIBUTE_UNUSED, | |
231 rtx insn ATTRIBUTE_UNUSED) | |
232 { | |
233 return 1; | |
234 } | |
235 | |
236 /* INSN is a JUMP_INSN, COND_SET is the set of registers that are | |
237 conditionally set before INSN. Store the set of registers that | |
238 must be considered as used by this jump in USED and that of | |
239 registers that must be considered as set in SET. */ | |
240 | |
241 void | |
242 ebb_compute_jump_reg_dependencies (rtx insn, regset cond_set, regset used, | |
243 regset set) | |
244 { | |
245 basic_block b = BLOCK_FOR_INSN (insn); | |
246 edge e; | |
247 edge_iterator ei; | |
248 | |
249 FOR_EACH_EDGE (e, ei, b->succs) | |
250 if (e->flags & EDGE_FALLTHRU) | |
251 /* The jump may be a by-product of a branch that has been merged | |
252 in the main codepath after being conditionalized. Therefore | |
253 it may guard the fallthrough block from using a value that has | |
254 conditionally overwritten that of the main codepath. So we | |
255 consider that it restores the value of the main codepath. */ | |
256 bitmap_and (set, df_get_live_in (e->dest), cond_set); | |
257 else | |
258 bitmap_ior_into (used, df_get_live_in (e->dest)); | |
259 } | |
260 | |
261 /* Used in schedule_insns to initialize current_sched_info for scheduling | |
262 regions (or single basic blocks). */ | |
263 | |
264 static struct common_sched_info_def ebb_common_sched_info; | |
265 | |
266 static struct sched_deps_info_def ebb_sched_deps_info = | |
267 { | |
268 ebb_compute_jump_reg_dependencies, | |
269 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
270 NULL, | |
271 1, 0, 0 | |
272 }; | |
273 | |
274 static struct haifa_sched_info ebb_sched_info = | |
275 { | |
276 init_ready_list, | |
277 NULL, | |
278 schedule_more_p, | |
279 NULL, | |
280 rank, | |
281 ebb_print_insn, | |
282 ebb_contributes_to_priority, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
283 NULL, /* insn_finishes_block_p */ |
0 | 284 |
285 NULL, NULL, | |
286 NULL, NULL, | |
287 1, 0, | |
288 | |
289 ebb_add_remove_insn, | |
290 begin_schedule_ready, | |
291 advance_target_bb, | |
292 SCHED_EBB | |
293 /* We can create new blocks in begin_schedule_ready (). */ | |
294 | NEW_BBS | |
295 }; | |
296 | |
297 /* Returns the earliest block in EBB currently being processed where a | |
298 "similar load" 'insn2' is found, and hence LOAD_INSN can move | |
299 speculatively into the found block. All the following must hold: | |
300 | |
301 (1) both loads have 1 base register (PFREE_CANDIDATEs). | |
302 (2) load_insn and load2 have a def-use dependence upon | |
303 the same insn 'insn1'. | |
304 | |
305 From all these we can conclude that the two loads access memory | |
306 addresses that differ at most by a constant, and hence if moving | |
307 load_insn would cause an exception, it would have been caused by | |
308 load2 anyhow. | |
309 | |
310 The function uses list (given by LAST_BLOCK) of already processed | |
311 blocks in EBB. The list is formed in `add_deps_for_risky_insns'. */ | |
312 | |
313 static basic_block | |
314 earliest_block_with_similiar_load (basic_block last_block, rtx load_insn) | |
315 { | |
316 sd_iterator_def back_sd_it; | |
317 dep_t back_dep; | |
318 basic_block bb, earliest_block = NULL; | |
319 | |
320 FOR_EACH_DEP (load_insn, SD_LIST_BACK, back_sd_it, back_dep) | |
321 { | |
322 rtx insn1 = DEP_PRO (back_dep); | |
323 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
324 if (DEP_TYPE (back_dep) == REG_DEP_TRUE) |
0 | 325 /* Found a DEF-USE dependence (insn1, load_insn). */ |
326 { | |
327 sd_iterator_def fore_sd_it; | |
328 dep_t fore_dep; | |
329 | |
330 FOR_EACH_DEP (insn1, SD_LIST_FORW, fore_sd_it, fore_dep) | |
331 { | |
332 rtx insn2 = DEP_CON (fore_dep); | |
333 basic_block insn2_block = BLOCK_FOR_INSN (insn2); | |
334 | |
335 if (DEP_TYPE (fore_dep) == REG_DEP_TRUE) | |
336 { | |
337 if (earliest_block != NULL | |
338 && earliest_block->index < insn2_block->index) | |
339 continue; | |
340 | |
341 /* Found a DEF-USE dependence (insn1, insn2). */ | |
342 if (haifa_classify_insn (insn2) != PFREE_CANDIDATE) | |
343 /* insn2 not guaranteed to be a 1 base reg load. */ | |
344 continue; | |
345 | |
346 for (bb = last_block; bb; bb = (basic_block) bb->aux) | |
347 if (insn2_block == bb) | |
348 break; | |
349 | |
350 if (!bb) | |
351 /* insn2 is the similar load. */ | |
352 earliest_block = insn2_block; | |
353 } | |
354 } | |
355 } | |
356 } | |
357 | |
358 return earliest_block; | |
359 } | |
360 | |
361 /* The following function adds dependencies between jumps and risky | |
362 insns in given ebb. */ | |
363 | |
364 static void | |
365 add_deps_for_risky_insns (rtx head, rtx tail) | |
366 { | |
367 rtx insn, prev; | |
368 int classification; | |
369 rtx last_jump = NULL_RTX; | |
370 rtx next_tail = NEXT_INSN (tail); | |
371 basic_block last_block = NULL, bb; | |
372 | |
373 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) | |
374 if (control_flow_insn_p (insn)) | |
375 { | |
376 bb = BLOCK_FOR_INSN (insn); | |
377 bb->aux = last_block; | |
378 last_block = bb; | |
379 last_jump = insn; | |
380 } | |
381 else if (INSN_P (insn) && last_jump != NULL_RTX) | |
382 { | |
383 classification = haifa_classify_insn (insn); | |
384 prev = last_jump; | |
385 switch (classification) | |
386 { | |
387 case PFREE_CANDIDATE: | |
388 if (flag_schedule_speculative_load) | |
389 { | |
390 bb = earliest_block_with_similiar_load (last_block, insn); | |
391 if (bb) | |
392 { | |
393 bb = (basic_block) bb->aux; | |
394 if (!bb) | |
395 break; | |
396 prev = BB_END (bb); | |
397 } | |
398 } | |
399 /* Fall through. */ | |
400 case TRAP_RISKY: | |
401 case IRISKY: | |
402 case PRISKY_CANDIDATE: | |
403 /* ??? We could implement better checking PRISKY_CANDIDATEs | |
404 analogous to sched-rgn.c. */ | |
405 /* We can not change the mode of the backward | |
406 dependency because REG_DEP_ANTI has the lowest | |
407 rank. */ | |
408 if (! sched_insns_conditions_mutex_p (insn, prev)) | |
409 { | |
410 dep_def _dep, *dep = &_dep; | |
411 | |
412 init_dep (dep, prev, insn, REG_DEP_ANTI); | |
413 | |
414 if (!(current_sched_info->flags & USE_DEPS_LIST)) | |
415 { | |
416 enum DEPS_ADJUST_RESULT res; | |
417 | |
418 res = sd_add_or_update_dep (dep, false); | |
419 | |
420 /* We can't change an existing dependency with | |
421 DEP_ANTI. */ | |
422 gcc_assert (res != DEP_CHANGED); | |
423 } | |
424 else | |
425 { | |
426 if ((current_sched_info->flags & DO_SPECULATION) | |
427 && (spec_info->mask & BEGIN_CONTROL)) | |
428 DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL, | |
429 MAX_DEP_WEAK); | |
430 | |
431 sd_add_or_update_dep (dep, false); | |
432 | |
433 /* Dep_status could have been changed. | |
434 No assertion here. */ | |
435 } | |
436 } | |
437 | |
438 break; | |
439 | |
440 default: | |
441 break; | |
442 } | |
443 } | |
444 /* Maintain the invariant that bb->aux is clear after use. */ | |
445 while (last_block) | |
446 { | |
447 bb = (basic_block) last_block->aux; | |
448 last_block->aux = NULL; | |
449 last_block = bb; | |
450 } | |
451 } | |
452 | |
453 /* Schedule a single extended basic block, defined by the boundaries HEAD | |
454 and TAIL. */ | |
455 | |
456 static basic_block | |
457 schedule_ebb (rtx head, rtx tail) | |
458 { | |
459 basic_block first_bb, target_bb; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
460 struct deps_desc tmp_deps; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
461 |
0 | 462 first_bb = BLOCK_FOR_INSN (head); |
463 last_bb = BLOCK_FOR_INSN (tail); | |
464 | |
465 if (no_real_insns_p (head, tail)) | |
466 return BLOCK_FOR_INSN (tail); | |
467 | |
468 gcc_assert (INSN_P (head) && INSN_P (tail)); | |
469 | |
470 if (!bitmap_bit_p (&dont_calc_deps, first_bb->index)) | |
471 { | |
472 init_deps_global (); | |
473 | |
474 /* Compute dependencies. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
475 init_deps (&tmp_deps, false); |
0 | 476 sched_analyze (&tmp_deps, head, tail); |
477 free_deps (&tmp_deps); | |
478 | |
479 add_deps_for_risky_insns (head, tail); | |
480 | |
481 if (targetm.sched.dependencies_evaluation_hook) | |
482 targetm.sched.dependencies_evaluation_hook (head, tail); | |
483 | |
484 finish_deps_global (); | |
485 } | |
486 else | |
487 /* Only recovery blocks can have their dependencies already calculated, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
488 and they always are single block ebbs. */ |
0 | 489 gcc_assert (first_bb == last_bb); |
490 | |
491 /* Set priorities. */ | |
492 current_sched_info->sched_max_insns_priority = 0; | |
493 rgn_n_insns = set_priorities (head, tail); | |
494 current_sched_info->sched_max_insns_priority++; | |
495 | |
496 current_sched_info->prev_head = PREV_INSN (head); | |
497 current_sched_info->next_tail = NEXT_INSN (tail); | |
498 | |
499 remove_notes (head, tail); | |
500 | |
501 unlink_bb_notes (first_bb, last_bb); | |
502 | |
503 target_bb = first_bb; | |
504 | |
505 /* Make ready list big enough to hold all the instructions from the ebb. */ | |
506 sched_extend_ready_list (rgn_n_insns); | |
507 schedule_block (&target_bb); | |
508 /* Free ready list. */ | |
509 sched_finish_ready_list (); | |
510 | |
511 /* We might pack all instructions into fewer blocks, | |
512 so we may made some of them empty. Can't assert (b == last_bb). */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 |
0 | 514 /* Sanity check: verify that all region insns were scheduled. */ |
515 gcc_assert (sched_rgn_n_insns == rgn_n_insns); | |
516 | |
517 /* Free dependencies. */ | |
518 sched_free_deps (current_sched_info->head, current_sched_info->tail, true); | |
519 | |
520 gcc_assert (haifa_recovery_bb_ever_added_p | |
521 || deps_pools_are_empty_p ()); | |
522 | |
523 if (EDGE_COUNT (last_bb->preds) == 0) | |
524 /* LAST_BB is unreachable. */ | |
525 { | |
526 gcc_assert (first_bb != last_bb | |
527 && EDGE_COUNT (last_bb->succs) == 0); | |
528 last_bb = last_bb->prev_bb; | |
529 delete_basic_block (last_bb->next_bb); | |
530 } | |
531 | |
532 return last_bb; | |
533 } | |
534 | |
535 /* The one entry point in this file. */ | |
536 | |
537 void | |
538 schedule_ebbs (void) | |
539 { | |
540 basic_block bb; | |
541 int probability_cutoff; | |
542 rtx tail; | |
543 | |
544 if (profile_info && flag_branch_probabilities) | |
545 probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK); | |
546 else | |
547 probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY); | |
548 probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff; | |
549 | |
550 /* Taking care of this degenerate case makes the rest of | |
551 this code simpler. */ | |
552 if (n_basic_blocks == NUM_FIXED_BLOCKS) | |
553 return; | |
554 | |
555 /* Setup infos. */ | |
556 { | |
557 memcpy (&ebb_common_sched_info, &haifa_common_sched_info, | |
558 sizeof (ebb_common_sched_info)); | |
559 | |
560 ebb_common_sched_info.fix_recovery_cfg = ebb_fix_recovery_cfg; | |
561 ebb_common_sched_info.add_block = ebb_add_block; | |
562 ebb_common_sched_info.sched_pass_id = SCHED_EBB_PASS; | |
563 | |
564 common_sched_info = &ebb_common_sched_info; | |
565 sched_deps_info = &ebb_sched_deps_info; | |
566 current_sched_info = &ebb_sched_info; | |
567 } | |
568 | |
569 haifa_sched_init (); | |
570 | |
571 compute_bb_for_insn (); | |
572 | |
573 /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers. */ | |
574 bitmap_initialize (&dont_calc_deps, 0); | |
575 bitmap_clear (&dont_calc_deps); | |
576 | |
577 /* Schedule every region in the subroutine. */ | |
578 FOR_EACH_BB (bb) | |
579 { | |
580 rtx head = BB_HEAD (bb); | |
581 | |
582 for (;;) | |
583 { | |
584 edge e; | |
585 tail = BB_END (bb); | |
586 if (bb->next_bb == EXIT_BLOCK_PTR | |
587 || LABEL_P (BB_HEAD (bb->next_bb))) | |
588 break; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
589 e = find_fallthru_edge (bb->succs); |
0 | 590 if (! e) |
591 break; | |
592 if (e->probability <= probability_cutoff) | |
593 break; | |
594 bb = bb->next_bb; | |
595 } | |
596 | |
597 /* Blah. We should fix the rest of the code not to get confused by | |
598 a note or two. */ | |
599 while (head != tail) | |
600 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
601 if (NOTE_P (head) || DEBUG_INSN_P (head)) |
0 | 602 head = NEXT_INSN (head); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
603 else if (NOTE_P (tail) || DEBUG_INSN_P (tail)) |
0 | 604 tail = PREV_INSN (tail); |
605 else if (LABEL_P (head)) | |
606 head = NEXT_INSN (head); | |
607 else | |
608 break; | |
609 } | |
610 | |
611 bb = schedule_ebb (head, tail); | |
612 } | |
613 bitmap_clear (&dont_calc_deps); | |
614 | |
615 /* Reposition the prologue and epilogue notes in case we moved the | |
616 prologue/epilogue insns. */ | |
617 if (reload_completed) | |
618 reposition_prologue_and_epilogue_notes (); | |
619 | |
620 haifa_sched_finish (); | |
621 } | |
622 | |
623 /* INSN has been added to/removed from current ebb. */ | |
624 static void | |
625 ebb_add_remove_insn (rtx insn ATTRIBUTE_UNUSED, int remove_p) | |
626 { | |
627 if (!remove_p) | |
628 rgn_n_insns++; | |
629 else | |
630 rgn_n_insns--; | |
631 } | |
632 | |
633 /* BB was added to ebb after AFTER. */ | |
634 static void | |
635 ebb_add_block (basic_block bb, basic_block after) | |
636 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
637 /* Recovery blocks are always bounded by BARRIERS, |
0 | 638 therefore, they always form single block EBB, |
639 therefore, we can use rec->index to identify such EBBs. */ | |
640 if (after == EXIT_BLOCK_PTR) | |
641 bitmap_set_bit (&dont_calc_deps, bb->index); | |
642 else if (after == last_bb) | |
643 last_bb = bb; | |
644 } | |
645 | |
646 /* Return next block in ebb chain. For parameter meaning please refer to | |
647 sched-int.h: struct sched_info: advance_target_bb. */ | |
648 static basic_block | |
649 advance_target_bb (basic_block bb, rtx insn) | |
650 { | |
651 if (insn) | |
652 { | |
653 if (BLOCK_FOR_INSN (insn) != bb | |
654 && control_flow_insn_p (insn) | |
655 /* We handle interblock movement of the speculation check | |
656 or over a speculation check in | |
657 haifa-sched.c: move_block_after_check (). */ | |
658 && !IS_SPECULATION_BRANCHY_CHECK_P (insn) | |
659 && !IS_SPECULATION_BRANCHY_CHECK_P (BB_END (bb))) | |
660 { | |
661 /* Assert that we don't move jumps across blocks. */ | |
662 gcc_assert (!control_flow_insn_p (BB_END (bb)) | |
663 && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb))); | |
664 return bb; | |
665 } | |
666 else | |
667 return 0; | |
668 } | |
669 else | |
670 /* Return next non empty block. */ | |
671 { | |
672 do | |
673 { | |
674 gcc_assert (bb != last_bb); | |
675 | |
676 bb = bb->next_bb; | |
677 } | |
678 while (bb_note (bb) == BB_END (bb)); | |
679 | |
680 return bb; | |
681 } | |
682 } | |
683 | |
684 /* Fix internal data after interblock movement of jump instruction. | |
685 For parameter meaning please refer to | |
686 sched-int.h: struct sched_info: fix_recovery_cfg. */ | |
687 static void | |
688 ebb_fix_recovery_cfg (int bbi ATTRIBUTE_UNUSED, int jump_bbi, | |
689 int jump_bb_nexti) | |
690 { | |
691 gcc_assert (last_bb->index != bbi); | |
692 | |
693 if (jump_bb_nexti == last_bb->index) | |
694 last_bb = BASIC_BLOCK (jump_bbi); | |
695 } | |
696 | |
697 #endif /* INSN_SCHEDULING */ |