]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Avoid deleting labels that got put into the constant pool
authorBernd Schmidt <bernds@redhat.com>
Wed, 28 Mar 2001 09:02:18 +0000 (09:02 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Wed, 28 Mar 2001 09:02:18 +0000 (09:02 +0000)
From-SVN: r40923

gcc/ChangeLog
gcc/flow.c
gcc/jump.c
gcc/varasm.c

index 921089dda7c4cba2a7871475d8bdd6be200768ad..98efc07a0175192605874cb7b7b83419a338e433 100644 (file)
@@ -1,3 +1,14 @@
+2001-03-28  Bernd Schmidt  <bernds@redhat.com>
+
+       * flow.c (propagate_block): When trying to delete a case vector, cope
+       if its label has LABEL_PRESERVE_P set.
+       * jump.c (jump_optimize_1): Move call to delete_barrier_successors to
+       a point where JUMP_LABELS and LABEL_NUSES are set up properly.
+       (delete_barrier_successors): If deleting a table jump, delete the case
+       vector as well.
+       * varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P
+       so it won't get deleted.
+
 Tue Mar 20 18:31:48 2001  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        1999-11-30  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
index 432a990220ab552cb191e788b3e515799821b039..f3b32139541c3c4eb661f0d573332e51834d430e 100644 (file)
@@ -2744,15 +2744,23 @@ propagate_block (old, first, last, final, significant, bnum, remove_dead_code)
                {
                  if (REG_NOTE_KIND (inote) == REG_LABEL)
                    {
+                     int n_forced;
                      rtx label = XEXP (inote, 0);
                      rtx next;
                      LABEL_NUSES (label)--;
 
+                     /* The label may be forced if it has been put in the
+                        constant pool.  We can't delete it in this case, but
+                        we still must discard a jump table following it.  */
+                     n_forced = 0;
+                     if (LABEL_PRESERVE_P (label))
+                       n_forced++;
+
                      /* 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
+                     if (LABEL_NUSES (label) == n_forced
                          && (next = next_nonnote_insn (label)) != NULL
                          && GET_CODE (next) == JUMP_INSN
                          && (GET_CODE (PATTERN (next)) == ADDR_VEC
index 32eebd1eb6c0dc42320720bd0a72c4289eec261c..68f967382ed1e207f77018ead8831a6302a33d6b 100644 (file)
@@ -200,8 +200,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
   if (flag_exceptions && cross_jump)
     init_insn_eh_region (f, max_uid);
 
-  delete_barrier_successors (f);
-
   /* Leave some extra room for labels and duplicate exit test insns
      we make.  */
   max_jump_chain = max_uid * 14 / 10;
@@ -224,6 +222,8 @@ 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))++;
 
+  delete_barrier_successors (f);
+
   /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
      notes and recompute LABEL_NUSES.  */
   if (mark_labels_only)
@@ -2139,7 +2139,23 @@ delete_barrier_successors (f)
          insn = NEXT_INSN (insn);
          while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
            {
-             if (GET_CODE (insn) == NOTE
+             if (GET_CODE (insn) == JUMP_INSN)
+               {
+                 /* Detect when we're deleting a tablejump; get rid of
+                    the jump table as well.  */
+                 rtx next1 = next_nonnote_insn (insn);
+                 rtx next2 = next1 ? next_nonnote_insn (next1) : 0;
+                 if (next2 && GET_CODE (next1) == CODE_LABEL
+                     && (GET_CODE (PATTERN (next2)) == ADDR_VEC
+                         || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC))
+                   {
+                     delete_insn (insn);
+                     insn = next2;
+                   }
+                 else
+                   insn = delete_insn (insn);
+               }
+             else if (GET_CODE (insn) == NOTE
                  && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
                insn = NEXT_INSN (insn);
              else
index b93506546bcf148793d936f96cdb9244f1d2a5bf..e5df1d8b52fe93ff695808389689d4f57d3b08fc 100644 (file)
@@ -3495,6 +3495,9 @@ force_const_mem (mode, x)
          pop_obstacks ();
        }
 
+      if (GET_CODE (x) == LABEL_REF)
+       LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
 
       pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));