diff options
author | Jan Hubicka <jh@suse.cz> | 2009-04-25 11:02:05 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2009-04-25 09:02:05 +0000 |
commit | 496a4ef59d7830dbedecb7718cb2b4c0a7377528 (patch) | |
tree | d9aa3a1c938bc4df3cbd34eb918dde4d83d84237 /gcc/tree-cfg.c | |
parent | bc2a4733e2715627ca95a1bccda96a9c2be30ea5 (diff) | |
download | gcc-496a4ef59d7830dbedecb7718cb2b4c0a7377528.zip gcc-496a4ef59d7830dbedecb7718cb2b4c0a7377528.tar.gz gcc-496a4ef59d7830dbedecb7718cb2b4c0a7377528.tar.bz2 |
tree-eh.c (tree_remove_unreachable_handlers): Handle shared labels.
* tree-eh.c (tree_remove_unreachable_handlers): Handle shared labels.
(tree_empty_eh_handler_p): Allow non-EH predecestors; allow region
to be reached by different label than left.
(update_eh_edges): Update comment; remove edge_to_remove if possible
and return true if suceeded.
(cleanup_empty_eh): Accept sharing map; handle shared regions.
(cleanup_eh): Compute sharing map.
* except.c (remove_eh_handler_and_replace): Add argument if we should
update regions.
(remove_unreachable_regions): Update for label sharing.
(label_to_region_map): Likewise.
(get_next_region_sharing_label): New function.
(remove_eh_handler_and_replace): Add update_catch_try parameter; update
prev_try pointers.
(remove_eh_handler): Update.
(remove_eh_region_and_replace_by_outer_of): New function.
* except.h (struct eh_region): Add next_region_sharing_label.
(remove_eh_region_and_replace_by_outer_of,
get_next_region_sharing_label): Declare.
* tree-cfgcleanup.c (tree_forwarder_block_p): Simplify.
* tree-cfg.c (split_critical_edges): Split also edges where we can't
insert code even if they are not critical.
* tree-cfg.c (gimple_can_merge_blocks_p): EH edges are unmergable.
(gimple_can_remove_branch_p): EH edges won't remove branch by
redirection.
* tree-inline.c (update_ssa_across_abnormal_edges): Do handle
updating of non-abnormal EH edges.
* tree-cfg.c (gimple_can_merge_blocks_p): EH edges are unmergable.
(gimple_can_remove_branch_p): EH edges are unremovable by redirection.
(split_critical_edges): Split also edges where emitting code on them
will lead to splitting later.
From-SVN: r146763
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 009f9a9..d514f45 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1212,7 +1212,7 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) if (!single_succ_p (a)) return false; - if (single_succ_edge (a)->flags & EDGE_ABNORMAL) + if (single_succ_edge (a)->flags & (EDGE_ABNORMAL | EDGE_EH)) return false; if (single_succ (a) != b) @@ -4892,7 +4892,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) static bool gimple_can_remove_branch_p (const_edge e) { - if (e->flags & EDGE_ABNORMAL) + if (e->flags & (EDGE_ABNORMAL | EDGE_EH)) return false; return true; @@ -6992,10 +6992,31 @@ split_critical_edges (void) FOR_ALL_BB (bb) { FOR_EACH_EDGE (e, ei, bb->succs) - if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL)) - { + { + if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL)) split_edge (e); - } + /* PRE inserts statements to edges and expects that + since split_critical_edges was done beforehand, committing edge + insertions will not split more edges. In addition to critical + edges we must split edges that have multiple successors and + end by control flow statements, such as RESX. + Go ahead and split them too. This matches the logic in + gimple_find_edge_insert_loc. */ + else if ((!single_pred_p (e->dest) + || phi_nodes (e->dest) + || e->dest == EXIT_BLOCK_PTR) + && e->src != ENTRY_BLOCK_PTR + && !(e->flags & EDGE_ABNORMAL)) + { + gimple_stmt_iterator gsi; + + gsi = gsi_last_bb (e->src); + if (!gsi_end_p (gsi) + && stmt_ends_bb_p (gsi_stmt (gsi)) + && gimple_code (gsi_stmt (gsi)) != GIMPLE_RETURN) + split_edge (e); + } + } } end_recording_case_labels (); return 0; |