flow.c (delete_dead_jumptables): New function.
authorJan Hubicka <jh@suse.cz>
Wed, 25 Jul 2001 20:51:24 +0000 (22:51 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 25 Jul 2001 20:51:24 +0000 (20:51 +0000)
* flow.c (delete_dead_jumptables): New function.
(life_analyzis): Call it.
* bb-reorder.c (skip_insns_after_block): Handle contradictive sequences.

From-SVN: r44365

gcc/ChangeLog
gcc/bb-reorder.c
gcc/flow.c

index 973a821b3c4d9eba9d9fd82b3f92370c84d7ca33..9eb513e515a44c8169a932561ce033332ff41ee2 100644 (file)
@@ -1,3 +1,9 @@
+Wed Jul 25 22:48:59 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * flow.c (delete_dead_jumptables): New function.
+       (life_analyzis): Call it.
+       * bb-reorder.c (skip_insns_after_block): Handle contradictive sequences.
+
 2001-07-25  Richard Henderson  <rth@redhat.com>
 
        * except.c (reachable_handlers): Handle a region being removed
index e2dc44c5053399e3dc4b66333dd9bd384fa587cd..e1b341755b1b62a19b989cc4f52e2b8c59bd2871 100644 (file)
@@ -205,7 +205,7 @@ static rtx
 skip_insns_after_block (bb)
      basic_block bb;
 {
-  rtx insn, last_insn, next_head;
+  rtx insn, last_insn, next_head, prev;
 
   next_head = NULL_RTX;
   if (bb->index + 1 != n_basic_blocks)
@@ -234,12 +234,7 @@ skip_insns_after_block (bb)
              continue;
 
            default:
-             /* Make line notes attached to the succesor block unless they
-                are followed by something attached to predecesor block.
-                These notes remained after removing code in the predecesor
-                block and thus should be kept together.  */
-             if (NOTE_LINE_NUMBER (insn) >= 0)
-               continue;
+             continue;
              break;
            }
          break;
@@ -262,6 +257,32 @@ skip_insns_after_block (bb)
 
       break;
     }
+  /* It is possible to hit contradicting sequence.  For instance:
+    
+     jump_insn
+     NOTE_INSN_LOOP_BEG
+     barrier
+
+     Where barrier belongs to jump_insn, but the note does not.
+     This can be created by removing the basic block originally
+     following NOTE_INSN_LOOP_BEG.
+
+     In such case reorder the notes.  */
+  for (insn = last_insn; insn != bb->end; insn = prev)
+    {
+    prev = PREV_INSN (insn);
+    if (GET_CODE (insn) == NOTE)
+      switch (NOTE_LINE_NUMBER (insn))
+        {
+          case NOTE_INSN_LOOP_END:
+          case NOTE_INSN_BLOCK_END:
+          case NOTE_INSN_DELETED:
+          case NOTE_INSN_DELETED_LABEL:
+       continue;
+          default:
+       reorder_insns (insn, insn, last_insn);
+        }
+    }
 
   return last_insn;
 }
index 67a2db559f254ff7aac7c25e8c6ecfb7a9309ac0..529eb00ddf03e2b29372b6dff23ab63df5e24702 100644 (file)
@@ -481,6 +481,7 @@ static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
 static void flow_loops_tree_build      PARAMS ((struct loops *));
 static int flow_loop_level_compute     PARAMS ((struct loop *, int));
 static int flow_loops_level_compute    PARAMS ((struct loops *));
+static void delete_dead_jumptables     PARAMS ((void));
 \f
 /* Find basic blocks of the current function.
    F is the first insn of the function and NREGS the number of register
@@ -4081,6 +4082,8 @@ life_analysis (f, file, flags)
       }
   }
 #endif
+  /* Removing dead insns should've made jumptables really dead.  */
+  delete_dead_jumptables ();
 }
 
 /* A subroutine of verify_wide_reg, called through for_each_rtx.
@@ -4334,6 +4337,32 @@ delete_noop_moves (f)
     }
 }
 
+/* Delete any jump tables never referenced.  We can't delete them at the
+   time of removing tablejump insn as they are referenced by the preceeding
+   insns computing the destination, so we delay deleting and garbagecollect
+   them once life information is computed.  */
+static void
+delete_dead_jumptables ()
+{
+  rtx insn, next;
+  for (insn = get_insns (); insn; insn = next)
+    {
+      next = NEXT_INSN (insn);
+      if (GET_CODE (insn) == CODE_LABEL
+         && LABEL_NUSES (insn) == 0
+         && GET_CODE (next) == JUMP_INSN
+         && (GET_CODE (PATTERN (next)) == ADDR_VEC
+             || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+       {
+         if (rtl_dump_file)
+           fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
+         flow_delete_insn (NEXT_INSN (insn));
+         flow_delete_insn (insn);
+         next = NEXT_INSN (next);
+       }
+    }
+}
+
 /* Determine if the stack pointer is constant over the life of the function.
    Only useful before prologues have been emitted.  */
 
@@ -7956,7 +7985,7 @@ set_block_for_new_insns (insn, bb)
 
    - test head/end pointers
    - overlapping of basic blocks
-   - edge list corectness
+   - edge list correctness
    - headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
    - tails of basic blocks (ensure that boundary is necesary)
    - scans body of the basic block for JUMP_INSN, CODE_LABEL
@@ -8031,8 +8060,9 @@ verify_flow_info ()
   for (i = n_basic_blocks - 1; i >= 0; i--)
     {
       basic_block bb = BASIC_BLOCK (i);
-      /* Check corectness of edge lists */
+      /* Check correctness of edge lists. */
       edge e;
+      int has_fallthru = 0;
 
       e = bb->succ;
       while (e)
@@ -8045,17 +8075,31 @@ verify_flow_info ()
            }
          last_visited [e->dest->index + 2] = bb;
 
+         if (e->flags & EDGE_FALLTHRU)
+           has_fallthru = 1;
+
          if ((e->flags & EDGE_FALLTHRU)
              && e->src != ENTRY_BLOCK_PTR
-             && e->dest != EXIT_BLOCK_PTR
-             && (e->src->index + 1 != e->dest->index
-                 || !can_fallthru (e->src, e->dest)))
+             && e->dest != EXIT_BLOCK_PTR)
            {
-             error ("verify_flow_info: Incorrect fallthru edge %i->%i",
-                    e->src->index, e->dest->index);
-             err = 1;
+             rtx insn;
+             if (e->src->index + 1 != e->dest->index)
+               {
+                   error ("verify_flow_info: Incorrect blocks for fallthru %i->%i",
+                          e->src->index, e->dest->index);
+                   err = 1;
+               }
+             else
+               for (insn = NEXT_INSN (e->src->end); insn != e->dest->head;
+                    insn = NEXT_INSN (insn))
+                 if (GET_CODE (insn) == BARRIER || INSN_P (insn))
+                   {
+                     error ("verify_flow_info: Incorrect fallthru %i->%i",
+                            e->src->index, e->dest->index);
+                     fatal_insn ("Wrong insn in the fallthru edge", insn);
+                     err = 1;
+                   }
            }
-           
          if (e->src != bb)
            {
              error ("verify_flow_info: Basic block %d succ edge is corrupted",
@@ -8080,6 +8124,21 @@ verify_flow_info ()
            }
          e = e->succ_next;
        }
+      if (!has_fallthru)
+       {
+         rtx insn = bb->end;
+
+         /* Ensure existence of barrier in BB with no fallthru edges.  */
+         for (insn = bb->end; GET_CODE (insn) != BARRIER;
+              insn = NEXT_INSN (insn))
+           if (!insn
+               || (GET_CODE (insn) == NOTE
+                   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
+               {
+                 error ("Missing barrier after block %i", bb->index);
+                 err = 1;
+               }
+       }
 
       e = bb->pred;
       while (e)