]>
Commit | Line | Data |
---|---|---|
402209ff JH |
1 | /* Control flow optimization code for GNU compiler. |
2 | Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | |
6a58eee9 | 3 | 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
402209ff JH |
4 | |
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 2, or (at your option) any later | |
10 | version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING. If not, write to the Free | |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
21 | ||
22 | /* This file contains optimizer of the control flow. The main entrypoint is | |
23 | cleanup_cfg. Following optimizations are performed: | |
24 | ||
25 | - Unreachable blocks removal | |
26 | - Edge forwarding (edge to the forwarder block is forwarded to it's | |
eaec9b3d | 27 | successor. Simplification of the branch instruction is performed by |
402209ff | 28 | underlying infrastructure so branch can be converted to simplejump or |
f5143c46 | 29 | eliminated). |
402209ff JH |
30 | - Cross jumping (tail merging) |
31 | - Conditional jump-around-simplejump simplification | |
32 | - Basic block merging. */ | |
33 | ||
34 | #include "config.h" | |
35 | #include "system.h" | |
36 | #include "rtl.h" | |
37 | #include "hard-reg-set.h" | |
38 | #include "basic-block.h" | |
39 | #include "timevar.h" | |
40 | #include "output.h" | |
41 | #include "insn-config.h" | |
42 | #include "flags.h" | |
43 | #include "recog.h" | |
44 | #include "toplev.h" | |
8ecba28a | 45 | #include "cselib.h" |
9f16e871 | 46 | #include "tm_p.h" |
e4ec2cac | 47 | #include "target.h" |
402209ff JH |
48 | |
49 | #include "obstack.h" | |
50 | ||
79f5e6be | 51 | /* cleanup_cfg maintains following flags for each basic block. */ |
5f0d2358 RK |
52 | |
53 | enum bb_flags | |
54 | { | |
635559ab JH |
55 | /* Set if BB is the forwarder block to avoid too many |
56 | forwarder_block_p calls. */ | |
1540f9eb JH |
57 | BB_FORWARDER_BLOCK = 1, |
58 | BB_NONTHREADABLE_BLOCK = 2 | |
5f0d2358 | 59 | }; |
635559ab | 60 | |
5f0d2358 RK |
61 | #define BB_FLAGS(BB) (enum bb_flags) (BB)->aux |
62 | #define BB_SET_FLAG(BB, FLAG) \ | |
63 | (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux | (FLAG)) | |
64 | #define BB_CLEAR_FLAG(BB, FLAG) \ | |
65 | (BB)->aux = (void *) (long) ((enum bb_flags) (BB)->aux & ~(FLAG)) | |
635559ab | 66 | |
5f0d2358 | 67 | #define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK) |
635559ab | 68 | |
402209ff JH |
69 | static bool try_crossjump_to_edge PARAMS ((int, edge, edge)); |
70 | static bool try_crossjump_bb PARAMS ((int, basic_block)); | |
0dd0e980 JH |
71 | static bool outgoing_edges_match PARAMS ((int, |
72 | basic_block, basic_block)); | |
402209ff JH |
73 | static int flow_find_cross_jump PARAMS ((int, basic_block, basic_block, |
74 | rtx *, rtx *)); | |
0dd0e980 | 75 | static bool insns_match_p PARAMS ((int, rtx, rtx)); |
402209ff | 76 | |
ec10f7c7 | 77 | static bool label_is_jump_target_p PARAMS ((rtx, rtx)); |
4262e623 JH |
78 | static bool tail_recursion_label_p PARAMS ((rtx)); |
79 | static void merge_blocks_move_predecessor_nojumps PARAMS ((basic_block, | |
402209ff | 80 | basic_block)); |
4262e623 | 81 | static void merge_blocks_move_successor_nojumps PARAMS ((basic_block, |
402209ff | 82 | basic_block)); |
4262e623 | 83 | static bool merge_blocks PARAMS ((edge,basic_block,basic_block, |
402209ff JH |
84 | int)); |
85 | static bool try_optimize_cfg PARAMS ((int)); | |
86 | static bool try_simplify_condjump PARAMS ((basic_block)); | |
87 | static bool try_forward_edges PARAMS ((int, basic_block)); | |
8ecba28a JH |
88 | static edge thread_jump PARAMS ((int, edge, basic_block)); |
89 | static bool mark_effect PARAMS ((rtx, bitmap)); | |
635559ab JH |
90 | static void notice_new_block PARAMS ((basic_block)); |
91 | static void update_forwarder_flag PARAMS ((basic_block)); | |
fe477d8b | 92 | static int mentions_nonequal_regs PARAMS ((rtx *, void *)); |
635559ab JH |
93 | \f |
94 | /* Set flags for newly created block. */ | |
95 | ||
96 | static void | |
97 | notice_new_block (bb) | |
98 | basic_block bb; | |
99 | { | |
100 | if (!bb) | |
101 | return; | |
5f0d2358 | 102 | |
635559ab JH |
103 | if (forwarder_block_p (bb)) |
104 | BB_SET_FLAG (bb, BB_FORWARDER_BLOCK); | |
105 | } | |
106 | ||
107 | /* Recompute forwarder flag after block has been modified. */ | |
108 | ||
109 | static void | |
110 | update_forwarder_flag (bb) | |
111 | basic_block bb; | |
112 | { | |
113 | if (forwarder_block_p (bb)) | |
114 | BB_SET_FLAG (bb, BB_FORWARDER_BLOCK); | |
115 | else | |
116 | BB_CLEAR_FLAG (bb, BB_FORWARDER_BLOCK); | |
117 | } | |
402209ff JH |
118 | \f |
119 | /* Simplify a conditional jump around an unconditional jump. | |
120 | Return true if something changed. */ | |
121 | ||
122 | static bool | |
123 | try_simplify_condjump (cbranch_block) | |
124 | basic_block cbranch_block; | |
125 | { | |
126 | basic_block jump_block, jump_dest_block, cbranch_dest_block; | |
127 | edge cbranch_jump_edge, cbranch_fallthru_edge; | |
128 | rtx cbranch_insn; | |
129 | ||
130 | /* Verify that there are exactly two successors. */ | |
131 | if (!cbranch_block->succ | |
132 | || !cbranch_block->succ->succ_next | |
133 | || cbranch_block->succ->succ_next->succ_next) | |
134 | return false; | |
135 | ||
136 | /* Verify that we've got a normal conditional branch at the end | |
137 | of the block. */ | |
138 | cbranch_insn = cbranch_block->end; | |
139 | if (!any_condjump_p (cbranch_insn)) | |
140 | return false; | |
141 | ||
142 | cbranch_fallthru_edge = FALLTHRU_EDGE (cbranch_block); | |
143 | cbranch_jump_edge = BRANCH_EDGE (cbranch_block); | |
144 | ||
145 | /* The next block must not have multiple predecessors, must not | |
146 | be the last block in the function, and must contain just the | |
147 | unconditional jump. */ | |
148 | jump_block = cbranch_fallthru_edge->dest; | |
149 | if (jump_block->pred->pred_next | |
f6366fc7 | 150 | || jump_block->next_bb == EXIT_BLOCK_PTR |
635559ab | 151 | || !FORWARDER_BLOCK_P (jump_block)) |
402209ff JH |
152 | return false; |
153 | jump_dest_block = jump_block->succ->dest; | |
154 | ||
155 | /* The conditional branch must target the block after the | |
156 | unconditional branch. */ | |
157 | cbranch_dest_block = cbranch_jump_edge->dest; | |
158 | ||
159 | if (!can_fallthru (jump_block, cbranch_dest_block)) | |
160 | return false; | |
161 | ||
ca6c03ca JH |
162 | /* Invert the conditional branch. */ |
163 | if (!invert_jump (cbranch_insn, block_label (jump_dest_block), 0)) | |
164 | return false; | |
402209ff JH |
165 | |
166 | if (rtl_dump_file) | |
167 | fprintf (rtl_dump_file, "Simplifying condjump %i around jump %i\n", | |
168 | INSN_UID (cbranch_insn), INSN_UID (jump_block->end)); | |
169 | ||
170 | /* Success. Update the CFG to match. Note that after this point | |
171 | the edge variable names appear backwards; the redirection is done | |
172 | this way to preserve edge profile data. */ | |
173 | cbranch_jump_edge = redirect_edge_succ_nodup (cbranch_jump_edge, | |
174 | cbranch_dest_block); | |
175 | cbranch_fallthru_edge = redirect_edge_succ_nodup (cbranch_fallthru_edge, | |
176 | jump_dest_block); | |
177 | cbranch_jump_edge->flags |= EDGE_FALLTHRU; | |
178 | cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU; | |
b446e5a2 | 179 | update_br_prob_note (cbranch_block); |
402209ff JH |
180 | |
181 | /* Delete the block with the unconditional jump, and clean up the mess. */ | |
182 | flow_delete_block (jump_block); | |
183 | tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block); | |
184 | ||
185 | return true; | |
186 | } | |
187 | \f | |
8ecba28a JH |
188 | /* Attempt to prove that operation is NOOP using CSElib or mark the effect |
189 | on register. Used by jump threading. */ | |
5f0d2358 | 190 | |
8ecba28a JH |
191 | static bool |
192 | mark_effect (exp, nonequal) | |
f87c27b4 KH |
193 | rtx exp; |
194 | regset nonequal; | |
8ecba28a | 195 | { |
9f16e871 JH |
196 | int regno; |
197 | rtx dest; | |
8ecba28a JH |
198 | switch (GET_CODE (exp)) |
199 | { | |
200 | /* In case we do clobber the register, mark it as equal, as we know the | |
201 | value is dead so it don't have to match. */ | |
f87c27b4 KH |
202 | case CLOBBER: |
203 | if (REG_P (XEXP (exp, 0))) | |
204 | { | |
205 | dest = XEXP (exp, 0); | |
206 | regno = REGNO (dest); | |
207 | CLEAR_REGNO_REG_SET (nonequal, regno); | |
208 | if (regno < FIRST_PSEUDO_REGISTER) | |
209 | { | |
210 | int n = HARD_REGNO_NREGS (regno, GET_MODE (dest)); | |
211 | while (--n > 0) | |
212 | CLEAR_REGNO_REG_SET (nonequal, regno + n); | |
213 | } | |
214 | } | |
215 | return false; | |
5f0d2358 | 216 | |
f87c27b4 KH |
217 | case SET: |
218 | if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp))) | |
8ecba28a | 219 | return false; |
f87c27b4 KH |
220 | dest = SET_DEST (exp); |
221 | if (dest == pc_rtx) | |
8ecba28a | 222 | return false; |
f87c27b4 KH |
223 | if (!REG_P (dest)) |
224 | return true; | |
225 | regno = REGNO (dest); | |
226 | SET_REGNO_REG_SET (nonequal, regno); | |
227 | if (regno < FIRST_PSEUDO_REGISTER) | |
228 | { | |
229 | int n = HARD_REGNO_NREGS (regno, GET_MODE (dest)); | |
230 | while (--n > 0) | |
231 | SET_REGNO_REG_SET (nonequal, regno + n); | |
232 | } | |
233 | return false; | |
234 | ||
235 | default: | |
236 | return false; | |
8ecba28a JH |
237 | } |
238 | } | |
fe477d8b JH |
239 | |
240 | /* Return nonzero if X is an register set in regset DATA. | |
241 | Called via for_each_rtx. */ | |
242 | static int | |
243 | mentions_nonequal_regs (x, data) | |
244 | rtx *x; | |
245 | void *data; | |
246 | { | |
247 | regset nonequal = (regset) data; | |
248 | if (REG_P (*x)) | |
249 | { | |
250 | int regno; | |
251 | ||
252 | regno = REGNO (*x); | |
253 | if (REGNO_REG_SET_P (nonequal, regno)) | |
254 | return 1; | |
255 | if (regno < FIRST_PSEUDO_REGISTER) | |
256 | { | |
257 | int n = HARD_REGNO_NREGS (regno, GET_MODE (*x)); | |
258 | while (--n > 0) | |
259 | if (REGNO_REG_SET_P (nonequal, regno + n)) | |
260 | return 1; | |
261 | } | |
262 | } | |
263 | return 0; | |
264 | } | |
8ecba28a JH |
265 | /* Attempt to prove that the basic block B will have no side effects and |
266 | allways continues in the same edge if reached via E. Return the edge | |
267 | if exist, NULL otherwise. */ | |
268 | ||
269 | static edge | |
270 | thread_jump (mode, e, b) | |
271 | int mode; | |
272 | edge e; | |
273 | basic_block b; | |
274 | { | |
275 | rtx set1, set2, cond1, cond2, insn; | |
276 | enum rtx_code code1, code2, reversed_code2; | |
277 | bool reverse1 = false; | |
278 | int i; | |
279 | regset nonequal; | |
280 | bool failed = false; | |
281 | ||
1540f9eb JH |
282 | if (BB_FLAGS (b) & BB_NONTHREADABLE_BLOCK) |
283 | return NULL; | |
284 | ||
8ecba28a JH |
285 | /* At the moment, we do handle only conditional jumps, but later we may |
286 | want to extend this code to tablejumps and others. */ | |
287 | if (!e->src->succ->succ_next || e->src->succ->succ_next->succ_next) | |
288 | return NULL; | |
289 | if (!b->succ || !b->succ->succ_next || b->succ->succ_next->succ_next) | |
1540f9eb JH |
290 | { |
291 | BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); | |
292 | return NULL; | |
293 | } | |
8ecba28a JH |
294 | |
295 | /* Second branch must end with onlyjump, as we will eliminate the jump. */ | |
1540f9eb | 296 | if (!any_condjump_p (e->src->end)) |
8ecba28a | 297 | return NULL; |
f87c27b4 | 298 | |
1540f9eb JH |
299 | if (!any_condjump_p (b->end) || !onlyjump_p (b->end)) |
300 | { | |
301 | BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); | |
302 | return NULL; | |
303 | } | |
8ecba28a JH |
304 | |
305 | set1 = pc_set (e->src->end); | |
306 | set2 = pc_set (b->end); | |
307 | if (((e->flags & EDGE_FALLTHRU) != 0) | |
68f3f6f1 | 308 | != (XEXP (SET_SRC (set1), 1) == pc_rtx)) |
8ecba28a JH |
309 | reverse1 = true; |
310 | ||
311 | cond1 = XEXP (SET_SRC (set1), 0); | |
312 | cond2 = XEXP (SET_SRC (set2), 0); | |
313 | if (reverse1) | |
68f3f6f1 | 314 | code1 = reversed_comparison_code (cond1, e->src->end); |
8ecba28a JH |
315 | else |
316 | code1 = GET_CODE (cond1); | |
317 | ||
318 | code2 = GET_CODE (cond2); | |
319 | reversed_code2 = reversed_comparison_code (cond2, b->end); | |
320 | ||
321 | if (!comparison_dominates_p (code1, code2) | |
322 | && !comparison_dominates_p (code1, reversed_code2)) | |
323 | return NULL; | |
324 | ||
325 | /* Ensure that the comparison operators are equivalent. | |
326 | ??? This is far too pesimistic. We should allow swapped operands, | |
327 | different CCmodes, or for example comparisons for interval, that | |
328 | dominate even when operands are not equivalent. */ | |
329 | if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) | |
330 | || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))) | |
331 | return NULL; | |
332 | ||
333 | /* Short circuit cases where block B contains some side effects, as we can't | |
334 | safely bypass it. */ | |
335 | for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end); | |
336 | insn = NEXT_INSN (insn)) | |
337 | if (INSN_P (insn) && side_effects_p (PATTERN (insn))) | |
1540f9eb JH |
338 | { |
339 | BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); | |
340 | return NULL; | |
341 | } | |
8ecba28a JH |
342 | |
343 | cselib_init (); | |
344 | ||
345 | /* First process all values computed in the source basic block. */ | |
346 | for (insn = NEXT_INSN (e->src->head); insn != NEXT_INSN (e->src->end); | |
347 | insn = NEXT_INSN (insn)) | |
348 | if (INSN_P (insn)) | |
349 | cselib_process_insn (insn); | |
350 | ||
351 | nonequal = BITMAP_XMALLOC(); | |
352 | CLEAR_REG_SET (nonequal); | |
5f0d2358 | 353 | |
8ecba28a JH |
354 | /* Now assume that we've continued by the edge E to B and continue |
355 | processing as if it were same basic block. | |
8ecba28a | 356 | Our goal is to prove that whole block is an NOOP. */ |
5f0d2358 | 357 | |
9f16e871 | 358 | for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end) && !failed; |
8ecba28a | 359 | insn = NEXT_INSN (insn)) |
f87c27b4 KH |
360 | { |
361 | if (INSN_P (insn)) | |
362 | { | |
363 | rtx pat = PATTERN (insn); | |
364 | ||
365 | if (GET_CODE (pat) == PARALLEL) | |
366 | { | |
367 | for (i = 0; i < XVECLEN (pat, 0); i++) | |
368 | failed |= mark_effect (XVECEXP (pat, 0, i), nonequal); | |
369 | } | |
370 | else | |
371 | failed |= mark_effect (pat, nonequal); | |
372 | } | |
5f0d2358 | 373 | |
f87c27b4 KH |
374 | cselib_process_insn (insn); |
375 | } | |
8ecba28a JH |
376 | |
377 | /* Later we should clear nonequal of dead registers. So far we don't | |
378 | have life information in cfg_cleanup. */ | |
379 | if (failed) | |
1540f9eb JH |
380 | { |
381 | BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK); | |
382 | goto failed_exit; | |
383 | } | |
8ecba28a | 384 | |
fe477d8b JH |
385 | /* cond2 must not mention any register that is not equal to the |
386 | former block. */ | |
387 | if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal)) | |
388 | goto failed_exit; | |
389 | ||
8ecba28a JH |
390 | /* In case liveness information is available, we need to prove equivalence |
391 | only of the live values. */ | |
392 | if (mode & CLEANUP_UPDATE_LIFE) | |
393 | AND_REG_SET (nonequal, b->global_live_at_end); | |
394 | ||
395 | EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, goto failed_exit;); | |
396 | ||
397 | BITMAP_XFREE (nonequal); | |
398 | cselib_finish (); | |
399 | if ((comparison_dominates_p (code1, code2) != 0) | |
4deaa2f8 | 400 | != (XEXP (SET_SRC (set2), 1) == pc_rtx)) |
8ecba28a JH |
401 | return BRANCH_EDGE (b); |
402 | else | |
403 | return FALLTHRU_EDGE (b); | |
404 | ||
405 | failed_exit: | |
406 | BITMAP_XFREE (nonequal); | |
407 | cselib_finish (); | |
408 | return NULL; | |
409 | } | |
410 | \f | |
402209ff | 411 | /* Attempt to forward edges leaving basic block B. |
eaec9b3d | 412 | Return true if successful. */ |
402209ff JH |
413 | |
414 | static bool | |
415 | try_forward_edges (mode, b) | |
416 | basic_block b; | |
417 | int mode; | |
418 | { | |
419 | bool changed = false; | |
1c570418 | 420 | edge e, next, *threaded_edges = NULL; |
402209ff | 421 | |
5f0d2358 | 422 | for (e = b->succ; e; e = next) |
402209ff JH |
423 | { |
424 | basic_block target, first; | |
425 | int counter; | |
8ecba28a | 426 | bool threaded = false; |
bcb3bc6d | 427 | int nthreaded_edges = 0; |
402209ff JH |
428 | |
429 | next = e->succ_next; | |
430 | ||
431 | /* Skip complex edges because we don't know how to update them. | |
432 | ||
eaec9b3d | 433 | Still handle fallthru edges, as we can succeed to forward fallthru |
402209ff | 434 | edge to the same place as the branch edge of conditional branch |
eaec9b3d | 435 | and turn conditional branch to an unconditional branch. */ |
402209ff JH |
436 | if (e->flags & EDGE_COMPLEX) |
437 | continue; | |
438 | ||
439 | target = first = e->dest; | |
440 | counter = 0; | |
441 | ||
0b17ab2f | 442 | while (counter < n_basic_blocks) |
402209ff | 443 | { |
8ecba28a JH |
444 | basic_block new_target = NULL; |
445 | bool new_target_threaded = false; | |
446 | ||
447 | if (FORWARDER_BLOCK_P (target) | |
448 | && target->succ->dest != EXIT_BLOCK_PTR) | |
449 | { | |
450 | /* Bypass trivial infinite loops. */ | |
451 | if (target == target->succ->dest) | |
0b17ab2f | 452 | counter = n_basic_blocks; |
8ecba28a JH |
453 | new_target = target->succ->dest; |
454 | } | |
5f0d2358 | 455 | |
8ecba28a JH |
456 | /* Allow to thread only over one edge at time to simplify updating |
457 | of probabilities. */ | |
1c570418 | 458 | else if (mode & CLEANUP_THREADING) |
8ecba28a | 459 | { |
1c570418 JH |
460 | edge t = thread_jump (mode, e, target); |
461 | if (t) | |
8ecba28a | 462 | { |
bcb3bc6d | 463 | if (!threaded_edges) |
1c570418 | 464 | threaded_edges = xmalloc (sizeof (*threaded_edges) |
0b17ab2f | 465 | * n_basic_blocks); |
3b3b1e32 RH |
466 | else |
467 | { | |
468 | int i; | |
469 | ||
470 | /* Detect an infinite loop across blocks not | |
471 | including the start block. */ | |
472 | for (i = 0; i < nthreaded_edges; ++i) | |
473 | if (threaded_edges[i] == t) | |
474 | break; | |
475 | if (i < nthreaded_edges) | |
b90e45ae | 476 | { |
0b17ab2f | 477 | counter = n_basic_blocks; |
b90e45ae JH |
478 | break; |
479 | } | |
3b3b1e32 RH |
480 | } |
481 | ||
482 | /* Detect an infinite loop across the start block. */ | |
483 | if (t->dest == b) | |
484 | break; | |
485 | ||
0b17ab2f | 486 | if (nthreaded_edges >= n_basic_blocks) |
3b3b1e32 | 487 | abort (); |
1c570418 | 488 | threaded_edges[nthreaded_edges++] = t; |
3b3b1e32 RH |
489 | |
490 | new_target = t->dest; | |
491 | new_target_threaded = true; | |
8ecba28a JH |
492 | } |
493 | } | |
5f0d2358 | 494 | |
8ecba28a JH |
495 | if (!new_target) |
496 | break; | |
402209ff JH |
497 | |
498 | /* Avoid killing of loop pre-headers, as it is the place loop | |
499 | optimizer wants to hoist code to. | |
500 | ||
501 | For fallthru forwarders, the LOOP_BEG note must appear between | |
502 | the header of block and CODE_LABEL of the loop, for non forwarders | |
503 | it must appear before the JUMP_INSN. */ | |
504 | if (mode & CLEANUP_PRE_LOOP) | |
505 | { | |
506 | rtx insn = (target->succ->flags & EDGE_FALLTHRU | |
f87c27b4 | 507 | ? target->head : prev_nonnote_insn (target->end)); |
402209ff JH |
508 | |
509 | if (GET_CODE (insn) != NOTE) | |
510 | insn = NEXT_INSN (insn); | |
511 | ||
5f0d2358 | 512 | for (; insn && GET_CODE (insn) != CODE_LABEL && !INSN_P (insn); |
402209ff JH |
513 | insn = NEXT_INSN (insn)) |
514 | if (GET_CODE (insn) == NOTE | |
515 | && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) | |
516 | break; | |
517 | ||
518 | if (GET_CODE (insn) == NOTE) | |
519 | break; | |
520 | } | |
5f0d2358 | 521 | |
8ecba28a JH |
522 | counter++; |
523 | target = new_target; | |
524 | threaded |= new_target_threaded; | |
f87c27b4 | 525 | } |
402209ff | 526 | |
0b17ab2f | 527 | if (counter >= n_basic_blocks) |
402209ff JH |
528 | { |
529 | if (rtl_dump_file) | |
530 | fprintf (rtl_dump_file, "Infinite loop in BB %i.\n", | |
0b17ab2f | 531 | target->index); |
402209ff JH |
532 | } |
533 | else if (target == first) | |
534 | ; /* We didn't do anything. */ | |
535 | else | |
536 | { | |
537 | /* Save the values now, as the edge may get removed. */ | |
538 | gcov_type edge_count = e->count; | |
539 | int edge_probability = e->probability; | |
8ecba28a | 540 | int edge_frequency; |
1c570418 | 541 | int n = 0; |
402209ff | 542 | |
6ee3c8e4 JJ |
543 | /* Don't force if target is exit block. */ |
544 | if (threaded && target != EXIT_BLOCK_PTR) | |
402209ff | 545 | { |
8ecba28a JH |
546 | notice_new_block (redirect_edge_and_branch_force (e, target)); |
547 | if (rtl_dump_file) | |
f87c27b4 | 548 | fprintf (rtl_dump_file, "Conditionals threaded.\n"); |
402209ff | 549 | } |
8ecba28a | 550 | else if (!redirect_edge_and_branch (e, target)) |
402209ff JH |
551 | { |
552 | if (rtl_dump_file) | |
5f0d2358 RK |
553 | fprintf (rtl_dump_file, |
554 | "Forwarding edge %i->%i to %i failed.\n", | |
0b17ab2f | 555 | b->index, e->dest->index, target->index); |
8ecba28a | 556 | continue; |
402209ff | 557 | } |
5f0d2358 | 558 | |
8ecba28a JH |
559 | /* We successfully forwarded the edge. Now update profile |
560 | data: for each edge we traversed in the chain, remove | |
561 | the original edge's execution count. */ | |
562 | edge_frequency = ((edge_probability * b->frequency | |
563 | + REG_BR_PROB_BASE / 2) | |
564 | / REG_BR_PROB_BASE); | |
565 | ||
566 | if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b)) | |
567 | BB_SET_FLAG (b, BB_FORWARDER_BLOCK); | |
8ecba28a JH |
568 | |
569 | do | |
570 | { | |
571 | edge t; | |
5f0d2358 | 572 | |
8ecba28a | 573 | first->count -= edge_count; |
b446e5a2 JH |
574 | if (first->count < 0) |
575 | first->count = 0; | |
8ecba28a | 576 | first->frequency -= edge_frequency; |
b446e5a2 JH |
577 | if (first->frequency < 0) |
578 | first->frequency = 0; | |
8ecba28a | 579 | if (first->succ->succ_next) |
3b3b1e32 | 580 | { |
bcb3bc6d JH |
581 | edge e; |
582 | int prob; | |
3b3b1e32 RH |
583 | if (n >= nthreaded_edges) |
584 | abort (); | |
585 | t = threaded_edges [n++]; | |
bcb3bc6d JH |
586 | if (t->src != first) |
587 | abort (); | |
588 | if (first->frequency) | |
589 | prob = edge_frequency * REG_BR_PROB_BASE / first->frequency; | |
590 | else | |
591 | prob = 0; | |
b446e5a2 JH |
592 | if (prob > t->probability) |
593 | prob = t->probability; | |
bcb3bc6d JH |
594 | t->probability -= prob; |
595 | prob = REG_BR_PROB_BASE - prob; | |
b446e5a2 | 596 | if (prob <= 0) |
bcb3bc6d JH |
597 | { |
598 | first->succ->probability = REG_BR_PROB_BASE; | |
599 | first->succ->succ_next->probability = 0; | |
600 | } | |
601 | else | |
602 | for (e = first->succ; e; e = e->succ_next) | |
603 | e->probability = ((e->probability * REG_BR_PROB_BASE) | |
604 | / (double) prob); | |
b446e5a2 | 605 | update_br_prob_note (first); |
3b3b1e32 | 606 | } |
8ecba28a | 607 | else |
bcb3bc6d JH |
608 | { |
609 | /* It is possible that as the result of | |
610 | threading we've removed edge as it is | |
611 | threaded to the fallthru edge. Avoid | |
612 | getting out of sync. */ | |
613 | if (n < nthreaded_edges | |
614 | && first == threaded_edges [n]->src) | |
615 | n++; | |
616 | t = first->succ; | |
f87c27b4 | 617 | } |
5f0d2358 | 618 | |
b446e5a2 JH |
619 | t->count -= edge_count; |
620 | if (t->count < 0) | |
621 | t->count = 0; | |
8ecba28a JH |
622 | first = t->dest; |
623 | } | |
624 | while (first != target); | |
625 | ||
626 | changed = true; | |
402209ff JH |
627 | } |
628 | } | |
629 | ||
1c570418 JH |
630 | if (threaded_edges) |
631 | free (threaded_edges); | |
402209ff JH |
632 | return changed; |
633 | } | |
634 | \f | |
ec10f7c7 RH |
635 | /* Return true if LABEL is a target of JUMP_INSN. This applies only |
636 | to non-complex jumps. That is, direct unconditional, conditional, | |
637 | and tablejumps, but not computed jumps or returns. It also does | |
638 | not apply to the fallthru case of a conditional jump. */ | |
639 | ||
640 | static bool | |
641 | label_is_jump_target_p (label, jump_insn) | |
642 | rtx label, jump_insn; | |
643 | { | |
644 | rtx tmp = JUMP_LABEL (jump_insn); | |
645 | ||
646 | if (label == tmp) | |
647 | return true; | |
648 | ||
649 | if (tmp != NULL_RTX | |
650 | && (tmp = NEXT_INSN (tmp)) != NULL_RTX | |
651 | && GET_CODE (tmp) == JUMP_INSN | |
652 | && (tmp = PATTERN (tmp), | |
653 | GET_CODE (tmp) == ADDR_VEC | |
654 | || GET_CODE (tmp) == ADDR_DIFF_VEC)) | |
655 | { | |
656 | rtvec vec = XVEC (tmp, GET_CODE (tmp) == ADDR_DIFF_VEC); | |
657 | int i, veclen = GET_NUM_ELEM (vec); | |
658 | ||
659 | for (i = 0; i < veclen; ++i) | |
660 | if (XEXP (RTVEC_ELT (vec, i), 0) == label) | |
661 | return true; | |
662 | } | |
663 | ||
664 | return false; | |
665 | } | |
666 | ||
4262e623 JH |
667 | /* Return true if LABEL is used for tail recursion. */ |
668 | ||
669 | static bool | |
402209ff JH |
670 | tail_recursion_label_p (label) |
671 | rtx label; | |
672 | { | |
673 | rtx x; | |
674 | ||
675 | for (x = tail_recursion_label_list; x; x = XEXP (x, 1)) | |
676 | if (label == XEXP (x, 0)) | |
4262e623 | 677 | return true; |
402209ff | 678 | |
4262e623 | 679 | return false; |
402209ff JH |
680 | } |
681 | ||
682 | /* Blocks A and B are to be merged into a single block. A has no incoming | |
683 | fallthru edge, so it can be moved before B without adding or modifying | |
684 | any jumps (aside from the jump from A to B). */ | |
685 | ||
4262e623 | 686 | static void |
402209ff JH |
687 | merge_blocks_move_predecessor_nojumps (a, b) |
688 | basic_block a, b; | |
689 | { | |
690 | rtx barrier; | |
0b17ab2f | 691 | int index; |
402209ff JH |
692 | |
693 | barrier = next_nonnote_insn (a->end); | |
694 | if (GET_CODE (barrier) != BARRIER) | |
695 | abort (); | |
53c17031 | 696 | delete_insn (barrier); |
402209ff JH |
697 | |
698 | /* Move block and loop notes out of the chain so that we do not | |
699 | disturb their order. | |
700 | ||
701 | ??? A better solution would be to squeeze out all the non-nested notes | |
702 | and adjust the block trees appropriately. Even better would be to have | |
703 | a tighter connection between block trees and rtl so that this is not | |
704 | necessary. */ | |
2b7d71b2 JJ |
705 | if (squeeze_notes (&a->head, &a->end)) |
706 | abort (); | |
402209ff JH |
707 | |
708 | /* Scramble the insn chain. */ | |
709 | if (a->end != PREV_INSN (b->head)) | |
3c030e88 | 710 | reorder_insns_nobb (a->head, a->end, PREV_INSN (b->head)); |
38c1593d | 711 | a->flags |= BB_DIRTY; |
402209ff JH |
712 | |
713 | if (rtl_dump_file) | |
5f0d2358 | 714 | fprintf (rtl_dump_file, "Moved block %d before %d and merged.\n", |
0b17ab2f | 715 | a->index, b->index); |
402209ff | 716 | |
0b17ab2f RH |
717 | /* Swap the records for the two blocks around. Although we are deleting B, |
718 | A is now where B was and we want to compact the BB array from where | |
719 | A used to be. */ | |
720 | BASIC_BLOCK (a->index) = b; | |
721 | BASIC_BLOCK (b->index) = a; | |
722 | index = a->index; | |
723 | a->index = b->index; | |
724 | b->index = index; | |
402209ff | 725 | |
918ed612 ZD |
726 | unlink_block (a); |
727 | link_block (a, b->prev_bb); | |
728 | ||
402209ff JH |
729 | /* Now blocks A and B are contiguous. Merge them. */ |
730 | merge_blocks_nomove (a, b); | |
402209ff JH |
731 | } |
732 | ||
733 | /* Blocks A and B are to be merged into a single block. B has no outgoing | |
734 | fallthru edge, so it can be moved after A without adding or modifying | |
735 | any jumps (aside from the jump from A to B). */ | |
736 | ||
4262e623 | 737 | static void |
402209ff JH |
738 | merge_blocks_move_successor_nojumps (a, b) |
739 | basic_block a, b; | |
740 | { | |
f62ce55b | 741 | rtx barrier, real_b_end; |
402209ff | 742 | |
f62ce55b | 743 | real_b_end = b->end; |
402209ff JH |
744 | barrier = NEXT_INSN (b->end); |
745 | ||
746 | /* Recognize a jump table following block B. */ | |
747 | if (barrier | |
748 | && GET_CODE (barrier) == CODE_LABEL | |
749 | && NEXT_INSN (barrier) | |
750 | && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN | |
751 | && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC | |
752 | || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC)) | |
753 | { | |
f62ce55b RE |
754 | /* Temporarily add the table jump insn to b, so that it will also |
755 | be moved to the correct location. */ | |
402209ff JH |
756 | b->end = NEXT_INSN (barrier); |
757 | barrier = NEXT_INSN (b->end); | |
758 | } | |
759 | ||
760 | /* There had better have been a barrier there. Delete it. */ | |
761 | if (barrier && GET_CODE (barrier) == BARRIER) | |
53c17031 | 762 | delete_insn (barrier); |
402209ff JH |
763 | |
764 | /* Move block and loop notes out of the chain so that we do not | |
765 | disturb their order. | |
766 | ||
767 | ??? A better solution would be to squeeze out all the non-nested notes | |
768 | and adjust the block trees appropriately. Even better would be to have | |
769 | a tighter connection between block trees and rtl so that this is not | |
770 | necessary. */ | |
2b7d71b2 JJ |
771 | if (squeeze_notes (&b->head, &b->end)) |
772 | abort (); | |
402209ff JH |
773 | |
774 | /* Scramble the insn chain. */ | |
3c030e88 | 775 | reorder_insns_nobb (b->head, b->end, a->end); |
402209ff | 776 | |
f62ce55b RE |
777 | /* Restore the real end of b. */ |
778 | b->end = real_b_end; | |
779 | ||
402209ff | 780 | if (rtl_dump_file) |
5f0d2358 | 781 | fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n", |
0b17ab2f | 782 | b->index, a->index); |
2150ad33 RH |
783 | |
784 | /* Now blocks A and B are contiguous. Merge them. */ | |
785 | merge_blocks_nomove (a, b); | |
402209ff JH |
786 | } |
787 | ||
788 | /* Attempt to merge basic blocks that are potentially non-adjacent. | |
789 | Return true iff the attempt succeeded. */ | |
790 | ||
4262e623 | 791 | static bool |
402209ff JH |
792 | merge_blocks (e, b, c, mode) |
793 | edge e; | |
794 | basic_block b, c; | |
795 | int mode; | |
796 | { | |
797 | /* If C has a tail recursion label, do not merge. There is no | |
798 | edge recorded from the call_placeholder back to this label, as | |
799 | that would make optimize_sibling_and_tail_recursive_calls more | |
800 | complex for no gain. */ | |
4262e623 JH |
801 | if ((mode & CLEANUP_PRE_SIBCALL) |
802 | && GET_CODE (c->head) == CODE_LABEL | |
402209ff | 803 | && tail_recursion_label_p (c->head)) |
4262e623 | 804 | return false; |
402209ff JH |
805 | |
806 | /* If B has a fallthru edge to C, no need to move anything. */ | |
807 | if (e->flags & EDGE_FALLTHRU) | |
808 | { | |
0b17ab2f | 809 | int b_index = b->index, c_index = c->index; |
402209ff | 810 | merge_blocks_nomove (b, c); |
635559ab | 811 | update_forwarder_flag (b); |
402209ff JH |
812 | |
813 | if (rtl_dump_file) | |
5f0d2358 | 814 | fprintf (rtl_dump_file, "Merged %d and %d without moving.\n", |
f87c27b4 | 815 | b_index, c_index); |
402209ff | 816 | |
4262e623 | 817 | return true; |
402209ff | 818 | } |
5f0d2358 | 819 | |
402209ff JH |
820 | /* Otherwise we will need to move code around. Do that only if expensive |
821 | transformations are allowed. */ | |
822 | else if (mode & CLEANUP_EXPENSIVE) | |
823 | { | |
4262e623 JH |
824 | edge tmp_edge, b_fallthru_edge; |
825 | bool c_has_outgoing_fallthru; | |
826 | bool b_has_incoming_fallthru; | |
402209ff JH |
827 | |
828 | /* Avoid overactive code motion, as the forwarder blocks should be | |
829 | eliminated by edge redirection instead. One exception might have | |
830 | been if B is a forwarder block and C has no fallthru edge, but | |
831 | that should be cleaned up by bb-reorder instead. */ | |
635559ab | 832 | if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c)) |
4262e623 | 833 | return false; |
402209ff JH |
834 | |
835 | /* We must make sure to not munge nesting of lexical blocks, | |
836 | and loop notes. This is done by squeezing out all the notes | |
837 | and leaving them there to lie. Not ideal, but functional. */ | |
838 | ||
839 | for (tmp_edge = c->succ; tmp_edge; tmp_edge = tmp_edge->succ_next) | |
840 | if (tmp_edge->flags & EDGE_FALLTHRU) | |
841 | break; | |
5f0d2358 | 842 | |
402209ff | 843 | c_has_outgoing_fallthru = (tmp_edge != NULL); |
402209ff JH |
844 | |
845 | for (tmp_edge = b->pred; tmp_edge; tmp_edge = tmp_edge->pred_next) | |
846 | if (tmp_edge->flags & EDGE_FALLTHRU) | |
847 | break; | |
5f0d2358 | 848 | |
402209ff | 849 | b_has_incoming_fallthru = (tmp_edge != NULL); |
4262e623 JH |
850 | b_fallthru_edge = tmp_edge; |
851 | ||
852 | /* Otherwise, we're going to try to move C after B. If C does | |
853 | not have an outgoing fallthru, then it can be moved | |
854 | immediately after B without introducing or modifying jumps. */ | |
855 | if (! c_has_outgoing_fallthru) | |
856 | { | |
857 | merge_blocks_move_successor_nojumps (b, c); | |
858 | return true; | |
859 | } | |
402209ff JH |
860 | |
861 | /* If B does not have an incoming fallthru, then it can be moved | |
862 | immediately before C without introducing or modifying jumps. | |
863 | C cannot be the first block, so we do not have to worry about | |
864 | accessing a non-existent block. */ | |
402209ff | 865 | |
4262e623 JH |
866 | if (b_has_incoming_fallthru) |
867 | { | |
473fb060 | 868 | basic_block bb; |
5f0d2358 | 869 | |
4262e623 JH |
870 | if (b_fallthru_edge->src == ENTRY_BLOCK_PTR) |
871 | return false; | |
7dddfb65 JH |
872 | bb = force_nonfallthru (b_fallthru_edge); |
873 | if (bb) | |
874 | notice_new_block (bb); | |
4262e623 | 875 | } |
5f0d2358 | 876 | |
4262e623 JH |
877 | merge_blocks_move_predecessor_nojumps (b, c); |
878 | return true; | |
402209ff | 879 | } |
5f0d2358 | 880 | |
4262e623 | 881 | return false; |
402209ff JH |
882 | } |
883 | \f | |
0dd0e980 JH |
884 | |
885 | /* Return true if I1 and I2 are equivalent and thus can be crossjumped. */ | |
886 | ||
887 | static bool | |
888 | insns_match_p (mode, i1, i2) | |
f87c27b4 KH |
889 | int mode ATTRIBUTE_UNUSED; |
890 | rtx i1, i2; | |
0dd0e980 JH |
891 | { |
892 | rtx p1, p2; | |
893 | ||
894 | /* Verify that I1 and I2 are equivalent. */ | |
895 | if (GET_CODE (i1) != GET_CODE (i2)) | |
896 | return false; | |
897 | ||
898 | p1 = PATTERN (i1); | |
899 | p2 = PATTERN (i2); | |
900 | ||
901 | if (GET_CODE (p1) != GET_CODE (p2)) | |
902 | return false; | |
903 | ||
904 | /* If this is a CALL_INSN, compare register usage information. | |
905 | If we don't check this on stack register machines, the two | |
906 | CALL_INSNs might be merged leaving reg-stack.c with mismatching | |
907 | numbers of stack registers in the same basic block. | |
908 | If we don't check this on machines with delay slots, a delay slot may | |
909 | be filled that clobbers a parameter expected by the subroutine. | |
910 | ||
911 | ??? We take the simple route for now and assume that if they're | |
912 | equal, they were constructed identically. */ | |
913 | ||
914 | if (GET_CODE (i1) == CALL_INSN | |
915 | && !rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1), | |
916 | CALL_INSN_FUNCTION_USAGE (i2))) | |
917 | return false; | |
918 | ||
919 | #ifdef STACK_REGS | |
920 | /* If cross_jump_death_matters is not 0, the insn's mode | |
921 | indicates whether or not the insn contains any stack-like | |
922 | regs. */ | |
923 | ||
924 | if ((mode & CLEANUP_POST_REGSTACK) && stack_regs_mentioned (i1)) | |
925 | { | |
926 | /* If register stack conversion has already been done, then | |
927 | death notes must also be compared before it is certain that | |
928 | the two instruction streams match. */ | |
929 | ||
930 | rtx note; | |
931 | HARD_REG_SET i1_regset, i2_regset; | |
932 | ||
933 | CLEAR_HARD_REG_SET (i1_regset); | |
934 | CLEAR_HARD_REG_SET (i2_regset); | |
935 | ||
936 | for (note = REG_NOTES (i1); note; note = XEXP (note, 1)) | |
937 | if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) | |
938 | SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0))); | |
939 | ||
940 | for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) | |
941 | if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) | |
942 | SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); | |
943 | ||
944 | GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done); | |
945 | ||
946 | return false; | |
947 | ||
948 | done: | |
949 | ; | |
950 | } | |
951 | #endif | |
952 | ||
953 | if (reload_completed | |
954 | ? ! rtx_renumbered_equal_p (p1, p2) : ! rtx_equal_p (p1, p2)) | |
955 | { | |
956 | /* The following code helps take care of G++ cleanups. */ | |
957 | rtx equiv1 = find_reg_equal_equiv_note (i1); | |
958 | rtx equiv2 = find_reg_equal_equiv_note (i2); | |
959 | ||
960 | if (equiv1 && equiv2 | |
961 | /* If the equivalences are not to a constant, they may | |
962 | reference pseudos that no longer exist, so we can't | |
963 | use them. */ | |
964 | && (! reload_completed | |
965 | || (CONSTANT_P (XEXP (equiv1, 0)) | |
966 | && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0))))) | |
967 | { | |
968 | rtx s1 = single_set (i1); | |
969 | rtx s2 = single_set (i2); | |
970 | if (s1 != 0 && s2 != 0 | |
971 | && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2))) | |
972 | { | |
973 | validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1); | |
974 | validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1); | |
975 | if (! rtx_renumbered_equal_p (p1, p2)) | |
976 | cancel_changes (0); | |
977 | else if (apply_change_group ()) | |
978 | return true; | |
979 | } | |
980 | } | |
5f0d2358 | 981 | |
0dd0e980 JH |
982 | return false; |
983 | } | |
5f0d2358 | 984 | |
0dd0e980 JH |
985 | return true; |
986 | } | |
987 | \f | |
402209ff JH |
988 | /* Look through the insns at the end of BB1 and BB2 and find the longest |
989 | sequence that are equivalent. Store the first insns for that sequence | |
990 | in *F1 and *F2 and return the sequence length. | |
991 | ||
992 | To simplify callers of this function, if the blocks match exactly, | |
993 | store the head of the blocks in *F1 and *F2. */ | |
994 | ||
995 | static int | |
996 | flow_find_cross_jump (mode, bb1, bb2, f1, f2) | |
997 | int mode ATTRIBUTE_UNUSED; | |
998 | basic_block bb1, bb2; | |
999 | rtx *f1, *f2; | |
1000 | { | |
0dd0e980 | 1001 | rtx i1, i2, last1, last2, afterlast1, afterlast2; |
402209ff JH |
1002 | int ninsns = 0; |
1003 | ||
1004 | /* Skip simple jumps at the end of the blocks. Complex jumps still | |
1005 | need to be compared for equivalence, which we'll do below. */ | |
1006 | ||
1007 | i1 = bb1->end; | |
08f7f057 | 1008 | last1 = afterlast1 = last2 = afterlast2 = NULL_RTX; |
402209ff JH |
1009 | if (onlyjump_p (i1) |
1010 | || (returnjump_p (i1) && !side_effects_p (PATTERN (i1)))) | |
08f7f057 JH |
1011 | { |
1012 | last1 = i1; | |
08f7f057 JH |
1013 | i1 = PREV_INSN (i1); |
1014 | } | |
5f0d2358 | 1015 | |
402209ff JH |
1016 | i2 = bb2->end; |
1017 | if (onlyjump_p (i2) | |
1018 | || (returnjump_p (i2) && !side_effects_p (PATTERN (i2)))) | |
08f7f057 JH |
1019 | { |
1020 | last2 = i2; | |
d1ee6d9b JH |
1021 | /* Count everything except for unconditional jump as insn. */ |
1022 | if (!simplejump_p (i2) && !returnjump_p (i2) && last1) | |
1023 | ninsns++; | |
08f7f057 JH |
1024 | i2 = PREV_INSN (i2); |
1025 | } | |
402209ff | 1026 | |
402209ff JH |
1027 | while (true) |
1028 | { | |
1029 | /* Ignore notes. */ | |
08f7f057 | 1030 | while (!active_insn_p (i1) && i1 != bb1->head) |
402209ff | 1031 | i1 = PREV_INSN (i1); |
5f0d2358 | 1032 | |
08f7f057 | 1033 | while (!active_insn_p (i2) && i2 != bb2->head) |
402209ff JH |
1034 | i2 = PREV_INSN (i2); |
1035 | ||
1036 | if (i1 == bb1->head || i2 == bb2->head) | |
1037 | break; | |
1038 | ||
0dd0e980 | 1039 | if (!insns_match_p (mode, i1, i2)) |
402209ff JH |
1040 | break; |
1041 | ||
402209ff | 1042 | /* Don't begin a cross-jump with a USE or CLOBBER insn. */ |
0dd0e980 | 1043 | if (active_insn_p (i1)) |
402209ff | 1044 | { |
7106d491 RE |
1045 | /* If the merged insns have different REG_EQUAL notes, then |
1046 | remove them. */ | |
1047 | rtx equiv1 = find_reg_equal_equiv_note (i1); | |
1048 | rtx equiv2 = find_reg_equal_equiv_note (i2); | |
1049 | ||
1050 | if (equiv1 && !equiv2) | |
1051 | remove_note (i1, equiv1); | |
1052 | else if (!equiv1 && equiv2) | |
1053 | remove_note (i2, equiv2); | |
1054 | else if (equiv1 && equiv2 | |
1055 | && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0))) | |
1056 | { | |
1057 | remove_note (i1, equiv1); | |
1058 | remove_note (i2, equiv2); | |
1059 | } | |
f87c27b4 | 1060 | |
402209ff JH |
1061 | afterlast1 = last1, afterlast2 = last2; |
1062 | last1 = i1, last2 = i2; | |
f87c27b4 | 1063 | ninsns++; |
402209ff | 1064 | } |
5f0d2358 | 1065 | |
402209ff JH |
1066 | i1 = PREV_INSN (i1); |
1067 | i2 = PREV_INSN (i2); | |
1068 | } | |
1069 | ||
1070 | #ifdef HAVE_cc0 | |
5f0d2358 RK |
1071 | /* Don't allow the insn after a compare to be shared by |
1072 | cross-jumping unless the compare is also shared. */ | |
1073 | if (ninsns && reg_mentioned_p (cc0_rtx, last1) && ! sets_cc0_p (last1)) | |
1074 | last1 = afterlast1, last2 = afterlast2, ninsns--; | |
402209ff JH |
1075 | #endif |
1076 | ||
eaec9b3d | 1077 | /* Include preceding notes and labels in the cross-jump. One, |
402209ff JH |
1078 | this may bring us to the head of the blocks as requested above. |
1079 | Two, it keeps line number notes as matched as may be. */ | |
1080 | if (ninsns) | |
1081 | { | |
08f7f057 | 1082 | while (last1 != bb1->head && !active_insn_p (PREV_INSN (last1))) |
402209ff | 1083 | last1 = PREV_INSN (last1); |
5f0d2358 | 1084 | |
402209ff JH |
1085 | if (last1 != bb1->head && GET_CODE (PREV_INSN (last1)) == CODE_LABEL) |
1086 | last1 = PREV_INSN (last1); | |
5f0d2358 | 1087 | |
08f7f057 | 1088 | while (last2 != bb2->head && !active_insn_p (PREV_INSN (last2))) |
402209ff | 1089 | last2 = PREV_INSN (last2); |
5f0d2358 | 1090 | |
402209ff JH |
1091 | if (last2 != bb2->head && GET_CODE (PREV_INSN (last2)) == CODE_LABEL) |
1092 | last2 = PREV_INSN (last2); | |
1093 | ||
1094 | *f1 = last1; | |
1095 | *f2 = last2; | |
1096 | } | |
1097 | ||
1098 | return ninsns; | |
1099 | } | |
1100 | ||
1101 | /* Return true iff outgoing edges of BB1 and BB2 match, together with | |
1102 | the branch instruction. This means that if we commonize the control | |
1103 | flow before end of the basic block, the semantic remains unchanged. | |
1104 | ||
1105 | We may assume that there exists one edge with a common destination. */ | |
1106 | ||
1107 | static bool | |
0dd0e980 JH |
1108 | outgoing_edges_match (mode, bb1, bb2) |
1109 | int mode; | |
402209ff JH |
1110 | basic_block bb1; |
1111 | basic_block bb2; | |
1112 | { | |
0dd0e980 JH |
1113 | int nehedges1 = 0, nehedges2 = 0; |
1114 | edge fallthru1 = 0, fallthru2 = 0; | |
1115 | edge e1, e2; | |
1116 | ||
c04cf67b RH |
1117 | /* If BB1 has only one successor, we may be looking at either an |
1118 | unconditional jump, or a fake edge to exit. */ | |
d1ee6d9b JH |
1119 | if (bb1->succ && !bb1->succ->succ_next |
1120 | && !(bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE))) | |
5f0d2358 RK |
1121 | return (bb2->succ && !bb2->succ->succ_next |
1122 | && (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0); | |
402209ff JH |
1123 | |
1124 | /* Match conditional jumps - this may get tricky when fallthru and branch | |
1125 | edges are crossed. */ | |
1126 | if (bb1->succ | |
1127 | && bb1->succ->succ_next | |
1128 | && !bb1->succ->succ_next->succ_next | |
d1ee6d9b JH |
1129 | && any_condjump_p (bb1->end) |
1130 | && onlyjump_p (bb1->end)) | |
402209ff JH |
1131 | { |
1132 | edge b1, f1, b2, f2; | |
1133 | bool reverse, match; | |
1134 | rtx set1, set2, cond1, cond2; | |
1135 | enum rtx_code code1, code2; | |
1136 | ||
1137 | if (!bb2->succ | |
f87c27b4 | 1138 | || !bb2->succ->succ_next |
0a2ed1f1 | 1139 | || bb2->succ->succ_next->succ_next |
d1ee6d9b | 1140 | || !any_condjump_p (bb2->end) |
0a2ed1f1 JH |
1141 | || !onlyjump_p (bb2->end)) |
1142 | return false; | |
1143 | ||
1144 | /* Do not crossjump across loop boundaries. This is a temporary | |
1145 | workaround for the common scenario in which crossjumping results | |
1146 | in killing the duplicated loop condition, making bb-reorder rotate | |
1147 | the loop incorectly, leaving an extra unconditional jump inside | |
1148 | the loop. | |
1149 | ||
1150 | This check should go away once bb-reorder knows how to duplicate | |
1151 | code in this case or rotate the loops to avoid this scenario. */ | |
1152 | if (bb1->loop_depth != bb2->loop_depth) | |
402209ff JH |
1153 | return false; |
1154 | ||
1155 | b1 = BRANCH_EDGE (bb1); | |
1156 | b2 = BRANCH_EDGE (bb2); | |
1157 | f1 = FALLTHRU_EDGE (bb1); | |
1158 | f2 = FALLTHRU_EDGE (bb2); | |
1159 | ||
1160 | /* Get around possible forwarders on fallthru edges. Other cases | |
1161 | should be optimized out already. */ | |
635559ab | 1162 | if (FORWARDER_BLOCK_P (f1->dest)) |
402209ff | 1163 | f1 = f1->dest->succ; |
5f0d2358 | 1164 | |
635559ab | 1165 | if (FORWARDER_BLOCK_P (f2->dest)) |
402209ff JH |
1166 | f2 = f2->dest->succ; |
1167 | ||
1168 | /* To simplify use of this function, return false if there are | |
1169 | unneeded forwarder blocks. These will get eliminated later | |
1170 | during cleanup_cfg. */ | |
635559ab JH |
1171 | if (FORWARDER_BLOCK_P (f1->dest) |
1172 | || FORWARDER_BLOCK_P (f2->dest) | |
1173 | || FORWARDER_BLOCK_P (b1->dest) | |
1174 | || FORWARDER_BLOCK_P (b2->dest)) | |
402209ff JH |
1175 | return false; |
1176 | ||
1177 | if (f1->dest == f2->dest && b1->dest == b2->dest) | |
1178 | reverse = false; | |
1179 | else if (f1->dest == b2->dest && b1->dest == f2->dest) | |
1180 | reverse = true; | |
1181 | else | |
1182 | return false; | |
1183 | ||
1184 | set1 = pc_set (bb1->end); | |
1185 | set2 = pc_set (bb2->end); | |
1186 | if ((XEXP (SET_SRC (set1), 1) == pc_rtx) | |
1187 | != (XEXP (SET_SRC (set2), 1) == pc_rtx)) | |
1188 | reverse = !reverse; | |
1189 | ||
1190 | cond1 = XEXP (SET_SRC (set1), 0); | |
1191 | cond2 = XEXP (SET_SRC (set2), 0); | |
1192 | code1 = GET_CODE (cond1); | |
1193 | if (reverse) | |
1194 | code2 = reversed_comparison_code (cond2, bb2->end); | |
1195 | else | |
1196 | code2 = GET_CODE (cond2); | |
5f0d2358 | 1197 | |
402209ff JH |
1198 | if (code2 == UNKNOWN) |
1199 | return false; | |
1200 | ||
1201 | /* Verify codes and operands match. */ | |
1202 | match = ((code1 == code2 | |
1203 | && rtx_renumbered_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) | |
1204 | && rtx_renumbered_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))) | |
1205 | || (code1 == swap_condition (code2) | |
1206 | && rtx_renumbered_equal_p (XEXP (cond1, 1), | |
1207 | XEXP (cond2, 0)) | |
1208 | && rtx_renumbered_equal_p (XEXP (cond1, 0), | |
1209 | XEXP (cond2, 1)))); | |
1210 | ||
1211 | /* If we return true, we will join the blocks. Which means that | |
1212 | we will only have one branch prediction bit to work with. Thus | |
1213 | we require the existing branches to have probabilities that are | |
1214 | roughly similar. */ | |
b446e5a2 JH |
1215 | if (match |
1216 | && !optimize_size | |
194734e9 JH |
1217 | && maybe_hot_bb_p (bb1) |
1218 | && maybe_hot_bb_p (bb2)) | |
402209ff | 1219 | { |
b446e5a2 | 1220 | int prob2; |
5f0d2358 | 1221 | |
b446e5a2 JH |
1222 | if (b1->dest == b2->dest) |
1223 | prob2 = b2->probability; | |
1224 | else | |
1225 | /* Do not use f2 probability as f2 may be forwarded. */ | |
1226 | prob2 = REG_BR_PROB_BASE - b2->probability; | |
402209ff | 1227 | |
0a2ed1f1 JH |
1228 | /* Fail if the difference in probabilities is greater than 50%. |
1229 | This rules out two well-predicted branches with opposite | |
1230 | outcomes. */ | |
7225b8ec | 1231 | if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2) |
402209ff | 1232 | { |
b446e5a2 JH |
1233 | if (rtl_dump_file) |
1234 | fprintf (rtl_dump_file, | |
1235 | "Outcomes of branch in bb %i and %i differs to much (%i %i)\n", | |
0b17ab2f | 1236 | bb1->index, bb2->index, b1->probability, prob2); |
5f0d2358 | 1237 | |
b446e5a2 JH |
1238 | return false; |
1239 | } | |
402209ff JH |
1240 | } |
1241 | ||
1242 | if (rtl_dump_file && match) | |
1243 | fprintf (rtl_dump_file, "Conditionals in bb %i and %i match.\n", | |
0b17ab2f | 1244 | bb1->index, bb2->index); |
402209ff JH |
1245 | |
1246 | return match; | |
1247 | } | |
1248 | ||
0dd0e980 JH |
1249 | /* Generic case - we are seeing an computed jump, table jump or trapping |
1250 | instruction. */ | |
1251 | ||
1252 | /* First ensure that the instructions match. There may be many outgoing | |
1253 | edges so this test is generally cheaper. | |
1254 | ??? Currently the tablejumps will never match, as they do have | |
1255 | different tables. */ | |
1256 | if (!insns_match_p (mode, bb1->end, bb2->end)) | |
1257 | return false; | |
1258 | ||
1259 | /* Search the outgoing edges, ensure that the counts do match, find possible | |
1260 | fallthru and exception handling edges since these needs more | |
1261 | validation. */ | |
1262 | for (e1 = bb1->succ, e2 = bb2->succ; e1 && e2; | |
1263 | e1 = e1->succ_next, e2 = e2->succ_next) | |
1264 | { | |
1265 | if (e1->flags & EDGE_EH) | |
1266 | nehedges1++; | |
5f0d2358 | 1267 | |
0dd0e980 JH |
1268 | if (e2->flags & EDGE_EH) |
1269 | nehedges2++; | |
5f0d2358 | 1270 | |
0dd0e980 JH |
1271 | if (e1->flags & EDGE_FALLTHRU) |
1272 | fallthru1 = e1; | |
1273 | if (e2->flags & EDGE_FALLTHRU) | |
1274 | fallthru2 = e2; | |
1275 | } | |
5f0d2358 | 1276 | |
0dd0e980 | 1277 | /* If number of edges of various types does not match, fail. */ |
5f0d2358 RK |
1278 | if (e1 || e2 |
1279 | || nehedges1 != nehedges2 | |
1280 | || (fallthru1 != 0) != (fallthru2 != 0)) | |
0dd0e980 JH |
1281 | return false; |
1282 | ||
1283 | /* fallthru edges must be forwarded to the same destination. */ | |
1284 | if (fallthru1) | |
1285 | { | |
1286 | basic_block d1 = (forwarder_block_p (fallthru1->dest) | |
f87c27b4 | 1287 | ? fallthru1->dest->succ->dest: fallthru1->dest); |
0dd0e980 | 1288 | basic_block d2 = (forwarder_block_p (fallthru2->dest) |
f87c27b4 | 1289 | ? fallthru2->dest->succ->dest: fallthru2->dest); |
5f0d2358 | 1290 | |
0dd0e980 JH |
1291 | if (d1 != d2) |
1292 | return false; | |
1293 | } | |
5f0d2358 | 1294 | |
0dd0e980 JH |
1295 | /* In case we do have EH edges, ensure we are in the same region. */ |
1296 | if (nehedges1) | |
1297 | { | |
1298 | rtx n1 = find_reg_note (bb1->end, REG_EH_REGION, 0); | |
1299 | rtx n2 = find_reg_note (bb2->end, REG_EH_REGION, 0); | |
5f0d2358 | 1300 | |
0dd0e980 JH |
1301 | if (XEXP (n1, 0) != XEXP (n2, 0)) |
1302 | return false; | |
1303 | } | |
5f0d2358 | 1304 | |
0dd0e980 JH |
1305 | /* We don't need to match the rest of edges as above checks should be enought |
1306 | to ensure that they are equivalent. */ | |
1307 | return true; | |
402209ff JH |
1308 | } |
1309 | ||
1310 | /* E1 and E2 are edges with the same destination block. Search their | |
1311 | predecessors for common code. If found, redirect control flow from | |
1312 | (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC. */ | |
1313 | ||
1314 | static bool | |
1315 | try_crossjump_to_edge (mode, e1, e2) | |
1316 | int mode; | |
1317 | edge e1, e2; | |
1318 | { | |
1319 | int nmatch; | |
1320 | basic_block src1 = e1->src, src2 = e2->src; | |
1321 | basic_block redirect_to; | |
1322 | rtx newpos1, newpos2; | |
1323 | edge s; | |
1324 | rtx last; | |
1325 | rtx label; | |
402209ff JH |
1326 | |
1327 | /* Search backward through forwarder blocks. We don't need to worry | |
1328 | about multiple entry or chained forwarders, as they will be optimized | |
1329 | away. We do this to look past the unconditional jump following a | |
1330 | conditional jump that is required due to the current CFG shape. */ | |
1331 | if (src1->pred | |
1332 | && !src1->pred->pred_next | |
635559ab | 1333 | && FORWARDER_BLOCK_P (src1)) |
5f0d2358 RK |
1334 | e1 = src1->pred, src1 = e1->src; |
1335 | ||
402209ff JH |
1336 | if (src2->pred |
1337 | && !src2->pred->pred_next | |
635559ab | 1338 | && FORWARDER_BLOCK_P (src2)) |
5f0d2358 | 1339 | e2 = src2->pred, src2 = e2->src; |
402209ff JH |
1340 | |
1341 | /* Nothing to do if we reach ENTRY, or a common source block. */ | |
1342 | if (src1 == ENTRY_BLOCK_PTR || src2 == ENTRY_BLOCK_PTR) | |
1343 | return false; | |
1344 | if (src1 == src2) | |
1345 | return false; | |
1346 | ||
1347 | /* Seeing more than 1 forwarder blocks would confuse us later... */ | |
635559ab JH |
1348 | if (FORWARDER_BLOCK_P (e1->dest) |
1349 | && FORWARDER_BLOCK_P (e1->dest->succ->dest)) | |
402209ff | 1350 | return false; |
5f0d2358 | 1351 | |
635559ab JH |
1352 | if (FORWARDER_BLOCK_P (e2->dest) |
1353 | && FORWARDER_BLOCK_P (e2->dest->succ->dest)) | |
402209ff JH |
1354 | return false; |
1355 | ||
1356 | /* Likewise with dead code (possibly newly created by the other optimizations | |
1357 | of cfg_cleanup). */ | |
1358 | if (!src1->pred || !src2->pred) | |
1359 | return false; | |
1360 | ||
402209ff | 1361 | /* Look for the common insn sequence, part the first ... */ |
0dd0e980 | 1362 | if (!outgoing_edges_match (mode, src1, src2)) |
402209ff JH |
1363 | return false; |
1364 | ||
1365 | /* ... and part the second. */ | |
1366 | nmatch = flow_find_cross_jump (mode, src1, src2, &newpos1, &newpos2); | |
1367 | if (!nmatch) | |
1368 | return false; | |
1369 | ||
1370 | /* Avoid splitting if possible. */ | |
1371 | if (newpos2 == src2->head) | |
1372 | redirect_to = src2; | |
1373 | else | |
1374 | { | |
1375 | if (rtl_dump_file) | |
1376 | fprintf (rtl_dump_file, "Splitting bb %i before %i insns\n", | |
0b17ab2f | 1377 | src2->index, nmatch); |
402209ff JH |
1378 | redirect_to = split_block (src2, PREV_INSN (newpos2))->dest; |
1379 | } | |
1380 | ||
1381 | if (rtl_dump_file) | |
1382 | fprintf (rtl_dump_file, | |
1383 | "Cross jumping from bb %i to bb %i; %i common insns\n", | |
0b17ab2f | 1384 | src1->index, src2->index, nmatch); |
402209ff JH |
1385 | |
1386 | redirect_to->count += src1->count; | |
1387 | redirect_to->frequency += src1->frequency; | |
2ca6672b JH |
1388 | /* We may have some registers visible trought the block. */ |
1389 | redirect_to->flags |= BB_DIRTY; | |
402209ff JH |
1390 | |
1391 | /* Recompute the frequencies and counts of outgoing edges. */ | |
1392 | for (s = redirect_to->succ; s; s = s->succ_next) | |
1393 | { | |
1394 | edge s2; | |
1395 | basic_block d = s->dest; | |
1396 | ||
635559ab | 1397 | if (FORWARDER_BLOCK_P (d)) |
402209ff | 1398 | d = d->succ->dest; |
5f0d2358 | 1399 | |
402209ff JH |
1400 | for (s2 = src1->succ; ; s2 = s2->succ_next) |
1401 | { | |
1402 | basic_block d2 = s2->dest; | |
635559ab | 1403 | if (FORWARDER_BLOCK_P (d2)) |
402209ff JH |
1404 | d2 = d2->succ->dest; |
1405 | if (d == d2) | |
1406 | break; | |
1407 | } | |
5f0d2358 | 1408 | |
402209ff JH |
1409 | s->count += s2->count; |
1410 | ||
1411 | /* Take care to update possible forwarder blocks. We verified | |
1412 | that there is no more than one in the chain, so we can't run | |
1413 | into infinite loop. */ | |
635559ab | 1414 | if (FORWARDER_BLOCK_P (s->dest)) |
402209ff JH |
1415 | { |
1416 | s->dest->succ->count += s2->count; | |
1417 | s->dest->count += s2->count; | |
1418 | s->dest->frequency += EDGE_FREQUENCY (s); | |
1419 | } | |
5f0d2358 | 1420 | |
635559ab | 1421 | if (FORWARDER_BLOCK_P (s2->dest)) |
402209ff JH |
1422 | { |
1423 | s2->dest->succ->count -= s2->count; | |
b446e5a2 JH |
1424 | if (s2->dest->succ->count < 0) |
1425 | s2->dest->succ->count = 0; | |
402209ff JH |
1426 | s2->dest->count -= s2->count; |
1427 | s2->dest->frequency -= EDGE_FREQUENCY (s); | |
b446e5a2 JH |
1428 | if (s2->dest->frequency < 0) |
1429 | s2->dest->frequency = 0; | |
1430 | if (s2->dest->count < 0) | |
1431 | s2->dest->count = 0; | |
402209ff | 1432 | } |
5f0d2358 | 1433 | |
402209ff JH |
1434 | if (!redirect_to->frequency && !src1->frequency) |
1435 | s->probability = (s->probability + s2->probability) / 2; | |
1436 | else | |
5f0d2358 RK |
1437 | s->probability |
1438 | = ((s->probability * redirect_to->frequency + | |
1439 | s2->probability * src1->frequency) | |
1440 | / (redirect_to->frequency + src1->frequency)); | |
402209ff JH |
1441 | } |
1442 | ||
b446e5a2 | 1443 | update_br_prob_note (redirect_to); |
402209ff JH |
1444 | |
1445 | /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */ | |
1446 | ||
1447 | /* Skip possible basic block header. */ | |
1448 | if (GET_CODE (newpos1) == CODE_LABEL) | |
1449 | newpos1 = NEXT_INSN (newpos1); | |
5f0d2358 | 1450 | |
402209ff JH |
1451 | if (GET_CODE (newpos1) == NOTE) |
1452 | newpos1 = NEXT_INSN (newpos1); | |
1453 | last = src1->end; | |
1454 | ||
6d2f8887 | 1455 | /* Emit the jump insn. */ |
402209ff | 1456 | label = block_label (redirect_to); |
53c17031 | 1457 | emit_jump_insn_after (gen_jump (label), src1->end); |
402209ff JH |
1458 | JUMP_LABEL (src1->end) = label; |
1459 | LABEL_NUSES (label)++; | |
402209ff JH |
1460 | |
1461 | /* Delete the now unreachable instructions. */ | |
53c17031 | 1462 | delete_insn_chain (newpos1, last); |
402209ff JH |
1463 | |
1464 | /* Make sure there is a barrier after the new jump. */ | |
1465 | last = next_nonnote_insn (src1->end); | |
1466 | if (!last || GET_CODE (last) != BARRIER) | |
1467 | emit_barrier_after (src1->end); | |
1468 | ||
1469 | /* Update CFG. */ | |
1470 | while (src1->succ) | |
1471 | remove_edge (src1->succ); | |
7ded4467 | 1472 | make_single_succ_edge (src1, redirect_to, 0); |
402209ff | 1473 | |
635559ab JH |
1474 | update_forwarder_flag (src1); |
1475 | ||
402209ff JH |
1476 | return true; |
1477 | } | |
1478 | ||
1479 | /* Search the predecessors of BB for common insn sequences. When found, | |
1480 | share code between them by redirecting control flow. Return true if | |
1481 | any changes made. */ | |
1482 | ||
1483 | static bool | |
1484 | try_crossjump_bb (mode, bb) | |
1485 | int mode; | |
1486 | basic_block bb; | |
1487 | { | |
1488 | edge e, e2, nexte2, nexte, fallthru; | |
1489 | bool changed; | |
f5eb5fd0 | 1490 | int n = 0; |
402209ff | 1491 | |
f63d1bf7 | 1492 | /* Nothing to do if there is not at least two incoming edges. */ |
402209ff JH |
1493 | if (!bb->pred || !bb->pred->pred_next) |
1494 | return false; | |
1495 | ||
1496 | /* It is always cheapest to redirect a block that ends in a branch to | |
1497 | a block that falls through into BB, as that adds no branches to the | |
1498 | program. We'll try that combination first. */ | |
f5eb5fd0 JH |
1499 | for (fallthru = bb->pred; fallthru; fallthru = fallthru->pred_next, n++) |
1500 | { | |
1501 | if (fallthru->flags & EDGE_FALLTHRU) | |
1502 | break; | |
1503 | if (n > 100) | |
1504 | return false; | |
1505 | } | |
402209ff JH |
1506 | |
1507 | changed = false; | |
1508 | for (e = bb->pred; e; e = nexte) | |
1509 | { | |
1510 | nexte = e->pred_next; | |
1511 | ||
402209ff JH |
1512 | /* As noted above, first try with the fallthru predecessor. */ |
1513 | if (fallthru) | |
1514 | { | |
1515 | /* Don't combine the fallthru edge into anything else. | |
1516 | If there is a match, we'll do it the other way around. */ | |
1517 | if (e == fallthru) | |
1518 | continue; | |
1519 | ||
1520 | if (try_crossjump_to_edge (mode, e, fallthru)) | |
1521 | { | |
1522 | changed = true; | |
1523 | nexte = bb->pred; | |
1524 | continue; | |
1525 | } | |
1526 | } | |
1527 | ||
1528 | /* Non-obvious work limiting check: Recognize that we're going | |
1529 | to call try_crossjump_bb on every basic block. So if we have | |
1530 | two blocks with lots of outgoing edges (a switch) and they | |
1531 | share lots of common destinations, then we would do the | |
1532 | cross-jump check once for each common destination. | |
1533 | ||
1534 | Now, if the blocks actually are cross-jump candidates, then | |
1535 | all of their destinations will be shared. Which means that | |
1536 | we only need check them for cross-jump candidacy once. We | |
1537 | can eliminate redundant checks of crossjump(A,B) by arbitrarily | |
1538 | choosing to do the check from the block for which the edge | |
1539 | in question is the first successor of A. */ | |
1540 | if (e->src->succ != e) | |
1541 | continue; | |
1542 | ||
1543 | for (e2 = bb->pred; e2; e2 = nexte2) | |
1544 | { | |
1545 | nexte2 = e2->pred_next; | |
1546 | ||
1547 | if (e2 == e) | |
1548 | continue; | |
1549 | ||
1550 | /* We've already checked the fallthru edge above. */ | |
1551 | if (e2 == fallthru) | |
1552 | continue; | |
1553 | ||
402209ff JH |
1554 | /* The "first successor" check above only prevents multiple |
1555 | checks of crossjump(A,B). In order to prevent redundant | |
1556 | checks of crossjump(B,A), require that A be the block | |
1557 | with the lowest index. */ | |
0b17ab2f | 1558 | if (e->src->index > e2->src->index) |
402209ff JH |
1559 | continue; |
1560 | ||
1561 | if (try_crossjump_to_edge (mode, e, e2)) | |
1562 | { | |
1563 | changed = true; | |
1564 | nexte = bb->pred; | |
1565 | break; | |
1566 | } | |
1567 | } | |
1568 | } | |
1569 | ||
1570 | return changed; | |
1571 | } | |
1572 | ||
1573 | /* Do simple CFG optimizations - basic block merging, simplifying of jump | |
1574 | instructions etc. Return nonzero if changes were made. */ | |
1575 | ||
1576 | static bool | |
1577 | try_optimize_cfg (mode) | |
1578 | int mode; | |
1579 | { | |
402209ff JH |
1580 | bool changed_overall = false; |
1581 | bool changed; | |
1582 | int iterations = 0; | |
e0082a72 | 1583 | basic_block bb, b; |
402209ff | 1584 | |
ca6c03ca JH |
1585 | if (mode & CLEANUP_CROSSJUMP) |
1586 | add_noreturn_fake_exit_edges (); | |
1587 | ||
e0082a72 ZD |
1588 | FOR_EACH_BB (bb) |
1589 | update_forwarder_flag (bb); | |
635559ab | 1590 | |
38c1593d JH |
1591 | if (mode & CLEANUP_UPDATE_LIFE) |
1592 | clear_bb_flags (); | |
1593 | ||
e4ec2cac | 1594 | if (! (* targetm.cannot_modify_jumps_p) ()) |
402209ff | 1595 | { |
e4ec2cac AO |
1596 | /* Attempt to merge blocks as made possible by edge removal. If |
1597 | a block has only one successor, and the successor has only | |
1598 | one predecessor, they may be combined. */ | |
1599 | do | |
402209ff | 1600 | { |
e4ec2cac AO |
1601 | changed = false; |
1602 | iterations++; | |
1603 | ||
1604 | if (rtl_dump_file) | |
1605 | fprintf (rtl_dump_file, | |
1606 | "\n\ntry_optimize_cfg iteration %i\n\n", | |
1607 | iterations); | |
402209ff | 1608 | |
e0082a72 | 1609 | for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR;) |
402209ff | 1610 | { |
e0082a72 | 1611 | basic_block c; |
e4ec2cac AO |
1612 | edge s; |
1613 | bool changed_here = false; | |
5f0d2358 | 1614 | |
e4ec2cac AO |
1615 | /* Delete trivially dead basic blocks. */ |
1616 | while (b->pred == NULL) | |
1617 | { | |
f6366fc7 | 1618 | c = b->prev_bb; |
e4ec2cac AO |
1619 | if (rtl_dump_file) |
1620 | fprintf (rtl_dump_file, "Deleting block %i.\n", | |
0b17ab2f | 1621 | b->index); |
e4ec2cac AO |
1622 | |
1623 | flow_delete_block (b); | |
1624 | changed = true; | |
1625 | b = c; | |
1626 | } | |
402209ff | 1627 | |
e4ec2cac AO |
1628 | /* Remove code labels no longer used. Don't do this |
1629 | before CALL_PLACEHOLDER is removed, as some branches | |
1630 | may be hidden within. */ | |
1631 | if (b->pred->pred_next == NULL | |
1632 | && (b->pred->flags & EDGE_FALLTHRU) | |
1633 | && !(b->pred->flags & EDGE_COMPLEX) | |
1634 | && GET_CODE (b->head) == CODE_LABEL | |
1635 | && (!(mode & CLEANUP_PRE_SIBCALL) | |
1636 | || !tail_recursion_label_p (b->head)) | |
1637 | /* If the previous block ends with a branch to this | |
1638 | block, we can't delete the label. Normally this | |
1639 | is a condjump that is yet to be simplified, but | |
1640 | if CASE_DROPS_THRU, this can be a tablejump with | |
1641 | some element going to the same place as the | |
1642 | default (fallthru). */ | |
1643 | && (b->pred->src == ENTRY_BLOCK_PTR | |
1644 | || GET_CODE (b->pred->src->end) != JUMP_INSN | |
1645 | || ! label_is_jump_target_p (b->head, | |
1646 | b->pred->src->end))) | |
1647 | { | |
1648 | rtx label = b->head; | |
5f0d2358 | 1649 | |
e4ec2cac AO |
1650 | b->head = NEXT_INSN (b->head); |
1651 | delete_insn_chain (label, label); | |
1652 | if (rtl_dump_file) | |
1653 | fprintf (rtl_dump_file, "Deleted label in block %i.\n", | |
0b17ab2f | 1654 | b->index); |
e4ec2cac | 1655 | } |
402209ff | 1656 | |
e4ec2cac AO |
1657 | /* If we fall through an empty block, we can remove it. */ |
1658 | if (b->pred->pred_next == NULL | |
1659 | && (b->pred->flags & EDGE_FALLTHRU) | |
1660 | && GET_CODE (b->head) != CODE_LABEL | |
1661 | && FORWARDER_BLOCK_P (b) | |
1662 | /* Note that forwarder_block_p true ensures that | |
1663 | there is a successor for this block. */ | |
1664 | && (b->succ->flags & EDGE_FALLTHRU) | |
0b17ab2f | 1665 | && n_basic_blocks > 1) |
e4ec2cac AO |
1666 | { |
1667 | if (rtl_dump_file) | |
1668 | fprintf (rtl_dump_file, | |
1669 | "Deleting fallthru block %i.\n", | |
0b17ab2f | 1670 | b->index); |
e4ec2cac | 1671 | |
f6366fc7 | 1672 | c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb; |
e4ec2cac AO |
1673 | redirect_edge_succ_nodup (b->pred, b->succ->dest); |
1674 | flow_delete_block (b); | |
1675 | changed = true; | |
1676 | b = c; | |
1677 | } | |
5f0d2358 | 1678 | |
e4ec2cac AO |
1679 | /* Merge blocks. Loop because chains of blocks might be |
1680 | combineable. */ | |
1681 | while ((s = b->succ) != NULL | |
1682 | && s->succ_next == NULL | |
1683 | && !(s->flags & EDGE_COMPLEX) | |
1684 | && (c = s->dest) != EXIT_BLOCK_PTR | |
1685 | && c->pred->pred_next == NULL | |
1686 | /* If the jump insn has side effects, | |
1687 | we can't kill the edge. */ | |
1688 | && (GET_CODE (b->end) != JUMP_INSN | |
3d4ce12a | 1689 | || simplejump_p (b->end)) |
e4ec2cac AO |
1690 | && merge_blocks (s, b, c, mode)) |
1691 | changed_here = true; | |
1692 | ||
1693 | /* Simplify branch over branch. */ | |
1694 | if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b)) | |
38c1593d | 1695 | changed_here = true; |
402209ff | 1696 | |
e4ec2cac AO |
1697 | /* If B has a single outgoing edge, but uses a |
1698 | non-trivial jump instruction without side-effects, we | |
1699 | can either delete the jump entirely, or replace it | |
1700 | with a simple unconditional jump. Use | |
1701 | redirect_edge_and_branch to do the dirty work. */ | |
1702 | if (b->succ | |
1703 | && ! b->succ->succ_next | |
1704 | && b->succ->dest != EXIT_BLOCK_PTR | |
1705 | && onlyjump_p (b->end) | |
1706 | && redirect_edge_and_branch (b->succ, b->succ->dest)) | |
1707 | { | |
e4ec2cac AO |
1708 | update_forwarder_flag (b); |
1709 | changed_here = true; | |
1710 | } | |
402209ff | 1711 | |
e4ec2cac AO |
1712 | /* Simplify branch to branch. */ |
1713 | if (try_forward_edges (mode, b)) | |
1714 | changed_here = true; | |
402209ff | 1715 | |
e4ec2cac AO |
1716 | /* Look for shared code between blocks. */ |
1717 | if ((mode & CLEANUP_CROSSJUMP) | |
1718 | && try_crossjump_bb (mode, b)) | |
1719 | changed_here = true; | |
402209ff | 1720 | |
e4ec2cac AO |
1721 | /* Don't get confused by the index shift caused by |
1722 | deleting blocks. */ | |
1723 | if (!changed_here) | |
e0082a72 | 1724 | b = b->next_bb; |
e4ec2cac AO |
1725 | else |
1726 | changed = true; | |
1727 | } | |
402209ff | 1728 | |
e4ec2cac AO |
1729 | if ((mode & CLEANUP_CROSSJUMP) |
1730 | && try_crossjump_bb (mode, EXIT_BLOCK_PTR)) | |
402209ff | 1731 | changed = true; |
402209ff JH |
1732 | |
1733 | #ifdef ENABLE_CHECKING | |
e4ec2cac AO |
1734 | if (changed) |
1735 | verify_flow_info (); | |
402209ff JH |
1736 | #endif |
1737 | ||
e4ec2cac AO |
1738 | changed_overall |= changed; |
1739 | } | |
1740 | while (changed); | |
402209ff | 1741 | } |
ca6c03ca JH |
1742 | |
1743 | if (mode & CLEANUP_CROSSJUMP) | |
1744 | remove_fake_edges (); | |
1745 | ||
1540f9eb | 1746 | clear_aux_for_blocks (); |
635559ab | 1747 | |
402209ff JH |
1748 | return changed_overall; |
1749 | } | |
1750 | \f | |
6d2f8887 | 1751 | /* Delete all unreachable basic blocks. */ |
4262e623 | 1752 | |
969d70ca | 1753 | bool |
402209ff JH |
1754 | delete_unreachable_blocks () |
1755 | { | |
402209ff | 1756 | bool changed = false; |
e0082a72 ZD |
1757 | basic_block b, next_bb; |
1758 | int j = 0; | |
402209ff JH |
1759 | |
1760 | find_unreachable_blocks (); | |
1761 | ||
0b17ab2f | 1762 | /* Delete all unreachable basic blocks. Do compaction concurrently, |
f87c27b4 | 1763 | as otherwise we can wind up with O(N^2) behaviour here when we |
0b17ab2f | 1764 | have oodles of dead code. */ |
402209ff | 1765 | |
e0082a72 | 1766 | for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb) |
402209ff | 1767 | { |
e0082a72 | 1768 | next_bb = b->next_bb; |
0b17ab2f | 1769 | |
402209ff | 1770 | if (!(b->flags & BB_REACHABLE)) |
6a58eee9 | 1771 | { |
0b17ab2f RH |
1772 | flow_delete_block_noexpunge (b); |
1773 | expunge_block_nocompact (b); | |
6a58eee9 RH |
1774 | changed = true; |
1775 | } | |
0b17ab2f RH |
1776 | else |
1777 | { | |
1778 | BASIC_BLOCK (j) = b; | |
1779 | b->index = j++; | |
1780 | } | |
402209ff | 1781 | } |
0b17ab2f RH |
1782 | n_basic_blocks = j; |
1783 | basic_block_info->num_elements = j; | |
402209ff JH |
1784 | |
1785 | if (changed) | |
1786 | tidy_fallthru_edges (); | |
1787 | return changed; | |
1788 | } | |
402209ff JH |
1789 | \f |
1790 | /* Tidy the CFG by deleting unreachable code and whatnot. */ | |
1791 | ||
1792 | bool | |
1793 | cleanup_cfg (mode) | |
1794 | int mode; | |
1795 | { | |
402209ff JH |
1796 | bool changed = false; |
1797 | ||
1798 | timevar_push (TV_CLEANUP_CFG); | |
3dec4024 JH |
1799 | if (delete_unreachable_blocks ()) |
1800 | { | |
1801 | changed = true; | |
1802 | /* We've possibly created trivially dead code. Cleanup it right | |
1803 | now to introduce more oppurtunities for try_optimize_cfg. */ | |
95479831 DM |
1804 | if (!(mode & (CLEANUP_NO_INSN_DEL |
1805 | | CLEANUP_UPDATE_LIFE | CLEANUP_PRE_SIBCALL)) | |
3dec4024 JH |
1806 | && !reload_completed) |
1807 | delete_trivially_dead_insns (get_insns(), max_reg_num ()); | |
1808 | } | |
1809 | while (try_optimize_cfg (mode)) | |
1810 | { | |
1811 | delete_unreachable_blocks (), changed = true; | |
1812 | if (mode & CLEANUP_UPDATE_LIFE) | |
1813 | { | |
1814 | /* Cleaning up CFG introduces more oppurtunities for dead code | |
1815 | removal that in turn may introduce more oppurtunities for | |
1816 | cleaning up the CFG. */ | |
e41f3392 | 1817 | if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, |
3dec4024 JH |
1818 | PROP_DEATH_NOTES |
1819 | | PROP_SCAN_DEAD_CODE | |
1820 | | PROP_KILL_DEAD_CODE | |
1821 | | PROP_LOG_LINKS)) | |
1822 | break; | |
1823 | } | |
95479831 DM |
1824 | else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL)) |
1825 | && !reload_completed) | |
3dec4024 JH |
1826 | { |
1827 | if (!delete_trivially_dead_insns (get_insns(), max_reg_num ())) | |
1828 | break; | |
1829 | } | |
1830 | else | |
1831 | break; | |
1832 | delete_dead_jumptables (); | |
1833 | } | |
402209ff | 1834 | |
402209ff JH |
1835 | /* Kill the data we won't maintain. */ |
1836 | free_EXPR_LIST_list (&label_value_list); | |
402209ff JH |
1837 | timevar_pop (TV_CLEANUP_CFG); |
1838 | ||
402209ff JH |
1839 | return changed; |
1840 | } |