OSDN Git Service

* tree-cfg.c (dump_function_to_file): Use cfun info only if it
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfg.c
index bb8e256..28af511 100644 (file)
@@ -54,10 +54,6 @@ Boston, MA 02111-1307, USA.  */
 /* Initial capacity for the basic block array.  */
 static const int initial_cfg_capacity = 20;
 
-/* Mapping of labels to their associated blocks.  This can greatly speed up
-   building of the CFG in code with lots of gotos.  */
-static GTY(()) varray_type label_to_block_map;
-
 /* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
    which use a particular edge.  The CASE_LABEL_EXPRs are chained together
    via their TREE_CHAIN field, which we clear after we're done with the
@@ -150,9 +146,6 @@ build_tree_cfg (tree *tp)
   /* Register specific tree functions.  */
   tree_register_cfg_hooks ();
 
-  /* Initialize rbi_pool.  */
-  alloc_rbi_pool ();
-
   /* Initialize the basic block array.  */
   init_flow ();
   profile_status = PROFILE_ABSENT;
@@ -812,7 +805,7 @@ make_switch_expr_edges (basic_block bb)
 /* Return the basic block holding label DEST.  */
 
 basic_block
-label_to_block (tree dest)
+label_to_block_fn (struct function *ifun, tree dest)
 {
   int uid = LABEL_DECL_UID (dest);
 
@@ -828,10 +821,9 @@ label_to_block (tree dest)
       bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
       uid = LABEL_DECL_UID (dest);
     }
-  return VARRAY_BB (label_to_block_map, uid);
+  return VARRAY_BB (ifun->cfg->x_label_to_block_map, uid);
 }
 
-
 /* Create edges for a goto statement at block BB.  */
 
 static void
@@ -1282,8 +1274,7 @@ tree_can_merge_blocks_p (basic_block a, basic_block b)
       && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
     return false;
 
-  /* There may be no phi nodes at the start of b.  Most of these degenerate
-     phi nodes should be cleaned up by kill_redundant_phi_nodes.  */
+  /* There may be no PHI nodes at the start of B.  */
   if (phi_nodes (b))
     return false;
 
@@ -1905,127 +1896,6 @@ struct tree_opt_pass pass_remove_useless_stmts =
   0                                    /* letter */
 };
 
-
-/* Remove obviously useless statements in basic block BB.  */
-
-static void
-cfg_remove_useless_stmts_bb (basic_block bb)
-{
-  block_stmt_iterator bsi;
-  tree stmt = NULL_TREE;
-  tree cond, var = NULL_TREE, val = NULL_TREE;
-  struct var_ann_d *ann;
-
-  /* Check whether we come here from a condition, and if so, get the
-     condition.  */
-  if (!single_pred_p (bb)
-      || !(single_pred_edge (bb)->flags
-          & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
-    return;
-
-  cond = COND_EXPR_COND (last_stmt (single_pred (bb)));
-
-  if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
-    {
-      var = cond;
-      val = (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE
-            ? boolean_false_node : boolean_true_node);
-    }
-  else if (TREE_CODE (cond) == TRUTH_NOT_EXPR
-          && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
-              || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL))
-    {
-      var = TREE_OPERAND (cond, 0);
-      val = (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE
-            ? boolean_true_node : boolean_false_node);
-    }
-  else
-    {
-      if (single_pred_edge (bb)->flags & EDGE_FALSE_VALUE)
-       cond = invert_truthvalue (cond);
-      if (TREE_CODE (cond) == EQ_EXPR
-         && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
-             || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
-         && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
-             || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
-             || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
-       {
-         var = TREE_OPERAND (cond, 0);
-         val = TREE_OPERAND (cond, 1);
-       }
-      else
-       return;
-    }
-
-  /* Only work for normal local variables.  */
-  ann = var_ann (var);
-  if (!ann
-      || ann->may_aliases
-      || TREE_ADDRESSABLE (var))
-    return;
-
-  if (! TREE_CONSTANT (val))
-    {
-      ann = var_ann (val);
-      if (!ann
-         || ann->may_aliases
-         || TREE_ADDRESSABLE (val))
-       return;
-    }
-
-  /* Ignore floating point variables, since comparison behaves weird for
-     them.  */
-  if (FLOAT_TYPE_P (TREE_TYPE (var)))
-    return;
-
-  for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
-    {
-      stmt = bsi_stmt (bsi);
-
-      /* If the THEN/ELSE clause merely assigns a value to a variable/parameter
-        which is already known to contain that value, then remove the useless
-        THEN/ELSE clause.  */
-      if (TREE_CODE (stmt) == MODIFY_EXPR
-         && TREE_OPERAND (stmt, 0) == var
-         && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0))
-       {
-         bsi_remove (&bsi);
-         continue;
-       }
-
-      /* Invalidate the var if we encounter something that could modify it.
-        Likewise for the value it was previously set to.  Note that we only
-        consider values that are either a VAR_DECL or PARM_DECL so we
-        can test for conflict very simply.  */
-      if (TREE_CODE (stmt) == ASM_EXPR
-         || (TREE_CODE (stmt) == MODIFY_EXPR
-             && (TREE_OPERAND (stmt, 0) == var
-                 || TREE_OPERAND (stmt, 0) == val)))
-       return;
-  
-      bsi_next (&bsi);
-    }
-}
-
-
-/* A CFG-aware version of remove_useless_stmts.  */
-
-void
-cfg_remove_useless_stmts (void)
-{
-  basic_block bb;
-
-#ifdef ENABLE_CHECKING
-  verify_flow_info ();
-#endif
-
-  FOR_EACH_BB (bb)
-    {
-      cfg_remove_useless_stmts_bb (bb);
-    }
-}
-
-
 /* Remove PHI nodes associated with basic block BB and all edges out of BB.  */
 
 static void
@@ -2552,7 +2422,7 @@ dump_cfg_stats (FILE *file)
 {
   static long max_num_merged_labels = 0;
   unsigned long size, total = 0;
-  int n_edges;
+  long num_edges;
   basic_block bb;
   const char * const fmt_str   = "%-30s%-13s%12s\n";
   const char * const fmt_str_1 = "%-30s%13d%11lu%c\n";
@@ -2573,12 +2443,12 @@ dump_cfg_stats (FILE *file)
   fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks,
           SCALE (size), LABEL (size));
 
-  n_edges = 0;
+  num_edges = 0;
   FOR_EACH_BB (bb)
-    n_edges += EDGE_COUNT (bb->succs);
-  size = n_edges * sizeof (struct edge_def);
+    num_edges += EDGE_COUNT (bb->succs);
+  size = num_edges * sizeof (struct edge_def);
   total += size;
-  fprintf (file, fmt_str_1, "Edges", n_edges, SCALE (size), LABEL (size));
+  fprintf (file, fmt_str_1, "Edges", num_edges, SCALE (size), LABEL (size));
 
   size = n_basic_blocks * sizeof (struct bb_ann_d);
   total += size;
@@ -2899,7 +2769,6 @@ delete_tree_cfg_annotations (void)
     free_blocks_annotations ();
 
   label_to_block_map = NULL;
-  free_rbi_pool ();
   FOR_EACH_BB (bb)
     bb->rbi = NULL;
 }
@@ -3428,6 +3297,15 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
        }
       break;
 
+    case ASSERT_EXPR:
+      x = fold (ASSERT_EXPR_COND (t));
+      if (x == boolean_false_node)
+       {
+         error ("ASSERT_EXPR with an always-false condition");
+         return *tp;
+       }
+      break;
+
     case MODIFY_EXPR:
       x = TREE_OPERAND (t, 0);
       if (TREE_CODE (x) == BIT_FIELD_REF
@@ -3872,7 +3750,7 @@ tree_verify_flow_info (void)
          if (TREE_CODE (stmt) == LABEL_EXPR)
            {
              error ("Label %s in the middle of basic block %d\n",
-                    IDENTIFIER_POINTER (DECL_NAME (stmt)),
+                    IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
                     bb->index);
              err = 1;
            }
@@ -4852,9 +4730,6 @@ tree_duplicate_bb (basic_block bb)
       if (TREE_CODE (stmt) == LABEL_EXPR)
        continue;
 
-      /* Record the definitions.  */
-      get_stmt_operands (stmt);
-
       FOR_EACH_SSA_TREE_OPERAND (val, stmt, op_iter, SSA_OP_ALL_DEFS)
        mark_for_rewrite (val);
 
@@ -5068,7 +4943,6 @@ rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map)
   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
     {
       stmt = bsi_stmt (bsi);
-      get_stmt_operands (stmt);
       ann = stmt_ann (stmt);
 
       uses = USE_OPS (ann);
@@ -5293,7 +5167,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
 
   /* When GIMPLE is lowered, the variables are no longer available in
      BIND_EXPRs, so display them separately.  */
-  if (cfun && cfun->unexpanded_var_list)
+  if (cfun && cfun->decl == fn && cfun->unexpanded_var_list)
     {
       ignore_topmost_bind = true;
 
@@ -5309,7 +5183,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
        }
     }
 
-  if (basic_block_info)
+  if (cfun && cfun->decl == fn && cfun->cfg && basic_block_info)
     {
       /* Make a CFG based dump.  */
       check_bb_profile (ENTRY_BLOCK_PTR, file);
@@ -6044,5 +5918,3 @@ struct tree_opt_pass pass_warn_function_return =
   0,                                   /* todo_flags_finish */
   0                                    /* letter */
 };
-
-#include "gt-tree-cfg.h"