summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-04 09:41:38 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-04 09:41:38 +0000
commit23ceb7b213c83177de7ebc9e593a91529d2066ad (patch)
tree952b95458e119610c40fb72e6d852f3a40843ba5 /gcc
parent639bdbf65ea3f0bed4f4b5f9760720101cbcc0e9 (diff)
downloadgcc-23ceb7b213c83177de7ebc9e593a91529d2066ad.tar.gz
./: * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16937 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/except.c54
-rw-r--r--gcc/except.c178
-rw-r--r--gcc/except.h10
-rw-r--r--gcc/flow.c19
-rw-r--r--gcc/libgcc2.c7
8 files changed, 109 insertions, 182 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ec46bc2bd50..c497a759440 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+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)
* i386/t-sol2 (CRTSTUFF_T_CFLAGS): Turn on the optimizer.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5f0acfc0198..e1fe81241ad 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -280,7 +280,7 @@ LIBGCC2 = libgcc2.a
#
# -fexceptions is necessary for eh.o now that the exceptions are
# 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@
# Additional options to use when compiling libgcc2.a.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 387c9d7e63e..6b9737d6291 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+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>
* pt.c (tsubst): Remove tree_cons call (places redundant info into
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 6e7c876467f..194c17d5e7f 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -185,10 +185,13 @@ static tree Unwind;
========================================================================= */
+#ifndef DWARF2_UNWIND_INFO
/* Holds the pc for doing "throw" */
static tree saved_pc;
extern int throw_used;
+#endif
+
extern rtx catch_clauses;
extern tree const_ptr_type_node;
@@ -255,12 +258,14 @@ init_exception_processing ()
pop_lang_context ();
+#ifndef DWARF2_UNWIND_INFO
d = build_decl (VAR_DECL, get_identifier ("__eh_pc"), ptr_type_node);
TREE_PUBLIC (d) = 1;
DECL_EXTERNAL (d) = 1;
DECL_ARTIFICIAL (d) = 1;
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);
saved_pc = d;
+#endif
/* If we use setjmp/longjmp EH, arrange for all cleanup actions to
be protected with __terminate. */
@@ -520,17 +525,6 @@ expand_start_catch_block (declspecs, declarator)
if (! doing_eh (1))
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
cleanup. */
pushlevel (0);
@@ -655,36 +649,11 @@ expand_end_catch_block ()
expand_end_bindings (getdecls (), kept_level_p (), 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
we fall off end of handler. This is jump Lresume in the
documentation. */
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. */
/* This the closing } in the `if (eq) {' of the documentation. */
emit_label (pop_label_entry (&false_label_stack));
@@ -1318,18 +1287,7 @@ expand_throw (exp)
expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
- if (exceptions_via_longjmp)
- 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);
- }
+ expand_internal_throw ();
}
/* Build a throw expression. */
diff --git a/gcc/except.c b/gcc/except.c
index a493375c8ab..c37f89d9087 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -417,7 +417,7 @@ int asynchronous_exceptions = 0;
/* One to protect cleanup actions with a handler that calls
__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
find_exception_handler_labels for the optimization passes. */
@@ -487,21 +487,20 @@ static tree protect_list;
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. */
struct label_node *false_label_stack = NULL;
+#ifndef DWARF2_UNWIND_INFO
/* The rtx and the tree for the saved PC value. */
rtx eh_saved_pc_rtx;
tree eh_saved_pc;
+#endif
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
used by the exception handling code. */
@@ -1097,7 +1096,9 @@ expand_eh_region_end (handler)
note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
NOTE_BLOCK_NUMBER (note)
= 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;
@@ -1107,14 +1108,8 @@ expand_eh_region_end (handler)
/* Emit a label marking the end of this exception region that
is used for rethrowing into the 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);
}
@@ -1159,9 +1154,7 @@ void
expand_fixup_region_end (cleanup)
tree cleanup;
{
- tree t;
struct eh_node *node;
- int yes;
if (! doing_eh (0) || exceptions_via_longjmp)
return;
@@ -1174,20 +1167,10 @@ expand_fixup_region_end (cleanup)
if (node == 0)
abort ();
- yes = suspend_momentary ();
-
- 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 ();
+ ehstack.top->entry->outer_context = node->entry->outer_context;
- resume_momentary (yes);
-
- expand_eh_region_end (t);
+ /* Just rethrow. size_zero_node is just a NOP. */
+ expand_eh_region_end (size_zero_node);
}
/* If we are using the setjmp/longjmp EH codegen method, we emit a
@@ -1225,27 +1208,23 @@ emit_throw ()
emit_barrier ();
}
-/* An internal throw with an indirect CONTEXT we want to throw from.
- CONTEXT evaluates to the context of the throw. */
-
-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. */
+/* Throw the current exception. If appropriate, this is done by jumping
+ to the next handler. */
void
-expand_internal_throw (context)
- rtx context;
+expand_internal_throw ()
{
- 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
@@ -1284,19 +1263,9 @@ expand_leftover_cleanups ()
prev = get_last_insn ();
if (prev == NULL || GET_CODE (prev) != BARRIER)
- {
- if (exceptions_via_longjmp)
- emit_throw ();
- 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);
- }
- }
+ /* Emit code to throw to the outer context if we fall off
+ the end of the handler. */
+ expand_rethrow (entry->outer_context);
do_pending_stack_adjust ();
free (entry);
@@ -1325,12 +1294,12 @@ expand_start_all_catch ()
{
struct eh_entry *entry;
tree label;
+ rtx outer_context;
if (! doing_eh (1))
return;
- push_label_entry (&outer_context_label_stack,
- ehstack.top->entry->outer_context, NULL_TREE);
+ outer_context = ehstack.top->entry->outer_context;
/* End the try block. */
expand_eh_region_end (integer_zero_node);
@@ -1342,16 +1311,6 @@ expand_start_all_catch ()
This is Lresume in the documention. */
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
the top of the label stack. */
push_label_entry (&caught_return_label_stack, NULL_RTX, label);
@@ -1402,25 +1361,24 @@ expand_start_all_catch ()
prev = get_last_insn ();
if (prev == NULL || GET_CODE (prev) != BARRIER)
- {
- if (exceptions_via_longjmp)
- emit_throw ();
- else
- {
- /* 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. */
+ /* 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. */
+ expand_rethrow (entry->outer_context);
- expand_internal_throw (entry->outer_context);
- }
- }
do_pending_stack_adjust ();
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
@@ -1432,27 +1390,26 @@ expand_start_all_catch ()
void
expand_end_all_catch ()
{
- rtx new_catch_clause;
+ rtx new_catch_clause, outer_context;
if (! doing_eh (1))
return;
- if (exceptions_via_longjmp)
- emit_throw ();
- else
- {
- /* 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
- 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. */
+ outer_context = ehstack.top->entry->outer_context;
+ if (! exceptions_via_longjmp)
+ /* 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
+ documentation. We use Lresume because we know that it will throw
+ to the correct context.
- 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. */
new_catch_clause = get_insns ();
@@ -1461,7 +1418,6 @@ expand_end_all_catch ()
/* This level of catch blocks is done, so set up the successful
catch jump label for the next layer of catch blocks. */
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. */
push_to_sequence (catch_clauses);
@@ -1472,6 +1428,18 @@ expand_end_all_catch ()
/* 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
will be emitted when expand_leftover_cleanups is invoked. */
@@ -2006,11 +1974,13 @@ init_eh ()
current context is saved. */
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);
DECL_EXTERNAL (eh_saved_pc) = 1;
TREE_PUBLIC (eh_saved_pc) = 1;
make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
+#endif
}
/* Initialize the per-function EH information. */
diff --git a/gcc/except.h b/gcc/except.h
index ac46fa4478f..172bac4d904 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -192,10 +192,9 @@ extern void add_partial_entry PROTO((tree handler));
extern void end_protect_partials PROTO((void));
-/* An internal throw with a direct CONTEXT we want to throw
- from. CONTEXT must be a label. */
+/* An internal throw. */
-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
expand and pending handlers. */
@@ -227,11 +226,6 @@ extern void check_exception_handler_labels PROTO((void));
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. */
extern struct label_node *false_label_stack;
diff --git a/gcc/flow.c b/gcc/flow.c
index 8311566e9c8..ed66ce7c4ef 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -472,15 +472,10 @@ find_basic_blocks (f, nonlocal_label_list)
/* If we encounter a CALL_INSN, note which exception handler it
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
for every insn, since most insns can throw. */
else if (eh_note
&& (asynchronous_exceptions
- || code == CODE_LABEL
|| (GET_CODE (insn) == CALL_INSN
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX))))
active_eh_handler[INSN_UID (insn)] = XEXP (eh_note, 0);
@@ -574,11 +569,7 @@ find_basic_blocks (f, nonlocal_label_list)
associated insns aren't marked dead, so we make
the block in question live and create an edge from
this insn to the label. This is not strictly
- 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. */
+ correct, but it is close enough for now. */
for (note = REG_NOTES (insn);
note;
note = XEXP (note, 1))
@@ -590,14 +581,6 @@ find_basic_blocks (f, nonlocal_label_list)
mark_label_ref (gen_rtx (LABEL_REF,
VOIDmode, x),
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);
}
}
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 53af01b0e31..faa3c14cf2e 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -3154,8 +3154,6 @@ __sjpopnthrow ()
/* This value identifies the place from which an exception is being
thrown. */
-void *__eh_pc;
-
#ifdef EH_TABLE_LOOKUP
EH_TABLE_LOOKUP
@@ -3212,6 +3210,8 @@ find_exception_handler (void *pc, exception_table *table)
/* Support code for exception handling using inline unwinders or
__unwind_function. */
+void *__eh_pc;
+
#ifndef EH_TABLE_LOOKUP
typedef struct exception_table_node {
exception_table *table;
@@ -3489,7 +3489,7 @@ in_reg_window (int reg, frame_state *udata)
void
__throw ()
{
- void *pc, *handler, *retaddr;
+ void *pc, *handler, *retaddr, *__eh_pc;
frame_state ustruct, ustruct2;
frame_state *udata = &ustruct;
frame_state *sub_udata = &ustruct2;
@@ -3524,6 +3524,7 @@ label:
__builtin_unwind_init ();
/* Now reset pc to the right throw point. */
+ __eh_pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
pc = __eh_pc;
handler = 0;