Commit e701eb4d by Jason Merrill Committed by Jason Merrill

./: * libgcc2.c (__throw): Use __builtin_return_addr instead of __eh_pc.

	* except.c: Lose outer_context_label_stack.
 	(expand_eh_region_end): Rethrow from outer_context here.
	(expand_fixup_region_end): Let expand_eh_region_end do the rethrow.
	(expand_internal_throw): Take no args.
	(expand_internal_throw_indirect): Lose.
	(expand_leftover_cleanups, expand_start_all_catch): Use expand_rethrow.
	(expand_start_all_catch): Start a rethrow region.
	(expand_end_all_catch): End it.
	(expand_rethrow): New fn.
	* except.h: Reflect above changes.

cp/:	* except.c (expand_end_catch_block): Lose rethrow region.
	(expand_start_catch_block): Likewise.
	(expand_end_catch_block): Don't expand_leftover_cleanups.

From-SVN: r16937
parent a1e343dd
Wed Dec 3 12:01:56 1997 Jason Merrill <jason@yorick.cygnus.com>
* libgcc2.c (__throw): Use __builtin_return_addr instead of __eh_pc.
* except.c: Lose outer_context_label_stack.
(expand_eh_region_end): Rethrow from outer_context here.
(expand_fixup_region_end): Let expand_eh_region_end do the rethrow.
(expand_internal_throw): Take no args.
(expand_internal_throw_indirect): Lose.
(expand_leftover_cleanups, expand_start_all_catch): Use expand_rethrow.
(expand_start_all_catch): Start a rethrow region.
(expand_end_all_catch): End it.
(expand_rethrow): New fn.
* except.h: Reflect above changes.
* flow.c: Revert change of Nov 27.
Thu Dec 4 00:24:09 1997 Jeffrey A Law (law@cygnus.com) Thu Dec 4 00:24:09 1997 Jeffrey A Law (law@cygnus.com)
* i386/t-sol2 (CRTSTUFF_T_CFLAGS): Turn on the optimizer. * i386/t-sol2 (CRTSTUFF_T_CFLAGS): Turn on the optimizer.
......
...@@ -280,7 +280,7 @@ LIBGCC2 = libgcc2.a ...@@ -280,7 +280,7 @@ LIBGCC2 = libgcc2.a
# #
# -fexceptions is necessary for eh.o now that the exceptions are # -fexceptions is necessary for eh.o now that the exceptions are
# the default for g++ only. # the default for g++ only.
LIBGCC2_DEBUG_CFLAGS = -g1 LIBGCC2_DEBUG_CFLAGS = -g
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -fexceptions @inhibit_libc@ LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -fexceptions @inhibit_libc@
# Additional options to use when compiling libgcc2.a. # Additional options to use when compiling libgcc2.a.
......
Wed Dec 3 20:02:39 1997 Jason Merrill <jason@yorick.cygnus.com>
* except.c (expand_end_catch_block): Lose rethrow region.
(expand_start_catch_block): Likewise.
(expand_end_catch_block): Don't expand_leftover_cleanups.
Wed Dec 3 13:24:04 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> Wed Dec 3 13:24:04 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
* pt.c (tsubst): Remove tree_cons call (places redundant info into * pt.c (tsubst): Remove tree_cons call (places redundant info into
......
...@@ -185,10 +185,13 @@ static tree Unwind; ...@@ -185,10 +185,13 @@ static tree Unwind;
========================================================================= */ ========================================================================= */
#ifndef DWARF2_UNWIND_INFO
/* Holds the pc for doing "throw" */ /* Holds the pc for doing "throw" */
static tree saved_pc; static tree saved_pc;
extern int throw_used; extern int throw_used;
#endif
extern rtx catch_clauses; extern rtx catch_clauses;
extern tree const_ptr_type_node; extern tree const_ptr_type_node;
...@@ -255,12 +258,14 @@ init_exception_processing () ...@@ -255,12 +258,14 @@ init_exception_processing ()
pop_lang_context (); pop_lang_context ();
#ifndef DWARF2_UNWIND_INFO
d = build_decl (VAR_DECL, get_identifier ("__eh_pc"), ptr_type_node); d = build_decl (VAR_DECL, get_identifier ("__eh_pc"), ptr_type_node);
TREE_PUBLIC (d) = 1; TREE_PUBLIC (d) = 1;
DECL_EXTERNAL (d) = 1; DECL_EXTERNAL (d) = 1;
DECL_ARTIFICIAL (d) = 1; DECL_ARTIFICIAL (d) = 1;
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);
saved_pc = d; saved_pc = d;
#endif
/* If we use setjmp/longjmp EH, arrange for all cleanup actions to /* If we use setjmp/longjmp EH, arrange for all cleanup actions to
be protected with __terminate. */ be protected with __terminate. */
...@@ -520,17 +525,6 @@ expand_start_catch_block (declspecs, declarator) ...@@ -520,17 +525,6 @@ expand_start_catch_block (declspecs, declarator)
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
/* If we are not doing setjmp/longjmp EH, because we are reordered
out of line, we arrange to rethrow in the outer context so as to
skip through the terminate region we are nested in, should we
encounter an exception in the catch handler. We also need to do
this because we are not physically within the try block, if any,
that contains this catch block.
Matches the end in expand_end_catch_block. */
if (! exceptions_via_longjmp)
expand_eh_region_start ();
/* Create a binding level for the eh_info and the exception object /* Create a binding level for the eh_info and the exception object
cleanup. */ cleanup. */
pushlevel (0); pushlevel (0);
...@@ -655,36 +649,11 @@ expand_end_catch_block () ...@@ -655,36 +649,11 @@ expand_end_catch_block ()
expand_end_bindings (getdecls (), kept_level_p (), 0); expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
if (! exceptions_via_longjmp)
{
/* If we are not doing setjmp/longjmp EH, we need an extra
region around the whole catch block to skip through the
terminate region we are nested in. */
tree t = make_node (RTL_EXPR);
TREE_TYPE (t) = void_type_node;
RTL_EXPR_RTL (t) = const0_rtx;
TREE_SIDE_EFFECTS (t) = 1;
do_pending_stack_adjust ();
start_sequence_for_rtl_expr (t);
expand_internal_throw (outer_context_label_stack->u.rlabel);
do_pending_stack_adjust ();
RTL_EXPR_SEQUENCE (t) = get_insns ();
end_sequence ();
/* For the rethrow region. */
expand_eh_region_end (t);
}
/* Fall to outside the try statement when done executing handler and /* Fall to outside the try statement when done executing handler and
we fall off end of handler. This is jump Lresume in the we fall off end of handler. This is jump Lresume in the
documentation. */ documentation. */
expand_goto (top_label_entry (&caught_return_label_stack)); expand_goto (top_label_entry (&caught_return_label_stack));
expand_leftover_cleanups ();
/* label we emit to jump to if this catch block didn't match. */ /* label we emit to jump to if this catch block didn't match. */
/* This the closing } in the `if (eq) {' of the documentation. */ /* This the closing } in the `if (eq) {' of the documentation. */
emit_label (pop_label_entry (&false_label_stack)); emit_label (pop_label_entry (&false_label_stack));
...@@ -1318,18 +1287,7 @@ expand_throw (exp) ...@@ -1318,18 +1287,7 @@ expand_throw (exp)
expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL); expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
} }
if (exceptions_via_longjmp) expand_internal_throw ();
emit_throw ();
else
{
/* This is the label that represents where in the code we were, when
we got an exception. This needs to be updated when we rethrow an
exception, so that the matching routine knows to search out. */
label = gen_label_rtx ();
emit_label (label);
expand_internal_throw (label);
}
} }
/* Build a throw expression. */ /* Build a throw expression. */
......
...@@ -417,7 +417,7 @@ int asynchronous_exceptions = 0; ...@@ -417,7 +417,7 @@ int asynchronous_exceptions = 0;
/* One to protect cleanup actions with a handler that calls /* One to protect cleanup actions with a handler that calls
__terminate, zero otherwise. */ __terminate, zero otherwise. */
int protect_cleanup_actions_with_terminate = 0; int protect_cleanup_actions_with_terminate;
/* A list of labels used for exception handlers. Created by /* A list of labels used for exception handlers. Created by
find_exception_handler_labels for the optimization passes. */ find_exception_handler_labels for the optimization passes. */
...@@ -487,21 +487,20 @@ static tree protect_list; ...@@ -487,21 +487,20 @@ static tree protect_list;
struct label_node *caught_return_label_stack = NULL; struct label_node *caught_return_label_stack = NULL;
/* Keeps track of the label used as the context of a throw to rethrow an
exception to the outer exception region. */
struct label_node *outer_context_label_stack = NULL;
/* A random data area for the front end's own use. */ /* A random data area for the front end's own use. */
struct label_node *false_label_stack = NULL; struct label_node *false_label_stack = NULL;
#ifndef DWARF2_UNWIND_INFO
/* The rtx and the tree for the saved PC value. */ /* The rtx and the tree for the saved PC value. */
rtx eh_saved_pc_rtx; rtx eh_saved_pc_rtx;
tree eh_saved_pc; tree eh_saved_pc;
#endif
rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx)); rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
static void expand_rethrow PROTO((rtx));
/* Various support routines to manipulate the various data structures /* Various support routines to manipulate the various data structures
used by the exception handling code. */ used by the exception handling code. */
...@@ -1097,7 +1096,9 @@ expand_eh_region_end (handler) ...@@ -1097,7 +1096,9 @@ expand_eh_region_end (handler)
note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END); note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
NOTE_BLOCK_NUMBER (note) NOTE_BLOCK_NUMBER (note)
= CODE_LABEL_NUMBER (entry->exception_handler_label); = CODE_LABEL_NUMBER (entry->exception_handler_label);
if (exceptions_via_longjmp == 0) if (exceptions_via_longjmp == 0
/* We share outer_context between regions; only emit it once. */
&& INSN_UID (entry->outer_context) == 0)
{ {
rtx label; rtx label;
...@@ -1107,14 +1108,8 @@ expand_eh_region_end (handler) ...@@ -1107,14 +1108,8 @@ expand_eh_region_end (handler)
/* Emit a label marking the end of this exception region that /* Emit a label marking the end of this exception region that
is used for rethrowing into the outer context. */ is used for rethrowing into the outer context. */
emit_label (entry->outer_context); emit_label (entry->outer_context);
expand_internal_throw ();
/* Put in something that takes up space, as otherwise the end
address for this EH region could have the exact same address as
its outer region. This would cause us to miss the fact that
resuming exception handling with this PC value would be inside
the outer region. */
emit_insn (gen_nop ());
emit_barrier ();
emit_label (label); emit_label (label);
} }
...@@ -1159,9 +1154,7 @@ void ...@@ -1159,9 +1154,7 @@ void
expand_fixup_region_end (cleanup) expand_fixup_region_end (cleanup)
tree cleanup; tree cleanup;
{ {
tree t;
struct eh_node *node; struct eh_node *node;
int yes;
if (! doing_eh (0) || exceptions_via_longjmp) if (! doing_eh (0) || exceptions_via_longjmp)
return; return;
...@@ -1174,20 +1167,10 @@ expand_fixup_region_end (cleanup) ...@@ -1174,20 +1167,10 @@ expand_fixup_region_end (cleanup)
if (node == 0) if (node == 0)
abort (); abort ();
yes = suspend_momentary (); ehstack.top->entry->outer_context = node->entry->outer_context;
t = build (RTL_EXPR, void_type_node, NULL_RTX, const0_rtx);
TREE_SIDE_EFFECTS (t) = 1;
do_pending_stack_adjust ();
start_sequence_for_rtl_expr (t);
expand_internal_throw (node->entry->outer_context);
do_pending_stack_adjust ();
RTL_EXPR_SEQUENCE (t) = get_insns ();
end_sequence ();
resume_momentary (yes); /* Just rethrow. size_zero_node is just a NOP. */
expand_eh_region_end (size_zero_node);
expand_eh_region_end (t);
} }
/* If we are using the setjmp/longjmp EH codegen method, we emit a /* If we are using the setjmp/longjmp EH codegen method, we emit a
...@@ -1225,27 +1208,23 @@ emit_throw () ...@@ -1225,27 +1208,23 @@ emit_throw ()
emit_barrier (); emit_barrier ();
} }
/* An internal throw with an indirect CONTEXT we want to throw from. /* Throw the current exception. If appropriate, this is done by jumping
CONTEXT evaluates to the context of the throw. */ to the next handler. */
static void
expand_internal_throw_indirect (context)
rtx context;
{
assemble_external (eh_saved_pc);
emit_move_insn (eh_saved_pc_rtx, context);
emit_throw ();
}
/* An internal throw with a direct CONTEXT we want to throw from.
CONTEXT must be a label; its address will be used as the context of
the throw. */
void void
expand_internal_throw (context) expand_internal_throw ()
rtx context;
{ {
expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context)); #ifndef DWARF2_UNWIND_INFO
if (! exceptions_via_longjmp)
{
rtx label = gen_label_rtx ();
emit_label (label);
label = gen_rtx (LABEL_REF, Pmode, label);
assemble_external (eh_saved_pc);
emit_move_insn (eh_saved_pc_rtx, label);
}
#endif
emit_throw ();
} }
/* Called from expand_exception_blocks and expand_end_catch_block to /* Called from expand_exception_blocks and expand_end_catch_block to
...@@ -1284,19 +1263,9 @@ expand_leftover_cleanups () ...@@ -1284,19 +1263,9 @@ expand_leftover_cleanups ()
prev = get_last_insn (); prev = get_last_insn ();
if (prev == NULL || GET_CODE (prev) != BARRIER) if (prev == NULL || GET_CODE (prev) != BARRIER)
{ /* Emit code to throw to the outer context if we fall off
if (exceptions_via_longjmp) the end of the handler. */
emit_throw (); expand_rethrow (entry->outer_context);
else
{
/* The below can be optimized away, and we could just
fall into the next EH handler, if we are certain they
are nested. */
/* Emit code to throw to the outer context if we fall off
the end of the handler. */
expand_internal_throw (entry->outer_context);
}
}
do_pending_stack_adjust (); do_pending_stack_adjust ();
free (entry); free (entry);
...@@ -1325,12 +1294,12 @@ expand_start_all_catch () ...@@ -1325,12 +1294,12 @@ expand_start_all_catch ()
{ {
struct eh_entry *entry; struct eh_entry *entry;
tree label; tree label;
rtx outer_context;
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
push_label_entry (&outer_context_label_stack, outer_context = ehstack.top->entry->outer_context;
ehstack.top->entry->outer_context, NULL_TREE);
/* End the try block. */ /* End the try block. */
expand_eh_region_end (integer_zero_node); expand_eh_region_end (integer_zero_node);
...@@ -1342,16 +1311,6 @@ expand_start_all_catch () ...@@ -1342,16 +1311,6 @@ expand_start_all_catch ()
This is Lresume in the documention. */ This is Lresume in the documention. */
expand_label (label); expand_label (label);
if (exceptions_via_longjmp == 0)
{
/* Put in something that takes up space, as otherwise the end
address for the EH region could have the exact same address as
the outer region, causing us to miss the fact that resuming
exception handling with this PC value would be inside the outer
region. */
emit_insn (gen_nop ());
}
/* Push the label that points to where normal flow is resumed onto /* Push the label that points to where normal flow is resumed onto
the top of the label stack. */ the top of the label stack. */
push_label_entry (&caught_return_label_stack, NULL_RTX, label); push_label_entry (&caught_return_label_stack, NULL_RTX, label);
...@@ -1402,25 +1361,24 @@ expand_start_all_catch () ...@@ -1402,25 +1361,24 @@ expand_start_all_catch ()
prev = get_last_insn (); prev = get_last_insn ();
if (prev == NULL || GET_CODE (prev) != BARRIER) if (prev == NULL || GET_CODE (prev) != BARRIER)
{ /* Code to throw out to outer context when we fall off end
if (exceptions_via_longjmp) of the handler. We can't do this here for catch blocks,
emit_throw (); so it's done in expand_end_all_catch instead. */
else expand_rethrow (entry->outer_context);
{
/* Code to throw out to outer context when we fall off end
of the handler. We can't do this here for catch blocks,
so it's done in expand_end_all_catch instead.
The below can be optimized away (and we could just fall
into the next EH handler) if we are certain they are
nested. */
expand_internal_throw (entry->outer_context);
}
}
do_pending_stack_adjust (); do_pending_stack_adjust ();
free (entry); free (entry);
} }
/* If we are not doing setjmp/longjmp EH, because we are reordered
out of line, we arrange to rethrow in the outer context. We need to
do this because we are not physically within the region, if any, that
logically contains this catch block. */
if (! exceptions_via_longjmp)
{
expand_eh_region_start ();
ehstack.top->entry->outer_context = outer_context;
}
} }
/* Finish up the catch block. At this point all the insns for the /* Finish up the catch block. At this point all the insns for the
...@@ -1432,27 +1390,26 @@ expand_start_all_catch () ...@@ -1432,27 +1390,26 @@ expand_start_all_catch ()
void void
expand_end_all_catch () expand_end_all_catch ()
{ {
rtx new_catch_clause; rtx new_catch_clause, outer_context;
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
if (exceptions_via_longjmp) outer_context = ehstack.top->entry->outer_context;
emit_throw (); if (! exceptions_via_longjmp)
else /* Finish the rethrow region. size_zero_node is just a NOP. */
{ expand_eh_region_end (size_zero_node);
/* Code to throw out to outer context, if we fall off end of catch
handlers. This is rethrow (Lresume, same id, same obj) in the /* Code to throw out to outer context, if we fall off end of catch
documentation. We use Lresume because we know that it will throw handlers. This is rethrow (Lresume, same id, same obj) in the
to the correct context. documentation. We use Lresume because we know that it will throw
to the correct context.
In other words, if the catch handler doesn't exit or return, we
do a "throw" (using the address of Lresume as the point being
thrown from) so that the outer EH region can then try to process
the exception. */
expand_internal_throw (outer_context_label_stack->u.rlabel); In other words, if the catch handler doesn't exit or return, we
} do a "throw" (using the address of Lresume as the point being
thrown from) so that the outer EH region can then try to process
the exception. */
expand_rethrow (outer_context);
/* Now we have the complete catch sequence. */ /* Now we have the complete catch sequence. */
new_catch_clause = get_insns (); new_catch_clause = get_insns ();
...@@ -1461,7 +1418,6 @@ expand_end_all_catch () ...@@ -1461,7 +1418,6 @@ expand_end_all_catch ()
/* This level of catch blocks is done, so set up the successful /* This level of catch blocks is done, so set up the successful
catch jump label for the next layer of catch blocks. */ catch jump label for the next layer of catch blocks. */
pop_label_entry (&caught_return_label_stack); pop_label_entry (&caught_return_label_stack);
pop_label_entry (&outer_context_label_stack);
/* Add the new sequence of catches to the main one for this function. */ /* Add the new sequence of catches to the main one for this function. */
push_to_sequence (catch_clauses); push_to_sequence (catch_clauses);
...@@ -1472,6 +1428,18 @@ expand_end_all_catch () ...@@ -1472,6 +1428,18 @@ expand_end_all_catch ()
/* Here we fall through into the continuation code. */ /* Here we fall through into the continuation code. */
} }
/* Rethrow from the outer context LABEL. */
static void
expand_rethrow (label)
rtx label;
{
if (exceptions_via_longjmp)
emit_throw ();
else
emit_jump (label);
}
/* End all the pending exception regions on protect_list. The handlers /* End all the pending exception regions on protect_list. The handlers
will be emitted when expand_leftover_cleanups is invoked. */ will be emitted when expand_leftover_cleanups is invoked. */
...@@ -2006,11 +1974,13 @@ init_eh () ...@@ -2006,11 +1974,13 @@ init_eh ()
current context is saved. */ current context is saved. */
tree type = build_pointer_type (make_node (VOID_TYPE)); tree type = build_pointer_type (make_node (VOID_TYPE));
#ifndef DWARF2_UNWIND_INFO
eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type); eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
DECL_EXTERNAL (eh_saved_pc) = 1; DECL_EXTERNAL (eh_saved_pc) = 1;
TREE_PUBLIC (eh_saved_pc) = 1; TREE_PUBLIC (eh_saved_pc) = 1;
make_decl_rtl (eh_saved_pc, NULL_PTR, 1); make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
eh_saved_pc_rtx = DECL_RTL (eh_saved_pc); eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
#endif
} }
/* Initialize the per-function EH information. */ /* Initialize the per-function EH information. */
......
...@@ -192,10 +192,9 @@ extern void add_partial_entry PROTO((tree handler)); ...@@ -192,10 +192,9 @@ extern void add_partial_entry PROTO((tree handler));
extern void end_protect_partials PROTO((void)); extern void end_protect_partials PROTO((void));
/* An internal throw with a direct CONTEXT we want to throw /* An internal throw. */
from. CONTEXT must be a label. */
extern void expand_internal_throw PROTO((rtx context)); extern void expand_internal_throw PROTO((void));
/* Called from expand_exception_blocks and expand_end_catch_block to /* Called from expand_exception_blocks and expand_end_catch_block to
expand and pending handlers. */ expand and pending handlers. */
...@@ -227,11 +226,6 @@ extern void check_exception_handler_labels PROTO((void)); ...@@ -227,11 +226,6 @@ extern void check_exception_handler_labels PROTO((void));
extern struct label_node *caught_return_label_stack; extern struct label_node *caught_return_label_stack;
/* Keeps track of the label used as the context of a throw to rethrow an
exception to the outer exception region. */
extern struct label_node *outer_context_label_stack;
/* A random area used for purposes elsewhere. */ /* A random area used for purposes elsewhere. */
extern struct label_node *false_label_stack; extern struct label_node *false_label_stack;
......
...@@ -472,15 +472,10 @@ find_basic_blocks (f, nonlocal_label_list) ...@@ -472,15 +472,10 @@ find_basic_blocks (f, nonlocal_label_list)
/* If we encounter a CALL_INSN, note which exception handler it /* If we encounter a CALL_INSN, note which exception handler it
might pass control to. might pass control to.
Because we do rethrows by loading the address of a label into
__eh_pc and throwing, we need to treat labels as potentially
jumping to exception handlers.
If doing asynchronous exceptions, record the active EH handler If doing asynchronous exceptions, record the active EH handler
for every insn, since most insns can throw. */ for every insn, since most insns can throw. */
else if (eh_note else if (eh_note
&& (asynchronous_exceptions && (asynchronous_exceptions
|| code == CODE_LABEL
|| (GET_CODE (insn) == CALL_INSN || (GET_CODE (insn) == CALL_INSN
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))) && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))))
active_eh_handler[INSN_UID (insn)] = XEXP (eh_note, 0); active_eh_handler[INSN_UID (insn)] = XEXP (eh_note, 0);
...@@ -574,11 +569,7 @@ find_basic_blocks (f, nonlocal_label_list) ...@@ -574,11 +569,7 @@ find_basic_blocks (f, nonlocal_label_list)
associated insns aren't marked dead, so we make associated insns aren't marked dead, so we make
the block in question live and create an edge from the block in question live and create an edge from
this insn to the label. This is not strictly this insn to the label. This is not strictly
correct, but it is close enough for now. correct, but it is close enough for now. */
We also need to mark the CODE_LABEL as reaching
its exception handler for nested exceptions to
to work. */
for (note = REG_NOTES (insn); for (note = REG_NOTES (insn);
note; note;
note = XEXP (note, 1)) note = XEXP (note, 1))
...@@ -590,14 +581,6 @@ find_basic_blocks (f, nonlocal_label_list) ...@@ -590,14 +581,6 @@ find_basic_blocks (f, nonlocal_label_list)
mark_label_ref (gen_rtx (LABEL_REF, mark_label_ref (gen_rtx (LABEL_REF,
VOIDmode, x), VOIDmode, x),
insn, 0); insn, 0);
/* If the CODE_LABEL has an active exception
handler, then make an edge to the exception
handler from this insn. */
if (active_eh_handler[INSN_UID (x)])
mark_label_ref (gen_rtx (LABEL_REF, VOIDmode,
active_eh_handler[INSN_UID (x)]),
insn, 0);
} }
} }
......
...@@ -3154,8 +3154,6 @@ __sjpopnthrow () ...@@ -3154,8 +3154,6 @@ __sjpopnthrow ()
/* This value identifies the place from which an exception is being /* This value identifies the place from which an exception is being
thrown. */ thrown. */
void *__eh_pc;
#ifdef EH_TABLE_LOOKUP #ifdef EH_TABLE_LOOKUP
EH_TABLE_LOOKUP EH_TABLE_LOOKUP
...@@ -3212,6 +3210,8 @@ find_exception_handler (void *pc, exception_table *table) ...@@ -3212,6 +3210,8 @@ find_exception_handler (void *pc, exception_table *table)
/* Support code for exception handling using inline unwinders or /* Support code for exception handling using inline unwinders or
__unwind_function. */ __unwind_function. */
void *__eh_pc;
#ifndef EH_TABLE_LOOKUP #ifndef EH_TABLE_LOOKUP
typedef struct exception_table_node { typedef struct exception_table_node {
exception_table *table; exception_table *table;
...@@ -3489,7 +3489,7 @@ in_reg_window (int reg, frame_state *udata) ...@@ -3489,7 +3489,7 @@ in_reg_window (int reg, frame_state *udata)
void void
__throw () __throw ()
{ {
void *pc, *handler, *retaddr; void *pc, *handler, *retaddr, *__eh_pc;
frame_state ustruct, ustruct2; frame_state ustruct, ustruct2;
frame_state *udata = &ustruct; frame_state *udata = &ustruct;
frame_state *sub_udata = &ustruct2; frame_state *sub_udata = &ustruct2;
...@@ -3524,6 +3524,7 @@ label: ...@@ -3524,6 +3524,7 @@ label:
__builtin_unwind_init (); __builtin_unwind_init ();
/* Now reset pc to the right throw point. */ /* Now reset pc to the right throw point. */
__eh_pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
pc = __eh_pc; pc = __eh_pc;
handler = 0; handler = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment