#include "config.h"#include "system.h"#include "coretypes.h"#include "tm.h"#include "tree.h"#include "rtl.h"#include "tm_p.h"#include "hard-reg-set.h"#include "basic-block.h"#include "output.h"#include "errors.h"#include "flags.h"#include "function.h"#include "expr.h"#include "ggc.h"#include "langhooks.h"#include "diagnostic.h"#include "tree-flow.h"#include "timevar.h"#include "tree-dump.h"#include "tree-pass.h"#include "toplev.h"#include "except.h"#include "cfgloop.h"#include "cfglayout.h"#include "hashtab.h"#include "tree-ssa-propagate.h"#include "tree-scalar-evolution.h"Include dependency graph for tree-cfgcleanup.c:

Go to the source code of this file.
Functions | |
| static bool | remove_fallthru_edge (VEC(edge, gc)*ev) |
| static bool | cleanup_control_expr_graph () |
| VEC (tree, gc) | |
| static bool | tree_forwarder_block_p () |
| static bool | has_abnormal_incoming_edge_p () |
| static bool | phi_alternatives_equal () |
| static bool | remove_forwarder_block () |
| static bool | cleanup_forwarder_blocks () |
| static bool | cleanup_tree_cfg_1 () |
| bool | cleanup_tree_cfg () |
| void | cleanup_tree_cfg_loop () |
| static void | remove_forwarder_block_with_phi () |
| static unsigned int | merge_phi_nodes () |
| static bool | gate_merge_phi () |
Variables | |
| tree_opt_pass | pass_merge_phi |
|
|
Disconnect an unreachable block in the control expression starting at block BB. Definition at line 71 of file tree-cfgcleanup.c. References bsi_stmt(), COND_EXPR_COND, find_taken_edge(), fold(), SWITCH_COND, and TREE_CODE. Referenced by VEC(). 00072 { 00073 edge taken_edge; 00074 bool retval = false; 00075 tree expr = bsi_stmt (bsi), val; 00076 00077 if (!single_succ_p (bb)) 00078 { 00079 edge e; 00080 edge_iterator ei; 00081 00082 switch (TREE_CODE (expr)) 00083 { 00084 case COND_EXPR: 00085 val = fold (COND_EXPR_COND (expr)); 00086 break; 00087 00088 case SWITCH_EXPR: 00089 val = fold (SWITCH_COND (expr)); 00090 if (TREE_CODE (val) != INTEGER_CST) 00091 return false; 00092 break; 00093 00094 default: 00095 gcc_unreachable (); 00096 } 00097 00098 taken_edge = find_taken_edge (bb, val); 00099 if (!taken_edge) 00100 return false; 00101 00102 /* Remove all the edges except the one that is always executed. */ 00103 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) 00104 { 00105 if (e != taken_edge) 00106 { 00107 taken_edge->probability += e->probability; 00108 taken_edge->count += e->count; 00109 remove_edge (e); 00110 retval = true; 00111 } 00112 else 00113 ei_next (&ei); 00114 } 00115 if (taken_edge->probability > REG_BR_PROB_BASE) 00116 taken_edge->probability = REG_BR_PROB_BASE; 00117 } 00118 else 00119 taken_edge = single_succ_edge (bb); 00120 00121 bsi_remove (&bsi, true); 00122 taken_edge->flags = EDGE_FALLTHRU; 00123 00124 /* We removed some paths from the cfg. */ 00125 free_dominance_info (CDI_DOMINATORS); 00126 00127 return retval; 00128 }
|
|
|
Removes forwarder blocks. Definition at line 494 of file tree-cfgcleanup.c. References changed, remove_forwarder_block(), and tree_forwarder_block_p(). Referenced by cleanup_tree_cfg_1(). 00495 { 00496 basic_block bb; 00497 bool changed = false; 00498 basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks); 00499 basic_block *current = worklist; 00500 00501 FOR_EACH_BB (bb) 00502 { 00503 if (tree_forwarder_block_p (bb, false)) 00504 *current++ = bb; 00505 } 00506 00507 while (current != worklist) 00508 { 00509 bb = *--current; 00510 changed |= remove_forwarder_block (bb, ¤t); 00511 } 00512 00513 free (worklist); 00514 return changed; 00515 }
|
|
|
Remove unreachable blocks and other miscellaneous clean up work. Return true if the flowgraph was modified, false otherwise. Definition at line 555 of file tree-cfgcleanup.c. References changed, and cleanup_tree_cfg_1(). Referenced by cleanup_tree_cfg_loop(), execute_cleanup_cfg_post_optimizing(), execute_cleanup_cfg_pre_ipa(), finalize_jump_threads(), fini_pre(), make_edges(), and tree_ssa_dominator_optimize(). 00556 { 00557 bool retval, changed; 00558 00559 timevar_push (TV_TREE_CLEANUP_CFG); 00560 00561 /* Iterate until there are no more cleanups left to do. If any 00562 iteration changed the flowgraph, set CHANGED to true. */ 00563 changed = false; 00564 do 00565 { 00566 retval = cleanup_tree_cfg_1 (); 00567 changed |= retval; 00568 } 00569 while (retval); 00570 00571 compact_blocks (); 00572 00573 #ifdef ENABLE_CHECKING 00574 verify_flow_info (); 00575 #endif 00576 00577 timevar_pop (TV_TREE_CLEANUP_CFG); 00578 00579 return changed; 00580 }
|
|
|
Do one round of CFG cleanup. Definition at line 520 of file tree-cfgcleanup.c. References cleanup_forwarder_blocks(), end_recording_case_labels(), and start_recording_case_labels(). Referenced by cleanup_tree_cfg(). 00521 { 00522 bool retval; 00523 00524 retval = cleanup_control_flow (); 00525 retval |= delete_unreachable_blocks (); 00526 00527 /* Forwarder blocks can carry line number information which is 00528 useful when debugging, so we only clean them up when 00529 optimizing. */ 00530 00531 if (optimize > 0) 00532 { 00533 /* cleanup_forwarder_blocks can redirect edges out of 00534 SWITCH_EXPRs, which can get expensive. So we want to enable 00535 recording of edge to CASE_LABEL_EXPR mappings around the call 00536 to cleanup_forwarder_blocks. */ 00537 start_recording_case_labels (); 00538 retval |= cleanup_forwarder_blocks (); 00539 end_recording_case_labels (); 00540 } 00541 00542 /* Merging the blocks may create new opportunities for folding 00543 conditional branches (due to the elimination of single-valued PHI 00544 nodes). */ 00545 retval |= merge_seq_blocks (); 00546 00547 return retval; 00548 }
|
|
|
Cleanup cfg and repair loop structures. Definition at line 585 of file tree-cfgcleanup.c. References changed, cleanup_tree_cfg(), current_loops, rewrite_into_loop_closed_ssa(), scev_reset(), and TODO_update_ssa. 00586 { 00587 bool changed = cleanup_tree_cfg (); 00588 00589 if (changed) 00590 { 00591 bitmap changed_bbs = BITMAP_ALLOC (NULL); 00592 fix_loop_structure (current_loops, changed_bbs); 00593 calculate_dominance_info (CDI_DOMINATORS); 00594 00595 /* This usually does nothing. But sometimes parts of cfg that originally 00596 were inside a loop get out of it due to edge removal (since they 00597 become unreachable by back edges from latch). */ 00598 rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa); 00599 00600 BITMAP_FREE (changed_bbs); 00601 00602 #ifdef ENABLE_CHECKING 00603 verify_loop_structure (current_loops); 00604 #endif 00605 scev_reset (); 00606 } 00607 }
|
|
|
Definition at line 822 of file tree-cfgcleanup.c.
|
|
|
Return true if BB has at least one abnormal incoming edge. Definition at line 318 of file tree-cfgcleanup.c. Referenced by merge_phi_nodes(), and remove_forwarder_block(). 00319 { 00320 edge e; 00321 edge_iterator ei; 00322 00323 FOR_EACH_EDGE (e, ei, bb->preds) 00324 if (e->flags & EDGE_ABNORMAL) 00325 return true; 00326 00327 return false; 00328 }
|
|
|
This pass merges PHI nodes if one feeds into another. For example, suppose we have the following: goto <bb 9> (<L9>); <L8>:; tem_17 = foo (); # tem_6 = PHI <tem_17(8), tem_23(7)>; <L9>:; # tem_3 = PHI <tem_6(9), tem_2(5)>; <L10>:; Then we merge the first PHI node into the second one like so: goto <bb 9> (<L10>); <L8>:; tem_17 = foo (); # tem_3 = PHI <tem_23(7), tem_2(5), tem_17(8)>; <L10>:; Definition at line 740 of file tree-cfgcleanup.c. References bb_for_stmt(), has_abnormal_incoming_edge_p(), has_zero_uses(), PHI_ARG_DEF, PHI_CHAIN, phi_nodes(), PHI_RESULT, single_imm_use(), TREE_CODE, and tree_forwarder_block_p(). 00741 { 00742 basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks); 00743 basic_block *current = worklist; 00744 basic_block bb; 00745 00746 calculate_dominance_info (CDI_DOMINATORS); 00747 00748 /* Find all PHI nodes that we may be able to merge. */ 00749 FOR_EACH_BB (bb) 00750 { 00751 basic_block dest; 00752 00753 /* Look for a forwarder block with PHI nodes. */ 00754 if (!tree_forwarder_block_p (bb, true)) 00755 continue; 00756 00757 dest = single_succ (bb); 00758 00759 /* We have to feed into another basic block with PHI 00760 nodes. */ 00761 if (!phi_nodes (dest) 00762 /* We don't want to deal with a basic block with 00763 abnormal edges. */ 00764 || has_abnormal_incoming_edge_p (bb)) 00765 continue; 00766 00767 if (!dominated_by_p (CDI_DOMINATORS, dest, bb)) 00768 { 00769 /* If BB does not dominate DEST, then the PHI nodes at 00770 DEST must be the only users of the results of the PHI 00771 nodes at BB. */ 00772 *current++ = bb; 00773 } 00774 else 00775 { 00776 tree phi; 00777 unsigned int dest_idx = single_succ_edge (bb)->dest_idx; 00778 00779 /* BB dominates DEST. There may be many users of the PHI 00780 nodes in BB. However, there is still a trivial case we 00781 can handle. If the result of every PHI in BB is used 00782 only by a PHI in DEST, then we can trivially merge the 00783 PHI nodes from BB into DEST. */ 00784 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) 00785 { 00786 tree result = PHI_RESULT (phi); 00787 use_operand_p imm_use; 00788 tree use_stmt; 00789 00790 /* If the PHI's result is never used, then we can just 00791 ignore it. */ 00792 if (has_zero_uses (result)) 00793 continue; 00794 00795 /* Get the single use of the result of this PHI node. */ 00796 if (!single_imm_use (result, &imm_use, &use_stmt) 00797 || TREE_CODE (use_stmt) != PHI_NODE 00798 || bb_for_stmt (use_stmt) != dest 00799 || PHI_ARG_DEF (use_stmt, dest_idx) != result) 00800 break; 00801 } 00802 00803 /* If the loop above iterated through all the PHI nodes 00804 in BB, then we can merge the PHIs from BB into DEST. */ 00805 if (!phi) 00806 *current++ = bb; 00807 } 00808 } 00809 00810 /* Now let's drain WORKLIST. */ 00811 while (current != worklist) 00812 { 00813 bb = *--current; 00814 remove_forwarder_block_with_phi (bb); 00815 } 00816 00817 free (worklist); 00818 return 0; 00819 }
|
|
|
If all the PHI nodes in DEST have alternatives for E1 and E2 and those alternatives are equal in each of the PHI nodes, then return true, else return false. Definition at line 335 of file tree-cfgcleanup.c. References NULL_TREE, operand_equal_for_phi_arg_p(), PHI_ARG_DEF, PHI_CHAIN, and phi_nodes(). Referenced by remove_forwarder_block(), and remove_forwarder_block_with_phi(). 00336 { 00337 int n1 = e1->dest_idx; 00338 int n2 = e2->dest_idx; 00339 tree phi; 00340 00341 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi)) 00342 { 00343 tree val1 = PHI_ARG_DEF (phi, n1); 00344 tree val2 = PHI_ARG_DEF (phi, n2); 00345 00346 gcc_assert (val1 != NULL_TREE); 00347 gcc_assert (val2 != NULL_TREE); 00348 00349 if (!operand_equal_for_phi_arg_p (val1, val2)) 00350 return false; 00351 } 00352 00353 return true; 00354 }
|
|
|
Remove any fallthru edge from EV. Return true if an edge was removed. Definition at line 53 of file tree-cfgcleanup.c. 00054 { 00055 edge_iterator ei; 00056 edge e; 00057 00058 FOR_EACH_EDGE (e, ei, ev) 00059 if ((e->flags & EDGE_FALLTHRU) != 0) 00060 { 00061 remove_edge (e); 00062 return true; 00063 } 00064 return false; 00065 }
|
|
|
Removes forwarder block BB. Returns false if this failed. If a new forwarder block is created due to redirection of edges, it is stored to worklist. Definition at line 361 of file tree-cfgcleanup.c. References DECL_NONLOCAL, first_stmt(), has_abnormal_incoming_edge_p(), LABEL_EXPR_LABEL, NULL_TREE, phi_alternatives_equal(), phi_nodes(), and TREE_CODE. Referenced by cleanup_forwarder_blocks(). 00362 { 00363 edge succ = single_succ_edge (bb), e, s; 00364 basic_block dest = succ->dest; 00365 tree label; 00366 tree phi; 00367 edge_iterator ei; 00368 block_stmt_iterator bsi, bsi_to; 00369 bool seen_abnormal_edge = false; 00370 00371 /* We check for infinite loops already in tree_forwarder_block_p. 00372 However it may happen that the infinite loop is created 00373 afterwards due to removal of forwarders. */ 00374 if (dest == bb) 00375 return false; 00376 00377 /* If the destination block consists of a nonlocal label, do not merge 00378 it. */ 00379 label = first_stmt (dest); 00380 if (label 00381 && TREE_CODE (label) == LABEL_EXPR 00382 && DECL_NONLOCAL (LABEL_EXPR_LABEL (label))) 00383 return false; 00384 00385 /* If there is an abnormal edge to basic block BB, but not into 00386 dest, problems might occur during removal of the phi node at out 00387 of ssa due to overlapping live ranges of registers. 00388 00389 If there is an abnormal edge in DEST, the problems would occur 00390 anyway since cleanup_dead_labels would then merge the labels for 00391 two different eh regions, and rest of exception handling code 00392 does not like it. 00393 00394 So if there is an abnormal edge to BB, proceed only if there is 00395 no abnormal edge to DEST and there are no phi nodes in DEST. */ 00396 if (has_abnormal_incoming_edge_p (bb)) 00397 { 00398 seen_abnormal_edge = true; 00399 00400 if (has_abnormal_incoming_edge_p (dest) 00401 || phi_nodes (dest) != NULL_TREE) 00402 return false; 00403 } 00404 00405 /* If there are phi nodes in DEST, and some of the blocks that are 00406 predecessors of BB are also predecessors of DEST, check that the 00407 phi node arguments match. */ 00408 if (phi_nodes (dest)) 00409 { 00410 FOR_EACH_EDGE (e, ei, bb->preds) 00411 { 00412 s = find_edge (e->src, dest); 00413 if (!s) 00414 continue; 00415 00416 if (!phi_alternatives_equal (dest, succ, s)) 00417 return false; 00418 } 00419 } 00420 00421 /* Redirect the edges. */ 00422 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) 00423 { 00424 if (e->flags & EDGE_ABNORMAL) 00425 { 00426 /* If there is an abnormal edge, redirect it anyway, and 00427 move the labels to the new block to make it legal. */ 00428 s = redirect_edge_succ_nodup (e, dest); 00429 } 00430 else 00431 s = redirect_edge_and_branch (e, dest); 00432 00433 if (s == e) 00434 { 00435 /* Create arguments for the phi nodes, since the edge was not 00436 here before. */ 00437 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi)) 00438 add_phi_arg (phi, PHI_ARG_DEF (phi, succ->dest_idx), s); 00439 } 00440 else 00441 { 00442 /* The source basic block might become a forwarder. We know 00443 that it was not a forwarder before, since it used to have 00444 at least two outgoing edges, so we may just add it to 00445 worklist. */ 00446 if (tree_forwarder_block_p (s->src, false)) 00447 *(*worklist)++ = s->src; 00448 } 00449 } 00450 00451 if (seen_abnormal_edge) 00452 { 00453 /* Move the labels to the new block, so that the redirection of 00454 the abnormal edges works. */ 00455 00456 bsi_to = bsi_start (dest); 00457 for (bsi = bsi_start (bb); !bsi_end_p (bsi); ) 00458 { 00459 label = bsi_stmt (bsi); 00460 gcc_assert (TREE_CODE (label) == LABEL_EXPR); 00461 bsi_remove (&bsi, false); 00462 bsi_insert_before (&bsi_to, label, BSI_CONTINUE_LINKING); 00463 } 00464 } 00465 00466 /* Update the dominators. */ 00467 if (dom_info_available_p (CDI_DOMINATORS)) 00468 { 00469 basic_block dom, dombb, domdest; 00470 00471 dombb = get_immediate_dominator (CDI_DOMINATORS, bb); 00472 domdest = get_immediate_dominator (CDI_DOMINATORS, dest); 00473 if (domdest == bb) 00474 { 00475 /* Shortcut to avoid calling (relatively expensive) 00476 nearest_common_dominator unless necessary. */ 00477 dom = dombb; 00478 } 00479 else 00480 dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb); 00481 00482 set_immediate_dominator (CDI_DOMINATORS, dest, dom); 00483 } 00484 00485 /* And kill the forwarder block. */ 00486 delete_basic_block (bb); 00487 00488 return true; 00489 }
|
|
|
Merge the PHI nodes at BB into those at BB's sole successor. Definition at line 612 of file tree-cfgcleanup.c. References add_phi_arg(), DECL_NONLOCAL, first_stmt(), LABEL_EXPR_LABEL, NULL_TREE, PENDING_STMT, phi_alternatives_equal(), PHI_ARG_DEF, PHI_CHAIN, phi_nodes(), TREE_CHAIN, TREE_CODE, TREE_PURPOSE, and TREE_VALUE. 00613 { 00614 edge succ = single_succ_edge (bb); 00615 basic_block dest = succ->dest; 00616 tree label; 00617 basic_block dombb, domdest, dom; 00618 00619 /* We check for infinite loops already in tree_forwarder_block_p. 00620 However it may happen that the infinite loop is created 00621 afterwards due to removal of forwarders. */ 00622 if (dest == bb) 00623 return; 00624 00625 /* If the destination block consists of a nonlocal label, do not 00626 merge it. */ 00627 label = first_stmt (dest); 00628 if (label 00629 && TREE_CODE (label) == LABEL_EXPR 00630 && DECL_NONLOCAL (LABEL_EXPR_LABEL (label))) 00631 return; 00632 00633 /* Redirect each incoming edge to BB to DEST. */ 00634 while (EDGE_COUNT (bb->preds) > 0) 00635 { 00636 edge e = EDGE_PRED (bb, 0), s; 00637 tree phi; 00638 00639 s = find_edge (e->src, dest); 00640 if (s) 00641 { 00642 /* We already have an edge S from E->src to DEST. If S and 00643 E->dest's sole successor edge have the same PHI arguments 00644 at DEST, redirect S to DEST. */ 00645 if (phi_alternatives_equal (dest, s, succ)) 00646 { 00647 e = redirect_edge_and_branch (e, dest); 00648 PENDING_STMT (e) = NULL_TREE; 00649 continue; 00650 } 00651 00652 /* PHI arguments are different. Create a forwarder block by 00653 splitting E so that we can merge PHI arguments on E to 00654 DEST. */ 00655 e = single_succ_edge (split_edge (e)); 00656 } 00657 00658 s = redirect_edge_and_branch (e, dest); 00659 00660 /* redirect_edge_and_branch must not create a new edge. */ 00661 gcc_assert (s == e); 00662 00663 /* Add to the PHI nodes at DEST each PHI argument removed at the 00664 destination of E. */ 00665 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi)) 00666 { 00667 tree def = PHI_ARG_DEF (phi, succ->dest_idx); 00668 00669 if (TREE_CODE (def) == SSA_NAME) 00670 { 00671 tree var; 00672 00673 /* If DEF is one of the results of PHI nodes removed during 00674 redirection, replace it with the PHI argument that used 00675 to be on E. */ 00676 for (var = PENDING_STMT (e); var; var = TREE_CHAIN (var)) 00677 { 00678 tree old_arg = TREE_PURPOSE (var); 00679 tree new_arg = TREE_VALUE (var); 00680 00681 if (def == old_arg) 00682 { 00683 def = new_arg; 00684 break; 00685 } 00686 } 00687 } 00688 00689 add_phi_arg (phi, def, s); 00690 } 00691 00692 PENDING_STMT (e) = NULL; 00693 } 00694 00695 /* Update the dominators. */ 00696 dombb = get_immediate_dominator (CDI_DOMINATORS, bb); 00697 domdest = get_immediate_dominator (CDI_DOMINATORS, dest); 00698 if (domdest == bb) 00699 { 00700 /* Shortcut to avoid calling (relatively expensive) 00701 nearest_common_dominator unless necessary. */ 00702 dom = dombb; 00703 } 00704 else 00705 dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb); 00706 00707 set_immediate_dominator (CDI_DOMINATORS, dest, dom); 00708 00709 /* Remove BB since all of BB's incoming edges have been redirected 00710 to DEST. */ 00711 delete_basic_block (bb); 00712 }
|
|
|
Return true if basic block BB does nothing except pass control flow to another block and that we can safely insert a label at the start of the successor block. As a precondition, we require that BB be not equal to ENTRY_BLOCK_PTR. Definition at line 239 of file tree-cfgcleanup.c. References bsi_end_p(), bsi_last, bsi_prev(), bsi_stmt(), DECL_NONLOCAL, LABEL_EXPR_LABEL, NULL_TREE, phi_nodes(), and TREE_CODE. Referenced by cleanup_forwarder_blocks(), and merge_phi_nodes(). 00240 { 00241 block_stmt_iterator bsi; 00242 edge_iterator ei; 00243 edge e, succ; 00244 basic_block dest; 00245 00246 /* BB must have a single outgoing edge. */ 00247 if (single_succ_p (bb) != 1 00248 /* If PHI_WANTED is false, BB must not have any PHI nodes. 00249 Otherwise, BB must have PHI nodes. */ 00250 || (phi_nodes (bb) != NULL_TREE) != phi_wanted 00251 /* BB may not be a predecessor of EXIT_BLOCK_PTR. */ 00252 || single_succ (bb) == EXIT_BLOCK_PTR 00253 /* Nor should this be an infinite loop. */ 00254 || single_succ (bb) == bb 00255 /* BB may not have an abnormal outgoing edge. */ 00256 || (single_succ_edge (bb)->flags & EDGE_ABNORMAL)) 00257 return false; 00258 00259 #if ENABLE_CHECKING 00260 gcc_assert (bb != ENTRY_BLOCK_PTR); 00261 #endif 00262 00263 /* Now walk through the statements backward. We can ignore labels, 00264 anything else means this is not a forwarder block. */ 00265 for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) 00266 { 00267 tree stmt = bsi_stmt (bsi); 00268 00269 switch (TREE_CODE (stmt)) 00270 { 00271 case LABEL_EXPR: 00272 if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt))) 00273 return false; 00274 break; 00275 00276 default: 00277 return false; 00278 } 00279 } 00280 00281 if (find_edge (ENTRY_BLOCK_PTR, bb)) 00282 return false; 00283 00284 if (current_loops) 00285 { 00286 basic_block dest; 00287 /* Protect loop latches, headers and preheaders. */ 00288 if (bb->loop_father->header == bb) 00289 return false; 00290 dest = EDGE_SUCC (bb, 0)->dest; 00291 00292 if (dest->loop_father->header == dest) 00293 return false; 00294 } 00295 00296 /* If we have an EH edge leaving this block, make sure that the 00297 destination of this block has only one predecessor. This ensures 00298 that we don't get into the situation where we try to remove two 00299 forwarders that go to the same basic block but are handlers for 00300 different EH regions. */ 00301 succ = single_succ_edge (bb); 00302 dest = succ->dest; 00303 FOR_EACH_EDGE (e, ei, bb->preds) 00304 { 00305 if (e->flags & EDGE_EH) 00306 { 00307 if (!single_pred_p (dest)) 00308 return false; 00309 } 00310 } 00311 00312 return true; 00313 }
|
|
||||||||||||
|
Try to remove superfluous control structures. Definition at line 136 of file tree-cfgcleanup.c. Referenced by access_functions_are_affine_or_constant_p(), add_graph_edge(), add_may_alias_for_new_tag(), add_virtual_operand(), allocate_graph_weights(), analyze_array(), build_constraint_graph(), build_constructor_from_list(), build_constructor_single(), build_tree_conflict_graph(), clear_edges_for_node(), compute_antic_aux(), compute_call_clobbered(), compute_data_dependences_for_loop(), compute_tag_properties(), compute_vuse_representatives(), create_name_tags(), create_overlap_variables_for(), create_structure_vars(), create_variable_info_for(), dequeue_and_dump(), do_structure_copy(), dump_may_aliases_for(), erase_graph_self_edge(), expand_vector_piecewise(), find_func_aliases(), find_idf(), get_graph_weights(), gimplify_compound_lval(), gimplify_init_constructor(), gimplify_init_ctor_preeval(), gimplify_switch_expr(), handle_ptr_arith(), init_data_ref(), is_aliased_with(), linear_transform_loops(), mark_aliases_call_clobbered(), merge_graph_nodes(), move_sese_region_to_fn(), new_type_alias(), perform_var_substitution(), phi_translate(), phi_translate_set(), prune_unused_phi_nodes(), reassociate_bb(), recalculate_used_alone(), remove_dead_inserted_code(), scev_analysis(), setup_pointers_and_addressables(), simple_cst_equal(), solve_graph(), topo_visit(), VEC(), vect_analyze_data_ref_accesses(), vect_analyze_data_ref_dependences(), vect_analyze_data_refs(), vect_compute_data_refs_alignment(), vect_create_cond_for_align_checks(), vect_enhance_data_refs_alignment(), vect_mark_stmts_to_be_vectorized(), vect_update_inits_of_drs(), vect_update_misalignment_for_peel(), vect_verify_datarefs_alignment(), verify_flow_insensitive_alias_info(), verify_name_tags(), and vn_lookup_or_add(). 00142 { 00143 basic_block bb; 00144 block_stmt_iterator bsi; 00145 bool retval = false; 00146 tree stmt; 00147 00148 /* Detect cases where a mid-block call is now known not to return. */ 00149 while (VEC_length (tree, modified_noreturn_calls)) 00150 { 00151 stmt = VEC_pop (tree, modified_noreturn_calls); 00152 bb = bb_for_stmt (stmt); 00153 if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt)) 00154 split_block (bb, stmt); 00155 } 00156 00157 FOR_EACH_BB (bb) 00158 { 00159 bsi = bsi_last (bb); 00160 00161 /* If the last statement of the block could throw and now cannot, 00162 we need to prune cfg. */ 00163 tree_purge_dead_eh_edges (bb); 00164 00165 if (bsi_end_p (bsi)) 00166 continue; 00167 00168 stmt = bsi_stmt (bsi); 00169 00170 if (TREE_CODE (stmt) == COND_EXPR 00171 || TREE_CODE (stmt) == SWITCH_EXPR) 00172 retval |= cleanup_control_expr_graph (bb, bsi); 00173 /* If we had a computed goto which has a compile-time determinable 00174 destination, then we can eliminate the goto. */ 00175 else if (TREE_CODE (stmt) == GOTO_EXPR 00176 && TREE_CODE (GOTO_DESTINATION (stmt)) == ADDR_EXPR 00177 && (TREE_CODE (TREE_OPERAND (GOTO_DESTINATION (stmt), 0)) 00178 == LABEL_DECL)) 00179 { 00180 edge e; 00181 tree label; 00182 edge_iterator ei; 00183 basic_block target_block; 00184 bool removed_edge = false; 00185 00186 /* First look at all the outgoing edges. Delete any outgoing 00187 edges which do not go to the right block. For the one 00188 edge which goes to the right block, fix up its flags. */ 00189 label = TREE_OPERAND (GOTO_DESTINATION (stmt), 0); 00190 target_block = label_to_block (label); 00191 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) 00192 { 00193 if (e->dest != target_block) 00194 { 00195 removed_edge = true; 00196 remove_edge (e); 00197 } 00198 else 00199 { 00200 /* Turn off the EDGE_ABNORMAL flag. */ 00201 e->flags &= ~EDGE_ABNORMAL; 00202 00203 /* And set EDGE_FALLTHRU. */ 00204 e->flags |= EDGE_FALLTHRU; 00205 ei_next (&ei); 00206 } 00207 } 00208 00209 /* If we removed one or more edges, then we will need to fix the 00210 dominators. It may be possible to incrementally update them. */ 00211 if (removed_edge) 00212 free_dominance_info (CDI_DOMINATORS); 00213 00214 /* Remove the GOTO_EXPR as it is not needed. The CFG has all the 00215 relevant information we need. */ 00216 bsi_remove (&bsi, true); 00217 retval = true; 00218 } 00219 00220 /* Check for indirect calls that have been turned into 00221 noreturn calls. */ 00222 else if (noreturn_call_p (stmt) && remove_fallthru_edge (bb->succs)) 00223 { 00224 free_dominance_info (CDI_DOMINATORS); 00225 retval = true; 00226 } 00227 } 00228 return retval; 00229 }
|
|
|
Initial value: {
"mergephi",
gate_merge_phi,
merge_phi_nodes,
NULL,
NULL,
0,
TV_TREE_MERGE_PHI,
PROP_cfg | PROP_ssa,
0,
0,
0,
TODO_dump_func | TODO_ggc_collect
| TODO_verify_ssa,
0
}
Definition at line 827 of file tree-cfgcleanup.c. |
1.4.6