OSDN Git Service

2004-09-16 Frank Ch. Eigler <fche@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfg.c
index ce0be96..b8b712b 100644 (file)
@@ -294,8 +294,7 @@ static void
 create_block_annotation (basic_block bb)
 {
   /* Verify that the tree_annotations field is clear.  */
-  if (bb->tree_annotations)
-    abort ();
+  gcc_assert (!bb->tree_annotations);
   bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
 }
 
@@ -374,8 +373,7 @@ create_bb (void *h, void *e, basic_block after)
 {
   basic_block bb;
 
-  if (e)
-    abort ();
+  gcc_assert (!e);
 
   /* Create and initialize a new basic block.  */
   bb = alloc_block ();
@@ -462,11 +460,7 @@ make_ctrl_stmt_edges (basic_block bb)
 {
   tree last = last_stmt (bb);
 
-#if defined ENABLE_CHECKING
-  if (last == NULL_TREE)
-    abort();
-#endif
-
+  gcc_assert (last);
   switch (TREE_CODE (last))
     {
     case GOTO_EXPR:
@@ -493,7 +487,7 @@ make_ctrl_stmt_edges (basic_block bb)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -507,9 +501,7 @@ make_exit_edges (basic_block bb)
 {
   tree last = last_stmt (bb), op;
 
-  if (last == NULL_TREE)
-    abort ();
-
+  gcc_assert (last);
   switch (TREE_CODE (last))
     {
     case CALL_EXPR:
@@ -555,7 +547,7 @@ make_exit_edges (basic_block bb)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -570,10 +562,8 @@ make_cond_expr_edges (basic_block bb)
   basic_block then_bb, else_bb;
   tree then_label, else_label;
 
-#if defined ENABLE_CHECKING
-  if (entry == NULL_TREE || TREE_CODE (entry) != COND_EXPR)
-    abort ();
-#endif
+  gcc_assert (entry);
+  gcc_assert (TREE_CODE (entry) == COND_EXPR);
 
   /* Entry basic blocks for each component.  */
   then_label = GOTO_DESTINATION (COND_EXPR_THEN (entry));
@@ -955,9 +945,7 @@ group_case_labels (void)
              tree base_case, base_label, base_high, type;
              base_case = TREE_VEC_ELT (labels, i);
 
-             if (! base_case)
-               abort ();
-
+             gcc_assert (base_case);
              base_label = CASE_LABEL (base_case);
 
              /* Discard cases that have the same destination as the
@@ -1080,12 +1068,8 @@ tree_merge_blocks (basic_block a, basic_block b)
   /* Ensure that B follows A.  */
   move_block_after (b, a);
 
-  if (!(a->succ->flags & EDGE_FALLTHRU))
-    abort ();
-
-  if (last_stmt (a)
-      && stmt_ends_bb_p (last_stmt (a)))
-    abort ();
+  gcc_assert (a->succ->flags & EDGE_FALLTHRU);
+  gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a)));
 
   /* Remove labels from B and set bb_for_stmt to A for other statements.  */
   for (bsi = bsi_start (b); !bsi_end_p (bsi);)
@@ -1818,6 +1802,7 @@ remove_bb (basic_block bb)
   for (i = bsi_start (bb); !bsi_end_p (i); bsi_remove (&i))
     {
       tree stmt = bsi_stmt (i);
+      release_defs (stmt);
 
       set_bb_for_stmt (stmt, NULL);
 
@@ -1964,7 +1949,7 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       taken_edge = find_taken_edge (bb, val);
@@ -2011,10 +1996,8 @@ find_taken_edge (basic_block bb, tree val)
 
   stmt = last_stmt (bb);
 
-#if defined ENABLE_CHECKING
-  if (stmt == NULL_TREE || !is_ctrl_stmt (stmt))
-    abort ();
-#endif
+  gcc_assert (stmt);
+  gcc_assert (is_ctrl_stmt (stmt));
 
   /* If VAL is a predicate of the form N RELOP N, where N is an
      SSA_NAME, we can always determine its truth value (except when
@@ -2097,8 +2080,7 @@ find_taken_edge_switch_expr (basic_block bb, tree val)
   dest_bb = label_to_block (CASE_LABEL (taken_case));
 
   e = find_edge (bb, dest_bb);
-  if (!e)
-    abort ();
+  gcc_assert (e);
   return e;
 }
 
@@ -2161,10 +2143,8 @@ phi_alternatives_equal (basic_block dest, edge e1, edge e2)
       n1 = phi_arg_from_edge (phi, e1);
       n2 = phi_arg_from_edge (phi, e2);
 
-#ifdef ENABLE_CHECKING
-      if (n1 < 0 || n2 < 0)
-       abort ();
-#endif
+      gcc_assert (n1 >= 0);
+      gcc_assert (n2 >= 0);
 
       val1 = PHI_ARG_DEF (phi, n1);
       val2 = PHI_ARG_DEF (phi, n2);
@@ -2430,11 +2410,7 @@ is_ctrl_altering_stmt (tree t)
 {
   tree call;
 
-#if defined ENABLE_CHECKING
-  if (t == NULL)
-    abort ();
-#endif
-
+  gcc_assert (t);
   call = get_call_expr_in (t);
   if (call)
     {
@@ -2556,7 +2532,7 @@ disband_implicit_edges (void)
              else if (e->flags & EDGE_FALSE_VALUE)
                COND_EXPR_ELSE (stmt) = build_empty_stmt ();
              else
-               abort ();
+               gcc_unreachable ();
              e->flags |= EDGE_FALLTHRU;
            }
 
@@ -2567,10 +2543,9 @@ disband_implicit_edges (void)
        {
          /* Remove the RETURN_EXPR if we may fall though to the exit
             instead.  */
-         if (!bb->succ
-             || bb->succ->succ_next
-             || bb->succ->dest != EXIT_BLOCK_PTR)
-           abort ();
+         gcc_assert (bb->succ);
+         gcc_assert (!bb->succ->succ_next);
+         gcc_assert (bb->succ->dest == EXIT_BLOCK_PTR);
 
          if (bb->next_bb == EXIT_BLOCK_PTR
              && !TREE_OPERAND (stmt, 0))
@@ -2594,9 +2569,7 @@ disband_implicit_edges (void)
       if (!e || e->dest == bb->next_bb)
        continue;
 
-      if (e->dest == EXIT_BLOCK_PTR)
-       abort ();
-
+      gcc_assert (e->dest != EXIT_BLOCK_PTR);
       label = tree_block_label (e->dest);
 
       stmt = build1 (GOTO_EXPR, void_type_node, label);
@@ -2694,7 +2667,9 @@ last_and_only_stmt (basic_block bb)
 void
 set_bb_for_stmt (tree t, basic_block bb)
 {
-  if (TREE_CODE (t) == STATEMENT_LIST)
+  if (TREE_CODE (t) == PHI_NODE)
+    PHI_BB (t) = bb;
+  else if (TREE_CODE (t) == STATEMENT_LIST)
     {
       tree_stmt_iterator i;
       for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
@@ -2720,14 +2695,9 @@ set_bb_for_stmt (tree t, basic_block bb)
                VARRAY_GROW (label_to_block_map, 3 * uid / 2);
            }
          else
-           {
-#ifdef ENABLE_CHECKING
-             /* We're moving an existing label.  Make sure that we've
-                removed it from the old block.  */
-             if (bb && VARRAY_BB (label_to_block_map, uid))
-               abort ();
-#endif
-           }
+           /* We're moving an existing label.  Make sure that we've
+               removed it from the old block.  */
+           gcc_assert (!bb || !VARRAY_BB (label_to_block_map, uid));
          VARRAY_BB (label_to_block_map, uid) = bb;
        }
     }
@@ -2744,7 +2714,7 @@ stmt_for_bsi (tree stmt)
     if (bsi_stmt (bsi) == stmt)
       return bsi;
 
-  abort ();
+  gcc_unreachable ();
 }
 
 /* Insert statement (or statement list) T before the statement
@@ -2926,8 +2896,7 @@ tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi,
          tree op = TREE_OPERAND (tmp, 0);
          if (!is_gimple_val (op))
            {
-             if (TREE_CODE (op) != MODIFY_EXPR)
-               abort ();
+             gcc_assert (TREE_CODE (op) == MODIFY_EXPR);
              bsi_insert_before (bsi, op, BSI_NEW_STMT);
              TREE_OPERAND (tmp, 0) = TREE_OPERAND (op, 0);
            }
@@ -3009,8 +2978,7 @@ bsi_insert_on_edge_immediate (edge e, tree stmt)
   block_stmt_iterator bsi;
   basic_block new_bb = NULL;
 
-  if (PENDING_STMT (e))
-    abort ();
+  gcc_assert (!PENDING_STMT (e));
 
   if (tree_find_edge_insert_loc (e, &bsi, &new_bb))
     bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
@@ -3036,8 +3004,7 @@ tree_split_edge (edge edge_in)
   int i, num_elem;
 
   /* Abnormal edges cannot be split.  */
-  if (edge_in->flags & EDGE_ABNORMAL)
-    abort ();
+  gcc_assert (!(edge_in->flags & EDGE_ABNORMAL));
 
   src = edge_in->src;
   dest = edge_in->dest;
@@ -3054,7 +3021,11 @@ tree_split_edge (edge edge_in)
     after_bb = edge_in->src;
 
   new_bb = create_empty_bb (after_bb);
+  new_bb->frequency = EDGE_FREQUENCY (edge_in);
+  new_bb->count = edge_in->count;
   new_edge = make_edge (new_bb, dest, EDGE_FALLTHRU);
+  new_edge->probability = REG_BR_PROB_BASE;
+  new_edge->count = edge_in->count;
 
   /* Find all the PHI arguments on the original edge, and change them to
      the new edge.  Do it before redirection, so that the argument does not
@@ -3070,11 +3041,9 @@ tree_split_edge (edge edge_in)
          }
     }
 
-  if (!redirect_edge_and_branch (edge_in, new_bb))
-    abort ();
-
-  if (PENDING_STMT (edge_in))
-    abort ();
+  e = redirect_edge_and_branch (edge_in, new_bb);
+  gcc_assert (e);
+  gcc_assert (!PENDING_STMT (edge_in));
 
   return new_bb;
 }
@@ -3305,7 +3274,7 @@ verify_stmt (tree stmt, bool last_in_block)
     {
       if (!tree_could_throw_p (stmt))
        {
-         error ("Statement marked for throw, but doesn't.");
+         error ("Statement marked for throw, but doesn%'t.");
          goto fail;
        }
       if (!last_in_block && tree_can_throw_internal (stmt))
@@ -3586,7 +3555,7 @@ tree_verify_flow_info (void)
            if (!has_label_p (true_edge->dest,
                              GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
              {
-               error ("`then' label does not match edge at end of bb %d\n",
+               error ("%<then%> label does not match edge at end of bb %d\n",
                       bb->index);
                err = 1;
              }
@@ -3594,7 +3563,7 @@ tree_verify_flow_info (void)
            if (!has_label_p (false_edge->dest,
                              GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
              {
-               error ("`else' label does not match edge at end of bb %d\n",
+               error ("%<else%> label does not match edge at end of bb %d\n",
                       bb->index);
                err = 1;
              }
@@ -3655,8 +3624,7 @@ tree_verify_flow_info (void)
                tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
                basic_block label_bb = label_to_block (lab);
 
-               if (label_bb->aux && label_bb->aux != (void *)1)
-                 abort ();
+               gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
                label_bb->aux = (void *)1;
              }
 
@@ -3891,6 +3859,8 @@ thread_jumps (void)
         forwardable.  */
       for (e = bb->succ; e; e = next)
        {
+         int freq;
+         gcov_type count;
          next = e->succ_next;
 
          /* If the edge is abnormal or its destination is not
@@ -3899,6 +3869,9 @@ thread_jumps (void)
              || !tree_forwarder_block_p (e->dest))
            continue;
 
+         count = e->count;
+         freq = EDGE_FREQUENCY (e);
+
          /* Now walk through as many forwarder block as possible to
             find the ultimate destination we want to thread our jump
             to.  */
@@ -3918,6 +3891,15 @@ thread_jumps (void)
                break;
 
              bb_ann (dest)->forwardable = 0;
+             dest->frequency -= freq;
+             if (dest->frequency < 0)
+               dest->frequency = 0;
+             dest->count -= count;
+             if (dest->count < 0)
+               dest->count = 0;
+             dest->succ->count -= count;
+             if (dest->succ->count < 0)
+               dest->succ->count = 0;
            }
 
          /* Reset the forwardable marks to 1.  */
@@ -3962,8 +3944,7 @@ thread_jumps (void)
              for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
                {
                  arg = phi_arg_from_edge (phi, last);
-                 if (arg < 0)
-                   abort ();
+                 gcc_assert (arg >= 0);
                  add_phi_arg (&phi, PHI_ARG_DEF (phi, arg), e);
                }
            }
@@ -3990,9 +3971,11 @@ thread_jumps (void)
                set_immediate_dominator (CDI_DOMINATORS, old_dest, bb);
 
              /* Now proceed like if we forwarded just over one edge at a time.
-                Algorithm for forwarding over edge A --> B then is
+                Algorithm for forwarding edge S --> A over edge A --> B then
+                is
 
-                if (idom (B) == A)
+                if (idom (B) == A
+                    && !dominated_by (S, B))
                   idom (B) = idom (A);
                 recount_idom (A);  */
 
@@ -4000,7 +3983,8 @@ thread_jumps (void)
                {
                  tmp = old_dest->succ->dest;
 
-                 if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest)
+                 if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest
+                     && !dominated_by_p (CDI_DOMINATORS, bb, tmp))
                    {
                      dom = get_immediate_dominator (CDI_DOMINATORS, old_dest);
                      set_immediate_dominator (CDI_DOMINATORS, tmp, dom);
@@ -4130,7 +4114,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
     case GOTO_EXPR:
       /* No non-abnormal edges should lead from a non-simple goto, and
         simple ones should be represented implicitly.  */
-      abort ();
+      gcc_unreachable ();
 
     case SWITCH_EXPR:
       {
@@ -4154,8 +4138,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
     default:
       /* Otherwise it must be a fallthru edge, and we don't need to
         do anything besides redirecting it.  */
-      if (!(e->flags & EDGE_FALLTHRU))
-       abort ();
+      gcc_assert (e->flags & EDGE_FALLTHRU);
       break;
     }
 
@@ -4174,8 +4157,7 @@ static basic_block
 tree_redirect_edge_and_branch_force (edge e, basic_block dest)
 {
   e = tree_redirect_edge_and_branch (e, dest);
-  if (!e)
-    abort ();
+  gcc_assert (e);
 
   return NULL;
 }
@@ -4650,8 +4632,7 @@ tree_flow_call_edges_add (sbitmap blocks)
 #ifdef ENABLE_CHECKING
                  if (stmt == last_stmt)
                    for (e = bb->succ; e; e = e->succ_next)
-                     if (e->dest == EXIT_BLOCK_PTR)
-                       abort ();
+                     gcc_assert (e->dest != EXIT_BLOCK_PTR);
 #endif
 
                  /* Note that the following may create a new basic block
@@ -4861,7 +4842,8 @@ execute_warn_function_return (void)
       && !TREE_THIS_VOLATILE (cfun->decl)
       && EXIT_BLOCK_PTR->pred == NULL
       && !lang_hooks.function.missing_noreturn_ok_p (cfun->decl))
-    warning ("%Jfunction might be possible candidate for attribute `noreturn'",
+    warning ("%Jfunction might be possible candidate for "
+            "attribute %<noreturn%>",
             cfun->decl);
 
   /* If we have a path to EXIT, then we do return.  */
@@ -4887,11 +4869,11 @@ execute_warn_function_return (void)
 #ifdef USE_MAPPED_LOCATION
       if (location == UNKNOWN_LOCATION)
        location = cfun->function_end_locus;
-      warning ("%H`noreturn' function does return", &location);
+      warning ("%H%<noreturn%> function does return", &location);
 #else
       if (!locus)
        locus = &cfun->function_end_locus;
-      warning ("%H`noreturn' function does return", locus);
+      warning ("%H%<noreturn%> function does return", locus);
 #endif
     }