summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/except.c16
-rw-r--r--gcc/except.h7
-rw-r--r--gcc/flow.c30
-rw-r--r--gcc/function.h2
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;
OpenPOWER on IntegriCloud