OSDN Git Service

* gdbinit.in: Set complaints to 0.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ivopts.c
index 0874620..0132fc9 100644 (file)
@@ -349,7 +349,7 @@ iv_cand (struct ivopts_data *data, unsigned i)
 edge
 single_dom_exit (struct loop *loop)
 {
-  edge exit = loop->single_exit;
+  edge exit = single_exit (loop);
 
   if (!exit)
     return NULL;
@@ -1037,14 +1037,14 @@ find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
   iv->base = NULL_TREE;
   iv->step = NULL_TREE;
 
-  if (TREE_CODE (stmt) != MODIFY_EXPR)
+  if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
     return false;
 
-  lhs = TREE_OPERAND (stmt, 0);
+  lhs = GIMPLE_STMT_OPERAND (stmt, 0);
   if (TREE_CODE (lhs) != SSA_NAME)
     return false;
 
-  if (!simple_iv (loop, stmt, TREE_OPERAND (stmt, 1), iv, true))
+  if (!simple_iv (loop, stmt, GIMPLE_STMT_OPERAND (stmt, 1), iv, true))
     return false;
   iv->base = expand_simple_operations (iv->base);
 
@@ -1065,7 +1065,7 @@ find_givs_in_stmt (struct ivopts_data *data, tree stmt)
   if (!find_givs_in_stmt_scev (data, stmt, &iv))
     return;
 
-  set_iv (data, TREE_OPERAND (stmt, 0), iv.base, iv.step);
+  set_iv (data, GIMPLE_STMT_OPERAND (stmt, 0), iv.base, iv.step);
 }
 
 /* Finds general ivs in basic block BB.  */
@@ -1222,7 +1222,7 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
 
   stmt = SSA_NAME_DEF_STMT (op);
   gcc_assert (TREE_CODE (stmt) == PHI_NODE
-             || TREE_CODE (stmt) == MODIFY_EXPR);
+             || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
 
   use = record_use (data, NULL, civ, stmt, USE_NONLINEAR_EXPR);
   iv->use_id = use->id;
@@ -1314,7 +1314,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
       return true;
     }
 
-  if (!EXPR_P (expr))
+  if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
     return false;
 
   len = TREE_CODE_LENGTH (TREE_CODE (expr));
@@ -1636,10 +1636,10 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
       return;
     }
 
-  if (TREE_CODE (stmt) == MODIFY_EXPR)
+  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
     {
-      lhs = TREE_OPERAND (stmt, 0);
-      rhs = TREE_OPERAND (stmt, 1);
+      lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
       if (TREE_CODE (lhs) == SSA_NAME)
        {
@@ -1655,13 +1655,16 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
       switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
        {
        case tcc_comparison:
-         find_interesting_uses_cond (data, stmt, &TREE_OPERAND (stmt, 1));
+         find_interesting_uses_cond (data, stmt,
+                                     &GIMPLE_STMT_OPERAND (stmt, 1));
          return;
 
        case tcc_reference:
-         find_interesting_uses_address (data, stmt, &TREE_OPERAND (stmt, 1));
+         find_interesting_uses_address (data, stmt,
+                                        &GIMPLE_STMT_OPERAND (stmt, 1));
          if (REFERENCE_CLASS_P (lhs))
-           find_interesting_uses_address (data, stmt, &TREE_OPERAND (stmt, 0));
+           find_interesting_uses_address (data, stmt,
+                                          &GIMPLE_STMT_OPERAND (stmt, 0));
          return;
 
        default: ;
@@ -1670,7 +1673,8 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
       if (REFERENCE_CLASS_P (lhs)
          && is_gimple_val (rhs))
        {
-         find_interesting_uses_address (data, stmt, &TREE_OPERAND (stmt, 0));
+         find_interesting_uses_address (data, stmt,
+                                        &GIMPLE_STMT_OPERAND (stmt, 0));
          find_interesting_uses_op (data, rhs);
          return;
        }
@@ -3318,35 +3322,36 @@ multiply_by_cost (HOST_WIDE_INT cst, enum machine_mode mode)
   return cost;
 }
 
-/* Returns true if multiplying by RATIO is allowed in address.  */
+/* Returns true if multiplying by RATIO is allowed in an address.  Test the
+   validity for a memory reference accessing memory of mode MODE.  */
 
 bool
-multiplier_allowed_in_address_p (HOST_WIDE_INT ratio)
+multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, enum machine_mode mode)
 {
 #define MAX_RATIO 128
-  static sbitmap valid_mult;
+  static sbitmap valid_mult[MAX_MACHINE_MODE];
   
-  if (!valid_mult)
+  if (!valid_mult[mode])
     {
       rtx reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
       rtx addr;
       HOST_WIDE_INT i;
 
-      valid_mult = sbitmap_alloc (2 * MAX_RATIO + 1);
-      sbitmap_zero (valid_mult);
+      valid_mult[mode] = sbitmap_alloc (2 * MAX_RATIO + 1);
+      sbitmap_zero (valid_mult[mode]);
       addr = gen_rtx_fmt_ee (MULT, Pmode, reg1, NULL_RTX);
       for (i = -MAX_RATIO; i <= MAX_RATIO; i++)
        {
          XEXP (addr, 1) = gen_int_mode (i, Pmode);
-         if (memory_address_p (Pmode, addr))
-           SET_BIT (valid_mult, i + MAX_RATIO);
+         if (memory_address_p (mode, addr))
+           SET_BIT (valid_mult[mode], i + MAX_RATIO);
        }
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "  allowed multipliers:");
          for (i = -MAX_RATIO; i <= MAX_RATIO; i++)
-           if (TEST_BIT (valid_mult, i + MAX_RATIO))
+           if (TEST_BIT (valid_mult[mode], i + MAX_RATIO))
              fprintf (dump_file, " %d", (int) i);
          fprintf (dump_file, "\n");
          fprintf (dump_file, "\n");
@@ -3356,71 +3361,78 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio)
   if (ratio > MAX_RATIO || ratio < -MAX_RATIO)
     return false;
 
-  return TEST_BIT (valid_mult, ratio + MAX_RATIO);
+  return TEST_BIT (valid_mult[mode], ratio + MAX_RATIO);
 }
 
 /* Returns cost of address in shape symbol + var + OFFSET + RATIO * index.
    If SYMBOL_PRESENT is false, symbol is omitted.  If VAR_PRESENT is false,
-   variable is omitted.  The created memory accesses MODE.
-   
+   variable is omitted.  Compute the cost for a memory reference that accesses
+   a memory location of mode MEM_MODE.
+
    TODO -- there must be some better way.  This all is quite crude.  */
 
 static unsigned
 get_address_cost (bool symbol_present, bool var_present,
-                 unsigned HOST_WIDE_INT offset, HOST_WIDE_INT ratio)
+                 unsigned HOST_WIDE_INT offset, HOST_WIDE_INT ratio,
+                 enum machine_mode mem_mode)
 {
-  static bool initialized = false;
-  static HOST_WIDE_INT rat, off;
-  static HOST_WIDE_INT min_offset, max_offset;
-  static unsigned costs[2][2][2][2];
+  static bool initialized[MAX_MACHINE_MODE];
+  static HOST_WIDE_INT rat[MAX_MACHINE_MODE], off[MAX_MACHINE_MODE];
+  static HOST_WIDE_INT min_offset[MAX_MACHINE_MODE], max_offset[MAX_MACHINE_MODE];
+  static unsigned costs[MAX_MACHINE_MODE][2][2][2][2];
   unsigned cost, acost;
   bool offset_p, ratio_p;
   HOST_WIDE_INT s_offset;
   unsigned HOST_WIDE_INT mask;
   unsigned bits;
 
-  if (!initialized)
+  if (!initialized[mem_mode])
     {
       HOST_WIDE_INT i;
+      HOST_WIDE_INT start = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
       int old_cse_not_expected;
       unsigned sym_p, var_p, off_p, rat_p, add_c;
       rtx seq, addr, base;
       rtx reg0, reg1;
 
-      initialized = true;
+      initialized[mem_mode] = true;
 
       reg1 = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
 
       addr = gen_rtx_fmt_ee (PLUS, Pmode, reg1, NULL_RTX);
-      for (i = 1; i <= 1 << 20; i <<= 1)
+      for (i = start; i <= 1 << 20; i <<= 1)
        {
          XEXP (addr, 1) = gen_int_mode (i, Pmode);
-         if (!memory_address_p (Pmode, addr))
+         if (!memory_address_p (mem_mode, addr))
            break;
        }
-      max_offset = i >> 1;
-      off = max_offset;
+      max_offset[mem_mode] = i == start ? 0 : i >> 1;
+      off[mem_mode] = max_offset[mem_mode];
 
-      for (i = 1; i <= 1 << 20; i <<= 1)
+      for (i = start; i <= 1 << 20; i <<= 1)
        {
          XEXP (addr, 1) = gen_int_mode (-i, Pmode);
-         if (!memory_address_p (Pmode, addr))
+         if (!memory_address_p (mem_mode, addr))
            break;
        }
-      min_offset = -(i >> 1);
+      min_offset[mem_mode] = i == start ? 0 : -(i >> 1);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "get_address_cost:\n");
-         fprintf (dump_file, "  min offset %d\n", (int) min_offset);
-         fprintf (dump_file, "  max offset %d\n", (int) max_offset);
+         fprintf (dump_file, "  min offset %s %d\n",
+                  GET_MODE_NAME (mem_mode),
+                  (int) min_offset[mem_mode]);
+         fprintf (dump_file, "  max offset %s %d\n",
+                  GET_MODE_NAME (mem_mode),
+                  (int) max_offset[mem_mode]);
        }
 
-      rat = 1;
+      rat[mem_mode] = 1;
       for (i = 2; i <= MAX_RATIO; i++)
-       if (multiplier_allowed_in_address_p (i))
+       if (multiplier_allowed_in_address_p (i, mem_mode))
          {
-           rat = i;
+           rat[mem_mode] = i;
            break;
          }
 
@@ -3438,7 +3450,8 @@ get_address_cost (bool symbol_present, bool var_present,
 
          addr = reg0;
          if (rat_p)
-           addr = gen_rtx_fmt_ee (MULT, Pmode, addr, gen_int_mode (rat, Pmode));
+           addr = gen_rtx_fmt_ee (MULT, Pmode, addr,
+                                  gen_int_mode (rat[mem_mode], Pmode));
 
          if (var_p)
            addr = gen_rtx_fmt_ee (PLUS, Pmode, addr, reg1);
@@ -3450,10 +3463,11 @@ get_address_cost (bool symbol_present, bool var_present,
                base = gen_rtx_fmt_e (CONST, Pmode,
                                      gen_rtx_fmt_ee (PLUS, Pmode,
                                                      base,
-                                                     gen_int_mode (off, Pmode)));
+                                                     gen_int_mode (off[mem_mode],
+                                                                   Pmode)));
            }
          else if (off_p)
-           base = gen_int_mode (off, Pmode);
+           base = gen_int_mode (off[mem_mode], Pmode);
          else
            base = NULL_RTX;
     
@@ -3465,17 +3479,17 @@ get_address_cost (bool symbol_present, bool var_present,
             follow.  */
          old_cse_not_expected = cse_not_expected;
          cse_not_expected = true;
-         addr = memory_address (Pmode, addr);
+         addr = memory_address (mem_mode, addr);
          cse_not_expected = old_cse_not_expected;
          seq = get_insns ();
          end_sequence ();
 
          acost = seq_cost (seq);
-         acost += address_cost (addr, Pmode);
+         acost += address_cost (addr, mem_mode);
 
          if (!acost)
            acost = 1;
-         costs[sym_p][var_p][off_p][rat_p] = acost;
+         costs[mem_mode][sym_p][var_p][off_p][rat_p] = acost;
        }
 
       /* On some targets, it is quite expensive to load symbol to a register,
@@ -3497,12 +3511,12 @@ get_address_cost (bool symbol_present, bool var_present,
          off_p = (i >> 1) & 1;
          rat_p = (i >> 2) & 1;
 
-         acost = costs[0][1][off_p][rat_p] + 1;
+         acost = costs[mem_mode][0][1][off_p][rat_p] + 1;
          if (var_p)
            acost += add_c;
 
-         if (acost < costs[1][var_p][off_p][rat_p])
-           costs[1][var_p][off_p][rat_p] = acost;
+         if (acost < costs[mem_mode][1][var_p][off_p][rat_p])
+           costs[mem_mode][1][var_p][off_p][rat_p] = acost;
        }
   
       if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3526,7 +3540,7 @@ get_address_cost (bool symbol_present, bool var_present,
              if (rat_p)
                fprintf (dump_file, "rat * ");
 
-             acost = costs[sym_p][var_p][off_p][rat_p];
+             acost = costs[mem_mode][sym_p][var_p][off_p][rat_p];
              fprintf (dump_file, "index costs %d\n", acost);
            }
          fprintf (dump_file, "\n");
@@ -3542,20 +3556,18 @@ get_address_cost (bool symbol_present, bool var_present,
 
   cost = 0;
   offset_p = (s_offset != 0
-             && min_offset <= s_offset && s_offset <= max_offset);
+             && min_offset[mem_mode] <= s_offset
+             && s_offset <= max_offset[mem_mode]);
   ratio_p = (ratio != 1
-            && multiplier_allowed_in_address_p (ratio));
+            && multiplier_allowed_in_address_p (ratio, mem_mode));
 
   if (ratio != 1 && !ratio_p)
     cost += multiply_by_cost (ratio, Pmode);
 
   if (s_offset && !offset_p && !symbol_present)
-    {
-      cost += add_cost (Pmode);
-      var_present = true;
-    }
+    cost += add_cost (Pmode);
 
-  acost = costs[symbol_present][var_present][offset_p][ratio_p];
+  acost = costs[mem_mode][symbol_present][var_present][offset_p][ratio_p];
   return cost + acost;
 }
 
@@ -3963,7 +3975,8 @@ get_computation_cost_at (struct ivopts_data *data,
      (symbol/var/const parts may be omitted).  If we are looking for an address,
      find the cost of addressing this.  */
   if (address_p)
-    return cost + get_address_cost (symbol_present, var_present, offset, ratio);
+    return cost + get_address_cost (symbol_present, var_present, offset, ratio,
+                                   TYPE_MODE (TREE_TYPE (*use->op_p)));
 
   /* Otherwise estimate the costs for computing the expression.  */
   aratio = ratio > 0 ? ratio : -ratio;
@@ -4392,8 +4405,8 @@ determine_iv_costs (struct ivopts_data *data)
        fprintf (dump_file, "  %d\t%d\n", i, cand->cost);
     }
   
-if (dump_file && (dump_flags & TDF_DETAILS))
-      fprintf (dump_file, "\n");
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "\n");
 }
 
 /* Calculates cost for having SIZE induction variables.  */
@@ -5374,8 +5387,8 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       tree step, ctype, utype;
       enum tree_code incr_code = PLUS_EXPR;
 
-      gcc_assert (TREE_CODE (use->stmt) == MODIFY_EXPR);
-      gcc_assert (TREE_OPERAND (use->stmt, 0) == cand->var_after);
+      gcc_assert (TREE_CODE (use->stmt) == GIMPLE_MODIFY_STMT);
+      gcc_assert (GIMPLE_STMT_OPERAND (use->stmt, 0) == cand->var_after);
 
       step = cand->iv->step;
       ctype = TREE_TYPE (step);
@@ -5391,7 +5404,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
         computations in the loop -- otherwise, the computation
         we rely upon may be removed in remove_unused_ivs,
         thus leading to ICE.  */
-      op = TREE_OPERAND (use->stmt, 1);
+      op = GIMPLE_STMT_OPERAND (use->stmt, 1);
       if (TREE_CODE (op) == PLUS_EXPR
          || TREE_CODE (op) == MINUS_EXPR)
        {
@@ -5439,8 +5452,8 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
        }
       break;
 
-    case MODIFY_EXPR:
-      tgt = TREE_OPERAND (use->stmt, 0);
+    case GIMPLE_MODIFY_STMT:
+      tgt = GIMPLE_STMT_OPERAND (use->stmt, 0);
       bsi = bsi_for_stmt (use->stmt);
       break;
 
@@ -5454,7 +5467,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
     {
       if (stmts)
        bsi_insert_after (&bsi, stmts, BSI_CONTINUE_LINKING);
-      ass = build2 (MODIFY_EXPR, TREE_TYPE (tgt), tgt, op);
+      ass = build2_gimple (GIMPLE_MODIFY_STMT, tgt, op);
       bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
       remove_statement (use->stmt, false);
       SSA_NAME_DEF_STMT (tgt) = ass;
@@ -5463,7 +5476,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
     {
       if (stmts)
        bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-      TREE_OPERAND (use->stmt, 1) = op;
+      GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
     }
 }
 
@@ -5869,10 +5882,10 @@ finish:
   return changed;
 }
 
-/* Main entry point.  Optimizes induction variables in LOOPS.  */
+/* Main entry point.  Optimizes induction variables in loops.  */
 
 void
-tree_ssa_iv_optimize (struct loops *loops)
+tree_ssa_iv_optimize (void)
 {
   struct loop *loop;
   struct ivopts_data data;
@@ -5880,12 +5893,12 @@ tree_ssa_iv_optimize (struct loops *loops)
   tree_ssa_iv_optimize_init (&data);
 
   /* Optimize the loops starting with the innermost ones.  */
-  loop = loops->tree_root;
+  loop = current_loops->tree_root;
   while (loop->inner)
     loop = loop->inner;
 
   /* Scan the loops, inner ones first.  */
-  while (loop != loops->tree_root)
+  while (loop != current_loops->tree_root)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        flow_loop_dump (loop, dump_file, NULL, 1);