OSDN Git Service

2006-01-18 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / cfgrtl.c
index 00a219d..7652472 100644 (file)
@@ -305,7 +305,7 @@ create_basic_block_structure (rtx head, rtx end, rtx bb_note, basic_block after)
   bb->index = last_basic_block++;
   bb->flags = BB_NEW | BB_RTL;
   link_block (bb, after);
-  BASIC_BLOCK (bb->index) = bb;
+  SET_BASIC_BLOCK (bb->index, bb);
   update_bb_for_insn (bb);
   BB_SET_PARTITION (bb, BB_UNPARTITIONED);
 
@@ -328,10 +328,14 @@ rtl_create_basic_block (void *headp, void *endp, basic_block after)
   basic_block bb;
 
   /* Grow the basic block array if needed.  */
-  if ((size_t) last_basic_block >= VARRAY_SIZE (basic_block_info))
+  if ((size_t) last_basic_block >= VEC_length (basic_block, basic_block_info))
     {
+      size_t old_size = VEC_length (basic_block, basic_block_info);
       size_t new_size = last_basic_block + (last_basic_block + 3) / 4;
-      VARRAY_GROW (basic_block_info, new_size);
+      basic_block *p;
+      VEC_safe_grow (basic_block, gc, basic_block_info, new_size);
+      p = VEC_address (basic_block, basic_block_info);
+      memset (&p[old_size], 0, sizeof (basic_block) * (new_size - old_size));
     }
 
   n_basic_blocks++;
@@ -440,7 +444,8 @@ struct tree_opt_pass pass_free_cfg =
 rtx
 entry_of_function (void)
 {
-  return (n_basic_blocks ? BB_HEAD (ENTRY_BLOCK_PTR->next_bb) : get_insns ());
+  return (n_basic_blocks > NUM_FIXED_BLOCKS ? 
+         BB_HEAD (ENTRY_BLOCK_PTR->next_bb) : get_insns ());
 }
 
 /* Update insns block within BB.  */
@@ -1013,9 +1018,6 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
      by creating a basic block afterwards to redirect fallthru edge.  */
   if (e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR
       && any_condjump_p (BB_END (e->src))
-      /* When called from cfglayout, fallthru edges do not
-         necessarily go to the next block.  */
-      && e->src->next_bb == e->dest
       && JUMP_LABEL (BB_END (e->src)) == BB_HEAD (e->dest))
     {
       rtx note;
@@ -1456,16 +1458,9 @@ safe_insert_insn_on_edge (rtx insn, edge e)
   regset killed;
   rtx save_regs = NULL_RTX;
   unsigned regno;
-  int noccmode;
   enum machine_mode mode;
   reg_set_iterator rsi;
 
-#ifdef AVOID_CCMODE_COPIES
-  noccmode = true;
-#else
-  noccmode = false;
-#endif
-
   killed = ALLOC_REG_SET (&reg_obstack);
 
   for (x = insn; x; x = NEXT_INSN (x))
@@ -1491,7 +1486,8 @@ safe_insert_insn_on_edge (rtx insn, edge e)
       if (mode == VOIDmode)
        return false;
 
-      if (noccmode && mode == CCmode)
+      /* Avoid copying in CCmode if we can't.  */
+      if (!can_copy_p (mode))
        return false;
        
       save_regs = alloc_EXPR_LIST (0,
@@ -2264,7 +2260,7 @@ rtl_verify_flow_info (void)
        curr_bb = NULL;
     }
 
-  if (num_bb_notes != n_basic_blocks)
+  if (num_bb_notes != n_basic_blocks - NUM_FIXED_BLOCKS)
     internal_error
       ("number of bb notes in insn chain (%d) != n_basic_blocks (%d)",
        num_bb_notes, n_basic_blocks);
@@ -2300,23 +2296,25 @@ purge_dead_edges (basic_block bb)
   /* Cleanup abnormal edges caused by exceptions or non-local gotos.  */
   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
     {
-      /* We must check for the most restrictive condition first.  Since
-        an abnormal call edge is always an EH edge, but an EH edge is not
-        always an abnormal call edge, we must check for an abnormal call
-        edge first.  */
-      if (e->flags & EDGE_ABNORMAL_CALL)
+      /* There are three types of edges we need to handle correctly here: EH
+        edges, abnormal call EH edges, and abnormal call non-EH edges.  The
+        latter can appear when nonlocal gotos are used.  */
+      if (e->flags & EDGE_EH)
        {
-         if (CALL_P (BB_END (bb))
-             && (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
-                 || INTVAL (XEXP (note, 0)) >= 0))
+         if (can_throw_internal (BB_END (bb))
+             /* If this is a call edge, verify that this is a call insn.  */
+             && (! (e->flags & EDGE_ABNORMAL_CALL)
+                 || CALL_P (BB_END (bb))))
            {
              ei_next (&ei);
              continue;
            }
        }
-      else if (e->flags & EDGE_EH)
+      else if (e->flags & EDGE_ABNORMAL_CALL)
        {
-         if (can_throw_internal (BB_END (bb)))
+         if (CALL_P (BB_END (bb))
+             && (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
+                 || INTVAL (XEXP (note, 0)) >= 0))
            {
              ei_next (&ei);
              continue;
@@ -2917,7 +2915,7 @@ rtl_flow_call_edges_add (sbitmap blocks)
   int last_bb = last_basic_block;
   bool check_last_block = false;
 
-  if (n_basic_blocks == 0)
+  if (n_basic_blocks == NUM_FIXED_BLOCKS)
     return 0;
 
   if (! blocks)
@@ -2964,7 +2962,7 @@ rtl_flow_call_edges_add (sbitmap blocks)
      calls since there is no way that we can determine if they will
      return or not...  */
 
-  for (i = 0; i < last_bb; i++)
+  for (i = NUM_FIXED_BLOCKS; i < last_bb; i++)
     {
       basic_block bb = BASIC_BLOCK (i);
       rtx insn;