diff options
author | Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> | 1998-09-09 21:48:42 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-09-09 15:48:42 -0600 |
commit | c708eef9868f06b0e70b98da9c440244b23dfb7b (patch) | |
tree | 7c1fc5c74cfa08035d86375a446d67f690e81e06 /gcc/flow.c | |
parent | e1e837810ee2bbfa22c4529a11ebc3a3a66aafbb (diff) | |
download | gcc-c708eef9868f06b0e70b98da9c440244b23dfb7b.zip gcc-c708eef9868f06b0e70b98da9c440244b23dfb7b.tar.gz gcc-c708eef9868f06b0e70b98da9c440244b23dfb7b.tar.bz2 |
except.h (current_function_eh_stub_label): Declare.
* 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.
From-SVN: r22369
Diffstat (limited to 'gcc/flow.c')
-rw-r--r-- | gcc/flow.c | 30 |
1 files changed, 26 insertions, 4 deletions
@@ -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); + } } } |