diff options
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/except.c | 16 | ||||
-rw-r--r-- | gcc/except.h | 7 | ||||
-rw-r--r-- | gcc/flow.c | 30 | ||||
-rw-r--r-- | gcc/function.h | 2 |
5 files changed, 67 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af6291d8423..ccb15b3f1e8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,22 @@ Wed Sep 9 21:58:41 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> + * except.h (current_function_eh_stub_label): Declare. + (current_function_eh_old_stub_label): Declare. + * function.h (struct function): New members eh_stub_label and + eh_old_stub_label. + * except.c (current_function_eh_stub_label): New variable. + (current_function_eh_old_stub_label): New variable. + (init_eh_for_function): Clear them. + (save_eh_status): Save them. + (restore_eh_status): Restore them. + (expand_builtin_eh_stub): Set current_function_eh_stub_label. + (expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label. + * flow.c (find_basic_blocks_1): When handling a REG_LABEL note, don't + make an edge from the block that contains it to the block starting + with the label if this label is one of the eh stub labels. + If eh stub labels exist, show they are reachable from the last block + in the function. + * reload1.c (reload): Break out several subroutines and make some variables global. (calculate_needs_all_insns): New function, broken out of reload. diff --git a/gcc/except.c b/gcc/except.c index 2d26e9ee9c1..5f2c61ad388 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -431,6 +431,12 @@ rtx exception_handler_labels; rtx current_function_ehc; +/* The labels generated by expand_builtin_eh_stub and + expand_builtin_eh_stub_old. */ + +rtx current_function_eh_stub_label; +rtx current_function_eh_old_stub_label; + /* A stack used for keeping track of the currently active exception handling region. As each exception region is started, an entry describing the region is pushed onto this stack. The current @@ -2148,6 +2154,8 @@ init_eh_for_function () caught_return_label_stack = 0; protect_list = NULL_TREE; current_function_ehc = NULL_RTX; + current_function_eh_stub_label = NULL_RTX; + current_function_eh_old_stub_label = NULL_RTX; } /* Save some of the per-function EH info into the save area denoted by @@ -2170,6 +2178,8 @@ save_eh_status (p) p->caught_return_label_stack = caught_return_label_stack; p->protect_list = protect_list; p->ehc = current_function_ehc; + p->eh_stub_label = current_function_eh_stub_label; + p->eh_old_stub_label = current_function_eh_old_stub_label; init_eh_for_function (); } @@ -2193,6 +2203,8 @@ restore_eh_status (p) ehstack = p->ehstack; catchstack = p->catchstack; current_function_ehc = p->ehc; + current_function_eh_stub_label = p->eh_stub_label; + current_function_eh_old_stub_label = p->eh_old_stub_label; } /* This section is for the exception handling specific optimization @@ -2502,6 +2514,8 @@ expand_builtin_eh_stub_old () rtx after_stub = gen_label_rtx (); rtx handler, offset; + current_function_eh_old_stub_label = stub_start; + emit_jump (after_stub); emit_label (stub_start); @@ -2521,6 +2535,8 @@ expand_builtin_eh_stub () rtx handler, offset; rtx temp; + current_function_eh_stub_label = stub_start; + emit_jump (after_stub); emit_label (stub_start); diff --git a/gcc/except.h b/gcc/except.h index b498a69c7e0..d20b6067cb0 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -24,6 +24,12 @@ typedef struct rtx_def *_except_rtx; #define rtx _except_rtx #endif +/* The labels generated by expand_builtin_eh_stub and + expand_builtin_eh_stub_old. */ + +extern rtx current_function_eh_stub_label; +extern rtx current_function_eh_old_stub_label; + #ifdef TREE_CODE /* A stack of labels. CHAIN points to the next entry in the stack. */ @@ -82,7 +88,6 @@ struct eh_queue { struct eh_node *tail; }; - /* Start an exception handling region. All instructions emitted after this point are considered to be part of the region until expand_eh_region_end () is invoked. */ diff --git a/gcc/flow.c b/gcc/flow.c index 715555d1804..af9eb1cde83 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -484,7 +484,9 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) { /* Make a list of all labels referred to other than by jumps. */ for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) - if (REG_NOTE_KIND (note) == REG_LABEL) + if (REG_NOTE_KIND (note) == REG_LABEL + && XEXP (note, 0) != current_function_eh_stub_label + && XEXP (note, 0) != current_function_eh_old_stub_label) label_value_list = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0), label_value_list); } @@ -589,7 +591,6 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) { if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') { - /* References to labels in non-jumping insns have REG_LABEL notes attached to them. @@ -609,12 +610,17 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) 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. */ + correct, but it is close enough for now. + + See below for code that handles the eh_stub labels + specially. */ for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) { - if (REG_NOTE_KIND (note) == REG_LABEL) + if (REG_NOTE_KIND (note) == REG_LABEL + && XEXP (note, 0) != current_function_eh_stub_label + && XEXP (note, 0) != current_function_eh_old_stub_label) { x = XEXP (note, 0); block_live[BLOCK_NUM (x)] = 1; @@ -695,6 +701,22 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p) } } } + /* We know something about the structure of the function + __throw in libgcc2.c. It is the only function that ever + contains eh_stub labels. It modifies its return address + so that the last block returns to one of the eh_stub labels + within it. So we have to make additional edges in the + flow graph. */ + if (i + 1 == n_basic_blocks + && current_function_eh_stub_label != 0) + { + mark_label_ref (gen_rtx_LABEL_REF (VOIDmode, + current_function_eh_stub_label), + basic_block_end[i], 0); + mark_label_ref (gen_rtx_LABEL_REF (VOIDmode, + current_function_eh_old_stub_label), + basic_block_end[i], 0); + } } } diff --git a/gcc/function.h b/gcc/function.h index 06e90dc88aa..786e062a487 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -142,6 +142,8 @@ struct function rtx catch_clauses; struct label_node *false_label_stack; struct label_node *caught_return_label_stack; + rtx eh_stub_label; + rtx eh_old_stub_label; tree protect_list; rtx ehc; |