static void start_dynamic_handler PARAMS ((void));
static void expand_rethrow PARAMS ((rtx));
static void output_exception_table_entry PARAMS ((FILE *, int));
-static int can_throw PARAMS ((rtx));
static rtx scan_region PARAMS ((rtx, int, int *));
static void eh_regs PARAMS ((rtx *, rtx *, rtx *, int));
static void set_insn_eh_region PARAMS ((rtx *, int));
int region_num;
{
rtx def;
- char *ptr;
+ const char *ptr;
char buf[60];
- push_obstacks_nochange ();
- end_temporary_allocation ();
-
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", region_num);
- ptr = ggc_alloc_string (buf, -1);
+ ptr = ggc_strdup (buf);
def = gen_rtx_SYMBOL_REF (Pmode, ptr);
SYMBOL_REF_NEED_ADJUST (def) = 1;
- pop_obstacks ();
return def;
}
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);
}
next = ptr->next;
free (ptr);
}
- free (function_eh_regions);
+ if (function_eh_regions)
+ free (function_eh_regions);
num_func_eh_entries = 0;
current_func_eh_entry = 0;
}
{
expand_eh_region_start ();
- /* Make sure the entry is on the correct obstack. */
- push_obstacks_nochange ();
- resume_temporary_allocation ();
-
/* Because this is a cleanup action, we may have to protect the handler
with __terminate. */
handler = protect_with_terminate (handler);
/* Add this entry to the front of the list. */
TREE_VALUE (protect_list)
= tree_cons (NULL_TREE, handler, TREE_VALUE (protect_list));
- pop_obstacks ();
}
/* Emit code to get EH context to current function. */
{
tree fntype;
fn = get_identifier ("__get_eh_context");
- push_obstacks_nochange ();
- end_temporary_allocation ();
fntype = build_pointer_type (build_pointer_type
(build_pointer_type (void_type_node)));
fntype = build_function_type (fntype, NULL_TREE);
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_READONLY (fn) = 1;
- make_decl_rtl (fn, NULL_PTR, 1);
+ make_decl_rtl (fn, NULL_PTR);
assemble_external (fn);
- pop_obstacks ();
ggc_add_tree_root (&fn, 1);
}
start_dynamic_handler ()
{
rtx dhc, dcc;
- rtx x, arg, buf;
+ rtx arg, buf;
int size;
#ifndef DONT_USE_BUILTIN_SETJMP
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, 1,
- 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. */
/* Now issue the call, and branch around handler if needed */
call_rtx = emit_library_call_value (eh_rtime_match_libfunc, NULL_RTX,
- 0, TYPE_MODE (integer_type_node),
+ LCT_NORMAL,
+ TYPE_MODE (integer_type_node),
1, rtime_address, Pmode);
/* Did the function return true? */
void
begin_protect_partials ()
{
- /* Put the entry on the function obstack. */
- push_obstacks_nochange ();
- resume_temporary_allocation ();
-
/* Push room for a new list. */
protect_list = tree_cons (NULL_TREE, NULL_TREE, protect_list);
-
- /* We're done with the function obstack now. */
- pop_obstacks ();
}
/* End all the pending exception regions on protect_list. The handlers
{
tree handler, result;
- /* All cleanups must be on the function_obstack. */
- push_obstacks_nochange ();
- resume_temporary_allocation ();
-
handler = make_node (RTL_EXPR);
TREE_TYPE (handler) = void_type_node;
RTL_EXPR_RTL (handler) = const0_rtx;
TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
TREE_READONLY (result) = TREE_READONLY (e);
- pop_obstacks ();
-
e = result;
}
void
free_exception_table ()
{
- free (eh_table);
+ if (eh_table)
+ free (eh_table);
clear_function_eh_region ();
}
mark_eh_queue (eh->x_ehqueue);
ggc_mark_rtx (eh->x_catch_clauses);
- lang_mark_false_label_stack (eh->x_false_label_stack);
+ if (lang_mark_false_label_stack)
+ (*lang_mark_false_label_stack) (eh->x_false_label_stack);
mark_tree_label_node (eh->x_caught_return_label_stack);
ggc_mark_tree (eh->x_protect_list);
}
\f
/* This section is for the exception handling specific optimization
- pass. First are the internal routines, and then the main
- optimization pass. */
+ pass. */
/* Determine if the given INSN can throw an exception. */
-static int
+int
can_throw (insn)
rtx insn;
{