OSDN Git Service

PR tree-optimization/27549
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ccp.c
index c0a2c6e..53050e6 100644 (file)
@@ -1,5 +1,5 @@
 /* Conditional constant propagation pass for the GNU compiler.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org>
    Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com>
@@ -1011,7 +1011,8 @@ fold_const_aggregate_ref (tree t)
        }
 
       if (ctor == NULL_TREE
-         || TREE_CODE (ctor) != CONSTRUCTOR
+         || (TREE_CODE (ctor) != CONSTRUCTOR
+             && TREE_CODE (ctor) != STRING_CST)
          || !TREE_STATIC (ctor))
        return NULL_TREE;
 
@@ -1036,6 +1037,20 @@ fold_const_aggregate_ref (tree t)
          return NULL_TREE;
        }
 
+      /* Fold read from constant string.  */
+      if (TREE_CODE (ctor) == STRING_CST)
+       {
+         if ((TYPE_MODE (TREE_TYPE (t))
+              == TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+             && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+                 == MODE_INT)
+             && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor)))) == 1
+             && compare_tree_int (idx, TREE_STRING_LENGTH (ctor)) < 0)
+           return build_int_cst (TREE_TYPE (t), (TREE_STRING_POINTER (ctor)
+                                                 [TREE_INT_CST_LOW (idx)]));
+         return NULL_TREE;
+       }
+
       /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
        if (tree_int_cst_equal (cfield, idx))
@@ -1104,7 +1119,7 @@ static prop_value_t
 evaluate_stmt (tree stmt)
 {
   prop_value_t val;
-  tree simplified;
+  tree simplified = NULL_TREE;
   ccp_lattice_t likelyvalue = likely_value (stmt);
 
   val.mem_ref = NULL_TREE;
@@ -1115,14 +1130,14 @@ evaluate_stmt (tree stmt)
     simplified = ccp_fold (stmt);
   /* If the statement is likely to have a VARYING result, then do not
      bother folding the statement.  */
-  else if (likelyvalue == VARYING)
+  if (likelyvalue == VARYING)
     simplified = get_rhs (stmt);
   /* If the statement is an ARRAY_REF or COMPONENT_REF into constant
      aggregates, extract the referenced constant.  Otherwise the
      statement is likely to have an UNDEFINED value, and there will be
      nothing to do.  Note that fold_const_aggregate_ref returns
      NULL_TREE if the first case does not match.  */
-  else
+  else if (!simplified)
     simplified = fold_const_aggregate_ref (get_rhs (stmt));
 
   if (simplified && is_gimple_min_invariant (simplified))
@@ -1378,10 +1393,11 @@ execute_ssa_ccp (bool store_ccp)
 }
 
 
-static void
+static unsigned int
 do_ssa_ccp (void)
 {
   execute_ssa_ccp (false);
+  return 0;
 }
 
 
@@ -1403,20 +1419,21 @@ struct tree_opt_pass pass_ccp =
   TV_TREE_CCP,                         /* tv_id */
   PROP_cfg | PROP_ssa | PROP_alias,    /* properties_required */
   0,                                   /* properties_provided */
-  PROP_tmt_usage,                      /* properties_destroyed */
+  PROP_smt_usage,                      /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_cleanup_cfg | TODO_dump_func | TODO_update_ssa
     | TODO_ggc_collect | TODO_verify_ssa
-    | TODO_verify_stmts | TODO_update_tmt_usage, /* todo_flags_finish */
+    | TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */
   0                                    /* letter */
 };
 
 
-static void
+static unsigned int
 do_ssa_store_ccp (void)
 {
   /* If STORE-CCP is not enabled, we just run regular CCP.  */
   execute_ssa_ccp (flag_tree_store_ccp != 0);
+  return 0;
 }
 
 static bool
@@ -1440,12 +1457,12 @@ struct tree_opt_pass pass_store_ccp =
   TV_TREE_STORE_CCP,                   /* tv_id */
   PROP_cfg | PROP_ssa | PROP_alias,    /* properties_required */
   0,                                   /* properties_provided */
-  PROP_tmt_usage,                      /* properties_destroyed */
+  PROP_smt_usage,                      /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func | TODO_update_ssa
     | TODO_ggc_collect | TODO_verify_ssa
     | TODO_cleanup_cfg
-    | TODO_verify_stmts | TODO_update_tmt_usage, /* todo_flags_finish */
+    | TODO_verify_stmts | TODO_update_smt_usage, /* todo_flags_finish */
   0                                    /* letter */
 };
 
@@ -1877,7 +1894,7 @@ maybe_fold_stmt_addition (tree expr)
              if (TREE_CODE (min_idx) != INTEGER_CST)
                break;
 
-             array_idx = convert (TREE_TYPE (min_idx), array_idx);
+             array_idx = fold_convert (TREE_TYPE (min_idx), array_idx);
              if (!integer_zerop (min_idx))
                array_idx = int_const_binop (MINUS_EXPR, array_idx,
                                             min_idx, 0);
@@ -1885,7 +1902,7 @@ maybe_fold_stmt_addition (tree expr)
        }
 
       /* Convert the index to a byte offset.  */
-      array_idx = convert (sizetype, array_idx);
+      array_idx = fold_convert (sizetype, array_idx);
       array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
 
       /* Update the operands for the next round, or for folding.  */
@@ -2469,7 +2486,7 @@ convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr)
 /* A simple pass that attempts to fold all builtin functions.  This pass
    is run after we've propagated as many constants as we can.  */
 
-static void
+static unsigned int
 execute_fold_all_builtins (void)
 {
   bool cfg_changed = false;
@@ -2561,6 +2578,7 @@ execute_fold_all_builtins (void)
   /* Delete unreachable blocks.  */
   if (cfg_changed)
     cleanup_tree_cfg ();
+  return 0;
 }