Mercurial > hg > CbC > CbC_gcc
comparison gcc/cfgcleanup.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Control flow optimization code for GNU compiler. | 1 /* Control flow optimization code for GNU compiler. |
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | 2 Copyright (C) 1987-2017 Free Software Foundation, Inc. |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 | |
4 Free Software Foundation, Inc. | |
5 | 3 |
6 This file is part of GCC. | 4 This file is part of GCC. |
7 | 5 |
8 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
9 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
32 - Basic block merging. */ | 30 - Basic block merging. */ |
33 | 31 |
34 #include "config.h" | 32 #include "config.h" |
35 #include "system.h" | 33 #include "system.h" |
36 #include "coretypes.h" | 34 #include "coretypes.h" |
37 #include "tm.h" | 35 #include "backend.h" |
36 #include "target.h" | |
38 #include "rtl.h" | 37 #include "rtl.h" |
39 #include "hard-reg-set.h" | 38 #include "tree.h" |
40 #include "regs.h" | 39 #include "cfghooks.h" |
41 #include "timevar.h" | 40 #include "df.h" |
42 #include "output.h" | 41 #include "memmodel.h" |
42 #include "tm_p.h" | |
43 #include "insn-config.h" | 43 #include "insn-config.h" |
44 #include "flags.h" | 44 #include "emit-rtl.h" |
45 #include "recog.h" | |
46 #include "diagnostic-core.h" | |
47 #include "cselib.h" | 45 #include "cselib.h" |
48 #include "params.h" | 46 #include "params.h" |
49 #include "tm_p.h" | |
50 #include "target.h" | |
51 #include "cfglayout.h" | |
52 #include "emit-rtl.h" | |
53 #include "tree-pass.h" | 47 #include "tree-pass.h" |
54 #include "cfgloop.h" | 48 #include "cfgloop.h" |
55 #include "expr.h" | 49 #include "cfgrtl.h" |
56 #include "df.h" | 50 #include "cfganal.h" |
51 #include "cfgbuild.h" | |
52 #include "cfgcleanup.h" | |
57 #include "dce.h" | 53 #include "dce.h" |
58 #include "dbgcnt.h" | 54 #include "dbgcnt.h" |
55 #include "rtl-iter.h" | |
59 | 56 |
60 #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) | 57 #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) |
61 | 58 |
62 /* Set to true when we are running first pass of try_optimize_cfg loop. */ | 59 /* Set to true when we are running first pass of try_optimize_cfg loop. */ |
63 static bool first_pass; | 60 static bool first_pass; |
64 | 61 |
65 /* Set to true if crossjumps occured in the latest run of try_optimize_cfg. */ | 62 /* Set to true if crossjumps occurred in the latest run of try_optimize_cfg. */ |
66 static bool crossjumps_occured; | 63 static bool crossjumps_occurred; |
67 | 64 |
68 /* Set to true if we couldn't run an optimization due to stale liveness | 65 /* Set to true if we couldn't run an optimization due to stale liveness |
69 information; we should run df_analyze to enable more opportunities. */ | 66 information; we should run df_analyze to enable more opportunities. */ |
70 static bool block_was_dirty; | 67 static bool block_was_dirty; |
71 | 68 |
72 static bool try_crossjump_to_edge (int, edge, edge); | 69 static bool try_crossjump_to_edge (int, edge, edge, enum replace_direction); |
73 static bool try_crossjump_bb (int, basic_block); | 70 static bool try_crossjump_bb (int, basic_block); |
74 static bool outgoing_edges_match (int, basic_block, basic_block); | 71 static bool outgoing_edges_match (int, basic_block, basic_block); |
75 static bool old_insns_match_p (int, rtx, rtx); | 72 static enum replace_direction old_insns_match_p (int, rtx_insn *, rtx_insn *); |
76 | 73 |
77 static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block); | 74 static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block); |
78 static void merge_blocks_move_successor_nojumps (basic_block, basic_block); | 75 static void merge_blocks_move_successor_nojumps (basic_block, basic_block); |
79 static bool try_optimize_cfg (int); | 76 static bool try_optimize_cfg (int); |
80 static bool try_simplify_condjump (basic_block); | 77 static bool try_simplify_condjump (basic_block); |
81 static bool try_forward_edges (int, basic_block); | 78 static bool try_forward_edges (int, basic_block); |
82 static edge thread_jump (edge, basic_block); | 79 static edge thread_jump (edge, basic_block); |
83 static bool mark_effect (rtx, bitmap); | 80 static bool mark_effect (rtx, bitmap); |
84 static void notice_new_block (basic_block); | 81 static void notice_new_block (basic_block); |
85 static void update_forwarder_flag (basic_block); | 82 static void update_forwarder_flag (basic_block); |
86 static int mentions_nonequal_regs (rtx *, void *); | |
87 static void merge_memattrs (rtx, rtx); | 83 static void merge_memattrs (rtx, rtx); |
88 | 84 |
89 /* Set flags for newly created block. */ | 85 /* Set flags for newly created block. */ |
90 | 86 |
91 static void | 87 static void |
115 static bool | 111 static bool |
116 try_simplify_condjump (basic_block cbranch_block) | 112 try_simplify_condjump (basic_block cbranch_block) |
117 { | 113 { |
118 basic_block jump_block, jump_dest_block, cbranch_dest_block; | 114 basic_block jump_block, jump_dest_block, cbranch_dest_block; |
119 edge cbranch_jump_edge, cbranch_fallthru_edge; | 115 edge cbranch_jump_edge, cbranch_fallthru_edge; |
120 rtx cbranch_insn; | 116 rtx_insn *cbranch_insn; |
121 | 117 |
122 /* Verify that there are exactly two successors. */ | 118 /* Verify that there are exactly two successors. */ |
123 if (EDGE_COUNT (cbranch_block->succs) != 2) | 119 if (EDGE_COUNT (cbranch_block->succs) != 2) |
124 return false; | 120 return false; |
125 | 121 |
135 /* The next block must not have multiple predecessors, must not | 131 /* The next block must not have multiple predecessors, must not |
136 be the last block in the function, and must contain just the | 132 be the last block in the function, and must contain just the |
137 unconditional jump. */ | 133 unconditional jump. */ |
138 jump_block = cbranch_fallthru_edge->dest; | 134 jump_block = cbranch_fallthru_edge->dest; |
139 if (!single_pred_p (jump_block) | 135 if (!single_pred_p (jump_block) |
140 || jump_block->next_bb == EXIT_BLOCK_PTR | 136 || jump_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun) |
141 || !FORWARDER_BLOCK_P (jump_block)) | 137 || !FORWARDER_BLOCK_P (jump_block)) |
142 return false; | 138 return false; |
143 jump_dest_block = single_succ (jump_block); | 139 jump_dest_block = single_succ (jump_block); |
144 | 140 |
145 /* If we are partitioning hot/cold basic blocks, we don't want to | 141 /* If we are partitioning hot/cold basic blocks, we don't want to |
158 | 154 |
159 /* The conditional branch must target the block after the | 155 /* The conditional branch must target the block after the |
160 unconditional branch. */ | 156 unconditional branch. */ |
161 cbranch_dest_block = cbranch_jump_edge->dest; | 157 cbranch_dest_block = cbranch_jump_edge->dest; |
162 | 158 |
163 if (cbranch_dest_block == EXIT_BLOCK_PTR | 159 if (cbranch_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun) |
160 || jump_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun) | |
164 || !can_fallthru (jump_block, cbranch_dest_block)) | 161 || !can_fallthru (jump_block, cbranch_dest_block)) |
165 return false; | 162 return false; |
166 | 163 |
167 /* Invert the conditional branch. */ | 164 /* Invert the conditional branch. */ |
168 if (!invert_jump (cbranch_insn, block_label (jump_dest_block), 0)) | 165 if (!invert_jump (as_a <rtx_jump_insn *> (cbranch_insn), |
166 block_label (jump_dest_block), 0)) | |
169 return false; | 167 return false; |
170 | 168 |
171 if (dump_file) | 169 if (dump_file) |
172 fprintf (dump_file, "Simplifying condjump %i around jump %i\n", | 170 fprintf (dump_file, "Simplifying condjump %i around jump %i\n", |
173 INSN_UID (cbranch_insn), INSN_UID (BB_END (jump_block))); | 171 INSN_UID (cbranch_insn), INSN_UID (BB_END (jump_block))); |
195 on register. Used by jump threading. */ | 193 on register. Used by jump threading. */ |
196 | 194 |
197 static bool | 195 static bool |
198 mark_effect (rtx exp, regset nonequal) | 196 mark_effect (rtx exp, regset nonequal) |
199 { | 197 { |
200 int regno; | |
201 rtx dest; | 198 rtx dest; |
202 switch (GET_CODE (exp)) | 199 switch (GET_CODE (exp)) |
203 { | 200 { |
204 /* In case we do clobber the register, mark it as equal, as we know the | 201 /* In case we do clobber the register, mark it as equal, as we know the |
205 value is dead so it don't have to match. */ | 202 value is dead so it don't have to match. */ |
206 case CLOBBER: | 203 case CLOBBER: |
207 if (REG_P (XEXP (exp, 0))) | 204 dest = XEXP (exp, 0); |
208 { | 205 if (REG_P (dest)) |
209 dest = XEXP (exp, 0); | 206 bitmap_clear_range (nonequal, REGNO (dest), REG_NREGS (dest)); |
210 regno = REGNO (dest); | |
211 CLEAR_REGNO_REG_SET (nonequal, regno); | |
212 if (regno < FIRST_PSEUDO_REGISTER) | |
213 { | |
214 int n = hard_regno_nregs[regno][GET_MODE (dest)]; | |
215 while (--n > 0) | |
216 CLEAR_REGNO_REG_SET (nonequal, regno + n); | |
217 } | |
218 } | |
219 return false; | 207 return false; |
220 | 208 |
221 case SET: | 209 case SET: |
222 if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp))) | 210 if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp))) |
223 return false; | 211 return false; |
224 dest = SET_DEST (exp); | 212 dest = SET_DEST (exp); |
225 if (dest == pc_rtx) | 213 if (dest == pc_rtx) |
226 return false; | 214 return false; |
227 if (!REG_P (dest)) | 215 if (!REG_P (dest)) |
228 return true; | 216 return true; |
229 regno = REGNO (dest); | 217 bitmap_set_range (nonequal, REGNO (dest), REG_NREGS (dest)); |
230 SET_REGNO_REG_SET (nonequal, regno); | |
231 if (regno < FIRST_PSEUDO_REGISTER) | |
232 { | |
233 int n = hard_regno_nregs[regno][GET_MODE (dest)]; | |
234 while (--n > 0) | |
235 SET_REGNO_REG_SET (nonequal, regno + n); | |
236 } | |
237 return false; | 218 return false; |
238 | 219 |
239 default: | 220 default: |
240 return false; | 221 return false; |
241 } | 222 } |
242 } | 223 } |
243 | 224 |
244 /* Return nonzero if X is a register set in regset DATA. | 225 /* Return true if X contains a register in NONEQUAL. */ |
245 Called via for_each_rtx. */ | 226 static bool |
246 static int | 227 mentions_nonequal_regs (const_rtx x, regset nonequal) |
247 mentions_nonequal_regs (rtx *x, void *data) | 228 { |
248 { | 229 subrtx_iterator::array_type array; |
249 regset nonequal = (regset) data; | 230 FOR_EACH_SUBRTX (iter, array, x, NONCONST) |
250 if (REG_P (*x)) | 231 { |
251 { | 232 const_rtx x = *iter; |
252 int regno; | 233 if (REG_P (x)) |
253 | 234 { |
254 regno = REGNO (*x); | 235 unsigned int end_regno = END_REGNO (x); |
255 if (REGNO_REG_SET_P (nonequal, regno)) | 236 for (unsigned int regno = REGNO (x); regno < end_regno; ++regno) |
256 return 1; | 237 if (REGNO_REG_SET_P (nonequal, regno)) |
257 if (regno < FIRST_PSEUDO_REGISTER) | 238 return true; |
258 { | 239 } |
259 int n = hard_regno_nregs[regno][GET_MODE (*x)]; | 240 } |
260 while (--n > 0) | 241 return false; |
261 if (REGNO_REG_SET_P (nonequal, regno + n)) | 242 } |
262 return 1; | 243 |
263 } | |
264 } | |
265 return 0; | |
266 } | |
267 /* Attempt to prove that the basic block B will have no side effects and | 244 /* Attempt to prove that the basic block B will have no side effects and |
268 always continues in the same edge if reached via E. Return the edge | 245 always continues in the same edge if reached via E. Return the edge |
269 if exist, NULL otherwise. */ | 246 if exist, NULL otherwise. */ |
270 | 247 |
271 static edge | 248 static edge |
272 thread_jump (edge e, basic_block b) | 249 thread_jump (edge e, basic_block b) |
273 { | 250 { |
274 rtx set1, set2, cond1, cond2, insn; | 251 rtx set1, set2, cond1, cond2; |
252 rtx_insn *insn; | |
275 enum rtx_code code1, code2, reversed_code2; | 253 enum rtx_code code1, code2, reversed_code2; |
276 bool reverse1 = false; | 254 bool reverse1 = false; |
277 unsigned i; | 255 unsigned i; |
278 regset nonequal; | 256 regset nonequal; |
279 bool failed = false; | 257 bool failed = false; |
384 goto failed_exit; | 362 goto failed_exit; |
385 } | 363 } |
386 | 364 |
387 /* cond2 must not mention any register that is not equal to the | 365 /* cond2 must not mention any register that is not equal to the |
388 former block. */ | 366 former block. */ |
389 if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal)) | 367 if (mentions_nonequal_regs (cond2, nonequal)) |
390 goto failed_exit; | 368 goto failed_exit; |
391 | 369 |
392 EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi) | 370 EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi) |
393 goto failed_exit; | 371 goto failed_exit; |
394 | 372 |
424 be optimizable (or blocks that appear to be mergeable), but which really | 402 be optimizable (or blocks that appear to be mergeable), but which really |
425 must be left untouched (they are required to make it safely across | 403 must be left untouched (they are required to make it safely across |
426 partition boundaries). See the comments at the top of | 404 partition boundaries). See the comments at the top of |
427 bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */ | 405 bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */ |
428 | 406 |
429 if (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)) | 407 if (JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))) |
430 return false; | 408 return false; |
431 | 409 |
432 for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); ) | 410 for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); ) |
433 { | 411 { |
434 basic_block target, first; | 412 basic_block target, first; |
435 int counter, goto_locus; | 413 location_t goto_locus; |
414 int counter; | |
436 bool threaded = false; | 415 bool threaded = false; |
437 int nthreaded_edges = 0; | 416 int nthreaded_edges = 0; |
438 bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0; | 417 bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0; |
439 | 418 |
440 /* Skip complex edges because we don't know how to update them. | 419 /* Skip complex edges because we don't know how to update them. |
460 really must be left untouched (they are required to make it safely | 439 really must be left untouched (they are required to make it safely |
461 across partition boundaries). See the comments at the top of | 440 across partition boundaries). See the comments at the top of |
462 bb-reorder.c:partition_hot_cold_basic_blocks for complete | 441 bb-reorder.c:partition_hot_cold_basic_blocks for complete |
463 details. */ | 442 details. */ |
464 | 443 |
465 if (first != EXIT_BLOCK_PTR | 444 if (first != EXIT_BLOCK_PTR_FOR_FN (cfun) |
466 && find_reg_note (BB_END (first), REG_CROSSING_JUMP, NULL_RTX)) | 445 && JUMP_P (BB_END (first)) |
467 return false; | 446 && CROSSING_JUMP_P (BB_END (first))) |
468 | 447 return changed; |
469 while (counter < n_basic_blocks) | 448 |
449 while (counter < n_basic_blocks_for_fn (cfun)) | |
470 { | 450 { |
471 basic_block new_target = NULL; | 451 basic_block new_target = NULL; |
472 bool new_target_threaded = false; | 452 bool new_target_threaded = false; |
473 may_thread |= (target->flags & BB_MODIFIED) != 0; | 453 may_thread |= (target->flags & BB_MODIFIED) != 0; |
474 | 454 |
475 if (FORWARDER_BLOCK_P (target) | 455 if (FORWARDER_BLOCK_P (target) |
476 && !(single_succ_edge (target)->flags & EDGE_CROSSING) | 456 && !(single_succ_edge (target)->flags & EDGE_CROSSING) |
477 && single_succ (target) != EXIT_BLOCK_PTR) | 457 && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun)) |
478 { | 458 { |
479 /* Bypass trivial infinite loops. */ | 459 /* Bypass trivial infinite loops. */ |
480 new_target = single_succ (target); | 460 new_target = single_succ (target); |
481 if (target == new_target) | 461 if (target == new_target) |
482 counter = n_basic_blocks; | 462 counter = n_basic_blocks_for_fn (cfun); |
483 else if (!optimize) | 463 else if (!optimize) |
484 { | 464 { |
485 /* When not optimizing, ensure that edges or forwarder | 465 /* When not optimizing, ensure that edges or forwarder |
486 blocks with different locus are not optimized out. */ | 466 blocks with different locus are not optimized out. */ |
487 int new_locus = single_succ_edge (target)->goto_locus; | 467 location_t new_locus = single_succ_edge (target)->goto_locus; |
488 int locus = goto_locus; | 468 location_t locus = goto_locus; |
489 | 469 |
490 if (new_locus && locus && !locator_eq (new_locus, locus)) | 470 if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION |
471 && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION | |
472 && new_locus != locus) | |
491 new_target = NULL; | 473 new_target = NULL; |
492 else | 474 else |
493 { | 475 { |
494 rtx last; | 476 if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION) |
495 | |
496 if (new_locus) | |
497 locus = new_locus; | 477 locus = new_locus; |
498 | 478 |
499 last = BB_END (target); | 479 rtx_insn *last = BB_END (target); |
500 if (DEBUG_INSN_P (last)) | 480 if (DEBUG_INSN_P (last)) |
501 last = prev_nondebug_insn (last); | 481 last = prev_nondebug_insn (last); |
502 | 482 if (last && INSN_P (last)) |
503 new_locus = last && INSN_P (last) | 483 new_locus = INSN_LOCATION (last); |
504 ? INSN_LOCATOR (last) : 0; | 484 else |
505 | 485 new_locus = UNKNOWN_LOCATION; |
506 if (new_locus && locus && !locator_eq (new_locus, locus)) | 486 |
487 if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION | |
488 && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION | |
489 && new_locus != locus) | |
507 new_target = NULL; | 490 new_target = NULL; |
508 else | 491 else |
509 { | 492 { |
510 if (new_locus) | 493 if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION) |
511 locus = new_locus; | 494 locus = new_locus; |
512 | 495 |
513 goto_locus = locus; | 496 goto_locus = locus; |
514 } | 497 } |
515 } | 498 } |
522 { | 505 { |
523 edge t = thread_jump (e, target); | 506 edge t = thread_jump (e, target); |
524 if (t) | 507 if (t) |
525 { | 508 { |
526 if (!threaded_edges) | 509 if (!threaded_edges) |
527 threaded_edges = XNEWVEC (edge, n_basic_blocks); | 510 threaded_edges = XNEWVEC (edge, |
511 n_basic_blocks_for_fn (cfun)); | |
528 else | 512 else |
529 { | 513 { |
530 int i; | 514 int i; |
531 | 515 |
532 /* Detect an infinite loop across blocks not | 516 /* Detect an infinite loop across blocks not |
534 for (i = 0; i < nthreaded_edges; ++i) | 518 for (i = 0; i < nthreaded_edges; ++i) |
535 if (threaded_edges[i] == t) | 519 if (threaded_edges[i] == t) |
536 break; | 520 break; |
537 if (i < nthreaded_edges) | 521 if (i < nthreaded_edges) |
538 { | 522 { |
539 counter = n_basic_blocks; | 523 counter = n_basic_blocks_for_fn (cfun); |
540 break; | 524 break; |
541 } | 525 } |
542 } | 526 } |
543 | 527 |
544 /* Detect an infinite loop across the start block. */ | 528 /* Detect an infinite loop across the start block. */ |
545 if (t->dest == b) | 529 if (t->dest == b) |
546 break; | 530 break; |
547 | 531 |
548 gcc_assert (nthreaded_edges < n_basic_blocks - NUM_FIXED_BLOCKS); | 532 gcc_assert (nthreaded_edges |
533 < (n_basic_blocks_for_fn (cfun) | |
534 - NUM_FIXED_BLOCKS)); | |
549 threaded_edges[nthreaded_edges++] = t; | 535 threaded_edges[nthreaded_edges++] = t; |
550 | 536 |
551 new_target = t->dest; | 537 new_target = t->dest; |
552 new_target_threaded = true; | 538 new_target_threaded = true; |
553 } | 539 } |
559 counter++; | 545 counter++; |
560 target = new_target; | 546 target = new_target; |
561 threaded |= new_target_threaded; | 547 threaded |= new_target_threaded; |
562 } | 548 } |
563 | 549 |
564 if (counter >= n_basic_blocks) | 550 if (counter >= n_basic_blocks_for_fn (cfun)) |
565 { | 551 { |
566 if (dump_file) | 552 if (dump_file) |
567 fprintf (dump_file, "Infinite loop in BB %i.\n", | 553 fprintf (dump_file, "Infinite loop in BB %i.\n", |
568 target->index); | 554 target->index); |
569 } | 555 } |
570 else if (target == first) | 556 else if (target == first) |
571 ; /* We didn't do anything. */ | 557 ; /* We didn't do anything. */ |
572 else | 558 else |
573 { | 559 { |
574 /* Save the values now, as the edge may get removed. */ | 560 /* Save the values now, as the edge may get removed. */ |
575 gcov_type edge_count = e->count; | 561 profile_count edge_count = e->count (); |
576 int edge_probability = e->probability; | 562 profile_probability edge_probability = e->probability; |
577 int edge_frequency; | 563 int edge_frequency; |
578 int n = 0; | 564 int n = 0; |
579 | 565 |
580 e->goto_locus = goto_locus; | 566 e->goto_locus = goto_locus; |
581 | 567 |
582 /* Don't force if target is exit block. */ | 568 /* Don't force if target is exit block. */ |
583 if (threaded && target != EXIT_BLOCK_PTR) | 569 if (threaded && target != EXIT_BLOCK_PTR_FOR_FN (cfun)) |
584 { | 570 { |
585 notice_new_block (redirect_edge_and_branch_force (e, target)); | 571 notice_new_block (redirect_edge_and_branch_force (e, target)); |
586 if (dump_file) | 572 if (dump_file) |
587 fprintf (dump_file, "Conditionals threaded.\n"); | 573 fprintf (dump_file, "Conditionals threaded.\n"); |
588 } | 574 } |
597 } | 583 } |
598 | 584 |
599 /* We successfully forwarded the edge. Now update profile | 585 /* We successfully forwarded the edge. Now update profile |
600 data: for each edge we traversed in the chain, remove | 586 data: for each edge we traversed in the chain, remove |
601 the original edge's execution count. */ | 587 the original edge's execution count. */ |
602 edge_frequency = ((edge_probability * b->frequency | 588 edge_frequency = edge_probability.apply (b->frequency); |
603 + REG_BR_PROB_BASE / 2) | |
604 / REG_BR_PROB_BASE); | |
605 | |
606 if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b)) | |
607 b->flags |= BB_FORWARDER_BLOCK; | |
608 | 589 |
609 do | 590 do |
610 { | 591 { |
611 edge t; | 592 edge t; |
612 | 593 |
620 update_br_prob_note (first); | 601 update_br_prob_note (first); |
621 } | 602 } |
622 else | 603 else |
623 { | 604 { |
624 first->count -= edge_count; | 605 first->count -= edge_count; |
625 if (first->count < 0) | |
626 first->count = 0; | |
627 first->frequency -= edge_frequency; | 606 first->frequency -= edge_frequency; |
628 if (first->frequency < 0) | 607 if (first->frequency < 0) |
629 first->frequency = 0; | 608 first->frequency = 0; |
630 /* It is possible that as the result of | 609 /* It is possible that as the result of |
631 threading we've removed edge as it is | 610 threading we've removed edge as it is |
635 && first == threaded_edges [n]->src) | 614 && first == threaded_edges [n]->src) |
636 n++; | 615 n++; |
637 t = single_succ_edge (first); | 616 t = single_succ_edge (first); |
638 } | 617 } |
639 | 618 |
640 t->count -= edge_count; | |
641 if (t->count < 0) | |
642 t->count = 0; | |
643 first = t->dest; | 619 first = t->dest; |
644 } | 620 } |
645 while (first != target); | 621 while (first != target); |
646 | 622 |
647 changed = true; | 623 changed = true; |
648 continue; | 624 continue; |
649 } | 625 } |
650 ei_next (&ei); | 626 ei_next (&ei); |
651 } | 627 } |
652 | 628 |
653 if (threaded_edges) | 629 free (threaded_edges); |
654 free (threaded_edges); | |
655 return changed; | 630 return changed; |
656 } | 631 } |
657 | 632 |
658 | 633 |
659 /* Blocks A and B are to be merged into a single block. A has no incoming | 634 /* Blocks A and B are to be merged into a single block. A has no incoming |
661 any jumps (aside from the jump from A to B). */ | 636 any jumps (aside from the jump from A to B). */ |
662 | 637 |
663 static void | 638 static void |
664 merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b) | 639 merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b) |
665 { | 640 { |
666 rtx barrier; | 641 rtx_insn *barrier; |
667 | 642 |
668 /* If we are partitioning hot/cold basic blocks, we don't want to | 643 /* If we are partitioning hot/cold basic blocks, we don't want to |
669 mess up unconditional or indirect jumps that cross between hot | 644 mess up unconditional or indirect jumps that cross between hot |
670 and cold sections. | 645 and cold sections. |
671 | 646 |
705 any jumps (aside from the jump from A to B). */ | 680 any jumps (aside from the jump from A to B). */ |
706 | 681 |
707 static void | 682 static void |
708 merge_blocks_move_successor_nojumps (basic_block a, basic_block b) | 683 merge_blocks_move_successor_nojumps (basic_block a, basic_block b) |
709 { | 684 { |
710 rtx barrier, real_b_end; | 685 rtx_insn *barrier, *real_b_end; |
711 rtx label, table; | 686 rtx_insn *label; |
687 rtx_jump_table_data *table; | |
712 | 688 |
713 /* If we are partitioning hot/cold basic blocks, we don't want to | 689 /* If we are partitioning hot/cold basic blocks, we don't want to |
714 mess up unconditional or indirect jumps that cross between hot | 690 mess up unconditional or indirect jumps that cross between hot |
715 and cold sections. | 691 and cold sections. |
716 | 692 |
785 | 761 |
786 /* If B has a fallthru edge to C, no need to move anything. */ | 762 /* If B has a fallthru edge to C, no need to move anything. */ |
787 if (e->flags & EDGE_FALLTHRU) | 763 if (e->flags & EDGE_FALLTHRU) |
788 { | 764 { |
789 int b_index = b->index, c_index = c->index; | 765 int b_index = b->index, c_index = c->index; |
766 | |
767 /* Protect the loop latches. */ | |
768 if (current_loops && c->loop_father->latch == c) | |
769 return NULL; | |
770 | |
790 merge_blocks (b, c); | 771 merge_blocks (b, c); |
791 update_forwarder_flag (b); | 772 update_forwarder_flag (b); |
792 | 773 |
793 if (dump_file) | 774 if (dump_file) |
794 fprintf (dump_file, "Merged %d and %d without moving.\n", | 775 fprintf (dump_file, "Merged %d and %d without moving.\n", |
795 b_index, c_index); | 776 b_index, c_index); |
796 | 777 |
797 return b->prev_bb == ENTRY_BLOCK_PTR ? b : b->prev_bb; | 778 return b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? b : b->prev_bb; |
798 } | 779 } |
799 | 780 |
800 /* Otherwise we will need to move code around. Do that only if expensive | 781 /* Otherwise we will need to move code around. Do that only if expensive |
801 transformations are allowed. */ | 782 transformations are allowed. */ |
802 else if (mode & CLEANUP_EXPENSIVE) | 783 else if (mode & CLEANUP_EXPENSIVE) |
830 not have an outgoing fallthru, then it can be moved | 811 not have an outgoing fallthru, then it can be moved |
831 immediately after B without introducing or modifying jumps. */ | 812 immediately after B without introducing or modifying jumps. */ |
832 if (! c_has_outgoing_fallthru) | 813 if (! c_has_outgoing_fallthru) |
833 { | 814 { |
834 merge_blocks_move_successor_nojumps (b, c); | 815 merge_blocks_move_successor_nojumps (b, c); |
835 return next == ENTRY_BLOCK_PTR ? next->next_bb : next; | 816 return next == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? next->next_bb : next; |
836 } | 817 } |
837 | 818 |
838 /* If B does not have an incoming fallthru, then it can be moved | 819 /* If B does not have an incoming fallthru, then it can be moved |
839 immediately before C without introducing or modifying jumps. | 820 immediately before C without introducing or modifying jumps. |
840 C cannot be the first block, so we do not have to worry about | 821 C cannot be the first block, so we do not have to worry about |
842 | 823 |
843 if (b_has_incoming_fallthru) | 824 if (b_has_incoming_fallthru) |
844 { | 825 { |
845 basic_block bb; | 826 basic_block bb; |
846 | 827 |
847 if (b_fallthru_edge->src == ENTRY_BLOCK_PTR) | 828 if (b_fallthru_edge->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
848 return NULL; | 829 return NULL; |
849 bb = force_nonfallthru (b_fallthru_edge); | 830 bb = force_nonfallthru (b_fallthru_edge); |
850 if (bb) | 831 if (bb) |
851 notice_new_block (bb); | 832 notice_new_block (bb); |
852 } | 833 } |
853 | 834 |
854 merge_blocks_move_predecessor_nojumps (b, c); | 835 merge_blocks_move_predecessor_nojumps (b, c); |
855 return next == ENTRY_BLOCK_PTR ? next->next_bb : next; | 836 return next == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? next->next_bb : next; |
856 } | 837 } |
857 | 838 |
858 return NULL; | 839 return NULL; |
859 } | 840 } |
860 | 841 |
861 | 842 |
862 /* Removes the memory attributes of MEM expression | 843 /* Removes the memory attributes of MEM expression |
863 if they are not equal. */ | 844 if they are not equal. */ |
864 | 845 |
865 void | 846 static void |
866 merge_memattrs (rtx x, rtx y) | 847 merge_memattrs (rtx x, rtx y) |
867 { | 848 { |
868 int i; | 849 int i; |
869 int j; | 850 int j; |
870 enum rtx_code code; | 851 enum rtx_code code; |
881 return; | 862 return; |
882 | 863 |
883 if (GET_MODE (x) != GET_MODE (y)) | 864 if (GET_MODE (x) != GET_MODE (y)) |
884 return; | 865 return; |
885 | 866 |
886 if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y)) | 867 if (code == MEM && !mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y))) |
887 { | 868 { |
888 if (! MEM_ATTRS (x)) | 869 if (! MEM_ATTRS (x)) |
889 MEM_ATTRS (y) = 0; | 870 MEM_ATTRS (y) = 0; |
890 else if (! MEM_ATTRS (y)) | 871 else if (! MEM_ATTRS (y)) |
891 MEM_ATTRS (x) = 0; | 872 MEM_ATTRS (x) = 0; |
892 else | 873 else |
893 { | 874 { |
894 rtx mem_size; | 875 HOST_WIDE_INT mem_size; |
895 | 876 |
896 if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) | 877 if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) |
897 { | 878 { |
898 set_mem_alias_set (x, 0); | 879 set_mem_alias_set (x, 0); |
899 set_mem_alias_set (y, 0); | 880 set_mem_alias_set (y, 0); |
901 | 882 |
902 if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y))) | 883 if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y))) |
903 { | 884 { |
904 set_mem_expr (x, 0); | 885 set_mem_expr (x, 0); |
905 set_mem_expr (y, 0); | 886 set_mem_expr (y, 0); |
906 set_mem_offset (x, 0); | 887 clear_mem_offset (x); |
907 set_mem_offset (y, 0); | 888 clear_mem_offset (y); |
908 } | 889 } |
909 else if (MEM_OFFSET (x) != MEM_OFFSET (y)) | 890 else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y) |
891 || (MEM_OFFSET_KNOWN_P (x) | |
892 && MEM_OFFSET (x) != MEM_OFFSET (y))) | |
910 { | 893 { |
911 set_mem_offset (x, 0); | 894 clear_mem_offset (x); |
912 set_mem_offset (y, 0); | 895 clear_mem_offset (y); |
913 } | 896 } |
914 | 897 |
915 if (!MEM_SIZE (x)) | 898 if (MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y)) |
916 mem_size = NULL_RTX; | 899 { |
917 else if (!MEM_SIZE (y)) | 900 mem_size = MAX (MEM_SIZE (x), MEM_SIZE (y)); |
918 mem_size = NULL_RTX; | 901 set_mem_size (x, mem_size); |
902 set_mem_size (y, mem_size); | |
903 } | |
919 else | 904 else |
920 mem_size = GEN_INT (MAX (INTVAL (MEM_SIZE (x)), | 905 { |
921 INTVAL (MEM_SIZE (y)))); | 906 clear_mem_size (x); |
922 set_mem_size (x, mem_size); | 907 clear_mem_size (y); |
923 set_mem_size (y, mem_size); | 908 } |
924 | 909 |
925 set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y))); | 910 set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y))); |
926 set_mem_align (y, MEM_ALIGN (x)); | 911 set_mem_align (y, MEM_ALIGN (x)); |
912 } | |
913 } | |
914 if (code == MEM) | |
915 { | |
916 if (MEM_READONLY_P (x) != MEM_READONLY_P (y)) | |
917 { | |
918 MEM_READONLY_P (x) = 0; | |
919 MEM_READONLY_P (y) = 0; | |
920 } | |
921 if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y)) | |
922 { | |
923 MEM_NOTRAP_P (x) = 0; | |
924 MEM_NOTRAP_P (y) = 0; | |
925 } | |
926 if (MEM_VOLATILE_P (x) != MEM_VOLATILE_P (y)) | |
927 { | |
928 MEM_VOLATILE_P (x) = 1; | |
929 MEM_VOLATILE_P (y) = 1; | |
927 } | 930 } |
928 } | 931 } |
929 | 932 |
930 fmt = GET_RTX_FORMAT (code); | 933 fmt = GET_RTX_FORMAT (code); |
931 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | 934 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) |
948 } | 951 } |
949 return; | 952 return; |
950 } | 953 } |
951 | 954 |
952 | 955 |
953 /* Return true if I1 and I2 are equivalent and thus can be crossjumped. */ | 956 /* Checks if patterns P1 and P2 are equivalent, apart from the possibly |
957 different single sets S1 and S2. */ | |
954 | 958 |
955 static bool | 959 static bool |
956 old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2) | 960 equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2) |
961 { | |
962 int i; | |
963 rtx e1, e2; | |
964 | |
965 if (p1 == s1 && p2 == s2) | |
966 return true; | |
967 | |
968 if (GET_CODE (p1) != PARALLEL || GET_CODE (p2) != PARALLEL) | |
969 return false; | |
970 | |
971 if (XVECLEN (p1, 0) != XVECLEN (p2, 0)) | |
972 return false; | |
973 | |
974 for (i = 0; i < XVECLEN (p1, 0); i++) | |
975 { | |
976 e1 = XVECEXP (p1, 0, i); | |
977 e2 = XVECEXP (p2, 0, i); | |
978 if (e1 == s1 && e2 == s2) | |
979 continue; | |
980 if (reload_completed | |
981 ? rtx_renumbered_equal_p (e1, e2) : rtx_equal_p (e1, e2)) | |
982 continue; | |
983 | |
984 return false; | |
985 } | |
986 | |
987 return true; | |
988 } | |
989 | |
990 | |
991 /* NOTE1 is the REG_EQUAL note, if any, attached to an insn | |
992 that is a single_set with a SET_SRC of SRC1. Similarly | |
993 for NOTE2/SRC2. | |
994 | |
995 So effectively NOTE1/NOTE2 are an alternate form of | |
996 SRC1/SRC2 respectively. | |
997 | |
998 Return nonzero if SRC1 or NOTE1 has the same constant | |
999 integer value as SRC2 or NOTE2. Else return zero. */ | |
1000 static int | |
1001 values_equal_p (rtx note1, rtx note2, rtx src1, rtx src2) | |
1002 { | |
1003 if (note1 | |
1004 && note2 | |
1005 && CONST_INT_P (XEXP (note1, 0)) | |
1006 && rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0))) | |
1007 return 1; | |
1008 | |
1009 if (!note1 | |
1010 && !note2 | |
1011 && CONST_INT_P (src1) | |
1012 && CONST_INT_P (src2) | |
1013 && rtx_equal_p (src1, src2)) | |
1014 return 1; | |
1015 | |
1016 if (note1 | |
1017 && CONST_INT_P (src2) | |
1018 && rtx_equal_p (XEXP (note1, 0), src2)) | |
1019 return 1; | |
1020 | |
1021 if (note2 | |
1022 && CONST_INT_P (src1) | |
1023 && rtx_equal_p (XEXP (note2, 0), src1)) | |
1024 return 1; | |
1025 | |
1026 return 0; | |
1027 } | |
1028 | |
1029 /* Examine register notes on I1 and I2 and return: | |
1030 - dir_forward if I1 can be replaced by I2, or | |
1031 - dir_backward if I2 can be replaced by I1, or | |
1032 - dir_both if both are the case. */ | |
1033 | |
1034 static enum replace_direction | |
1035 can_replace_by (rtx_insn *i1, rtx_insn *i2) | |
1036 { | |
1037 rtx s1, s2, d1, d2, src1, src2, note1, note2; | |
1038 bool c1, c2; | |
1039 | |
1040 /* Check for 2 sets. */ | |
1041 s1 = single_set (i1); | |
1042 s2 = single_set (i2); | |
1043 if (s1 == NULL_RTX || s2 == NULL_RTX) | |
1044 return dir_none; | |
1045 | |
1046 /* Check that the 2 sets set the same dest. */ | |
1047 d1 = SET_DEST (s1); | |
1048 d2 = SET_DEST (s2); | |
1049 if (!(reload_completed | |
1050 ? rtx_renumbered_equal_p (d1, d2) : rtx_equal_p (d1, d2))) | |
1051 return dir_none; | |
1052 | |
1053 /* Find identical req_equiv or reg_equal note, which implies that the 2 sets | |
1054 set dest to the same value. */ | |
1055 note1 = find_reg_equal_equiv_note (i1); | |
1056 note2 = find_reg_equal_equiv_note (i2); | |
1057 | |
1058 src1 = SET_SRC (s1); | |
1059 src2 = SET_SRC (s2); | |
1060 | |
1061 if (!values_equal_p (note1, note2, src1, src2)) | |
1062 return dir_none; | |
1063 | |
1064 if (!equal_different_set_p (PATTERN (i1), s1, PATTERN (i2), s2)) | |
1065 return dir_none; | |
1066 | |
1067 /* Although the 2 sets set dest to the same value, we cannot replace | |
1068 (set (dest) (const_int)) | |
1069 by | |
1070 (set (dest) (reg)) | |
1071 because we don't know if the reg is live and has the same value at the | |
1072 location of replacement. */ | |
1073 c1 = CONST_INT_P (src1); | |
1074 c2 = CONST_INT_P (src2); | |
1075 if (c1 && c2) | |
1076 return dir_both; | |
1077 else if (c2) | |
1078 return dir_forward; | |
1079 else if (c1) | |
1080 return dir_backward; | |
1081 | |
1082 return dir_none; | |
1083 } | |
1084 | |
1085 /* Merges directions A and B. */ | |
1086 | |
1087 static enum replace_direction | |
1088 merge_dir (enum replace_direction a, enum replace_direction b) | |
1089 { | |
1090 /* Implements the following table: | |
1091 |bo fw bw no | |
1092 ---+----------- | |
1093 bo |bo fw bw no | |
1094 fw |-- fw no no | |
1095 bw |-- -- bw no | |
1096 no |-- -- -- no. */ | |
1097 | |
1098 if (a == b) | |
1099 return a; | |
1100 | |
1101 if (a == dir_both) | |
1102 return b; | |
1103 if (b == dir_both) | |
1104 return a; | |
1105 | |
1106 return dir_none; | |
1107 } | |
1108 | |
1109 /* Array of flags indexed by reg note kind, true if the given | |
1110 reg note is CFA related. */ | |
1111 static const bool reg_note_cfa_p[] = { | |
1112 #undef REG_CFA_NOTE | |
1113 #define DEF_REG_NOTE(NAME) false, | |
1114 #define REG_CFA_NOTE(NAME) true, | |
1115 #include "reg-notes.def" | |
1116 #undef REG_CFA_NOTE | |
1117 #undef DEF_REG_NOTE | |
1118 false | |
1119 }; | |
1120 | |
1121 /* Return true if I1 and I2 have identical CFA notes (the same order | |
1122 and equivalent content). */ | |
1123 | |
1124 static bool | |
1125 insns_have_identical_cfa_notes (rtx_insn *i1, rtx_insn *i2) | |
1126 { | |
1127 rtx n1, n2; | |
1128 for (n1 = REG_NOTES (i1), n2 = REG_NOTES (i2); ; | |
1129 n1 = XEXP (n1, 1), n2 = XEXP (n2, 1)) | |
1130 { | |
1131 /* Skip over reg notes not related to CFI information. */ | |
1132 while (n1 && !reg_note_cfa_p[REG_NOTE_KIND (n1)]) | |
1133 n1 = XEXP (n1, 1); | |
1134 while (n2 && !reg_note_cfa_p[REG_NOTE_KIND (n2)]) | |
1135 n2 = XEXP (n2, 1); | |
1136 if (n1 == NULL_RTX && n2 == NULL_RTX) | |
1137 return true; | |
1138 if (n1 == NULL_RTX || n2 == NULL_RTX) | |
1139 return false; | |
1140 if (XEXP (n1, 0) == XEXP (n2, 0)) | |
1141 ; | |
1142 else if (XEXP (n1, 0) == NULL_RTX || XEXP (n2, 0) == NULL_RTX) | |
1143 return false; | |
1144 else if (!(reload_completed | |
1145 ? rtx_renumbered_equal_p (XEXP (n1, 0), XEXP (n2, 0)) | |
1146 : rtx_equal_p (XEXP (n1, 0), XEXP (n2, 0)))) | |
1147 return false; | |
1148 } | |
1149 } | |
1150 | |
1151 /* Examine I1 and I2 and return: | |
1152 - dir_forward if I1 can be replaced by I2, or | |
1153 - dir_backward if I2 can be replaced by I1, or | |
1154 - dir_both if both are the case. */ | |
1155 | |
1156 static enum replace_direction | |
1157 old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) | |
957 { | 1158 { |
958 rtx p1, p2; | 1159 rtx p1, p2; |
959 | 1160 |
960 /* Verify that I1 and I2 are equivalent. */ | 1161 /* Verify that I1 and I2 are equivalent. */ |
961 if (GET_CODE (i1) != GET_CODE (i2)) | 1162 if (GET_CODE (i1) != GET_CODE (i2)) |
962 return false; | 1163 return dir_none; |
963 | 1164 |
964 /* __builtin_unreachable() may lead to empty blocks (ending with | 1165 /* __builtin_unreachable() may lead to empty blocks (ending with |
965 NOTE_INSN_BASIC_BLOCK). They may be crossjumped. */ | 1166 NOTE_INSN_BASIC_BLOCK). They may be crossjumped. */ |
966 if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2)) | 1167 if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2)) |
967 return true; | 1168 return dir_both; |
1169 | |
1170 /* ??? Do not allow cross-jumping between different stack levels. */ | |
1171 p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL); | |
1172 p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL); | |
1173 if (p1 && p2) | |
1174 { | |
1175 p1 = XEXP (p1, 0); | |
1176 p2 = XEXP (p2, 0); | |
1177 if (!rtx_equal_p (p1, p2)) | |
1178 return dir_none; | |
1179 | |
1180 /* ??? Worse, this adjustment had better be constant lest we | |
1181 have differing incoming stack levels. */ | |
1182 if (!frame_pointer_needed | |
1183 && find_args_size_adjust (i1) == HOST_WIDE_INT_MIN) | |
1184 return dir_none; | |
1185 } | |
1186 else if (p1 || p2) | |
1187 return dir_none; | |
1188 | |
1189 /* Do not allow cross-jumping between frame related insns and other | |
1190 insns. */ | |
1191 if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2)) | |
1192 return dir_none; | |
968 | 1193 |
969 p1 = PATTERN (i1); | 1194 p1 = PATTERN (i1); |
970 p2 = PATTERN (i2); | 1195 p2 = PATTERN (i2); |
971 | 1196 |
972 if (GET_CODE (p1) != GET_CODE (p2)) | 1197 if (GET_CODE (p1) != GET_CODE (p2)) |
973 return false; | 1198 return dir_none; |
974 | 1199 |
975 /* If this is a CALL_INSN, compare register usage information. | 1200 /* If this is a CALL_INSN, compare register usage information. |
976 If we don't check this on stack register machines, the two | 1201 If we don't check this on stack register machines, the two |
977 CALL_INSNs might be merged leaving reg-stack.c with mismatching | 1202 CALL_INSNs might be merged leaving reg-stack.c with mismatching |
978 numbers of stack registers in the same basic block. | 1203 numbers of stack registers in the same basic block. |
989 /* Ensure the same EH region. */ | 1214 /* Ensure the same EH region. */ |
990 rtx n1 = find_reg_note (i1, REG_EH_REGION, 0); | 1215 rtx n1 = find_reg_note (i1, REG_EH_REGION, 0); |
991 rtx n2 = find_reg_note (i2, REG_EH_REGION, 0); | 1216 rtx n2 = find_reg_note (i2, REG_EH_REGION, 0); |
992 | 1217 |
993 if (!n1 && n2) | 1218 if (!n1 && n2) |
994 return false; | 1219 return dir_none; |
995 | 1220 |
996 if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0))) | 1221 if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0))) |
997 return false; | 1222 return dir_none; |
998 | 1223 |
999 if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1), | 1224 if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1), |
1000 CALL_INSN_FUNCTION_USAGE (i2)) | 1225 CALL_INSN_FUNCTION_USAGE (i2)) |
1001 || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)) | 1226 || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)) |
1002 return false; | 1227 return dir_none; |
1003 } | 1228 |
1229 /* For address sanitizer, never crossjump __asan_report_* builtins, | |
1230 otherwise errors might be reported on incorrect lines. */ | |
1231 if (flag_sanitize & SANITIZE_ADDRESS) | |
1232 { | |
1233 rtx call = get_call_rtx_from (i1); | |
1234 if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) | |
1235 { | |
1236 rtx symbol = XEXP (XEXP (call, 0), 0); | |
1237 if (SYMBOL_REF_DECL (symbol) | |
1238 && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL) | |
1239 { | |
1240 if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol)) | |
1241 == BUILT_IN_NORMAL) | |
1242 && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) | |
1243 >= BUILT_IN_ASAN_REPORT_LOAD1 | |
1244 && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) | |
1245 <= BUILT_IN_ASAN_STOREN) | |
1246 return dir_none; | |
1247 } | |
1248 } | |
1249 } | |
1250 } | |
1251 | |
1252 /* If both i1 and i2 are frame related, verify all the CFA notes | |
1253 in the same order and with the same content. */ | |
1254 if (RTX_FRAME_RELATED_P (i1) && !insns_have_identical_cfa_notes (i1, i2)) | |
1255 return dir_none; | |
1004 | 1256 |
1005 #ifdef STACK_REGS | 1257 #ifdef STACK_REGS |
1006 /* If cross_jump_death_matters is not 0, the insn's mode | 1258 /* If cross_jump_death_matters is not 0, the insn's mode |
1007 indicates whether or not the insn contains any stack-like | 1259 indicates whether or not the insn contains any stack-like |
1008 regs. */ | 1260 regs. */ |
1026 for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) | 1278 for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) |
1027 if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) | 1279 if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) |
1028 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); | 1280 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); |
1029 | 1281 |
1030 if (!hard_reg_set_equal_p (i1_regset, i2_regset)) | 1282 if (!hard_reg_set_equal_p (i1_regset, i2_regset)) |
1031 return false; | 1283 return dir_none; |
1032 } | 1284 } |
1033 #endif | 1285 #endif |
1034 | 1286 |
1035 if (reload_completed | 1287 if (reload_completed |
1036 ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2)) | 1288 ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2)) |
1037 return true; | 1289 return dir_both; |
1038 | 1290 |
1039 return false; | 1291 return can_replace_by (i1, i2); |
1040 } | 1292 } |
1041 | 1293 |
1042 /* When comparing insns I1 and I2 in flow_find_cross_jump or | 1294 /* When comparing insns I1 and I2 in flow_find_cross_jump or |
1043 flow_find_head_matching_sequence, ensure the notes match. */ | 1295 flow_find_head_matching_sequence, ensure the notes match. */ |
1044 | 1296 |
1045 static void | 1297 static void |
1046 merge_notes (rtx i1, rtx i2) | 1298 merge_notes (rtx_insn *i1, rtx_insn *i2) |
1047 { | 1299 { |
1048 /* If the merged insns have different REG_EQUAL notes, then | 1300 /* If the merged insns have different REG_EQUAL notes, then |
1049 remove them. */ | 1301 remove them. */ |
1050 rtx equiv1 = find_reg_equal_equiv_note (i1); | 1302 rtx equiv1 = find_reg_equal_equiv_note (i1); |
1051 rtx equiv2 = find_reg_equal_equiv_note (i2); | 1303 rtx equiv2 = find_reg_equal_equiv_note (i2); |
1060 remove_note (i1, equiv1); | 1312 remove_note (i1, equiv1); |
1061 remove_note (i2, equiv2); | 1313 remove_note (i2, equiv2); |
1062 } | 1314 } |
1063 } | 1315 } |
1064 | 1316 |
1317 /* Walks from I1 in BB1 backward till the next non-debug insn, and returns the | |
1318 resulting insn in I1, and the corresponding bb in BB1. At the head of a | |
1319 bb, if there is a predecessor bb that reaches this bb via fallthru, and | |
1320 FOLLOW_FALLTHRU, walks further in the predecessor bb and registers this in | |
1321 DID_FALLTHRU. Otherwise, stops at the head of the bb. */ | |
1322 | |
1323 static void | |
1324 walk_to_nondebug_insn (rtx_insn **i1, basic_block *bb1, bool follow_fallthru, | |
1325 bool *did_fallthru) | |
1326 { | |
1327 edge fallthru; | |
1328 | |
1329 *did_fallthru = false; | |
1330 | |
1331 /* Ignore notes. */ | |
1332 while (!NONDEBUG_INSN_P (*i1)) | |
1333 { | |
1334 if (*i1 != BB_HEAD (*bb1)) | |
1335 { | |
1336 *i1 = PREV_INSN (*i1); | |
1337 continue; | |
1338 } | |
1339 | |
1340 if (!follow_fallthru) | |
1341 return; | |
1342 | |
1343 fallthru = find_fallthru_edge ((*bb1)->preds); | |
1344 if (!fallthru || fallthru->src == ENTRY_BLOCK_PTR_FOR_FN (cfun) | |
1345 || !single_succ_p (fallthru->src)) | |
1346 return; | |
1347 | |
1348 *bb1 = fallthru->src; | |
1349 *i1 = BB_END (*bb1); | |
1350 *did_fallthru = true; | |
1351 } | |
1352 } | |
1353 | |
1065 /* Look through the insns at the end of BB1 and BB2 and find the longest | 1354 /* Look through the insns at the end of BB1 and BB2 and find the longest |
1066 sequence that are equivalent. Store the first insns for that sequence | 1355 sequence that are either equivalent, or allow forward or backward |
1067 in *F1 and *F2 and return the sequence length. | 1356 replacement. Store the first insns for that sequence in *F1 and *F2 and |
1357 return the sequence length. | |
1358 | |
1359 DIR_P indicates the allowed replacement direction on function entry, and | |
1360 the actual replacement direction on function exit. If NULL, only equivalent | |
1361 sequences are allowed. | |
1068 | 1362 |
1069 To simplify callers of this function, if the blocks match exactly, | 1363 To simplify callers of this function, if the blocks match exactly, |
1070 store the head of the blocks in *F1 and *F2. */ | 1364 store the head of the blocks in *F1 and *F2. */ |
1071 | 1365 |
1072 int | 1366 int |
1073 flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2) | 1367 flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx_insn **f1, |
1074 { | 1368 rtx_insn **f2, enum replace_direction *dir_p) |
1075 rtx i1, i2, last1, last2, afterlast1, afterlast2; | 1369 { |
1370 rtx_insn *i1, *i2, *last1, *last2, *afterlast1, *afterlast2; | |
1076 int ninsns = 0; | 1371 int ninsns = 0; |
1372 enum replace_direction dir, last_dir, afterlast_dir; | |
1373 bool follow_fallthru, did_fallthru; | |
1374 | |
1375 if (dir_p) | |
1376 dir = *dir_p; | |
1377 else | |
1378 dir = dir_both; | |
1379 afterlast_dir = dir; | |
1380 last_dir = afterlast_dir; | |
1077 | 1381 |
1078 /* Skip simple jumps at the end of the blocks. Complex jumps still | 1382 /* Skip simple jumps at the end of the blocks. Complex jumps still |
1079 need to be compared for equivalence, which we'll do below. */ | 1383 need to be compared for equivalence, which we'll do below. */ |
1080 | 1384 |
1081 i1 = BB_END (bb1); | 1385 i1 = BB_END (bb1); |
1082 last1 = afterlast1 = last2 = afterlast2 = NULL_RTX; | 1386 last1 = afterlast1 = last2 = afterlast2 = NULL; |
1083 if (onlyjump_p (i1) | 1387 if (onlyjump_p (i1) |
1084 || (returnjump_p (i1) && !side_effects_p (PATTERN (i1)))) | 1388 || (returnjump_p (i1) && !side_effects_p (PATTERN (i1)))) |
1085 { | 1389 { |
1086 last1 = i1; | 1390 last1 = i1; |
1087 i1 = PREV_INSN (i1); | 1391 i1 = PREV_INSN (i1); |
1090 i2 = BB_END (bb2); | 1394 i2 = BB_END (bb2); |
1091 if (onlyjump_p (i2) | 1395 if (onlyjump_p (i2) |
1092 || (returnjump_p (i2) && !side_effects_p (PATTERN (i2)))) | 1396 || (returnjump_p (i2) && !side_effects_p (PATTERN (i2)))) |
1093 { | 1397 { |
1094 last2 = i2; | 1398 last2 = i2; |
1095 /* Count everything except for unconditional jump as insn. */ | 1399 /* Count everything except for unconditional jump as insn. |
1096 if (!simplejump_p (i2) && !returnjump_p (i2) && last1) | 1400 Don't count any jumps if dir_p is NULL. */ |
1401 if (!simplejump_p (i2) && !returnjump_p (i2) && last1 && dir_p) | |
1097 ninsns++; | 1402 ninsns++; |
1098 i2 = PREV_INSN (i2); | 1403 i2 = PREV_INSN (i2); |
1099 } | 1404 } |
1100 | 1405 |
1101 while (true) | 1406 while (true) |
1102 { | 1407 { |
1103 /* Ignore notes. */ | 1408 /* In the following example, we can replace all jumps to C by jumps to A. |
1104 while (!NONDEBUG_INSN_P (i1) && i1 != BB_HEAD (bb1)) | 1409 |
1105 i1 = PREV_INSN (i1); | 1410 This removes 4 duplicate insns. |
1106 | 1411 [bb A] insn1 [bb C] insn1 |
1107 while (!NONDEBUG_INSN_P (i2) && i2 != BB_HEAD (bb2)) | 1412 insn2 insn2 |
1108 i2 = PREV_INSN (i2); | 1413 [bb B] insn3 insn3 |
1414 insn4 insn4 | |
1415 jump_insn jump_insn | |
1416 | |
1417 We could also replace all jumps to A by jumps to C, but that leaves B | |
1418 alive, and removes only 2 duplicate insns. In a subsequent crossjump | |
1419 step, all jumps to B would be replaced with jumps to the middle of C, | |
1420 achieving the same result with more effort. | |
1421 So we allow only the first possibility, which means that we don't allow | |
1422 fallthru in the block that's being replaced. */ | |
1423 | |
1424 follow_fallthru = dir_p && dir != dir_forward; | |
1425 walk_to_nondebug_insn (&i1, &bb1, follow_fallthru, &did_fallthru); | |
1426 if (did_fallthru) | |
1427 dir = dir_backward; | |
1428 | |
1429 follow_fallthru = dir_p && dir != dir_backward; | |
1430 walk_to_nondebug_insn (&i2, &bb2, follow_fallthru, &did_fallthru); | |
1431 if (did_fallthru) | |
1432 dir = dir_forward; | |
1109 | 1433 |
1110 if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2)) | 1434 if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2)) |
1111 break; | 1435 break; |
1112 | 1436 |
1113 if (!old_insns_match_p (0, i1, i2)) | 1437 /* Do not turn corssing edge to non-crossing or vice versa after |
1438 reload. */ | |
1439 if (BB_PARTITION (BLOCK_FOR_INSN (i1)) | |
1440 != BB_PARTITION (BLOCK_FOR_INSN (i2)) | |
1441 && reload_completed) | |
1442 break; | |
1443 | |
1444 dir = merge_dir (dir, old_insns_match_p (0, i1, i2)); | |
1445 if (dir == dir_none || (!dir_p && dir != dir_both)) | |
1114 break; | 1446 break; |
1115 | 1447 |
1116 merge_memattrs (i1, i2); | 1448 merge_memattrs (i1, i2); |
1117 | 1449 |
1118 /* Don't begin a cross-jump with a NOTE insn. */ | 1450 /* Don't begin a cross-jump with a NOTE insn. */ |
1120 { | 1452 { |
1121 merge_notes (i1, i2); | 1453 merge_notes (i1, i2); |
1122 | 1454 |
1123 afterlast1 = last1, afterlast2 = last2; | 1455 afterlast1 = last1, afterlast2 = last2; |
1124 last1 = i1, last2 = i2; | 1456 last1 = i1, last2 = i2; |
1125 ninsns++; | 1457 afterlast_dir = last_dir; |
1458 last_dir = dir; | |
1459 if (active_insn_p (i1)) | |
1460 ninsns++; | |
1126 } | 1461 } |
1127 | 1462 |
1128 i1 = PREV_INSN (i1); | 1463 i1 = PREV_INSN (i1); |
1129 i2 = PREV_INSN (i2); | 1464 i2 = PREV_INSN (i2); |
1130 } | 1465 } |
1131 | 1466 |
1132 #ifdef HAVE_cc0 | |
1133 /* Don't allow the insn after a compare to be shared by | 1467 /* Don't allow the insn after a compare to be shared by |
1134 cross-jumping unless the compare is also shared. */ | 1468 cross-jumping unless the compare is also shared. */ |
1135 if (ninsns && reg_mentioned_p (cc0_rtx, last1) && ! sets_cc0_p (last1)) | 1469 if (HAVE_cc0 && ninsns && reg_mentioned_p (cc0_rtx, last1) |
1136 last1 = afterlast1, last2 = afterlast2, ninsns--; | 1470 && ! sets_cc0_p (last1)) |
1137 #endif | 1471 last1 = afterlast1, last2 = afterlast2, last_dir = afterlast_dir, ninsns--; |
1138 | 1472 |
1139 /* Include preceding notes and labels in the cross-jump. One, | 1473 /* Include preceding notes and labels in the cross-jump. One, |
1140 this may bring us to the head of the blocks as requested above. | 1474 this may bring us to the head of the blocks as requested above. |
1141 Two, it keeps line number notes as matched as may be. */ | 1475 Two, it keeps line number notes as matched as may be. */ |
1142 if (ninsns) | 1476 if (ninsns) |
1143 { | 1477 { |
1478 bb1 = BLOCK_FOR_INSN (last1); | |
1144 while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1))) | 1479 while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1))) |
1145 last1 = PREV_INSN (last1); | 1480 last1 = PREV_INSN (last1); |
1146 | 1481 |
1147 if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1))) | 1482 if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1))) |
1148 last1 = PREV_INSN (last1); | 1483 last1 = PREV_INSN (last1); |
1149 | 1484 |
1485 bb2 = BLOCK_FOR_INSN (last2); | |
1150 while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2))) | 1486 while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2))) |
1151 last2 = PREV_INSN (last2); | 1487 last2 = PREV_INSN (last2); |
1152 | 1488 |
1153 if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2))) | 1489 if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2))) |
1154 last2 = PREV_INSN (last2); | 1490 last2 = PREV_INSN (last2); |
1155 | 1491 |
1156 *f1 = last1; | 1492 *f1 = last1; |
1157 *f2 = last2; | 1493 *f2 = last2; |
1158 } | 1494 } |
1159 | 1495 |
1496 if (dir_p) | |
1497 *dir_p = last_dir; | |
1160 return ninsns; | 1498 return ninsns; |
1161 } | 1499 } |
1162 | 1500 |
1163 /* Like flow_find_cross_jump, except start looking for a matching sequence from | 1501 /* Like flow_find_cross_jump, except start looking for a matching sequence from |
1164 the head of the two blocks. Do not include jumps at the end. | 1502 the head of the two blocks. Do not include jumps at the end. |
1165 If STOP_AFTER is nonzero, stop after finding that many matching | 1503 If STOP_AFTER is nonzero, stop after finding that many matching |
1166 instructions. */ | 1504 instructions. If STOP_AFTER is zero, count all INSN_P insns, if it is |
1505 non-zero, only count active insns. */ | |
1167 | 1506 |
1168 int | 1507 int |
1169 flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx *f1, | 1508 flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx_insn **f1, |
1170 rtx *f2, int stop_after) | 1509 rtx_insn **f2, int stop_after) |
1171 { | 1510 { |
1172 rtx i1, i2, last1, last2, beforelast1, beforelast2; | 1511 rtx_insn *i1, *i2, *last1, *last2, *beforelast1, *beforelast2; |
1173 int ninsns = 0; | 1512 int ninsns = 0; |
1174 edge e; | 1513 edge e; |
1175 edge_iterator ei; | 1514 edge_iterator ei; |
1176 int nehedges1 = 0, nehedges2 = 0; | 1515 int nehedges1 = 0, nehedges2 = 0; |
1177 | 1516 |
1182 if (e->flags & EDGE_EH) | 1521 if (e->flags & EDGE_EH) |
1183 nehedges2++; | 1522 nehedges2++; |
1184 | 1523 |
1185 i1 = BB_HEAD (bb1); | 1524 i1 = BB_HEAD (bb1); |
1186 i2 = BB_HEAD (bb2); | 1525 i2 = BB_HEAD (bb2); |
1187 last1 = beforelast1 = last2 = beforelast2 = NULL_RTX; | 1526 last1 = beforelast1 = last2 = beforelast2 = NULL; |
1188 | 1527 |
1189 while (true) | 1528 while (true) |
1190 { | 1529 { |
1191 /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG. */ | 1530 /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG. */ |
1192 while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1)) | 1531 while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1)) |
1221 && nehedges2 > 0) | 1560 && nehedges2 > 0) |
1222 || (i1 == BB_END (bb1) && i2 == BB_END (bb2) | 1561 || (i1 == BB_END (bb1) && i2 == BB_END (bb2) |
1223 && nehedges1 != nehedges2)) | 1562 && nehedges1 != nehedges2)) |
1224 break; | 1563 break; |
1225 | 1564 |
1226 if (!old_insns_match_p (0, i1, i2)) | 1565 if (old_insns_match_p (0, i1, i2) != dir_both) |
1227 break; | 1566 break; |
1228 | 1567 |
1229 merge_memattrs (i1, i2); | 1568 merge_memattrs (i1, i2); |
1230 | 1569 |
1231 /* Don't begin a cross-jump with a NOTE insn. */ | 1570 /* Don't begin a cross-jump with a NOTE insn. */ |
1233 { | 1572 { |
1234 merge_notes (i1, i2); | 1573 merge_notes (i1, i2); |
1235 | 1574 |
1236 beforelast1 = last1, beforelast2 = last2; | 1575 beforelast1 = last1, beforelast2 = last2; |
1237 last1 = i1, last2 = i2; | 1576 last1 = i1, last2 = i2; |
1238 ninsns++; | 1577 if (!stop_after || active_insn_p (i1)) |
1578 ninsns++; | |
1239 } | 1579 } |
1240 | 1580 |
1241 if (i1 == BB_END (bb1) || i2 == BB_END (bb2) | 1581 if (i1 == BB_END (bb1) || i2 == BB_END (bb2) |
1242 || (stop_after > 0 && ninsns == stop_after)) | 1582 || (stop_after > 0 && ninsns == stop_after)) |
1243 break; | 1583 break; |
1244 | 1584 |
1245 i1 = NEXT_INSN (i1); | 1585 i1 = NEXT_INSN (i1); |
1246 i2 = NEXT_INSN (i2); | 1586 i2 = NEXT_INSN (i2); |
1247 } | 1587 } |
1248 | 1588 |
1249 #ifdef HAVE_cc0 | |
1250 /* Don't allow a compare to be shared by cross-jumping unless the insn | 1589 /* Don't allow a compare to be shared by cross-jumping unless the insn |
1251 after the compare is also shared. */ | 1590 after the compare is also shared. */ |
1252 if (ninsns && reg_mentioned_p (cc0_rtx, last1) && sets_cc0_p (last1)) | 1591 if (HAVE_cc0 && ninsns && reg_mentioned_p (cc0_rtx, last1) |
1592 && sets_cc0_p (last1)) | |
1253 last1 = beforelast1, last2 = beforelast2, ninsns--; | 1593 last1 = beforelast1, last2 = beforelast2, ninsns--; |
1254 #endif | |
1255 | 1594 |
1256 if (ninsns) | 1595 if (ninsns) |
1257 { | 1596 { |
1258 *f1 = last1; | 1597 *f1 = last1; |
1259 *f2 = last2; | 1598 *f2 = last2; |
1274 int nehedges1 = 0, nehedges2 = 0; | 1613 int nehedges1 = 0, nehedges2 = 0; |
1275 edge fallthru1 = 0, fallthru2 = 0; | 1614 edge fallthru1 = 0, fallthru2 = 0; |
1276 edge e1, e2; | 1615 edge e1, e2; |
1277 edge_iterator ei; | 1616 edge_iterator ei; |
1278 | 1617 |
1618 /* If we performed shrink-wrapping, edges to the exit block can | |
1619 only be distinguished for JUMP_INSNs. The two paths may differ in | |
1620 whether they went through the prologue. Sibcalls are fine, we know | |
1621 that we either didn't need or inserted an epilogue before them. */ | |
1622 if (crtl->shrink_wrapped | |
1623 && single_succ_p (bb1) | |
1624 && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun) | |
1625 && !JUMP_P (BB_END (bb1)) | |
1626 && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1)))) | |
1627 return false; | |
1628 | |
1279 /* If BB1 has only one successor, we may be looking at either an | 1629 /* If BB1 has only one successor, we may be looking at either an |
1280 unconditional jump, or a fake edge to exit. */ | 1630 unconditional jump, or a fake edge to exit. */ |
1281 if (single_succ_p (bb1) | 1631 if (single_succ_p (bb1) |
1282 && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0 | 1632 && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0 |
1283 && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1)))) | 1633 && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1)))) |
1364 roughly similar. */ | 1714 roughly similar. */ |
1365 if (match | 1715 if (match |
1366 && optimize_bb_for_speed_p (bb1) | 1716 && optimize_bb_for_speed_p (bb1) |
1367 && optimize_bb_for_speed_p (bb2)) | 1717 && optimize_bb_for_speed_p (bb2)) |
1368 { | 1718 { |
1369 int prob2; | 1719 profile_probability prob2; |
1370 | 1720 |
1371 if (b1->dest == b2->dest) | 1721 if (b1->dest == b2->dest) |
1372 prob2 = b2->probability; | 1722 prob2 = b2->probability; |
1373 else | 1723 else |
1374 /* Do not use f2 probability as f2 may be forwarded. */ | 1724 /* Do not use f2 probability as f2 may be forwarded. */ |
1375 prob2 = REG_BR_PROB_BASE - b2->probability; | 1725 prob2 = b2->probability.invert (); |
1376 | 1726 |
1377 /* Fail if the difference in probabilities is greater than 50%. | 1727 /* Fail if the difference in probabilities is greater than 50%. |
1378 This rules out two well-predicted branches with opposite | 1728 This rules out two well-predicted branches with opposite |
1379 outcomes. */ | 1729 outcomes. */ |
1380 if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2) | 1730 if (b1->probability.differs_lot_from_p (prob2)) |
1381 { | 1731 { |
1382 if (dump_file) | 1732 if (dump_file) |
1383 fprintf (dump_file, | 1733 { |
1384 "Outcomes of branch in bb %i and %i differ too much (%i %i)\n", | 1734 fprintf (dump_file, |
1385 bb1->index, bb2->index, b1->probability, prob2); | 1735 "Outcomes of branch in bb %i and %i differ too" |
1386 | 1736 " much (", bb1->index, bb2->index); |
1737 b1->probability.dump (dump_file); | |
1738 prob2.dump (dump_file); | |
1739 fprintf (dump_file, ")\n"); | |
1740 } | |
1387 return false; | 1741 return false; |
1388 } | 1742 } |
1389 } | 1743 } |
1390 | 1744 |
1391 if (dump_file && match) | 1745 if (dump_file && match) |
1399 instruction. */ | 1753 instruction. */ |
1400 | 1754 |
1401 /* Check whether there are tablejumps in the end of BB1 and BB2. | 1755 /* Check whether there are tablejumps in the end of BB1 and BB2. |
1402 Return true if they are identical. */ | 1756 Return true if they are identical. */ |
1403 { | 1757 { |
1404 rtx label1, label2; | 1758 rtx_insn *label1, *label2; |
1405 rtx table1, table2; | 1759 rtx_jump_table_data *table1, *table2; |
1406 | 1760 |
1407 if (tablejump_p (BB_END (bb1), &label1, &table1) | 1761 if (tablejump_p (BB_END (bb1), &label1, &table1) |
1408 && tablejump_p (BB_END (bb2), &label2, &table2) | 1762 && tablejump_p (BB_END (bb2), &label2, &table2) |
1409 && GET_CODE (PATTERN (table1)) == GET_CODE (PATTERN (table2))) | 1763 && GET_CODE (PATTERN (table1)) == GET_CODE (PATTERN (table2))) |
1410 { | 1764 { |
1440 identical = false; | 1794 identical = false; |
1441 } | 1795 } |
1442 | 1796 |
1443 if (identical) | 1797 if (identical) |
1444 { | 1798 { |
1445 replace_label_data rr; | |
1446 bool match; | 1799 bool match; |
1447 | 1800 |
1448 /* Temporarily replace references to LABEL1 with LABEL2 | 1801 /* Temporarily replace references to LABEL1 with LABEL2 |
1449 in BB1->END so that we could compare the instructions. */ | 1802 in BB1->END so that we could compare the instructions. */ |
1450 rr.r1 = label1; | 1803 replace_label_in_insn (BB_END (bb1), label1, label2, false); |
1451 rr.r2 = label2; | 1804 |
1452 rr.update_label_nuses = false; | 1805 match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)) |
1453 for_each_rtx (&BB_END (bb1), replace_label, &rr); | 1806 == dir_both); |
1454 | |
1455 match = old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)); | |
1456 if (dump_file && match) | 1807 if (dump_file && match) |
1457 fprintf (dump_file, | 1808 fprintf (dump_file, |
1458 "Tablejumps in bb %i and %i match.\n", | 1809 "Tablejumps in bb %i and %i match.\n", |
1459 bb1->index, bb2->index); | 1810 bb1->index, bb2->index); |
1460 | 1811 |
1461 /* Set the original label in BB1->END because when deleting | 1812 /* Set the original label in BB1->END because when deleting |
1462 a block whose end is a tablejump, the tablejump referenced | 1813 a block whose end is a tablejump, the tablejump referenced |
1463 from the instruction is deleted too. */ | 1814 from the instruction is deleted too. */ |
1464 rr.r1 = label2; | 1815 replace_label_in_insn (BB_END (bb1), label2, label1, false); |
1465 rr.r2 = label1; | |
1466 for_each_rtx (&BB_END (bb1), replace_label, &rr); | |
1467 | 1816 |
1468 return match; | 1817 return match; |
1469 } | 1818 } |
1470 } | 1819 } |
1471 return false; | 1820 return false; |
1472 } | 1821 } |
1473 } | 1822 } |
1474 | 1823 |
1824 /* Find the last non-debug non-note instruction in each bb, except | |
1825 stop when we see the NOTE_INSN_BASIC_BLOCK, as old_insns_match_p | |
1826 handles that case specially. old_insns_match_p does not handle | |
1827 other types of instruction notes. */ | |
1828 rtx_insn *last1 = BB_END (bb1); | |
1829 rtx_insn *last2 = BB_END (bb2); | |
1830 while (!NOTE_INSN_BASIC_BLOCK_P (last1) && | |
1831 (DEBUG_INSN_P (last1) || NOTE_P (last1))) | |
1832 last1 = PREV_INSN (last1); | |
1833 while (!NOTE_INSN_BASIC_BLOCK_P (last2) && | |
1834 (DEBUG_INSN_P (last2) || NOTE_P (last2))) | |
1835 last2 = PREV_INSN (last2); | |
1836 gcc_assert (last1 && last2); | |
1837 | |
1475 /* First ensure that the instructions match. There may be many outgoing | 1838 /* First ensure that the instructions match. There may be many outgoing |
1476 edges so this test is generally cheaper. */ | 1839 edges so this test is generally cheaper. */ |
1477 if (!old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))) | 1840 if (old_insns_match_p (mode, last1, last2) != dir_both) |
1478 return false; | 1841 return false; |
1479 | 1842 |
1480 /* Search the outgoing edges, ensure that the counts do match, find possible | 1843 /* Search the outgoing edges, ensure that the counts do match, find possible |
1481 fallthru and exception handling edges since these needs more | 1844 fallthru and exception handling edges since these needs more |
1482 validation. */ | 1845 validation. */ |
1483 if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs)) | 1846 if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs)) |
1484 return false; | 1847 return false; |
1485 | 1848 |
1849 bool nonfakeedges = false; | |
1486 FOR_EACH_EDGE (e1, ei, bb1->succs) | 1850 FOR_EACH_EDGE (e1, ei, bb1->succs) |
1487 { | 1851 { |
1488 e2 = EDGE_SUCC (bb2, ei.index); | 1852 e2 = EDGE_SUCC (bb2, ei.index); |
1853 | |
1854 if ((e1->flags & EDGE_FAKE) == 0) | |
1855 nonfakeedges = true; | |
1489 | 1856 |
1490 if (e1->flags & EDGE_EH) | 1857 if (e1->flags & EDGE_EH) |
1491 nehedges1++; | 1858 nehedges1++; |
1492 | 1859 |
1493 if (e2->flags & EDGE_EH) | 1860 if (e2->flags & EDGE_EH) |
1500 } | 1867 } |
1501 | 1868 |
1502 /* If number of edges of various types does not match, fail. */ | 1869 /* If number of edges of various types does not match, fail. */ |
1503 if (nehedges1 != nehedges2 | 1870 if (nehedges1 != nehedges2 |
1504 || (fallthru1 != 0) != (fallthru2 != 0)) | 1871 || (fallthru1 != 0) != (fallthru2 != 0)) |
1872 return false; | |
1873 | |
1874 /* If !ACCUMULATE_OUTGOING_ARGS, bb1 (and bb2) have no successors | |
1875 and the last real insn doesn't have REG_ARGS_SIZE note, don't | |
1876 attempt to optimize, as the two basic blocks might have different | |
1877 REG_ARGS_SIZE depths. For noreturn calls and unconditional | |
1878 traps there should be REG_ARG_SIZE notes, they could be missing | |
1879 for __builtin_unreachable () uses though. */ | |
1880 if (!nonfakeedges | |
1881 && !ACCUMULATE_OUTGOING_ARGS | |
1882 && (!INSN_P (last1) | |
1883 || !find_reg_note (last1, REG_ARGS_SIZE, NULL))) | |
1505 return false; | 1884 return false; |
1506 | 1885 |
1507 /* fallthru edges must be forwarded to the same destination. */ | 1886 /* fallthru edges must be forwarded to the same destination. */ |
1508 if (fallthru1) | 1887 if (fallthru1) |
1509 { | 1888 { |
1565 && LABEL_PRESERVE_P (block_label (bb))); | 1944 && LABEL_PRESERVE_P (block_label (bb))); |
1566 } | 1945 } |
1567 | 1946 |
1568 /* E1 and E2 are edges with the same destination block. Search their | 1947 /* E1 and E2 are edges with the same destination block. Search their |
1569 predecessors for common code. If found, redirect control flow from | 1948 predecessors for common code. If found, redirect control flow from |
1570 (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC. */ | 1949 (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC (dir_forward), |
1950 or the other way around (dir_backward). DIR specifies the allowed | |
1951 replacement direction. */ | |
1571 | 1952 |
1572 static bool | 1953 static bool |
1573 try_crossjump_to_edge (int mode, edge e1, edge e2) | 1954 try_crossjump_to_edge (int mode, edge e1, edge e2, |
1955 enum replace_direction dir) | |
1574 { | 1956 { |
1575 int nmatch; | 1957 int nmatch; |
1576 basic_block src1 = e1->src, src2 = e2->src; | 1958 basic_block src1 = e1->src, src2 = e2->src; |
1577 basic_block redirect_to, redirect_from, to_remove; | 1959 basic_block redirect_to, redirect_from, to_remove; |
1578 rtx newpos1, newpos2; | 1960 basic_block osrc1, osrc2, redirect_edges_to, tmp; |
1961 rtx_insn *newpos1, *newpos2; | |
1579 edge s; | 1962 edge s; |
1580 edge_iterator ei; | 1963 edge_iterator ei; |
1581 | 1964 |
1582 newpos1 = newpos2 = NULL_RTX; | 1965 newpos1 = newpos2 = NULL; |
1583 | |
1584 /* If we have partitioned hot/cold basic blocks, it is a bad idea | |
1585 to try this optimization. | |
1586 | |
1587 Basic block partitioning may result in some jumps that appear to | |
1588 be optimizable (or blocks that appear to be mergeable), but which really | |
1589 must be left untouched (they are required to make it safely across | |
1590 partition boundaries). See the comments at the top of | |
1591 bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */ | |
1592 | |
1593 if (flag_reorder_blocks_and_partition && reload_completed) | |
1594 return false; | |
1595 | 1966 |
1596 /* Search backward through forwarder blocks. We don't need to worry | 1967 /* Search backward through forwarder blocks. We don't need to worry |
1597 about multiple entry or chained forwarders, as they will be optimized | 1968 about multiple entry or chained forwarders, as they will be optimized |
1598 away. We do this to look past the unconditional jump following a | 1969 away. We do this to look past the unconditional jump following a |
1599 conditional jump that is required due to the current CFG shape. */ | 1970 conditional jump that is required due to the current CFG shape. */ |
1604 if (single_pred_p (src2) | 1975 if (single_pred_p (src2) |
1605 && FORWARDER_BLOCK_P (src2)) | 1976 && FORWARDER_BLOCK_P (src2)) |
1606 e2 = single_pred_edge (src2), src2 = e2->src; | 1977 e2 = single_pred_edge (src2), src2 = e2->src; |
1607 | 1978 |
1608 /* Nothing to do if we reach ENTRY, or a common source block. */ | 1979 /* Nothing to do if we reach ENTRY, or a common source block. */ |
1609 if (src1 == ENTRY_BLOCK_PTR || src2 == ENTRY_BLOCK_PTR) | 1980 if (src1 == ENTRY_BLOCK_PTR_FOR_FN (cfun) || src2 |
1981 == ENTRY_BLOCK_PTR_FOR_FN (cfun)) | |
1610 return false; | 1982 return false; |
1611 if (src1 == src2) | 1983 if (src1 == src2) |
1612 return false; | 1984 return false; |
1613 | 1985 |
1614 /* Seeing more than 1 forwarder blocks would confuse us later... */ | 1986 /* Seeing more than 1 forwarder blocks would confuse us later... */ |
1623 /* Likewise with dead code (possibly newly created by the other optimizations | 1995 /* Likewise with dead code (possibly newly created by the other optimizations |
1624 of cfg_cleanup). */ | 1996 of cfg_cleanup). */ |
1625 if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0) | 1997 if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0) |
1626 return false; | 1998 return false; |
1627 | 1999 |
2000 /* Do not turn corssing edge to non-crossing or vice versa after reload. */ | |
2001 if (BB_PARTITION (src1) != BB_PARTITION (src2) | |
2002 && reload_completed) | |
2003 return false; | |
2004 | |
1628 /* Look for the common insn sequence, part the first ... */ | 2005 /* Look for the common insn sequence, part the first ... */ |
1629 if (!outgoing_edges_match (mode, src1, src2)) | 2006 if (!outgoing_edges_match (mode, src1, src2)) |
1630 return false; | 2007 return false; |
1631 | 2008 |
1632 /* ... and part the second. */ | 2009 /* ... and part the second. */ |
1633 nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2); | 2010 nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir); |
2011 | |
2012 osrc1 = src1; | |
2013 osrc2 = src2; | |
2014 if (newpos1 != NULL_RTX) | |
2015 src1 = BLOCK_FOR_INSN (newpos1); | |
2016 if (newpos2 != NULL_RTX) | |
2017 src2 = BLOCK_FOR_INSN (newpos2); | |
2018 | |
2019 /* Check that SRC1 and SRC2 have preds again. They may have changed | |
2020 above due to the call to flow_find_cross_jump. */ | |
2021 if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0) | |
2022 return false; | |
2023 | |
2024 if (dir == dir_backward) | |
2025 { | |
2026 std::swap (osrc1, osrc2); | |
2027 std::swap (src1, src2); | |
2028 std::swap (e1, e2); | |
2029 std::swap (newpos1, newpos2); | |
2030 } | |
1634 | 2031 |
1635 /* Don't proceed with the crossjump unless we found a sufficient number | 2032 /* Don't proceed with the crossjump unless we found a sufficient number |
1636 of matching instructions or the 'from' block was totally matched | 2033 of matching instructions or the 'from' block was totally matched |
1637 (such that its predecessors will hopefully be redirected and the | 2034 (such that its predecessors will hopefully be redirected and the |
1638 block removed). */ | 2035 block removed). */ |
1648 /* Here we know that the insns in the end of SRC1 which are common with SRC2 | 2045 /* Here we know that the insns in the end of SRC1 which are common with SRC2 |
1649 will be deleted. | 2046 will be deleted. |
1650 If we have tablejumps in the end of SRC1 and SRC2 | 2047 If we have tablejumps in the end of SRC1 and SRC2 |
1651 they have been already compared for equivalence in outgoing_edges_match () | 2048 they have been already compared for equivalence in outgoing_edges_match () |
1652 so replace the references to TABLE1 by references to TABLE2. */ | 2049 so replace the references to TABLE1 by references to TABLE2. */ |
1653 { | 2050 { |
1654 rtx label1, label2; | 2051 rtx_insn *label1, *label2; |
1655 rtx table1, table2; | 2052 rtx_jump_table_data *table1, *table2; |
1656 | 2053 |
1657 if (tablejump_p (BB_END (src1), &label1, &table1) | 2054 if (tablejump_p (BB_END (osrc1), &label1, &table1) |
1658 && tablejump_p (BB_END (src2), &label2, &table2) | 2055 && tablejump_p (BB_END (osrc2), &label2, &table2) |
1659 && label1 != label2) | 2056 && label1 != label2) |
1660 { | 2057 { |
1661 replace_label_data rr; | 2058 rtx_insn *insn; |
1662 rtx insn; | |
1663 | 2059 |
1664 /* Replace references to LABEL1 with LABEL2. */ | 2060 /* Replace references to LABEL1 with LABEL2. */ |
1665 rr.r1 = label1; | |
1666 rr.r2 = label2; | |
1667 rr.update_label_nuses = true; | |
1668 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | 2061 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) |
1669 { | 2062 { |
1670 /* Do not replace the label in SRC1->END because when deleting | 2063 /* Do not replace the label in SRC1->END because when deleting |
1671 a block whose end is a tablejump, the tablejump referenced | 2064 a block whose end is a tablejump, the tablejump referenced |
1672 from the instruction is deleted too. */ | 2065 from the instruction is deleted too. */ |
1673 if (insn != BB_END (src1)) | 2066 if (insn != BB_END (osrc1)) |
1674 for_each_rtx (&insn, replace_label, &rr); | 2067 replace_label_in_insn (insn, label1, label2, true); |
1675 } | 2068 } |
1676 } | 2069 } |
1677 } | 2070 } |
1678 | 2071 |
1679 /* Avoid splitting if possible. We must always split when SRC2 has | 2072 /* Avoid splitting if possible. We must always split when SRC2 has |
1680 EH predecessor edges, or we may end up with basic blocks with both | 2073 EH predecessor edges, or we may end up with basic blocks with both |
1681 normal and EH predecessor edges. */ | 2074 normal and EH predecessor edges. */ |
1682 if (newpos2 == BB_HEAD (src2) | 2075 if (newpos2 == BB_HEAD (src2) |
1709 src1->index, src2->index, nmatch); | 2102 src1->index, src2->index, nmatch); |
1710 | 2103 |
1711 /* We may have some registers visible through the block. */ | 2104 /* We may have some registers visible through the block. */ |
1712 df_set_bb_dirty (redirect_to); | 2105 df_set_bb_dirty (redirect_to); |
1713 | 2106 |
2107 if (osrc2 == src2) | |
2108 redirect_edges_to = redirect_to; | |
2109 else | |
2110 redirect_edges_to = osrc2; | |
2111 | |
1714 /* Recompute the frequencies and counts of outgoing edges. */ | 2112 /* Recompute the frequencies and counts of outgoing edges. */ |
1715 FOR_EACH_EDGE (s, ei, redirect_to->succs) | 2113 FOR_EACH_EDGE (s, ei, redirect_edges_to->succs) |
1716 { | 2114 { |
1717 edge s2; | 2115 edge s2; |
1718 edge_iterator ei; | 2116 edge_iterator ei; |
1719 basic_block d = s->dest; | 2117 basic_block d = s->dest; |
1720 | 2118 |
1728 d2 = single_succ (d2); | 2126 d2 = single_succ (d2); |
1729 if (d == d2) | 2127 if (d == d2) |
1730 break; | 2128 break; |
1731 } | 2129 } |
1732 | 2130 |
1733 s->count += s2->count; | |
1734 | |
1735 /* Take care to update possible forwarder blocks. We verified | 2131 /* Take care to update possible forwarder blocks. We verified |
1736 that there is no more than one in the chain, so we can't run | 2132 that there is no more than one in the chain, so we can't run |
1737 into infinite loop. */ | 2133 into infinite loop. */ |
1738 if (FORWARDER_BLOCK_P (s->dest)) | 2134 if (FORWARDER_BLOCK_P (s->dest)) |
1739 { | 2135 { |
1740 single_succ_edge (s->dest)->count += s2->count; | |
1741 s->dest->count += s2->count; | |
1742 s->dest->frequency += EDGE_FREQUENCY (s); | 2136 s->dest->frequency += EDGE_FREQUENCY (s); |
1743 } | 2137 } |
1744 | 2138 |
1745 if (FORWARDER_BLOCK_P (s2->dest)) | 2139 if (FORWARDER_BLOCK_P (s2->dest)) |
1746 { | 2140 { |
1747 single_succ_edge (s2->dest)->count -= s2->count; | |
1748 if (single_succ_edge (s2->dest)->count < 0) | |
1749 single_succ_edge (s2->dest)->count = 0; | |
1750 s2->dest->count -= s2->count; | |
1751 s2->dest->frequency -= EDGE_FREQUENCY (s); | 2141 s2->dest->frequency -= EDGE_FREQUENCY (s); |
1752 if (s2->dest->frequency < 0) | 2142 if (s2->dest->frequency < 0) |
1753 s2->dest->frequency = 0; | 2143 s2->dest->frequency = 0; |
1754 if (s2->dest->count < 0) | 2144 } |
1755 s2->dest->count = 0; | 2145 |
1756 } | 2146 if (!redirect_edges_to->frequency && !src1->frequency) |
1757 | 2147 s->probability = s->probability.combine_with_freq |
1758 if (!redirect_to->frequency && !src1->frequency) | 2148 (redirect_edges_to->frequency, |
1759 s->probability = (s->probability + s2->probability) / 2; | 2149 s2->probability, src1->frequency); |
1760 else | |
1761 s->probability | |
1762 = ((s->probability * redirect_to->frequency + | |
1763 s2->probability * src1->frequency) | |
1764 / (redirect_to->frequency + src1->frequency)); | |
1765 } | 2150 } |
1766 | 2151 |
1767 /* Adjust count and frequency for the block. An earlier jump | 2152 /* Adjust count and frequency for the block. An earlier jump |
1768 threading pass may have left the profile in an inconsistent | 2153 threading pass may have left the profile in an inconsistent |
1769 state (see update_bb_profile_for_threading) so we must be | 2154 state (see update_bb_profile_for_threading) so we must be |
1770 prepared for overflows. */ | 2155 prepared for overflows. */ |
1771 redirect_to->count += src1->count; | 2156 tmp = redirect_to; |
1772 redirect_to->frequency += src1->frequency; | 2157 do |
1773 if (redirect_to->frequency > BB_FREQ_MAX) | 2158 { |
1774 redirect_to->frequency = BB_FREQ_MAX; | 2159 tmp->count += src1->count; |
1775 update_br_prob_note (redirect_to); | 2160 tmp->frequency += src1->frequency; |
2161 if (tmp->frequency > BB_FREQ_MAX) | |
2162 tmp->frequency = BB_FREQ_MAX; | |
2163 if (tmp == redirect_edges_to) | |
2164 break; | |
2165 tmp = find_fallthru_edge (tmp->succs)->dest; | |
2166 } | |
2167 while (true); | |
2168 update_br_prob_note (redirect_edges_to); | |
1776 | 2169 |
1777 /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */ | 2170 /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */ |
1778 | 2171 |
1779 /* Skip possible basic block header. */ | 2172 /* Skip possible basic block header. */ |
1780 if (LABEL_P (newpos1)) | 2173 if (LABEL_P (newpos1)) |
1810 try_crossjump_bb (int mode, basic_block bb) | 2203 try_crossjump_bb (int mode, basic_block bb) |
1811 { | 2204 { |
1812 edge e, e2, fallthru; | 2205 edge e, e2, fallthru; |
1813 bool changed; | 2206 bool changed; |
1814 unsigned max, ix, ix2; | 2207 unsigned max, ix, ix2; |
1815 basic_block ev, ev2; | |
1816 | 2208 |
1817 /* Nothing to do if there is not at least two incoming edges. */ | 2209 /* Nothing to do if there is not at least two incoming edges. */ |
1818 if (EDGE_COUNT (bb->preds) < 2) | 2210 if (EDGE_COUNT (bb->preds) < 2) |
1819 return false; | 2211 return false; |
1820 | 2212 |
1821 /* Don't crossjump if this block ends in a computed jump, | 2213 /* Don't crossjump if this block ends in a computed jump, |
1822 unless we are optimizing for size. */ | 2214 unless we are optimizing for size. */ |
1823 if (optimize_bb_for_size_p (bb) | 2215 if (optimize_bb_for_size_p (bb) |
1824 && bb != EXIT_BLOCK_PTR | 2216 && bb != EXIT_BLOCK_PTR_FOR_FN (cfun) |
1825 && computed_jump_p (BB_END (bb))) | 2217 && computed_jump_p (BB_END (bb))) |
1826 return false; | 2218 return false; |
1827 | 2219 |
1828 /* If we are partitioning hot/cold basic blocks, we don't want to | 2220 /* If we are partitioning hot/cold basic blocks, we don't want to |
1829 mess up unconditional or indirect jumps that cross between hot | 2221 mess up unconditional or indirect jumps that cross between hot |
1850 return false; | 2242 return false; |
1851 | 2243 |
1852 fallthru = find_fallthru_edge (bb->preds); | 2244 fallthru = find_fallthru_edge (bb->preds); |
1853 | 2245 |
1854 changed = false; | 2246 changed = false; |
1855 for (ix = 0, ev = bb; ix < EDGE_COUNT (ev->preds); ) | 2247 for (ix = 0; ix < EDGE_COUNT (bb->preds);) |
1856 { | 2248 { |
1857 e = EDGE_PRED (ev, ix); | 2249 e = EDGE_PRED (bb, ix); |
1858 ix++; | 2250 ix++; |
1859 | 2251 |
1860 /* As noted above, first try with the fallthru predecessor (or, a | 2252 /* As noted above, first try with the fallthru predecessor (or, a |
1861 fallthru predecessor if we are in cfglayout mode). */ | 2253 fallthru predecessor if we are in cfglayout mode). */ |
1862 if (fallthru) | 2254 if (fallthru) |
1870 if (!first_pass | 2262 if (!first_pass |
1871 && !((e->src->flags & BB_MODIFIED) | 2263 && !((e->src->flags & BB_MODIFIED) |
1872 || (fallthru->src->flags & BB_MODIFIED))) | 2264 || (fallthru->src->flags & BB_MODIFIED))) |
1873 continue; | 2265 continue; |
1874 | 2266 |
1875 if (try_crossjump_to_edge (mode, e, fallthru)) | 2267 if (try_crossjump_to_edge (mode, e, fallthru, dir_forward)) |
1876 { | 2268 { |
1877 changed = true; | 2269 changed = true; |
1878 ix = 0; | 2270 ix = 0; |
1879 ev = bb; | |
1880 continue; | 2271 continue; |
1881 } | 2272 } |
1882 } | 2273 } |
1883 | 2274 |
1884 /* Non-obvious work limiting check: Recognize that we're going | 2275 /* Non-obvious work limiting check: Recognize that we're going |
1894 choosing to do the check from the block for which the edge | 2285 choosing to do the check from the block for which the edge |
1895 in question is the first successor of A. */ | 2286 in question is the first successor of A. */ |
1896 if (EDGE_SUCC (e->src, 0) != e) | 2287 if (EDGE_SUCC (e->src, 0) != e) |
1897 continue; | 2288 continue; |
1898 | 2289 |
1899 for (ix2 = 0, ev2 = bb; ix2 < EDGE_COUNT (ev2->preds); ) | 2290 for (ix2 = 0; ix2 < EDGE_COUNT (bb->preds); ix2++) |
1900 { | 2291 { |
1901 e2 = EDGE_PRED (ev2, ix2); | 2292 e2 = EDGE_PRED (bb, ix2); |
1902 ix2++; | |
1903 | 2293 |
1904 if (e2 == e) | 2294 if (e2 == e) |
1905 continue; | 2295 continue; |
1906 | 2296 |
1907 /* We've already checked the fallthru edge above. */ | 2297 /* We've already checked the fallthru edge above. */ |
1920 if (!first_pass | 2310 if (!first_pass |
1921 && !((e->src->flags & BB_MODIFIED) | 2311 && !((e->src->flags & BB_MODIFIED) |
1922 || (e2->src->flags & BB_MODIFIED))) | 2312 || (e2->src->flags & BB_MODIFIED))) |
1923 continue; | 2313 continue; |
1924 | 2314 |
1925 if (try_crossjump_to_edge (mode, e, e2)) | 2315 /* Both e and e2 are not fallthru edges, so we can crossjump in either |
2316 direction. */ | |
2317 if (try_crossjump_to_edge (mode, e, e2, dir_both)) | |
1926 { | 2318 { |
1927 changed = true; | 2319 changed = true; |
1928 ev2 = bb; | |
1929 ix = 0; | 2320 ix = 0; |
1930 break; | 2321 break; |
1931 } | 2322 } |
1932 } | 2323 } |
1933 } | 2324 } |
1934 | 2325 |
1935 if (changed) | 2326 if (changed) |
1936 crossjumps_occured = true; | 2327 crossjumps_occurred = true; |
1937 | 2328 |
1938 return changed; | 2329 return changed; |
1939 } | 2330 } |
1940 | 2331 |
1941 /* Search the successors of BB for common insn sequences. When found, | 2332 /* Search the successors of BB for common insn sequences. When found, |
1946 try_head_merge_bb (basic_block bb) | 2337 try_head_merge_bb (basic_block bb) |
1947 { | 2338 { |
1948 basic_block final_dest_bb = NULL; | 2339 basic_block final_dest_bb = NULL; |
1949 int max_match = INT_MAX; | 2340 int max_match = INT_MAX; |
1950 edge e0; | 2341 edge e0; |
1951 rtx *headptr, *currptr, *nextptr; | 2342 rtx_insn **headptr, **currptr, **nextptr; |
1952 bool changed, moveall; | 2343 bool changed, moveall; |
1953 unsigned ix; | 2344 unsigned ix; |
1954 rtx e0_last_head, cond, move_before; | 2345 rtx_insn *e0_last_head; |
2346 rtx cond; | |
2347 rtx_insn *move_before; | |
1955 unsigned nedges = EDGE_COUNT (bb->succs); | 2348 unsigned nedges = EDGE_COUNT (bb->succs); |
1956 rtx jump = BB_END (bb); | 2349 rtx_insn *jump = BB_END (bb); |
1957 regset live, live_union; | 2350 regset live, live_union; |
1958 | 2351 |
1959 /* Nothing to do if there is not at least two outgoing edges. */ | 2352 /* Nothing to do if there is not at least two outgoing edges. */ |
1960 if (nedges < 2) | 2353 if (nedges < 2) |
1961 return false; | 2354 return false; |
1962 | 2355 |
1963 /* Don't crossjump if this block ends in a computed jump, | 2356 /* Don't crossjump if this block ends in a computed jump, |
1964 unless we are optimizing for size. */ | 2357 unless we are optimizing for size. */ |
1965 if (optimize_bb_for_size_p (bb) | 2358 if (optimize_bb_for_size_p (bb) |
1966 && bb != EXIT_BLOCK_PTR | 2359 && bb != EXIT_BLOCK_PTR_FOR_FN (cfun) |
1967 && computed_jump_p (BB_END (bb))) | 2360 && computed_jump_p (BB_END (bb))) |
1968 return false; | 2361 return false; |
1969 | 2362 |
1970 cond = get_condition (jump, &move_before, true, false); | 2363 cond = get_condition (jump, &move_before, true, false); |
1971 if (cond == NULL_RTX) | 2364 if (cond == NULL_RTX) |
1972 move_before = jump; | 2365 { |
2366 if (HAVE_cc0 && reg_mentioned_p (cc0_rtx, jump)) | |
2367 move_before = prev_nonnote_nondebug_insn (jump); | |
2368 else | |
2369 move_before = jump; | |
2370 } | |
1973 | 2371 |
1974 for (ix = 0; ix < nedges; ix++) | 2372 for (ix = 0; ix < nedges; ix++) |
1975 if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR) | 2373 if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) |
1976 return false; | 2374 return false; |
1977 | 2375 |
1978 for (ix = 0; ix < nedges; ix++) | 2376 for (ix = 0; ix < nedges; ix++) |
1979 { | 2377 { |
1980 edge e = EDGE_SUCC (bb, ix); | 2378 edge e = EDGE_SUCC (bb, ix); |
2034 return false; | 2432 return false; |
2035 } | 2433 } |
2036 } | 2434 } |
2037 | 2435 |
2038 e0 = EDGE_SUCC (bb, 0); | 2436 e0 = EDGE_SUCC (bb, 0); |
2039 e0_last_head = NULL_RTX; | 2437 e0_last_head = NULL; |
2040 changed = false; | 2438 changed = false; |
2041 | 2439 |
2042 for (ix = 1; ix < nedges; ix++) | 2440 for (ix = 1; ix < nedges; ix++) |
2043 { | 2441 { |
2044 edge e = EDGE_SUCC (bb, ix); | 2442 edge e = EDGE_SUCC (bb, ix); |
2045 rtx e0_last, e_last; | 2443 rtx_insn *e0_last, *e_last; |
2046 int nmatch; | 2444 int nmatch; |
2047 | 2445 |
2048 nmatch = flow_find_head_matching_sequence (e0->dest, e->dest, | 2446 nmatch = flow_find_head_matching_sequence (e0->dest, e->dest, |
2049 &e0_last, &e_last, 0); | 2447 &e0_last, &e_last, 0); |
2050 if (nmatch == 0) | 2448 if (nmatch == 0) |
2077 | 2475 |
2078 /* We must find a union of the live registers at each of the end points. */ | 2476 /* We must find a union of the live registers at each of the end points. */ |
2079 live = BITMAP_ALLOC (NULL); | 2477 live = BITMAP_ALLOC (NULL); |
2080 live_union = BITMAP_ALLOC (NULL); | 2478 live_union = BITMAP_ALLOC (NULL); |
2081 | 2479 |
2082 currptr = XNEWVEC (rtx, nedges); | 2480 currptr = XNEWVEC (rtx_insn *, nedges); |
2083 headptr = XNEWVEC (rtx, nedges); | 2481 headptr = XNEWVEC (rtx_insn *, nedges); |
2084 nextptr = XNEWVEC (rtx, nedges); | 2482 nextptr = XNEWVEC (rtx_insn *, nedges); |
2085 | 2483 |
2086 for (ix = 0; ix < nedges; ix++) | 2484 for (ix = 0; ix < nedges; ix++) |
2087 { | 2485 { |
2088 int j; | 2486 int j; |
2089 basic_block merge_bb = EDGE_SUCC (bb, ix)->dest; | 2487 basic_block merge_bb = EDGE_SUCC (bb, ix)->dest; |
2090 rtx head = BB_HEAD (merge_bb); | 2488 rtx_insn *head = BB_HEAD (merge_bb); |
2091 | 2489 |
2092 while (!NONDEBUG_INSN_P (head)) | 2490 while (!NONDEBUG_INSN_P (head)) |
2093 head = NEXT_INSN (head); | 2491 head = NEXT_INSN (head); |
2094 headptr[ix] = head; | 2492 headptr[ix] = head; |
2095 currptr[ix] = head; | 2493 currptr[ix] = head; |
2106 /* If we're moving across two blocks, verify the validity of the | 2504 /* If we're moving across two blocks, verify the validity of the |
2107 first move, then adjust the target and let the loop below deal | 2505 first move, then adjust the target and let the loop below deal |
2108 with the final move. */ | 2506 with the final move. */ |
2109 if (final_dest_bb != NULL) | 2507 if (final_dest_bb != NULL) |
2110 { | 2508 { |
2111 rtx move_upto; | 2509 rtx_insn *move_upto; |
2112 | 2510 |
2113 moveall = can_move_insns_across (currptr[0], e0_last_head, move_before, | 2511 moveall = can_move_insns_across (currptr[0], e0_last_head, move_before, |
2114 jump, e0->dest, live_union, | 2512 jump, e0->dest, live_union, |
2115 NULL, &move_upto); | 2513 NULL, &move_upto); |
2116 if (!moveall) | 2514 if (!moveall) |
2129 goto out; | 2527 goto out; |
2130 | 2528 |
2131 jump = BB_END (final_dest_bb); | 2529 jump = BB_END (final_dest_bb); |
2132 cond = get_condition (jump, &move_before, true, false); | 2530 cond = get_condition (jump, &move_before, true, false); |
2133 if (cond == NULL_RTX) | 2531 if (cond == NULL_RTX) |
2134 move_before = jump; | 2532 { |
2533 if (HAVE_cc0 && reg_mentioned_p (cc0_rtx, jump)) | |
2534 move_before = prev_nonnote_nondebug_insn (jump); | |
2535 else | |
2536 move_before = jump; | |
2537 } | |
2135 } | 2538 } |
2136 | 2539 |
2137 do | 2540 do |
2138 { | 2541 { |
2139 rtx move_upto; | 2542 rtx_insn *move_upto; |
2140 moveall = can_move_insns_across (currptr[0], e0_last_head, | 2543 moveall = can_move_insns_across (currptr[0], e0_last_head, |
2141 move_before, jump, e0->dest, live_union, | 2544 move_before, jump, e0->dest, live_union, |
2142 NULL, &move_upto); | 2545 NULL, &move_upto); |
2143 if (!moveall && move_upto == NULL_RTX) | 2546 if (!moveall && move_upto == NULL_RTX) |
2144 { | 2547 { |
2146 break; | 2549 break; |
2147 | 2550 |
2148 /* Try again, using a different insertion point. */ | 2551 /* Try again, using a different insertion point. */ |
2149 move_before = jump; | 2552 move_before = jump; |
2150 | 2553 |
2151 #ifdef HAVE_cc0 | |
2152 /* Don't try moving before a cc0 user, as that may invalidate | 2554 /* Don't try moving before a cc0 user, as that may invalidate |
2153 the cc0. */ | 2555 the cc0. */ |
2154 if (reg_mentioned_p (cc0_rtx, jump)) | 2556 if (HAVE_cc0 && reg_mentioned_p (cc0_rtx, jump)) |
2155 break; | 2557 break; |
2156 #endif | |
2157 | 2558 |
2158 continue; | 2559 continue; |
2159 } | 2560 } |
2160 | 2561 |
2161 if (final_dest_bb && !moveall) | 2562 if (final_dest_bb && !moveall) |
2168 { | 2569 { |
2169 if (currptr[0] == move_upto) | 2570 if (currptr[0] == move_upto) |
2170 break; | 2571 break; |
2171 for (ix = 0; ix < nedges; ix++) | 2572 for (ix = 0; ix < nedges; ix++) |
2172 { | 2573 { |
2173 rtx curr = currptr[ix]; | 2574 rtx_insn *curr = currptr[ix]; |
2174 do | 2575 do |
2175 curr = NEXT_INSN (curr); | 2576 curr = NEXT_INSN (curr); |
2176 while (!NONDEBUG_INSN_P (curr)); | 2577 while (!NONDEBUG_INSN_P (curr)); |
2177 currptr[ix] = curr; | 2578 currptr[ix] = curr; |
2178 } | 2579 } |
2181 /* If we can't currently move all of the identical insns, remember | 2582 /* If we can't currently move all of the identical insns, remember |
2182 each insn after the range that we'll merge. */ | 2583 each insn after the range that we'll merge. */ |
2183 if (!moveall) | 2584 if (!moveall) |
2184 for (ix = 0; ix < nedges; ix++) | 2585 for (ix = 0; ix < nedges; ix++) |
2185 { | 2586 { |
2186 rtx curr = currptr[ix]; | 2587 rtx_insn *curr = currptr[ix]; |
2187 do | 2588 do |
2188 curr = NEXT_INSN (curr); | 2589 curr = NEXT_INSN (curr); |
2189 while (!NONDEBUG_INSN_P (curr)); | 2590 while (!NONDEBUG_INSN_P (curr)); |
2190 nextptr[ix] = curr; | 2591 nextptr[ix] = curr; |
2191 } | 2592 } |
2206 break; | 2607 break; |
2207 | 2608 |
2208 /* For the unmerged insns, try a different insertion point. */ | 2609 /* For the unmerged insns, try a different insertion point. */ |
2209 move_before = jump; | 2610 move_before = jump; |
2210 | 2611 |
2211 #ifdef HAVE_cc0 | |
2212 /* Don't try moving before a cc0 user, as that may invalidate | 2612 /* Don't try moving before a cc0 user, as that may invalidate |
2213 the cc0. */ | 2613 the cc0. */ |
2214 if (reg_mentioned_p (cc0_rtx, jump)) | 2614 if (HAVE_cc0 && reg_mentioned_p (cc0_rtx, jump)) |
2215 break; | 2615 break; |
2216 #endif | |
2217 | 2616 |
2218 for (ix = 0; ix < nedges; ix++) | 2617 for (ix = 0; ix < nedges; ix++) |
2219 currptr[ix] = headptr[ix] = nextptr[ix]; | 2618 currptr[ix] = headptr[ix] = nextptr[ix]; |
2220 } | 2619 } |
2221 } | 2620 } |
2224 out: | 2623 out: |
2225 free (currptr); | 2624 free (currptr); |
2226 free (headptr); | 2625 free (headptr); |
2227 free (nextptr); | 2626 free (nextptr); |
2228 | 2627 |
2229 crossjumps_occured |= changed; | 2628 crossjumps_occurred |= changed; |
2230 | 2629 |
2231 return changed; | 2630 return changed; |
2232 } | 2631 } |
2233 | 2632 |
2234 /* Return true if BB contains just bb note, or bb note followed | 2633 /* Return true if BB contains just bb note, or bb note followed |
2235 by only DEBUG_INSNs. */ | 2634 by only DEBUG_INSNs. */ |
2236 | 2635 |
2237 static bool | 2636 static bool |
2238 trivially_empty_bb_p (basic_block bb) | 2637 trivially_empty_bb_p (basic_block bb) |
2239 { | 2638 { |
2240 rtx insn = BB_END (bb); | 2639 rtx_insn *insn = BB_END (bb); |
2241 | 2640 |
2242 while (1) | 2641 while (1) |
2243 { | 2642 { |
2244 if (insn == BB_HEAD (bb)) | 2643 if (insn == BB_HEAD (bb)) |
2245 return true; | 2644 return true; |
2247 return false; | 2646 return false; |
2248 insn = PREV_INSN (insn); | 2647 insn = PREV_INSN (insn); |
2249 } | 2648 } |
2250 } | 2649 } |
2251 | 2650 |
2651 /* Return true if BB contains just a return and possibly a USE of the | |
2652 return value. Fill in *RET and *USE with the return and use insns | |
2653 if any found, otherwise NULL. All CLOBBERs are ignored. */ | |
2654 | |
2655 static bool | |
2656 bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use) | |
2657 { | |
2658 *ret = *use = NULL; | |
2659 rtx_insn *insn; | |
2660 | |
2661 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)) | |
2662 return false; | |
2663 | |
2664 FOR_BB_INSNS (bb, insn) | |
2665 if (NONDEBUG_INSN_P (insn)) | |
2666 { | |
2667 rtx pat = PATTERN (insn); | |
2668 | |
2669 if (!*ret && ANY_RETURN_P (pat)) | |
2670 *ret = insn; | |
2671 else if (!*ret && !*use && GET_CODE (pat) == USE | |
2672 && REG_P (XEXP (pat, 0)) | |
2673 && REG_FUNCTION_VALUE_P (XEXP (pat, 0))) | |
2674 *use = insn; | |
2675 else if (GET_CODE (pat) != CLOBBER) | |
2676 return false; | |
2677 } | |
2678 | |
2679 return !!*ret; | |
2680 } | |
2681 | |
2252 /* Do simple CFG optimizations - basic block merging, simplifying of jump | 2682 /* Do simple CFG optimizations - basic block merging, simplifying of jump |
2253 instructions etc. Return nonzero if changes were made. */ | 2683 instructions etc. Return nonzero if changes were made. */ |
2254 | 2684 |
2255 static bool | 2685 static bool |
2256 try_optimize_cfg (int mode) | 2686 try_optimize_cfg (int mode) |
2261 basic_block bb, b, next; | 2691 basic_block bb, b, next; |
2262 | 2692 |
2263 if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING)) | 2693 if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING)) |
2264 clear_bb_flags (); | 2694 clear_bb_flags (); |
2265 | 2695 |
2266 crossjumps_occured = false; | 2696 crossjumps_occurred = false; |
2267 | 2697 |
2268 FOR_EACH_BB (bb) | 2698 FOR_EACH_BB_FN (bb, cfun) |
2269 update_forwarder_flag (bb); | 2699 update_forwarder_flag (bb); |
2270 | 2700 |
2271 if (! targetm.cannot_modify_jumps_p ()) | 2701 if (! targetm.cannot_modify_jumps_p ()) |
2272 { | 2702 { |
2273 first_pass = true; | 2703 first_pass = true; |
2283 if (dump_file) | 2713 if (dump_file) |
2284 fprintf (dump_file, | 2714 fprintf (dump_file, |
2285 "\n\ntry_optimize_cfg iteration %i\n\n", | 2715 "\n\ntry_optimize_cfg iteration %i\n\n", |
2286 iterations); | 2716 iterations); |
2287 | 2717 |
2288 for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR;) | 2718 for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b |
2719 != EXIT_BLOCK_PTR_FOR_FN (cfun);) | |
2289 { | 2720 { |
2290 basic_block c; | 2721 basic_block c; |
2291 edge s; | 2722 edge s; |
2292 bool changed_here = false; | 2723 bool changed_here = false; |
2293 | 2724 |
2300 passes. Empty blocks may result from expanding | 2731 passes. Empty blocks may result from expanding |
2301 __builtin_unreachable (). */ | 2732 __builtin_unreachable (). */ |
2302 if (EDGE_COUNT (b->preds) == 0 | 2733 if (EDGE_COUNT (b->preds) == 0 |
2303 || (EDGE_COUNT (b->succs) == 0 | 2734 || (EDGE_COUNT (b->succs) == 0 |
2304 && trivially_empty_bb_p (b) | 2735 && trivially_empty_bb_p (b) |
2305 && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b)) | 2736 && single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest |
2737 != b)) | |
2306 { | 2738 { |
2307 c = b->prev_bb; | 2739 c = b->prev_bb; |
2308 if (EDGE_COUNT (b->preds) > 0) | 2740 if (EDGE_COUNT (b->preds) > 0) |
2309 { | 2741 { |
2310 edge e; | 2742 edge e; |
2311 edge_iterator ei; | 2743 edge_iterator ei; |
2312 | 2744 |
2313 if (current_ir_type () == IR_RTL_CFGLAYOUT) | 2745 if (current_ir_type () == IR_RTL_CFGLAYOUT) |
2314 { | 2746 { |
2315 if (b->il.rtl->footer | 2747 if (BB_FOOTER (b) |
2316 && BARRIER_P (b->il.rtl->footer)) | 2748 && BARRIER_P (BB_FOOTER (b))) |
2317 FOR_EACH_EDGE (e, ei, b->preds) | 2749 FOR_EACH_EDGE (e, ei, b->preds) |
2318 if ((e->flags & EDGE_FALLTHRU) | 2750 if ((e->flags & EDGE_FALLTHRU) |
2319 && e->src->il.rtl->footer == NULL) | 2751 && BB_FOOTER (e->src) == NULL) |
2320 { | 2752 { |
2321 if (b->il.rtl->footer) | 2753 if (BB_FOOTER (b)) |
2322 { | 2754 { |
2323 e->src->il.rtl->footer = b->il.rtl->footer; | 2755 BB_FOOTER (e->src) = BB_FOOTER (b); |
2324 b->il.rtl->footer = NULL; | 2756 BB_FOOTER (b) = NULL; |
2325 } | 2757 } |
2326 else | 2758 else |
2327 { | 2759 { |
2328 start_sequence (); | 2760 start_sequence (); |
2329 e->src->il.rtl->footer = emit_barrier (); | 2761 BB_FOOTER (e->src) = emit_barrier (); |
2330 end_sequence (); | 2762 end_sequence (); |
2331 } | 2763 } |
2332 } | 2764 } |
2333 } | 2765 } |
2334 else | 2766 else |
2335 { | 2767 { |
2336 rtx last = get_last_bb_insn (b); | 2768 rtx_insn *last = get_last_bb_insn (b); |
2337 if (last && BARRIER_P (last)) | 2769 if (last && BARRIER_P (last)) |
2338 FOR_EACH_EDGE (e, ei, b->preds) | 2770 FOR_EACH_EDGE (e, ei, b->preds) |
2339 if ((e->flags & EDGE_FALLTHRU)) | 2771 if ((e->flags & EDGE_FALLTHRU)) |
2340 emit_barrier_after (BB_END (e->src)); | 2772 emit_barrier_after (BB_END (e->src)); |
2341 } | 2773 } |
2342 } | 2774 } |
2343 delete_basic_block (b); | 2775 delete_basic_block (b); |
2344 changed = true; | 2776 changed = true; |
2345 /* Avoid trying to remove ENTRY_BLOCK_PTR. */ | 2777 /* Avoid trying to remove the exit block. */ |
2346 b = (c == ENTRY_BLOCK_PTR ? c->next_bb : c); | 2778 b = (c == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? c->next_bb : c); |
2347 continue; | 2779 continue; |
2348 } | 2780 } |
2349 | 2781 |
2350 /* Remove code labels no longer used. */ | 2782 /* Remove code labels no longer used. */ |
2351 if (single_pred_p (b) | 2783 if (single_pred_p (b) |
2352 && (single_pred_edge (b)->flags & EDGE_FALLTHRU) | 2784 && (single_pred_edge (b)->flags & EDGE_FALLTHRU) |
2353 && !(single_pred_edge (b)->flags & EDGE_COMPLEX) | 2785 && !(single_pred_edge (b)->flags & EDGE_COMPLEX) |
2354 && LABEL_P (BB_HEAD (b)) | 2786 && LABEL_P (BB_HEAD (b)) |
2787 && !LABEL_PRESERVE_P (BB_HEAD (b)) | |
2355 /* If the previous block ends with a branch to this | 2788 /* If the previous block ends with a branch to this |
2356 block, we can't delete the label. Normally this | 2789 block, we can't delete the label. Normally this |
2357 is a condjump that is yet to be simplified, but | 2790 is a condjump that is yet to be simplified, but |
2358 if CASE_DROPS_THRU, this can be a tablejump with | 2791 if CASE_DROPS_THRU, this can be a tablejump with |
2359 some element going to the same place as the | 2792 some element going to the same place as the |
2360 default (fallthru). */ | 2793 default (fallthru). */ |
2361 && (single_pred (b) == ENTRY_BLOCK_PTR | 2794 && (single_pred (b) == ENTRY_BLOCK_PTR_FOR_FN (cfun) |
2362 || !JUMP_P (BB_END (single_pred (b))) | 2795 || !JUMP_P (BB_END (single_pred (b))) |
2363 || ! label_is_jump_target_p (BB_HEAD (b), | 2796 || ! label_is_jump_target_p (BB_HEAD (b), |
2364 BB_END (single_pred (b))))) | 2797 BB_END (single_pred (b))))) |
2365 { | 2798 { |
2366 rtx label = BB_HEAD (b); | 2799 delete_insn (BB_HEAD (b)); |
2367 | |
2368 delete_insn_chain (label, label, false); | |
2369 /* If the case label is undeletable, move it after the | |
2370 BASIC_BLOCK note. */ | |
2371 if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL) | |
2372 { | |
2373 rtx bb_note = NEXT_INSN (BB_HEAD (b)); | |
2374 | |
2375 reorder_insns_nobb (label, label, bb_note); | |
2376 BB_HEAD (b) = bb_note; | |
2377 if (BB_END (b) == bb_note) | |
2378 BB_END (b) = label; | |
2379 } | |
2380 if (dump_file) | 2800 if (dump_file) |
2381 fprintf (dump_file, "Deleted label in block %i.\n", | 2801 fprintf (dump_file, "Deleted label in block %i.\n", |
2382 b->index); | 2802 b->index); |
2383 } | 2803 } |
2384 | 2804 |
2385 /* If we fall through an empty block, we can remove it. */ | 2805 /* If we fall through an empty block, we can remove it. */ |
2386 if (!(mode & CLEANUP_CFGLAYOUT) | 2806 if (!(mode & (CLEANUP_CFGLAYOUT | CLEANUP_NO_INSN_DEL)) |
2387 && single_pred_p (b) | 2807 && single_pred_p (b) |
2388 && (single_pred_edge (b)->flags & EDGE_FALLTHRU) | 2808 && (single_pred_edge (b)->flags & EDGE_FALLTHRU) |
2389 && !LABEL_P (BB_HEAD (b)) | 2809 && !LABEL_P (BB_HEAD (b)) |
2390 && FORWARDER_BLOCK_P (b) | 2810 && FORWARDER_BLOCK_P (b) |
2391 /* Note that forwarder_block_p true ensures that | 2811 /* Note that forwarder_block_p true ensures that |
2392 there is a successor for this block. */ | 2812 there is a successor for this block. */ |
2393 && (single_succ_edge (b)->flags & EDGE_FALLTHRU) | 2813 && (single_succ_edge (b)->flags & EDGE_FALLTHRU) |
2394 && n_basic_blocks > NUM_FIXED_BLOCKS + 1) | 2814 && n_basic_blocks_for_fn (cfun) > NUM_FIXED_BLOCKS + 1) |
2395 { | 2815 { |
2396 if (dump_file) | 2816 if (dump_file) |
2397 fprintf (dump_file, | 2817 fprintf (dump_file, |
2398 "Deleting fallthru block %i.\n", | 2818 "Deleting fallthru block %i.\n", |
2399 b->index); | 2819 b->index); |
2400 | 2820 |
2401 c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb; | 2821 c = ((b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
2822 ? b->next_bb : b->prev_bb); | |
2402 redirect_edge_succ_nodup (single_pred_edge (b), | 2823 redirect_edge_succ_nodup (single_pred_edge (b), |
2403 single_succ (b)); | 2824 single_succ (b)); |
2404 delete_basic_block (b); | 2825 delete_basic_block (b); |
2405 changed = true; | 2826 changed = true; |
2406 b = c; | 2827 b = c; |
2409 | 2830 |
2410 /* Merge B with its single successor, if any. */ | 2831 /* Merge B with its single successor, if any. */ |
2411 if (single_succ_p (b) | 2832 if (single_succ_p (b) |
2412 && (s = single_succ_edge (b)) | 2833 && (s = single_succ_edge (b)) |
2413 && !(s->flags & EDGE_COMPLEX) | 2834 && !(s->flags & EDGE_COMPLEX) |
2414 && (c = s->dest) != EXIT_BLOCK_PTR | 2835 && (c = s->dest) != EXIT_BLOCK_PTR_FOR_FN (cfun) |
2415 && single_pred_p (c) | 2836 && single_pred_p (c) |
2416 && b != c) | 2837 && b != c) |
2417 { | 2838 { |
2418 /* When not in cfg_layout mode use code aware of reordering | 2839 /* When not in cfg_layout mode use code aware of reordering |
2419 INSN. This code possibly creates new basic blocks so it | 2840 INSN. This code possibly creates new basic blocks so it |
2442 b = next; | 2863 b = next; |
2443 changed_here = true; | 2864 changed_here = true; |
2444 } | 2865 } |
2445 } | 2866 } |
2446 | 2867 |
2868 /* Try to change a branch to a return to just that return. */ | |
2869 rtx_insn *ret, *use; | |
2870 if (single_succ_p (b) | |
2871 && onlyjump_p (BB_END (b)) | |
2872 && bb_is_just_return (single_succ (b), &ret, &use)) | |
2873 { | |
2874 if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)), | |
2875 PATTERN (ret), 0)) | |
2876 { | |
2877 if (use) | |
2878 emit_insn_before (copy_insn (PATTERN (use)), | |
2879 BB_END (b)); | |
2880 if (dump_file) | |
2881 fprintf (dump_file, "Changed jump %d->%d to return.\n", | |
2882 b->index, single_succ (b)->index); | |
2883 redirect_edge_succ (single_succ_edge (b), | |
2884 EXIT_BLOCK_PTR_FOR_FN (cfun)); | |
2885 single_succ_edge (b)->flags &= ~EDGE_CROSSING; | |
2886 changed_here = true; | |
2887 } | |
2888 } | |
2889 | |
2890 /* Try to change a conditional branch to a return to the | |
2891 respective conditional return. */ | |
2892 if (EDGE_COUNT (b->succs) == 2 | |
2893 && any_condjump_p (BB_END (b)) | |
2894 && bb_is_just_return (BRANCH_EDGE (b)->dest, &ret, &use)) | |
2895 { | |
2896 if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)), | |
2897 PATTERN (ret), 0)) | |
2898 { | |
2899 if (use) | |
2900 emit_insn_before (copy_insn (PATTERN (use)), | |
2901 BB_END (b)); | |
2902 if (dump_file) | |
2903 fprintf (dump_file, "Changed conditional jump %d->%d " | |
2904 "to conditional return.\n", | |
2905 b->index, BRANCH_EDGE (b)->dest->index); | |
2906 redirect_edge_succ (BRANCH_EDGE (b), | |
2907 EXIT_BLOCK_PTR_FOR_FN (cfun)); | |
2908 BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING; | |
2909 changed_here = true; | |
2910 } | |
2911 } | |
2912 | |
2913 /* Try to flip a conditional branch that falls through to | |
2914 a return so that it becomes a conditional return and a | |
2915 new jump to the original branch target. */ | |
2916 if (EDGE_COUNT (b->succs) == 2 | |
2917 && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) | |
2918 && any_condjump_p (BB_END (b)) | |
2919 && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use)) | |
2920 { | |
2921 if (invert_jump (as_a <rtx_jump_insn *> (BB_END (b)), | |
2922 JUMP_LABEL (BB_END (b)), 0)) | |
2923 { | |
2924 basic_block new_ft = BRANCH_EDGE (b)->dest; | |
2925 if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)), | |
2926 PATTERN (ret), 0)) | |
2927 { | |
2928 if (use) | |
2929 emit_insn_before (copy_insn (PATTERN (use)), | |
2930 BB_END (b)); | |
2931 if (dump_file) | |
2932 fprintf (dump_file, "Changed conditional jump " | |
2933 "%d->%d to conditional return, adding " | |
2934 "fall-through jump.\n", | |
2935 b->index, BRANCH_EDGE (b)->dest->index); | |
2936 redirect_edge_succ (BRANCH_EDGE (b), | |
2937 EXIT_BLOCK_PTR_FOR_FN (cfun)); | |
2938 BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING; | |
2939 std::swap (BRANCH_EDGE (b)->probability, | |
2940 FALLTHRU_EDGE (b)->probability); | |
2941 update_br_prob_note (b); | |
2942 basic_block jb = force_nonfallthru (FALLTHRU_EDGE (b)); | |
2943 notice_new_block (jb); | |
2944 if (!redirect_jump (as_a <rtx_jump_insn *> (BB_END (jb)), | |
2945 block_label (new_ft), 0)) | |
2946 gcc_unreachable (); | |
2947 redirect_edge_succ (single_succ_edge (jb), new_ft); | |
2948 changed_here = true; | |
2949 } | |
2950 else | |
2951 { | |
2952 /* Invert the jump back to what it was. This should | |
2953 never fail. */ | |
2954 if (!invert_jump (as_a <rtx_jump_insn *> (BB_END (b)), | |
2955 JUMP_LABEL (BB_END (b)), 0)) | |
2956 gcc_unreachable (); | |
2957 } | |
2958 } | |
2959 } | |
2960 | |
2447 /* Simplify branch over branch. */ | 2961 /* Simplify branch over branch. */ |
2448 if ((mode & CLEANUP_EXPENSIVE) | 2962 if ((mode & CLEANUP_EXPENSIVE) |
2449 && !(mode & CLEANUP_CFGLAYOUT) | 2963 && !(mode & CLEANUP_CFGLAYOUT) |
2450 && try_simplify_condjump (b)) | 2964 && try_simplify_condjump (b)) |
2451 changed_here = true; | 2965 changed_here = true; |
2453 /* If B has a single outgoing edge, but uses a | 2967 /* If B has a single outgoing edge, but uses a |
2454 non-trivial jump instruction without side-effects, we | 2968 non-trivial jump instruction without side-effects, we |
2455 can either delete the jump entirely, or replace it | 2969 can either delete the jump entirely, or replace it |
2456 with a simple unconditional jump. */ | 2970 with a simple unconditional jump. */ |
2457 if (single_succ_p (b) | 2971 if (single_succ_p (b) |
2458 && single_succ (b) != EXIT_BLOCK_PTR | 2972 && single_succ (b) != EXIT_BLOCK_PTR_FOR_FN (cfun) |
2459 && onlyjump_p (BB_END (b)) | 2973 && onlyjump_p (BB_END (b)) |
2460 && !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX) | 2974 && !CROSSING_JUMP_P (BB_END (b)) |
2461 && try_redirect_by_replacing_jump (single_succ_edge (b), | 2975 && try_redirect_by_replacing_jump (single_succ_edge (b), |
2462 single_succ (b), | 2976 single_succ (b), |
2463 (mode & CLEANUP_CFGLAYOUT) != 0)) | 2977 (mode & CLEANUP_CFGLAYOUT) != 0)) |
2464 { | 2978 { |
2465 update_forwarder_flag (b); | 2979 update_forwarder_flag (b); |
2466 changed_here = true; | 2980 changed_here = true; |
2467 } | 2981 } |
2468 | 2982 |
2469 /* Simplify branch to branch. */ | 2983 /* Simplify branch to branch. */ |
2470 if (try_forward_edges (mode, b)) | 2984 if (try_forward_edges (mode, b)) |
2471 changed_here = true; | 2985 { |
2986 update_forwarder_flag (b); | |
2987 changed_here = true; | |
2988 } | |
2472 | 2989 |
2473 /* Look for shared code between blocks. */ | 2990 /* Look for shared code between blocks. */ |
2474 if ((mode & CLEANUP_CROSSJUMP) | 2991 if ((mode & CLEANUP_CROSSJUMP) |
2475 && try_crossjump_bb (mode, b)) | 2992 && try_crossjump_bb (mode, b)) |
2476 changed_here = true; | 2993 changed_here = true; |
2489 else | 3006 else |
2490 changed = true; | 3007 changed = true; |
2491 } | 3008 } |
2492 | 3009 |
2493 if ((mode & CLEANUP_CROSSJUMP) | 3010 if ((mode & CLEANUP_CROSSJUMP) |
2494 && try_crossjump_bb (mode, EXIT_BLOCK_PTR)) | 3011 && try_crossjump_bb (mode, EXIT_BLOCK_PTR_FOR_FN (cfun))) |
2495 changed = true; | 3012 changed = true; |
2496 | 3013 |
2497 if (block_was_dirty) | 3014 if (block_was_dirty) |
2498 { | 3015 { |
2499 /* This should only be set by head-merging. */ | 3016 /* This should only be set by head-merging. */ |
2500 gcc_assert (mode & CLEANUP_CROSSJUMP); | 3017 gcc_assert (mode & CLEANUP_CROSSJUMP); |
2501 df_analyze (); | 3018 df_analyze (); |
2502 } | 3019 } |
2503 | 3020 |
2504 #ifdef ENABLE_CHECKING | |
2505 if (changed) | 3021 if (changed) |
2506 verify_flow_info (); | 3022 { |
2507 #endif | 3023 /* Edge forwarding in particular can cause hot blocks previously |
3024 reached by both hot and cold blocks to become dominated only | |
3025 by cold blocks. This will cause the verification below to fail, | |
3026 and lead to now cold code in the hot section. This is not easy | |
3027 to detect and fix during edge forwarding, and in some cases | |
3028 is only visible after newly unreachable blocks are deleted, | |
3029 which will be done in fixup_partitions. */ | |
3030 fixup_partitions (); | |
3031 checking_verify_flow_info (); | |
3032 } | |
2508 | 3033 |
2509 changed_overall |= changed; | 3034 changed_overall |= changed; |
2510 first_pass = false; | 3035 first_pass = false; |
2511 } | 3036 } |
2512 while (changed); | 3037 while (changed); |
2513 } | 3038 } |
2514 | 3039 |
2515 FOR_ALL_BB (b) | 3040 FOR_ALL_BB_FN (b, cfun) |
2516 b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK); | 3041 b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK); |
2517 | 3042 |
2518 return changed_overall; | 3043 return changed_overall; |
2519 } | 3044 } |
2520 | 3045 |
2532 delete blocks in reverse dominator order, so as to get a chance | 3057 delete blocks in reverse dominator order, so as to get a chance |
2533 to substitute all released DEFs into debug stmts. If we don't | 3058 to substitute all released DEFs into debug stmts. If we don't |
2534 have dominators information, walking blocks backward gets us a | 3059 have dominators information, walking blocks backward gets us a |
2535 better chance of retaining most debug information than | 3060 better chance of retaining most debug information than |
2536 otherwise. */ | 3061 otherwise. */ |
2537 if (MAY_HAVE_DEBUG_STMTS && current_ir_type () == IR_GIMPLE | 3062 if (MAY_HAVE_DEBUG_INSNS && current_ir_type () == IR_GIMPLE |
2538 && dom_info_available_p (CDI_DOMINATORS)) | 3063 && dom_info_available_p (CDI_DOMINATORS)) |
2539 { | 3064 { |
2540 for (b = EXIT_BLOCK_PTR->prev_bb; b != ENTRY_BLOCK_PTR; b = prev_bb) | 3065 for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; |
3066 b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb) | |
2541 { | 3067 { |
2542 prev_bb = b->prev_bb; | 3068 prev_bb = b->prev_bb; |
2543 | 3069 |
2544 if (!(b->flags & BB_REACHABLE)) | 3070 if (!(b->flags & BB_REACHABLE)) |
2545 { | 3071 { |
2548 case. */ | 3074 case. */ |
2549 if (!first_dom_son (CDI_DOMINATORS, b)) | 3075 if (!first_dom_son (CDI_DOMINATORS, b)) |
2550 delete_basic_block (b); | 3076 delete_basic_block (b); |
2551 else | 3077 else |
2552 { | 3078 { |
2553 VEC (basic_block, heap) *h | 3079 vec<basic_block> h |
2554 = get_all_dominated_blocks (CDI_DOMINATORS, b); | 3080 = get_all_dominated_blocks (CDI_DOMINATORS, b); |
2555 | 3081 |
2556 while (VEC_length (basic_block, h)) | 3082 while (h.length ()) |
2557 { | 3083 { |
2558 b = VEC_pop (basic_block, h); | 3084 b = h.pop (); |
2559 | 3085 |
2560 prev_bb = b->prev_bb; | 3086 prev_bb = b->prev_bb; |
2561 | 3087 |
2562 gcc_assert (!(b->flags & BB_REACHABLE)); | 3088 gcc_assert (!(b->flags & BB_REACHABLE)); |
2563 | 3089 |
2564 delete_basic_block (b); | 3090 delete_basic_block (b); |
2565 } | 3091 } |
2566 | 3092 |
2567 VEC_free (basic_block, heap, h); | 3093 h.release (); |
2568 } | 3094 } |
2569 | 3095 |
2570 changed = true; | 3096 changed = true; |
2571 } | 3097 } |
2572 } | 3098 } |
2573 } | 3099 } |
2574 else | 3100 else |
2575 { | 3101 { |
2576 for (b = EXIT_BLOCK_PTR->prev_bb; b != ENTRY_BLOCK_PTR; b = prev_bb) | 3102 for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; |
3103 b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb) | |
2577 { | 3104 { |
2578 prev_bb = b->prev_bb; | 3105 prev_bb = b->prev_bb; |
2579 | 3106 |
2580 if (!(b->flags & BB_REACHABLE)) | 3107 if (!(b->flags & BB_REACHABLE)) |
2581 { | 3108 { |
2599 { | 3126 { |
2600 basic_block bb; | 3127 basic_block bb; |
2601 | 3128 |
2602 /* A dead jump table does not belong to any basic block. Scan insns | 3129 /* A dead jump table does not belong to any basic block. Scan insns |
2603 between two adjacent basic blocks. */ | 3130 between two adjacent basic blocks. */ |
2604 FOR_EACH_BB (bb) | 3131 FOR_EACH_BB_FN (bb, cfun) |
2605 { | 3132 { |
2606 rtx insn, next; | 3133 rtx_insn *insn, *next; |
2607 | 3134 |
2608 for (insn = NEXT_INSN (BB_END (bb)); | 3135 for (insn = NEXT_INSN (BB_END (bb)); |
2609 insn && !NOTE_INSN_BASIC_BLOCK_P (insn); | 3136 insn && !NOTE_INSN_BASIC_BLOCK_P (insn); |
2610 insn = next) | 3137 insn = next) |
2611 { | 3138 { |
2612 next = NEXT_INSN (insn); | 3139 next = NEXT_INSN (insn); |
2613 if (LABEL_P (insn) | 3140 if (LABEL_P (insn) |
2614 && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn) | 3141 && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn) |
2615 && JUMP_TABLE_DATA_P (next)) | 3142 && JUMP_TABLE_DATA_P (next)) |
2616 { | 3143 { |
2617 rtx label = insn, jump = next; | 3144 rtx_insn *label = insn, *jump = next; |
2618 | 3145 |
2619 if (dump_file) | 3146 if (dump_file) |
2620 fprintf (dump_file, "Dead jumptable %i removed\n", | 3147 fprintf (dump_file, "Dead jumptable %i removed\n", |
2621 INSN_UID (insn)); | 3148 INSN_UID (insn)); |
2622 | 3149 |
2683 code, so delete_trivially_dead_insns or even doing nothing at all | 3210 code, so delete_trivially_dead_insns or even doing nothing at all |
2684 is good enough. */ | 3211 is good enough. */ |
2685 if ((mode & CLEANUP_EXPENSIVE) && !reload_completed | 3212 if ((mode & CLEANUP_EXPENSIVE) && !reload_completed |
2686 && !delete_trivially_dead_insns (get_insns (), max_reg_num ())) | 3213 && !delete_trivially_dead_insns (get_insns (), max_reg_num ())) |
2687 break; | 3214 break; |
2688 if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occured) | 3215 if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred) |
2689 run_fast_dce (); | 3216 run_fast_dce (); |
2690 } | 3217 } |
2691 else | 3218 else |
2692 break; | 3219 break; |
2693 } | 3220 } |
2702 not in a basic block. Dead jumptables are cleaned up when | 3229 not in a basic block. Dead jumptables are cleaned up when |
2703 going out of cfglayout mode. */ | 3230 going out of cfglayout mode. */ |
2704 if (!(mode & CLEANUP_CFGLAYOUT)) | 3231 if (!(mode & CLEANUP_CFGLAYOUT)) |
2705 delete_dead_jumptables (); | 3232 delete_dead_jumptables (); |
2706 | 3233 |
3234 /* ??? We probably do this way too often. */ | |
3235 if (current_loops | |
3236 && (changed | |
3237 || (mode & CLEANUP_CFG_CHANGED))) | |
3238 { | |
3239 timevar_push (TV_REPAIR_LOOPS); | |
3240 /* The above doesn't preserve dominance info if available. */ | |
3241 gcc_assert (!dom_info_available_p (CDI_DOMINATORS)); | |
3242 calculate_dominance_info (CDI_DOMINATORS); | |
3243 fix_loop_structure (NULL); | |
3244 free_dominance_info (CDI_DOMINATORS); | |
3245 timevar_pop (TV_REPAIR_LOOPS); | |
3246 } | |
3247 | |
2707 timevar_pop (TV_CLEANUP_CFG); | 3248 timevar_pop (TV_CLEANUP_CFG); |
2708 | 3249 |
2709 return changed; | 3250 return changed; |
2710 } | 3251 } |
2711 | 3252 |
2712 static unsigned int | 3253 namespace { |
2713 rest_of_handle_jump (void) | 3254 |
2714 { | 3255 const pass_data pass_data_jump = |
2715 if (crtl->tail_call_emit) | 3256 { |
2716 fixup_tail_calls (); | 3257 RTL_PASS, /* type */ |
2717 return 0; | 3258 "jump", /* name */ |
2718 } | 3259 OPTGROUP_NONE, /* optinfo_flags */ |
2719 | 3260 TV_JUMP, /* tv_id */ |
2720 struct rtl_opt_pass pass_jump = | 3261 0, /* properties_required */ |
2721 { | 3262 0, /* properties_provided */ |
2722 { | 3263 0, /* properties_destroyed */ |
2723 RTL_PASS, | 3264 0, /* todo_flags_start */ |
2724 "sibling", /* name */ | 3265 0, /* todo_flags_finish */ |
2725 NULL, /* gate */ | |
2726 rest_of_handle_jump, /* execute */ | |
2727 NULL, /* sub */ | |
2728 NULL, /* next */ | |
2729 0, /* static_pass_number */ | |
2730 TV_JUMP, /* tv_id */ | |
2731 0, /* properties_required */ | |
2732 0, /* properties_provided */ | |
2733 0, /* properties_destroyed */ | |
2734 TODO_ggc_collect, /* todo_flags_start */ | |
2735 TODO_verify_flow, /* todo_flags_finish */ | |
2736 } | |
2737 }; | 3266 }; |
2738 | 3267 |
2739 | 3268 class pass_jump : public rtl_opt_pass |
2740 static unsigned int | 3269 { |
2741 rest_of_handle_jump2 (void) | 3270 public: |
3271 pass_jump (gcc::context *ctxt) | |
3272 : rtl_opt_pass (pass_data_jump, ctxt) | |
3273 {} | |
3274 | |
3275 /* opt_pass methods: */ | |
3276 virtual unsigned int execute (function *); | |
3277 | |
3278 }; // class pass_jump | |
3279 | |
3280 unsigned int | |
3281 pass_jump::execute (function *) | |
2742 { | 3282 { |
2743 delete_trivially_dead_insns (get_insns (), max_reg_num ()); | 3283 delete_trivially_dead_insns (get_insns (), max_reg_num ()); |
2744 if (dump_file) | 3284 if (dump_file) |
2745 dump_flow_info (dump_file, dump_flags); | 3285 dump_flow_info (dump_file, dump_flags); |
2746 cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | 3286 cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) |
2747 | (flag_thread_jumps ? CLEANUP_THREADING : 0)); | 3287 | (flag_thread_jumps ? CLEANUP_THREADING : 0)); |
2748 return 0; | 3288 return 0; |
2749 } | 3289 } |
2750 | 3290 |
2751 | 3291 } // anon namespace |
2752 struct rtl_opt_pass pass_jump2 = | 3292 |
2753 { | 3293 rtl_opt_pass * |
2754 { | 3294 make_pass_jump (gcc::context *ctxt) |
2755 RTL_PASS, | 3295 { |
2756 "jump", /* name */ | 3296 return new pass_jump (ctxt); |
2757 NULL, /* gate */ | 3297 } |
2758 rest_of_handle_jump2, /* execute */ | 3298 |
2759 NULL, /* sub */ | 3299 namespace { |
2760 NULL, /* next */ | 3300 |
2761 0, /* static_pass_number */ | 3301 const pass_data pass_data_jump2 = |
2762 TV_JUMP, /* tv_id */ | 3302 { |
2763 0, /* properties_required */ | 3303 RTL_PASS, /* type */ |
2764 0, /* properties_provided */ | 3304 "jump2", /* name */ |
2765 0, /* properties_destroyed */ | 3305 OPTGROUP_NONE, /* optinfo_flags */ |
2766 TODO_ggc_collect, /* todo_flags_start */ | 3306 TV_JUMP, /* tv_id */ |
2767 TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */ | 3307 0, /* properties_required */ |
2768 } | 3308 0, /* properties_provided */ |
3309 0, /* properties_destroyed */ | |
3310 0, /* todo_flags_start */ | |
3311 0, /* todo_flags_finish */ | |
2769 }; | 3312 }; |
2770 | 3313 |
2771 | 3314 class pass_jump2 : public rtl_opt_pass |
3315 { | |
3316 public: | |
3317 pass_jump2 (gcc::context *ctxt) | |
3318 : rtl_opt_pass (pass_data_jump2, ctxt) | |
3319 {} | |
3320 | |
3321 /* opt_pass methods: */ | |
3322 virtual unsigned int execute (function *) | |
3323 { | |
3324 cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0); | |
3325 return 0; | |
3326 } | |
3327 | |
3328 }; // class pass_jump2 | |
3329 | |
3330 } // anon namespace | |
3331 | |
3332 rtl_opt_pass * | |
3333 make_pass_jump2 (gcc::context *ctxt) | |
3334 { | |
3335 return new pass_jump2 (ctxt); | |
3336 } |