aboutsummaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorBernd Schmidt <crux@pool.informatik.rwth-aachen.de>1998-09-09 21:48:42 +0000
committerJeff Law <law@gcc.gnu.org>1998-09-09 15:48:42 -0600
commitc708eef9868f06b0e70b98da9c440244b23dfb7b (patch)
tree7c1fc5c74cfa08035d86375a446d67f690e81e06 /gcc/flow.c
parente1e837810ee2bbfa22c4529a11ebc3a3a66aafbb (diff)
downloadgcc-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.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/gcc/flow.c b/gcc/flow.c
index 715555d..af9eb1c 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);
+ }
}
}