OSDN Git Service

* doc/invoke.texi (Darwin Options): Document -mkernel.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-propagate.c
index 07b13e3..f9ece62 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic SSA value propagation engine.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
    This file is part of GCC.
@@ -130,7 +130,7 @@ static ssa_prop_visit_phi_fn ssa_prop_visit_phi;
 static sbitmap executable_blocks;
 
 /* Array of control flow edges on the worklist.  */
-static GTY(()) varray_type cfg_blocks = NULL;
+static VEC(basic_block,heap) *cfg_blocks;
 
 static unsigned int cfg_blocks_num = 0;
 static int cfg_blocks_tail;
@@ -187,19 +187,23 @@ cfg_blocks_add (basic_block bb)
   else
     {
       cfg_blocks_num++;
-      if (cfg_blocks_num > VARRAY_SIZE (cfg_blocks))
+      if (cfg_blocks_num > VEC_length (basic_block, cfg_blocks))
        {
-         /* We have to grow the array now.  Adjust to queue to occupy the
-            full space of the original array.  */
-         cfg_blocks_tail = VARRAY_SIZE (cfg_blocks);
+         /* We have to grow the array now.  Adjust to queue to occupy
+            the full space of the original array.  We do not need to
+            initialize the newly allocated portion of the array
+            because we keep track of CFG_BLOCKS_HEAD and
+            CFG_BLOCKS_HEAD.  */
+         cfg_blocks_tail = VEC_length (basic_block, cfg_blocks);
          cfg_blocks_head = 0;
-         VARRAY_GROW (cfg_blocks, 2 * VARRAY_SIZE (cfg_blocks));
+         VEC_safe_grow (basic_block, heap, cfg_blocks, 2 * cfg_blocks_tail);
        }
       else
-       cfg_blocks_tail = (cfg_blocks_tail + 1) % VARRAY_SIZE (cfg_blocks);
+       cfg_blocks_tail = ((cfg_blocks_tail + 1)
+                          % VEC_length (basic_block, cfg_blocks));
     }
 
-  VARRAY_BB (cfg_blocks, cfg_blocks_tail) = bb;
+  VEC_replace (basic_block, cfg_blocks, cfg_blocks_tail, bb);
   SET_BIT (bb_in_list, bb->index);
 }
 
@@ -211,12 +215,13 @@ cfg_blocks_get (void)
 {
   basic_block bb;
 
-  bb = VARRAY_BB (cfg_blocks, cfg_blocks_head);
+  bb = VEC_index (basic_block, cfg_blocks, cfg_blocks_head);
 
   gcc_assert (!cfg_blocks_empty_p ());
   gcc_assert (bb);
 
-  cfg_blocks_head = (cfg_blocks_head + 1) % VARRAY_SIZE (cfg_blocks);
+  cfg_blocks_head = ((cfg_blocks_head + 1)
+                    % VEC_length (basic_block, cfg_blocks));
   --cfg_blocks_num;
   RESET_BIT (bb_in_list, bb->index);
 
@@ -473,7 +478,8 @@ ssa_prop_init (void)
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_immediate_uses (dump_file);
 
-  VARRAY_BB_INIT (cfg_blocks, 20, "cfg_blocks");
+  cfg_blocks = VEC_alloc (basic_block, heap, 20);
+  VEC_safe_grow (basic_block, heap, cfg_blocks, 20);
 
   /* Initialize the values for every SSA_NAME.  */
   for (i = 1; i < num_ssa_names; i++)
@@ -507,6 +513,7 @@ ssa_prop_fini (void)
 {
   VEC_free (tree, gc, interesting_ssa_edges);
   VEC_free (tree, gc, varying_ssa_edges);
+  VEC_free (basic_block, heap, cfg_blocks);
   cfg_blocks = NULL;
   sbitmap_free (bb_in_list);
   sbitmap_free (executable_blocks);
@@ -581,9 +588,17 @@ set_rhs (tree *stmt_p, tree expr)
          && !is_gimple_val (TREE_OPERAND (TREE_OPERAND (expr, 0), 1)))
        return false;
     }
-  else if (code == COMPOUND_EXPR)
+  else if (code == COMPOUND_EXPR
+          || code == MODIFY_EXPR)
     return false;
 
+  if (EXPR_HAS_LOCATION (stmt)
+      && EXPR_P (expr)
+      && ! EXPR_HAS_LOCATION (expr)
+      && TREE_SIDE_EFFECTS (expr)
+      && TREE_CODE (expr) != LABEL_EXPR)
+    SET_EXPR_LOCATION (expr, EXPR_LOCATION (stmt));
+
   switch (TREE_CODE (stmt))
     {
     case RETURN_EXPR:
@@ -604,6 +619,8 @@ set_rhs (tree *stmt_p, tree expr)
       break;
 
     case COND_EXPR:
+      if (!is_gimple_condexpr (expr))
+        return false;
       COND_EXPR_COND (stmt) = expr;
       break;
     case SWITCH_EXPR:
@@ -623,7 +640,8 @@ set_rhs (tree *stmt_p, tree expr)
       *stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
       (*stmt_p)->common.ann = (tree_ann_t) ann;
 
-      if (TREE_SIDE_EFFECTS (expr))
+      if (in_ssa_p
+         && TREE_SIDE_EFFECTS (expr))
        {
          /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
             replacement.  */
@@ -1115,14 +1133,7 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
          /* If we have range information, see if we can fold
             predicate expressions.  */
          if (use_ranges_p)
-           {
-             did_replace = fold_predicate_in (stmt);
-
-             /* Some statements may be simplified using ranges.  For
-                example, division may be replaced by shifts, modulo
-                replaced with bitwise and, etc.  */
-             simplify_stmt_using_ranges (stmt);
-           }
+           did_replace = fold_predicate_in (stmt);
 
          if (prop_value)
            {
@@ -1158,7 +1169,7 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
 
              rhs = get_rhs (stmt);
              if (TREE_CODE (rhs) == ADDR_EXPR)
-               recompute_tree_invarant_for_addr_expr (rhs);
+               recompute_tree_invariant_for_addr_expr (rhs);
 
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
@@ -1169,6 +1180,16 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
                  fprintf (dump_file, "\n");
                }
            }
+
+         /* Some statements may be simplified using ranges.  For
+            example, division may be replaced by shifts, modulo
+            replaced with bitwise and, etc.   Do this after 
+            substituting constants, folding, etc so that we're
+            presented with a fully propagated, canonicalized
+            statement.  */
+         if (use_ranges_p)
+           simplify_stmt_using_ranges (stmt);
+
        }
     }