aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/flow.c3
-rw-r--r--gcc/jump.c13
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c30
5 files changed, 52 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2494b89..db5281d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Mon Apr 12 03:11:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (flow_delete_insn): If we delete a CODE_LABEL, also remove
+ it from the nonlocal_goto_handler_labels list.
+ * jump.c (delete_insn): Likewise.
+ (jump_optimize_1): Also recompute LABEL_NUSES when we are just
+ marking labels.
+ * rtl.h (remove_node_from_expr_list): Declare.
+ * rtlanal.c (remove_node_from_expr_list): New function.
+
Mon Apr 12 02:37:02 1999 Jan Hubicka <hubicka@freesoft.cz>
* reg-stack.c: Update comment, include varray.h.
diff --git a/gcc/flow.c b/gcc/flow.c
index 7952965..c9bf5ab 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -1802,6 +1802,9 @@ flow_delete_insn (insn)
else
set_last_insn (prev);
+ if (GET_CODE (insn) == CODE_LABEL)
+ remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+
/* If deleting a jump, decrement the use count of the label. Deleting
the label itself should happen in the normal course of block merging. */
if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
diff --git a/gcc/jump.c b/gcc/jump.c
index f961acc..9b727fa 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -210,11 +210,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
mark_all_labels (f, cross_jump);
- /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
- notes. */
- if (mark_labels_only)
- return;
-
/* Keep track of labels used from static data;
they cannot ever be deleted. */
@@ -229,6 +224,11 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
LABEL_NUSES (XEXP (insn, 0))++;
+ /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
+ notes and recompute LABEL_NUSES. */
+ if (mark_labels_only)
+ return;
+
exception_optimize ();
last_insn = delete_unreferenced_labels (f);
@@ -3922,6 +3922,9 @@ delete_insn (insn)
if (INSN_DELETED_P (insn))
return next;
+ if (was_code_label)
+ remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+
/* Don't delete user-declared labels. Convert them to special NOTEs
instead. */
if (was_code_label && LABEL_NAME (insn) != 0
diff --git a/gcc/rtl.h b/gcc/rtl.h
index ef6440c..964a8ab 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1081,6 +1081,7 @@ typedef int (*rtx_function) PROTO((rtx *, void *));
extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
extern rtx regno_use_in PROTO((int, rtx));
extern int auto_inc_p PROTO((rtx));
+extern void remove_node_from_expr_list PROTO((rtx, rtx *));
/* flow.c */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d39071b..fb4f87c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1529,6 +1529,36 @@ remove_note (insn, note)
abort ();
}
+
+/* Search LISTP (an EXPR_LIST) for NODE and remove NODE from the list
+ if it is found.
+
+ A simple equality test is used to determine if NODE is on the
+ EXPR_LIST. */
+
+void
+remove_node_from_expr_list (node, listp)
+ rtx node;
+ rtx *listp;
+{
+ rtx temp = *listp;
+ rtx prev = NULL_RTX;
+
+ while (temp)
+ {
+ if (node == XEXP (temp, 0))
+ {
+ /* Splice the node out of the list. */
+ if (prev)
+ XEXP (prev, 1) = XEXP (temp, 1);
+ else
+ *listp = XEXP (temp, 1);
+
+ return;
+ }
+ temp = XEXP (temp, 1);
+ }
+}
/* Nonzero if X contains any volatile instructions. These are instructions
which may cause unpredictable machine state instructions, and thus no