summaryrefslogtreecommitdiff
path: root/gcc/tree-optimize.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-29 06:32:58 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-29 06:32:58 +0000
commit2c8a1497c34d993b24a00f9962f72ab05d749471 (patch)
treec8e2772aad71fdf66dba0112c42b9178748e598f /gcc/tree-optimize.c
parentfc4a9273d580b8ed8519c3349130a73bda16c5b9 (diff)
downloadgcc-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.c56
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 */
};