summaryrefslogtreecommitdiff
path: root/gcc/builtins.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/builtins.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/builtins.c')
-rw-r--r--gcc/builtins.c132
1 files changed, 57 insertions, 75 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 4684a5482ad..8fb58ca052d 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -81,7 +81,6 @@ static int apply_result_size (void);
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
static rtx result_vector (int, rtx);
#endif
-static rtx expand_builtin_setjmp (tree, rtx);
static void expand_builtin_update_setjmp_buf (rtx);
static void expand_builtin_prefetch (tree);
static rtx expand_builtin_apply_args (void);
@@ -608,8 +607,8 @@ expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
static HOST_WIDE_INT setjmp_alias_set = -1;
/* Construct the leading half of a __builtin_setjmp call. Control will
- return to RECEIVER_LABEL. This is used directly by sjlj exception
- handling code. */
+ return to RECEIVER_LABEL. This is also called directly by the SJLJ
+ exception handling code. */
void
expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
@@ -660,8 +659,8 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
current_function_has_nonlocal_label = 1;
}
-/* Construct the trailing part of a __builtin_setjmp call.
- This is used directly by sjlj exception handling code. */
+/* Construct the trailing part of a __builtin_setjmp call. This is
+ also called directly by the SJLJ exception handling code. */
void
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
@@ -729,73 +728,10 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
}
-/* __builtin_setjmp is passed a pointer to an array of five words (not
- all will be used on all machines). It operates similarly to the C
- library function of the same name, but is more efficient. Much of
- the code below (and for longjmp) is copied from the handling of
- non-local gotos.
-
- NOTE: This is intended for use by GNAT and the exception handling
- scheme in the compiler and will only work in the method used by
- them. */
-
-static rtx
-expand_builtin_setjmp (tree arglist, rtx target)
-{
- rtx buf_addr, next_lab, cont_lab;
-
- if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
- return NULL_RTX;
-
- if (target == 0 || !REG_P (target)
- || REGNO (target) < FIRST_PSEUDO_REGISTER)
- target = gen_reg_rtx (TYPE_MODE (integer_type_node));
-
- buf_addr = expand_normal (TREE_VALUE (arglist));
-
- next_lab = gen_label_rtx ();
- cont_lab = gen_label_rtx ();
-
- expand_builtin_setjmp_setup (buf_addr, next_lab);
-
- /* Set TARGET to zero and branch to the continue label. Use emit_jump to
- ensure that pending stack adjustments are flushed. */
- emit_move_insn (target, const0_rtx);
- emit_jump (cont_lab);
-
- emit_label (next_lab);
-
- /* Because setjmp and longjmp are not represented in the CFG, a cfgcleanup
- may find that the basic block starting with NEXT_LAB is unreachable.
- The whole block, along with NEXT_LAB, would be removed (see PR26983).
- Make sure that never happens. */
- LABEL_PRESERVE_P (next_lab) = 1;
-
- expand_builtin_setjmp_receiver (next_lab);
-
- /* Set TARGET to one. */
- emit_move_insn (target, const1_rtx);
- emit_label (cont_lab);
-
- /* Tell flow about the strange goings on. Putting `next_lab' on
- `nonlocal_goto_handler_labels' to indicates that function
- calls may traverse the arc back to this label. */
-
- current_function_has_nonlocal_label = 1;
- nonlocal_goto_handler_labels
- = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
-
- return target;
-}
-
/* __builtin_longjmp is passed a pointer to an array of five words (not
all will be used on all machines). It operates similarly to the C
library function of the same name, but is more efficient. Much of
- the code below is copied from the handling of non-local gotos.
-
- NOTE: This is intended for use by GNAT and the exception handling
- scheme in the compiler and will only work in the method used by
- them. */
+ the code below is copied from the handling of non-local gotos. */
static void
expand_builtin_longjmp (rtx buf_addr, rtx value)
@@ -6077,18 +6013,63 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
break;
case BUILT_IN_SETJMP:
- target = expand_builtin_setjmp (arglist, target);
- if (target)
- return target;
+ /* This should have been lowered to the builtins below. */
+ gcc_unreachable ();
+
+ case BUILT_IN_SETJMP_SETUP:
+ /* __builtin_setjmp_setup is passed a pointer to an array of five words
+ and the receiver label. */
+ if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ {
+ rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
+ VOIDmode, EXPAND_NORMAL);
+ tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
+ rtx label_r = label_rtx (label);
+
+ /* This is copied from the handling of non-local gotos. */
+ expand_builtin_setjmp_setup (buf_addr, label_r);
+ nonlocal_goto_handler_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, label_r,
+ nonlocal_goto_handler_labels);
+ /* ??? Do not let expand_label treat us as such since we would
+ not want to be both on the list of non-local labels and on
+ the list of forced labels. */
+ FORCED_LABEL (label) = 0;
+ return const0_rtx;
+ }
+ break;
+
+ case BUILT_IN_SETJMP_DISPATCHER:
+ /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
+ if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
+ {
+ tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
+ rtx label_r = label_rtx (label);
+
+ /* Remove the dispatcher label from the list of non-local labels
+ since the receiver labels have been added to it above. */
+ remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
+ return const0_rtx;
+ }
+ break;
+
+ case BUILT_IN_SETJMP_RECEIVER:
+ /* __builtin_setjmp_receiver is passed the receiver label. */
+ if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
+ {
+ tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
+ rtx label_r = label_rtx (label);
+
+ expand_builtin_setjmp_receiver (label_r);
+ return const0_rtx;
+ }
break;
/* __builtin_longjmp is passed a pointer to an array of five words.
It's similar to the C library longjmp function but works with
__builtin_setjmp above. */
case BUILT_IN_LONGJMP:
- if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
- break;
- else
+ if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
{
rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
VOIDmode, EXPAND_NORMAL);
@@ -6103,6 +6084,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
expand_builtin_longjmp (buf_addr, value);
return const0_rtx;
}
+ break;
case BUILT_IN_NONLOCAL_GOTO:
target = expand_builtin_nonlocal_goto (arglist);