OSDN Git Service

* cppfiles.c (open_file): Correct typo.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ivopts.c
index 5982b3d..7337d02 100644 (file)
@@ -1,5 +1,5 @@
 /* Induction variable optimizations.
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    
 This file is part of GCC.
    
@@ -91,6 +91,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "params.h"
 #include "langhooks.h"
 #include "tree-affine.h"
+#include "target.h"
 
 /* The infinite cost.  */
 #define INFTY 10000000
@@ -633,13 +634,13 @@ bool
 contains_abnormal_ssa_name_p (tree expr)
 {
   enum tree_code code;
-  enum tree_code_class class;
+  enum tree_code_class codeclass;
 
   if (!expr)
     return false;
 
   code = TREE_CODE (expr);
-  class = TREE_CODE_CLASS (code);
+  codeclass = TREE_CODE_CLASS (code);
 
   if (code == SSA_NAME)
     return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
@@ -653,7 +654,7 @@ contains_abnormal_ssa_name_p (tree expr)
                            idx_contains_abnormal_ssa_name_p,
                            NULL);
 
-  switch (class)
+  switch (codeclass)
     {
     case tcc_binary:
     case tcc_comparison:
@@ -710,7 +711,7 @@ niter_for_exit (struct ivopts_data *data, edge exit)
       *pointer_map_insert (data->niters, exit) = niter;
     }
   else
-    niter = *slot;
+    niter = (tree) *slot;
 
   return niter;
 }
@@ -754,7 +755,7 @@ static tree
 determine_base_object (tree expr)
 {
   enum tree_code code = TREE_CODE (expr);
-  tree base, obj, op0, op1;
+  tree base, obj;
 
   /* If this is a pointer casted to any type, we need to determine
      the base object for the pointer; so handle conversions before
@@ -784,20 +785,13 @@ determine_base_object (tree expr)
       return fold_convert (ptr_type_node,
                           build_fold_addr_expr (base));
 
+    case POINTER_PLUS_EXPR:
+      return determine_base_object (TREE_OPERAND (expr, 0));
+
     case PLUS_EXPR:
     case MINUS_EXPR:
-      op0 = determine_base_object (TREE_OPERAND (expr, 0));
-      op1 = determine_base_object (TREE_OPERAND (expr, 1));
-      
-      if (!op1)
-       return op0;
-
-      if (!op0)
-       return (code == PLUS_EXPR
-               ? op1
-               : fold_build1 (NEGATE_EXPR, ptr_type_node, op1));
-
-      return fold_build2 (code, ptr_type_node, op0, op1);
+      /* Pointer addition is done solely using POINTER_PLUS_EXPR.  */
+      gcc_unreachable ();
 
     default:
       return fold_convert (ptr_type_node, expr);
@@ -1272,7 +1266,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
   if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
     return false;
 
-  len = TREE_CODE_LENGTH (TREE_CODE (expr));
+  len = TREE_OPERAND_LENGTH (expr);
   for (i = 0; i < len; i++)
     if (!expr_invariant_in_loop_p (loop, TREE_OPERAND (expr, i)))
       return false;
@@ -1294,7 +1288,7 @@ struct ifs_ivopts_data
 static bool
 idx_find_step (tree base, tree *idx, void *data)
 {
-  struct ifs_ivopts_data *dta = data;
+  struct ifs_ivopts_data *dta = (struct ifs_ivopts_data *) data;
   struct iv *iv;
   tree step, iv_base, iv_step, lbound, off;
   struct loop *loop = dta->ivopts_data->current_loop;
@@ -1373,8 +1367,9 @@ idx_find_step (tree base, tree *idx, void *data)
 
 static bool
 idx_record_use (tree base, tree *idx,
-               void *data)
+               void *vdata)
 {
+  struct ivopts_data *data = (struct ivopts_data *) vdata;
   find_interesting_uses_op (data, *idx);
   if (TREE_CODE (base) == ARRAY_REF)
     {
@@ -1904,7 +1899,7 @@ static struct ivopts_data *fd_ivopts_data;
 static tree
 find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
 {
-  bitmap *depends_on = data;
+  bitmap *depends_on = (bitmap *) data;
   struct version_info *info;
 
   if (TREE_CODE (*expr_p) != SSA_NAME)
@@ -2380,11 +2375,17 @@ produce_memory_decl_rtl (tree obj, int *regno)
     {
       const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
       x = gen_rtx_SYMBOL_REF (Pmode, name);
+      SET_SYMBOL_REF_DECL (x, obj);
+      x = gen_rtx_MEM (DECL_MODE (obj), x);
+      targetm.encode_section_info (obj, x, true);
     }
   else
-    x = gen_raw_REG (Pmode, (*regno)++);
+    {
+      x = gen_raw_REG (Pmode, (*regno)++);
+      x = gen_rtx_MEM (DECL_MODE (obj), x);
+    }
 
-  return gen_rtx_MEM (DECL_MODE (obj), x);
+  return x;
 }
 
 /* Prepares decl_rtl for variables referred in *EXPR_P.  Callback for
@@ -2395,7 +2396,7 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data)
 {
   tree obj = NULL_TREE;
   rtx x = NULL_RTX;
-  int *regno = data;
+  int *regno = (int *) data;
 
   switch (TREE_CODE (*expr_p))
     {
@@ -2749,7 +2750,7 @@ struct mbc_entry
 static hashval_t
 mbc_entry_hash (const void *entry)
 {
-  const struct mbc_entry *e = entry;
+  const struct mbc_entry *e = (const struct mbc_entry *) entry;
 
   return 57 * (hashval_t) e->mode + (hashval_t) (e->cst % 877);
 }
@@ -2759,8 +2760,8 @@ mbc_entry_hash (const void *entry)
 static int
 mbc_entry_eq (const void *entry1, const void *entry2)
 {
-  const struct mbc_entry *e1 = entry1;
-  const struct mbc_entry *e2 = entry2;
+  const struct mbc_entry *e1 = (const struct mbc_entry *) entry1;
+  const struct mbc_entry *e2 = (const struct mbc_entry *) entry2;
 
   return (e1->mode == e2->mode
          && e1->cst == e2->cst);
@@ -2943,6 +2944,12 @@ get_address_cost (bool symbol_present, bool var_present,
          if (sym_p)
            {
              base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (""));
+             /* ??? We can run into trouble with some backends by presenting
+                it with symbols which havn't been properly passed through
+                targetm.encode_section_info.  By setting the local bit, we
+                enhance the probability of things working.  */
+             SYMBOL_REF_FLAGS (base) = SYMBOL_FLAG_LOCAL;
+
              if (off_p)
                base = gen_rtx_fmt_e (CONST, Pmode,
                                      gen_rtx_fmt_ee (PLUS, Pmode,
@@ -3070,24 +3077,25 @@ force_expr_to_var_cost (tree expr)
 
   if (!costs_initialized)
     {
-      tree var = create_tmp_var_raw (integer_type_node, "test_var");
-      rtx x = gen_rtx_MEM (DECL_MODE (var),
-                          gen_rtx_SYMBOL_REF (Pmode, "test_var"));
-      tree addr;
       tree type = build_pointer_type (integer_type_node);
+      tree var, addr;
+      rtx x;
+
+      var = create_tmp_var_raw (integer_type_node, "test_var");
+      TREE_STATIC (var) = 1;
+      x = produce_memory_decl_rtl (var, NULL);
+      SET_DECL_RTL (var, x);
 
       integer_cost = computation_cost (build_int_cst (integer_type_node,
                                                      2000));
 
-      SET_DECL_RTL (var, x);
-      TREE_STATIC (var) = 1;
       addr = build1 (ADDR_EXPR, type, var);
       symbol_cost = computation_cost (addr) + 1;
 
       address_cost
-       = computation_cost (build2 (PLUS_EXPR, type,
+       = computation_cost (build2 (POINTER_PLUS_EXPR, type,
                                    addr,
-                                   build_int_cst (type, 2000))) + 1;
+                                   build_int_cst (sizetype, 2000))) + 1;
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "force_expr_to_var_cost:\n");
@@ -3126,6 +3134,7 @@ force_expr_to_var_cost (tree expr)
 
   switch (TREE_CODE (expr))
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -3154,6 +3163,7 @@ force_expr_to_var_cost (tree expr)
   mode = TYPE_MODE (TREE_TYPE (expr));
   switch (TREE_CODE (expr))
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
       cost = add_cost (mode);
@@ -3894,7 +3904,9 @@ determine_iv_costs (struct ivopts_data *data)
 static unsigned
 ivopts_global_cost_for_size (struct ivopts_data *data, unsigned size)
 {
-  return global_cost_for_size (size, data->regs_used, n_iv_uses (data));
+  /* We add size to the cost, so that we prefer eliminating ivs
+     if possible.  */
+  return size + estimate_reg_pressure_cost (size, data->regs_used);
 }
 
 /* For each size of the induction variable set determine the penalty.  */
@@ -3931,8 +3943,7 @@ determine_set_costs (struct ivopts_data *data)
     {
       fprintf (dump_file, "Global costs:\n");
       fprintf (dump_file, "  target_avail_regs %d\n", target_avail_regs);
-      fprintf (dump_file, "  target_small_cost %d\n", target_small_cost);
-      fprintf (dump_file, "  target_pres_cost %d\n", target_pres_cost);
+      fprintf (dump_file, "  target_reg_cost %d\n", target_reg_cost);
       fprintf (dump_file, "  target_spill_cost %d\n", target_spill_cost);
     }
 
@@ -4851,7 +4862,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
 {
   tree comp;
   tree op, stmts, tgt, ass;
-  block_stmt_iterator bsi, pbsi;
+  block_stmt_iterator bsi;
 
   /* An important special case -- if we are asked to express value of
      the original iv by itself, just exit; there is no need to
@@ -4922,13 +4933,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       if (name_info (data, tgt)->preserve_biv)
        return;
 
-      pbsi = bsi = bsi_start (bb_for_stmt (use->stmt));
-      while (!bsi_end_p (pbsi)
-            && TREE_CODE (bsi_stmt (pbsi)) == LABEL_EXPR)
-       {
-         bsi = pbsi;
-         bsi_next (&pbsi);
-       }
+      bsi = bsi_after_labels (bb_for_stmt (use->stmt));
       break;
 
     case GIMPLE_MODIFY_STMT:
@@ -4941,22 +4946,18 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
     }
 
   op = force_gimple_operand (comp, &stmts, false, SSA_NAME_VAR (tgt));
+  if (stmts)
+    bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
 
   if (TREE_CODE (use->stmt) == PHI_NODE)
     {
-      if (stmts)
-       bsi_insert_after (&bsi, stmts, BSI_CONTINUE_LINKING);
-      ass = build2_gimple (GIMPLE_MODIFY_STMT, tgt, op);
-      bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
+      ass = build_gimple_modify_stmt (tgt, op);
+      bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
       remove_statement (use->stmt, false);
       SSA_NAME_DEF_STMT (tgt) = ass;
     }
   else
-    {
-      if (stmts)
-       bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-      GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
-    }
+    GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
 }
 
 /* Replaces ssa name in index IDX by its basic variable.  Callback for