This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
sjlj eh flow patch
- To: egcs at cygnus dot com
- Subject: sjlj eh flow patch
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 10 Nov 1997 19:23:54 -0800
- Reply-To: Richard Henderson <rth at cygnus dot com>
The following patch generates more optimal basic block flows when
using sjlj by taking into account the fact that we know that longjmp
will go through a different path than the original call to setjmp.
It also gets rid of the stupid call to __dummy. There is one backend
that needs to be fixed up because of this (MIPS); I'd been meaning to
do it but forgot. If this patch is accepted for the post-1.00 release
I'll finish that bit.
r~
Mon Nov 10 18:48:02 1997 Richard Henderson <rth@cygnus.com>
* expr.c (expand_builtin_setjmp): Accept two new arguments for
the labels to branch to on first and subsequent executions. Don't
play with __dummy.
(expand_builtin) [BUILTIN_SETJMP]: Generate a label for use by setjmp.
(expand_builtin) [BUILTIN_LONGJMP]: Don't play with __dummy. Correct
arguments to nonlocal_goto.
* expr.h (expand_builtin_setjmp): Update prototype.
* except.c (start_dynamic_handler): When using builtin_setjmp,
generate correct flow information.
Index: except.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.10.2.1
diff -u -p -d -r1.10.2.1 except.c
--- except.c 1997/11/10 20:06:46 1.10.2.1
+++ except.c 1997/11/11 02:30:50
@@ -914,14 +914,17 @@ start_dynamic_handler ()
#ifdef DONT_USE_BUILTIN_SETJMP
x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 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
- x = expand_builtin_setjmp (buf, NULL_RTX);
+ {
+ /* 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);
+ }
#endif
-
- /* If we come back here for a catch, transfer control to the
- handler. */
-
- jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
/* We are committed to this, so update the handler chain. */
Index: expr.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.16
diff -u -p -d -r1.16 expr.c
--- expr.c 1997/11/02 05:15:13 1.16
+++ expr.c 1997/11/11 02:30:51
@@ -8072,20 +8072,16 @@ expand_builtin_return_addr (fndecl_code,
them. */
rtx
-expand_builtin_setjmp (buf_addr, target)
+expand_builtin_setjmp (buf_addr, target, first_label, next_label)
rtx buf_addr;
rtx target;
+ rtx first_label, next_label;
{
- rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
+ rtx lab1 = gen_label_rtx ();
enum machine_mode sa_mode = Pmode, value_mode;
rtx stack_save;
int old_inhibit_defer_pop = inhibit_defer_pop;
- int return_pops
- = RETURN_POPS_ARGS (get_identifier ("__dummy"),
- build_function_type (void_type_node, NULL_TREE),
- 0);
rtx next_arg_reg;
- CUMULATIVE_ARGS args_so_far;
rtx op0;
int i;
@@ -8129,9 +8125,9 @@ expand_builtin_setjmp (buf_addr, target)
emit_insn (gen_setjmp ());
#endif
- /* Set TARGET to zero and branch around the other case. */
+ /* Set TARGET to zero and branch to the first-time-through label. */
emit_move_insn (target, const0_rtx);
- emit_jump_insn (gen_jump (lab2));
+ emit_jump_insn (gen_jump (first_label));
emit_barrier ();
emit_label (lab1);
@@ -8151,12 +8147,7 @@ expand_builtin_setjmp (buf_addr, target)
#endif
emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
- /* Do we need to do something like:
-
- current_function_has_nonlocal_label = 1;
-
- here? It seems like we might have to, or some subset of that
- functionality, but I am unsure. (mrs) */
+ current_function_has_nonlocal_label = 1;
#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
if (fixed_regs[ARG_POINTER_REGNUM])
@@ -8189,39 +8180,12 @@ expand_builtin_setjmp (buf_addr, target)
if (HAVE_nonlocal_goto_receiver)
emit_insn (gen_nonlocal_goto_receiver ());
#endif
- /* The static chain pointer contains the address of dummy function.
- We need to call it here to handle some PIC cases of restoring a
- global pointer. Then return 1. */
- op0 = copy_to_mode_reg (Pmode, static_chain_rtx);
-
- /* We can't actually call emit_library_call here, so do everything
- it does, which isn't much for a libfunc with no args. */
- op0 = memory_address (FUNCTION_MODE, op0);
-
- INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE,
- gen_rtx (SYMBOL_REF, Pmode, "__dummy"), 1);
- next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
-
-#ifndef ACCUMULATE_OUTGOING_ARGS
-#ifdef HAVE_call_pop
- if (HAVE_call_pop)
- emit_call_insn (gen_call_pop (gen_rtx (MEM, FUNCTION_MODE, op0),
- const0_rtx, next_arg_reg,
- GEN_INT (return_pops)));
- else
-#endif
-#endif
-
-#ifdef HAVE_call
- if (HAVE_call)
- emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, op0),
- const0_rtx, next_arg_reg, const0_rtx));
- else
-#endif
- abort ();
+ /* Set TARGET to one and branch to the next-time-through label. */
emit_move_insn (target, const1_rtx);
- emit_label (lab2);
+ emit_jump_insn (gen_jump (next_label));
+ emit_barrier ();
+
return target;
}
@@ -9080,21 +9044,21 @@ expand_builtin (exp, target, subtarget,
{
rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
VOIDmode, 0);
- return expand_builtin_setjmp (buf_addr, target);
+ rtx lab = gen_label_rtx ();
+ rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
+ emit_label (lab);
+ return ret;
}
- /* __builtin_longjmp is passed a pointer to an array of five words
- and a value, which is a dummy. It's similar to the C library longjmp
- function but works with __builtin_setjmp above. */
+ /* __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 (arglist == 0 || TREE_CHAIN (arglist) == 0
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
break;
{
- tree dummy_id = get_identifier ("__dummy");
- tree dummy_type = build_function_type (void_type_node, NULL_TREE);
- tree dummy_decl = build_decl (FUNCTION_DECL, dummy_id, dummy_type);
#ifdef POINTERS_EXTEND_UNSIGNED
rtx buf_addr
= force_reg (Pmode,
@@ -9123,35 +9087,24 @@ expand_builtin (exp, target, subtarget,
plus_constant (buf_addr,
2 * GET_MODE_SIZE (Pmode)));
- DECL_EXTERNAL (dummy_decl) = 1;
- TREE_PUBLIC (dummy_decl) = 1;
- make_decl_rtl (dummy_decl, NULL_PTR, 1);
-
/* Expand the second expression just for side-effects. */
expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
const0_rtx, VOIDmode, 0);
- assemble_external (dummy_decl);
-
/* Pick up FP, label, and SP from the block and jump. This code is
from expand_goto in stmt.c; see there for detailed comments. */
#if HAVE_nonlocal_goto
if (HAVE_nonlocal_goto)
- emit_insn (gen_nonlocal_goto (fp, lab, stack,
- XEXP (DECL_RTL (dummy_decl), 0)));
- else
+ emit_insn (gen_nonlocal_goto (fp, lab, stack, NULL_RTX));
+ else
#endif
{
lab = copy_to_reg (lab);
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
- /* Put in the static chain register the address of the dummy
- function. */
- emit_move_insn (static_chain_rtx, XEXP (DECL_RTL (dummy_decl), 0));
emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
- emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
emit_indirect_jump (lab);
}
Index: expr.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.h,v
retrieving revision 1.4
diff -u -p -d -r1.4 expr.h
--- expr.h 1997/08/29 15:02:03 1.4
+++ expr.h 1997/11/11 02:30:51
@@ -750,7 +750,7 @@ extern rtx store_expr PROTO((tree, rtx,
Useful after calling expand_expr with 1 as sum_ok. */
extern rtx force_operand PROTO((rtx, rtx));
-extern rtx expand_builtin_setjmp PROTO((rtx, rtx));
+extern rtx expand_builtin_setjmp PROTO((rtx, rtx, rtx, rtx));
#ifdef TREE_CODE
/* Generate code for computing expression EXP.