]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-cfg.c (make_ctrl_stmt_edges, [...]): Merge into...
authorRichard Henderson <rth@redhat.com>
Sat, 1 Apr 2006 00:37:13 +0000 (16:37 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 1 Apr 2006 00:37:13 +0000 (16:37 -0800)
        * tree-cfg.c (make_ctrl_stmt_edges, make_exit_edges): Merge into...
        (make_edges): ... here.  Control fallthru creation with a local
        variable.  Do not play with fake edges.
        (make_omp_sections_edges): Don't set EDGE_ABNORMAL.
        (make_goto_expr_edges): Don't play with fake edges.  Make for_call
        a boolean.

From-SVN: r112603

gcc/ChangeLog
gcc/tree-cfg.c

index 2266b33b3b12aa4d34ec30615a0c23bc965cb1e1..7f383beea2543262e9e611363cf07675ec99ac9a 100644 (file)
@@ -1,3 +1,12 @@
+2004-03-31  Richard Henderson  <rth@redhat.com>
+
+       * tree-cfg.c (make_ctrl_stmt_edges, make_exit_edges): Merge into...
+       (make_edges): ... here.  Control fallthru creation with a local
+       variable.  Do not play with fake edges.
+       (make_omp_sections_edges): Don't set EDGE_ABNORMAL.
+       (make_goto_expr_edges): Don't play with fake edges.  Make for_call
+       a boolean.
+
 2006-04-01  Joseph S. Myers  <joseph@codesourcery.com>
 
        * dwarf2.h (DW64_CIE_ID): Define.
index 6f0e947f9432d5e1957bd0aae934c2c0cbb7908d..a62331b56d8ef1761c1c3d9460a6b9cfafc9c000 100644 (file)
@@ -1,5 +1,6 @@
 /* Control flow functions for trees.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -99,11 +100,10 @@ static void factor_computed_gotos (void);
 
 /* Edges.  */
 static void make_edges (void);
-static void make_ctrl_stmt_edges (basic_block);
-static void make_exit_edges (basic_block);
 static void make_cond_expr_edges (basic_block);
 static void make_switch_expr_edges (basic_block);
 static void make_goto_expr_edges (basic_block);
+static void make_omp_sections_edges (basic_block);
 static edge tree_redirect_edge_and_branch (edge, basic_block);
 static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
 static unsigned int split_critical_edges (void);
@@ -455,30 +455,99 @@ make_edges (void)
   /* Traverse the basic block array placing edges.  */
   FOR_EACH_BB (bb)
     {
-      tree first = first_stmt (bb);
       tree last = last_stmt (bb);
+      bool fallthru;
 
-      if (first)
+      if (last)
        {
-         /* Edges for statements that always alter flow control.  */
-         if (is_ctrl_stmt (last))
-           make_ctrl_stmt_edges (bb);
+         switch (TREE_CODE (last))
+           {
+           case GOTO_EXPR:
+             make_goto_expr_edges (bb);
+             fallthru = false;
+             break;
+           case RETURN_EXPR:
+             make_edge (bb, EXIT_BLOCK_PTR, 0);
+             fallthru = false;
+             break;
+           case COND_EXPR:
+             make_cond_expr_edges (bb);
+             fallthru = false;
+             break;
+           case SWITCH_EXPR:
+             make_switch_expr_edges (bb);
+             fallthru = false;
+             break;
+           case RESX_EXPR:
+             make_eh_edges (last);
+             fallthru = false;
+             break;
+
+           case CALL_EXPR:
+             /* If this function receives a nonlocal goto, then we need to
+                make edges from this call site to all the nonlocal goto
+                handlers.  */
+             if (TREE_SIDE_EFFECTS (last)
+                 && current_function_has_nonlocal_label)
+               make_goto_expr_edges (bb);
+
+             /* If this statement has reachable exception handlers, then
+                create abnormal edges to them.  */
+             make_eh_edges (last);
+
+             /* Some calls are known not to return.  */
+             fallthru = !(call_expr_flags (last) & ECF_NORETURN);
+             break;
+
+           case MODIFY_EXPR:
+             if (is_ctrl_altering_stmt (last))
+               {
+                 /* A MODIFY_EXPR may have a CALL_EXPR on its RHS and the
+                    CALL_EXPR may have an abnormal edge.  Search the RHS for
+                    this case and create any required edges.  */
+                 tree op = get_call_expr_in (last);
+                 if (op && TREE_SIDE_EFFECTS (op)
+                     && current_function_has_nonlocal_label)
+                   make_goto_expr_edges (bb);
+
+                 make_eh_edges (last);
+               }
+             fallthru = true;
+             break;
+
+           case OMP_PARALLEL:
+           case OMP_FOR:
+           case OMP_SINGLE:
+           case OMP_MASTER:
+           case OMP_ORDERED:
+           case OMP_CRITICAL:
+           case OMP_SECTION:
+             fallthru = true;
+             break;
+
+           case OMP_RETURN_EXPR:
+             /* In the case of an OMP_SECTION, we may have already made
+                an edge in make_omp_sections_edges.  */
+             fallthru = EDGE_COUNT (bb->succs) == 0;
+             break;
 
-         /* Edges for statements that sometimes alter flow control.  */
-         if (is_ctrl_altering_stmt (last))
-           make_exit_edges (bb);
+           case OMP_SECTIONS:
+             make_omp_sections_edges (bb);
+             fallthru = false;
+             break;
+
+           default:
+             gcc_assert (!stmt_ends_bb_p (last));
+             fallthru = true;
+           }
        }
+      else
+       fallthru = true;
 
-      /* Finally, if no edges were created above, this is a regular
-        basic block that only needs a fallthru edge.  */
-      if (EDGE_COUNT (bb->succs) == 0)
+      if (fallthru)
        make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
     }
 
-  /* We do not care about fake edges, so remove any that the CFG
-     builder inserted for completeness.  */
-  remove_fake_exit_edges ();
-
   /* Fold COND_EXPR_COND of each COND_EXPR.  */
   fold_cond_expr_cond ();
 
@@ -505,7 +574,7 @@ make_omp_sections_edges (basic_block bb)
     {
       basic_block start_bb = bb_for_stmt (TREE_VEC_ELT (vec, i));
       basic_block end_bb = bb_for_stmt (TREE_VEC_ELT (vec, i + 1));
-      make_edge (bb, start_bb, EDGE_ABNORMAL);
+      make_edge (bb, start_bb, 0);
       make_edge (end_bb, exit_bb, EDGE_FALLTHRU);
     }
 
@@ -516,130 +585,6 @@ make_omp_sections_edges (basic_block bb)
   OMP_SECTIONS_SECTIONS (stmt) = NULL_TREE;
 }
 
-
-
-/* Create edges for control statement at basic block BB.  */
-
-static void
-make_ctrl_stmt_edges (basic_block bb)
-{
-  tree last = last_stmt (bb);
-
-  gcc_assert (last);
-  switch (TREE_CODE (last))
-    {
-    case GOTO_EXPR:
-      make_goto_expr_edges (bb);
-      break;
-
-    case RETURN_EXPR:
-      make_edge (bb, EXIT_BLOCK_PTR, 0);
-      break;
-
-    case COND_EXPR:
-      make_cond_expr_edges (bb);
-      break;
-
-    case SWITCH_EXPR:
-      make_switch_expr_edges (bb);
-      break;
-
-    case RESX_EXPR:
-      make_eh_edges (last);
-      /* Yet another NORETURN hack.  */
-      if (EDGE_COUNT (bb->succs) == 0)
-       make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
-
-/* Create exit edges for statements in block BB that alter the flow of
-   control.  Statements that alter the control flow are 'goto', 'return'
-   and calls to non-returning functions.  */
-
-static void
-make_exit_edges (basic_block bb)
-{
-  tree last = last_stmt (bb), op;
-
-  gcc_assert (last);
-  switch (TREE_CODE (last))
-    {
-    case RESX_EXPR:
-      break;
-    case CALL_EXPR:
-      /* If this function receives a nonlocal goto, then we need to
-        make edges from this call site to all the nonlocal goto
-        handlers.  */
-      if (TREE_SIDE_EFFECTS (last)
-         && current_function_has_nonlocal_label)
-       make_goto_expr_edges (bb);
-
-      /* If this statement has reachable exception handlers, then
-        create abnormal edges to them.  */
-      make_eh_edges (last);
-
-      /* Some calls are known not to return.  For such calls we create
-        a fake edge.
-
-        We really need to revamp how we build edges so that it's not
-        such a bloody pain to avoid creating edges for this case since
-        all we do is remove these edges when we're done building the
-        CFG.  */
-      if (call_expr_flags (last) & ECF_NORETURN)
-       {
-         make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
-         return;
-       }
-
-      /* Don't forget the fall-thru edge.  */
-      make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
-      break;
-
-    case MODIFY_EXPR:
-      /* A MODIFY_EXPR may have a CALL_EXPR on its RHS and the CALL_EXPR
-        may have an abnormal edge.  Search the RHS for this case and
-        create any required edges.  */
-      op = get_call_expr_in (last);
-      if (op && TREE_SIDE_EFFECTS (op)
-         && current_function_has_nonlocal_label)
-       make_goto_expr_edges (bb);
-
-      make_eh_edges (last);
-      make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
-      break;
-
-    case OMP_PARALLEL:
-    case OMP_FOR:
-    case OMP_SINGLE:
-    case OMP_MASTER:
-    case OMP_ORDERED:
-    case OMP_CRITICAL:
-      make_edge (bb, bb->next_bb, EDGE_ABNORMAL);
-
-    case OMP_RETURN_EXPR:
-      if (EDGE_COUNT (bb->succs) == 0)
-       make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
-      break;
-
-    case OMP_SECTIONS:
-      make_omp_sections_edges (bb);
-      break;
-
-    case OMP_SECTION:
-      make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
-
 /* Create the edges for a COND_EXPR starting at block BB.
    At this point, both clauses must contain only simple gotos.  */
 
@@ -887,7 +832,7 @@ make_goto_expr_edges (basic_block bb)
 {
   tree goto_t;
   basic_block target_bb;
-  int for_call;
+  bool for_call;
   block_stmt_iterator last = bsi_last (bb);
 
   goto_t = bsi_stmt (last);
@@ -896,11 +841,11 @@ make_goto_expr_edges (basic_block bb)
      CALL_EXPR or MODIFY_EXPR), then the edge is an abnormal edge resulting
      from a nonlocal goto.  */
   if (TREE_CODE (goto_t) != GOTO_EXPR)
-    for_call = 1;
+    for_call = true;
   else
     {
       tree dest = GOTO_DESTINATION (goto_t);
-      for_call = 0;
+      for_call = false;
 
       /* A GOTO to a local label creates normal edges.  */
       if (simple_goto_p (goto_t))
@@ -939,21 +884,17 @@ make_goto_expr_edges (basic_block bb)
          if (
              /* Computed GOTOs.  Make an edge to every label block that has
                 been marked as a potential target for a computed goto.  */
-             (FORCED_LABEL (LABEL_EXPR_LABEL (target)) && for_call == 0)
+             (FORCED_LABEL (LABEL_EXPR_LABEL (target)) && !for_call)
              /* Nonlocal GOTO target.  Make an edge to every label block
                 that has been marked as a potential target for a nonlocal
                 goto.  */
-             || (DECL_NONLOCAL (LABEL_EXPR_LABEL (target)) && for_call == 1))
+             || (DECL_NONLOCAL (LABEL_EXPR_LABEL (target)) && for_call))
            {
              make_edge (bb, target_bb, EDGE_ABNORMAL);
              break;
            }
        }
     }
-
-  /* Degenerate case of computed goto with no labels.  */
-  if (!for_call && EDGE_COUNT (bb->succs) == 0)
-    make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
 }