From 250d07b61f2772c7b4b35bbb8f8839fd77a1b8bc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 3 Dec 2000 15:58:44 -0800 Subject: [PATCH] bb-reorder.c (reorder_basic_blocks): Don't check for EH edges unless exception handling is enabled... * bb-reorder.c (reorder_basic_blocks): Don't check for EH edges unless exception handling is enabled, and if not using sjlj. * builtins.c (expand_builtin_setjmp_setup): New. (expand_builtin_setjmp_receiver): New. (expand_builtin_setjmp): Split out _setup and _receiver functions. Move argument parsing in from ... (expand_builtin): ... here. * except.c (receive_exception_label): Branch around receiver unless new-style exceptions. Call expand_builtin_setjmp_receiver. (start_dynamic_handler): Call expand_builtin_setjmp_setup. * expr.h: Update builtin setjmp decls. From-SVN: r37982 --- gcc/ChangeLog | 15 ++++++ gcc/bb-reorder.c | 18 ++++--- gcc/builtins.c | 135 +++++++++++++++++++++++++++-------------------- gcc/except.c | 57 +++++++++++++------- gcc/expr.h | 3 +- 5 files changed, 143 insertions(+), 85 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 329031494ec..73ddb4cb55c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2000-12-03 Richard Henderson + + * bb-reorder.c (reorder_basic_blocks): Don't check for EH edges + unless exception handling is enabled, and if not using sjlj. + + * builtins.c (expand_builtin_setjmp_setup): New. + (expand_builtin_setjmp_receiver): New. + (expand_builtin_setjmp): Split out _setup and _receiver functions. + Move argument parsing in from ... + (expand_builtin): ... here. + * except.c (receive_exception_label): Branch around receiver + unless new-style exceptions. Call expand_builtin_setjmp_receiver. + (start_dynamic_handler): Call expand_builtin_setjmp_setup. + * expr.h: Update builtin setjmp decls. + 2000-12-03 Bruce Korb * fixinc/mkfixinc.sh(build machine): Sometimes, there is no canonical diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index d2ea95d1f4e..45b5f2f680c 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -1346,14 +1346,16 @@ reorder_basic_blocks () if (n_basic_blocks <= 1) return; - /* We do not currently handle correct re-placement of EH notes. */ - for (i = 0; i < n_basic_blocks; i++) - { - edge e; - for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next) - if (e->flags & EDGE_EH) - return; - } + /* We do not currently handle correct re-placement of EH notes. + But that does not matter unless we intend to use them. */ + if (flag_exceptions && ! exceptions_via_longjmp) + for (i = 0; i < n_basic_blocks; i++) + { + edge e; + for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next) + if (e->flags & EDGE_EH) + return; + } for (i = 0; i < n_basic_blocks; i++) BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def)); diff --git a/gcc/builtins.c b/gcc/builtins.c index 7994f63dcad..1d8e5e24dbd 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -90,6 +90,7 @@ static int apply_result_size PARAMS ((void)); #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) static rtx result_vector PARAMS ((int, rtx)); #endif +static rtx expand_builtin_setjmp PARAMS ((tree, rtx)); static rtx expand_builtin_apply_args PARAMS ((void)); static rtx expand_builtin_apply_args_1 PARAMS ((void)); static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx)); @@ -453,30 +454,19 @@ expand_builtin_return_addr (fndecl_code, count, tem) /* Alias set used for setjmp buffer. */ static HOST_WIDE_INT setjmp_alias_set = -1; -/* __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. +/* Construct the leading half of a __builtin_setjmp call. Control will + return to RECEIVER_LABEL. This is used directly by sjlj exception + handling code. */ - 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. */ - -rtx -expand_builtin_setjmp (buf_addr, target, first_label, next_label) +void +expand_builtin_setjmp_setup (buf_addr, receiver_label) rtx buf_addr; - rtx target; - rtx first_label, next_label; + rtx receiver_label; { - rtx lab1 = gen_label_rtx (); enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); - enum machine_mode value_mode; rtx stack_save; rtx mem; - value_mode = TYPE_MODE (integer_type_node); - if (setjmp_alias_set == -1) setjmp_alias_set = new_alias_set (); @@ -486,15 +476,11 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX)); - if (target == 0 || GET_CODE (target) != REG - || REGNO (target) < FIRST_PSEUDO_REGISTER) - target = gen_reg_rtx (value_mode); - emit_queue (); - /* We store the frame pointer and the address of lab1 in the buffer - and use the rest of it for the stack save area, which is - machine-dependent. */ + /* We store the frame pointer and the address of receiver_label in + the buffer and use the rest of it for the stack save area, which + is machine-dependent. */ #ifndef BUILTIN_SETJMP_FRAME_VALUE #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx @@ -508,7 +494,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) MEM_ALIAS_SET (mem) = setjmp_alias_set; emit_move_insn (validize_mem (mem), - force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1))); + force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label))); stack_save = gen_rtx_MEM (sa_mode, plus_constant (buf_addr, @@ -522,21 +508,18 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) emit_insn (gen_builtin_setjmp_setup (buf_addr)); #endif - /* Set TARGET to zero and branch to the first-time-through label. */ - emit_move_insn (target, const0_rtx); - emit_jump_insn (gen_jump (first_label)); - emit_barrier (); - emit_label (lab1); - - /* Tell flow about the strange goings on. Putting `lab1' on - `nonlocal_goto_handler_labels' to indicates that function - calls may traverse the arc back to this label. */ - - current_function_has_nonlocal_label = 1; + /* Tell optimize_save_area_alloca that extra work is going to + need to go on during alloca. */ current_function_calls_setjmp = 1; - nonlocal_goto_handler_labels - = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels); +} +/* Construct the trailing part of a __builtin_setjmp call. + This is used directly by sjlj exception handling code. */ + +void +expand_builtin_setjmp_receiver (receiver_label) + rtx receiver_label ATTRIBUTE_UNUSED; +{ /* Clobber the FP when we get here, so we have to make sure it's marked as used by this function. */ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); @@ -583,7 +566,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) #ifdef HAVE_builtin_setjmp_receiver if (HAVE_builtin_setjmp_receiver) - emit_insn (gen_builtin_setjmp_receiver (lab1)); + emit_insn (gen_builtin_setjmp_receiver (receiver_label)); else #endif #ifdef HAVE_nonlocal_goto_receiver @@ -591,14 +574,60 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label) emit_insn (gen_nonlocal_goto_receiver ()); else #endif - { - ; /* Nothing */ - } + { /* Nothing */ } +} - /* Set TARGET, and branch to the next-time-through label. */ - emit_move_insn (target, const1_rtx); - emit_jump_insn (gen_jump (next_label)); +/* __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 (arglist, target) + tree arglist; + rtx target; +{ + rtx buf_addr, next_lab, cont_lab; + + if (arglist == 0 + || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE) + return NULL_RTX; + + if (target == 0 || GET_CODE (target) != REG + || REGNO (target) < FIRST_PSEUDO_REGISTER) + target = gen_reg_rtx (TYPE_MODE (integer_type_node)); + + buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0); + + 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. */ + emit_move_insn (target, const0_rtx); + emit_jump_insn (gen_jump (cont_lab)); emit_barrier (); + emit_label (next_lab); + + 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; } @@ -3569,18 +3598,10 @@ expand_builtin (exp, target, subtarget, mode, ignore) #endif case BUILT_IN_SETJMP: - if (arglist == 0 - || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE) - break; - else - { - rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget, - VOIDmode, 0); - rtx lab = gen_label_rtx (); - rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab); - emit_label (lab); - return ret; - } + target = expand_builtin_setjmp (arglist, target); + if (target) + return target; + 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 diff --git a/gcc/except.c b/gcc/except.c index 5364b250328..c1dd0cbbe32 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -672,19 +672,40 @@ static void receive_exception_label (handler_label) rtx handler_label; { + rtx around_label = NULL_RTX; + + if (! flag_new_exceptions || exceptions_via_longjmp) + { + around_label = gen_label_rtx (); + emit_jump (around_label); + emit_barrier (); + } + emit_label (handler_label); -#ifdef HAVE_exception_receiver if (! exceptions_via_longjmp) - if (HAVE_exception_receiver) - emit_insn (gen_exception_receiver ()); + { +#ifdef HAVE_exception_receiver + if (HAVE_exception_receiver) + emit_insn (gen_exception_receiver ()); + else #endif - #ifdef HAVE_nonlocal_goto_receiver - if (! exceptions_via_longjmp) - if (HAVE_nonlocal_goto_receiver) - emit_insn (gen_nonlocal_goto_receiver ()); + if (HAVE_nonlocal_goto_receiver) + emit_insn (gen_nonlocal_goto_receiver ()); + else #endif + { /* Nothing */ } + } + else + { +#ifndef DONT_USE_BUILTIN_SETJMP + expand_builtin_setjmp_receiver (handler_label); +#endif + } + + if (around_label) + emit_label (around_label); } @@ -1304,7 +1325,7 @@ static void start_dynamic_handler () { rtx dhc, dcc; - rtx x, arg, buf; + rtx arg, buf; int size; #ifndef DONT_USE_BUILTIN_SETJMP @@ -1351,19 +1372,17 @@ start_dynamic_handler () buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2); #ifdef DONT_USE_BUILTIN_SETJMP - x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST, - TYPE_MODE (integer_type_node), 1, - buf, Pmode); - /* If we come back here for a catch, transfer control to the handler. */ - jumpif_rtx (x, ehstack.top->entry->exception_handler_label); -#else { - /* A label to continue execution for the no exception case. */ - rtx noex = gen_label_rtx(); - x = expand_builtin_setjmp (buf, NULL_RTX, noex, - ehstack.top->entry->exception_handler_label); - emit_label (noex); + rtx x; + x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST, + TYPE_MODE (integer_type_node), 1, + buf, Pmode); + /* If we come back here for a catch, transfer control to the handler. */ + jumpif_rtx (x, ehstack.top->entry->exception_handler_label); } +#else + expand_builtin_setjmp_setup (buf, + ehstack.top->entry->exception_handler_label); #endif /* We are committed to this, so update the handler chain. */ diff --git a/gcc/expr.h b/gcc/expr.h index 74af2d9957f..eea9b97f08a 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -924,7 +924,8 @@ extern rtx std_expand_builtin_va_arg PARAMS ((tree, tree)); extern rtx expand_builtin_va_arg PARAMS ((tree, tree)); #endif -extern rtx expand_builtin_setjmp PARAMS ((rtx, rtx, rtx, rtx)); +extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx)); +extern void expand_builtin_setjmp_receiver PARAMS ((rtx)); extern void expand_builtin_longjmp PARAMS ((rtx, rtx)); extern rtx expand_builtin_saveregs PARAMS ((void)); extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void)); -- 2.30.2