diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-12-04 09:41:38 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-12-04 09:41:38 +0000 |
commit | 23ceb7b213c83177de7ebc9e593a91529d2066ad (patch) | |
tree | 952b95458e119610c40fb72e6d852f3a40843ba5 /gcc | |
parent | 639bdbf65ea3f0bed4f4b5f9760720101cbcc0e9 (diff) | |
download | gcc-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/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/except.c | 54 | ||||
-rw-r--r-- | gcc/except.c | 178 | ||||
-rw-r--r-- | gcc/except.h | 10 | ||||
-rw-r--r-- | gcc/flow.c | 19 | ||||
-rw-r--r-- | gcc/libgcc2.c | 7 |
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; |