aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>1999-10-28 20:37:37 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>1999-10-28 20:37:37 +0000
commita6092975367388a74307ea5c40eb539ad83a1fb1 (patch)
tree61d216c911f0d0d3176bf1ca4b90cc34802a10e7 /gcc
parentaf05822029866791f4fb4a241ac5f0bc529c09cf (diff)
downloadgcc-a6092975367388a74307ea5c40eb539ad83a1fb1.zip
gcc-a6092975367388a74307ea5c40eb539ad83a1fb1.tar.gz
gcc-a6092975367388a74307ea5c40eb539ad83a1fb1.tar.bz2
flow.c (propagate_block): When the last reference to a label before an ADDR_VEC is deleted because the...
* flow.c (propagate_block): When the last reference to a label before an ADDR_VEC is deleted because the reference is a dead store, delete the ADDR_VEC. From-SVN: r30247
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/flow.c34
2 files changed, 40 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5595acc..97e54f5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+Fri Oct 29 06:32:44 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * flow.c (propagate_block): When the last reference to a label
+ before an ADDR_VEC is deleted because the reference is a dead
+ store, delete the ADDR_VEC.
+
Thu Oct 28 12:28:50 1999 Richard Henderson <rth@cygnus.com>
* resource.c (find_free_register): Don't use the frame pointer
diff --git a/gcc/flow.c b/gcc/flow.c
index 9ce099f..8758ea8 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -3321,6 +3321,40 @@ propagate_block (old, first, last, significant, bnum, flags)
can cause trouble for first or last insn in a basic block. */
if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
{
+ rtx inote;
+ /* If the insn referred to a label, note that the label is
+ now less used. */
+ for (inote = REG_NOTES (insn); inote; inote = XEXP (inote, 1))
+ {
+ if (REG_NOTE_KIND (inote) == REG_LABEL)
+ {
+ rtx label = XEXP (inote, 0);
+ rtx next;
+ LABEL_NUSES (label)--;
+
+ /* If this label was attached to an ADDR_VEC, it's
+ safe to delete the ADDR_VEC. In fact, it's pretty much
+ mandatory to delete it, because the ADDR_VEC may
+ be referencing labels that no longer exist. */
+ if (LABEL_NUSES (label) == 0
+ && (next = next_nonnote_insn (label)) != NULL
+ && GET_CODE (next) == JUMP_INSN
+ && (GET_CODE (PATTERN (next)) == ADDR_VEC
+ || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ {
+ rtx pat = PATTERN (next);
+ int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
+ int len = XVECLEN (pat, diff_vec_p);
+ int i;
+ for (i = 0; i < len; i++)
+ LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
+ PUT_CODE (next, NOTE);
+ NOTE_LINE_NUMBER (next) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (next) = 0;
+ }
+ }
+ }
+
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;