diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-09-29 06:32:58 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-09-29 06:32:58 +0000 |
commit | 2c8a1497c34d993b24a00f9962f72ab05d749471 (patch) | |
tree | c8e2772aad71fdf66dba0112c42b9178748e598f /gcc/tree-optimize.c | |
parent | fc4a9273d580b8ed8519c3349130a73bda16c5b9 (diff) | |
download | gcc-2c8a1497c34d993b24a00f9962f72ab05d749471.tar.gz |
* builtins.c (expand_builtin_setjmp): Delete.
(expand_builtin) <BUILT_IN_SETJMP>: Mark as unreachable.
<BUILT_IN_SETJMP_SETUP>: New case.
<BUILT_IN_SETJMP_DISPATCHER>: Likewise.
<BUILT_IN_SETJMP_RECEIVER>: Likewise.
* builtins.def (BUILT_IN_SETJMP_SETUP): New built-in stub.
(BUILT_IN_SETJMP_DISPATCHER): Likewise.
(BUILT_IN_SETJMP_RECEIVER): Likewise.
* gimple-low.c (struct lower_data): New field calls_builtin_setjmp.
(lower_function_body): Initialize it to false. If it is set to true
at the end of the processing, emit the setjmp dispatcher.
(lower_stmt) <CALL_EXPR>: Invoke lower_builtin_setjmp if the callee
is __builtin_setjmp and set calls_builtin_setjmp to true as well.
<MODIFY_EXPR>: Fall through to above case if there is a CALL_EXPR
on the rhs of the assignment.
(lower_builtin_setjmp): New function.
* tree.c (build_common_builtin_nodes): Build BUILT_IN_SETJMP_SETUP,
BUILT_IN_SETJMP_DISPATCHER and BUILT_IN_SETJMP_RECEIVER nodes.
* tree-cfg.c (make_exit_edges) <CALL_EXPR>: Use specific predicate
to detect calls that can go to non-local labels. Use specific
helper to create the abnormal edges associated with them.
<MODIFY_EXPR>: Likewise.
(make_abnormal_goto_edges): New function extracted from...
(make_goto_expr_edges): ...here. Call it for computed gotos.
(simple_goto_p): Minor tweak.
(tree_can_make_abnormal_goto): New predicate.
(tree_redirect_edge_and_branch): Return zero on all abnormal edges.
(tree_purge_dead_abnormal_call_edges): New function.
* tree-flow.h (tree_can_make_abnormal_goto): Declare.
(tree_purge_dead_abnormal_call_edges): Likewise.
(make_abnormal_goto_edges): Likewise.
* tree-inline.c (expand_call_inline): Simplify statement frobbing.
Purge all dead abnormal edges if the call was in the last statement.
* tree-optimize.c (has_abnormal_outgoing_edge_p): New predicate.
(execute_fixup_cfg): If there are non-local labels in the function,
scan the basic blocks and split them at calls that can go to non-local
labels or add missing abnormal call edges. Write down the CFG in the
dump file.
(pass_fixup_cfg): Remove TODO_dump_func flag.
* unwind-sjlj.c: Poison setjmp.
* doc/install.texi (enable-sjlj-exceptions): Use more general wording.
* doc/tm.texi (DWARF2_UNWIND_INFO): Likewise.
(TARGET_UNWIND_TABLES_DEFAULT): Fix typo.
(DONT_USE_BUILTIN_SETJMP): Document it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117298 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-optimize.c')
-rw-r--r-- | gcc/tree-optimize.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 3f4471a468c..50dd22b451f 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -237,9 +237,26 @@ struct tree_opt_pass pass_free_cfg_annotations = 0, /* todo_flags_finish */ 0 /* letter */ }; -/* Pass: fixup_cfg - IPA passes or compilation of earlier functions might've - changed some properties - such as marked functions nothrow. Remove now - redundant edges and basic blocks. */ + +/* Return true if BB has at least one abnormal outgoing edge. */ + +static inline bool +has_abnormal_outgoing_edge_p (basic_block bb) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & EDGE_ABNORMAL) + return true; + + return false; +} + +/* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining + might have changed some properties, such as marked functions nothrow or + added calls that can potentially go to non-local labels. Remove redundant + edges and basic blocks, and create new ones if necessary. */ static unsigned int execute_fixup_cfg (void) @@ -262,8 +279,37 @@ execute_fixup_cfg (void) } tree_purge_dead_eh_edges (bb); } - + + if (current_function_has_nonlocal_label) + FOR_EACH_BB (bb) + { + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + tree stmt = bsi_stmt (bsi); + if (tree_can_make_abnormal_goto (stmt)) + { + if (stmt == bsi_stmt (bsi_last (bb))) + { + if (!has_abnormal_outgoing_edge_p (bb)) + make_abnormal_goto_edges (bb, true); + } + else + { + edge e = split_block (bb, stmt); + bb = e->src; + make_abnormal_goto_edges (bb, true); + } + break; + } + } + } + cleanup_tree_cfg (); + + /* Dump a textual representation of the flowgraph. */ + if (dump_file) + dump_tree_cfg (dump_file, dump_flags); + return 0; } @@ -280,7 +326,7 @@ struct tree_opt_pass pass_fixup_cfg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + 0, /* todo_flags_finish */ 0 /* letter */ }; |