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/builtins.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/builtins.c')
-rw-r--r-- | gcc/builtins.c | 132 |
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); |