OSDN Git Service

PR c++/48930
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ivopts.c
index 432b3f9..b00b8d4 100644 (file)
@@ -1,5 +1,5 @@
 /* Induction variable optimizations.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -834,7 +834,8 @@ htab_inv_expr_eq (const void *ent1, const void *ent2)
   const struct iv_inv_expr_ent *expr2 =
       (const struct iv_inv_expr_ent *)ent2;
 
-  return operand_equal_p (expr1->expr, expr2->expr, 0);
+  return expr1->hash == expr2->hash
+        && operand_equal_p (expr1->expr, expr2->expr, 0);
 }
 
 /* Hash function for loop invariant expressions.  */
@@ -1101,6 +1102,12 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
       || contains_abnormal_ssa_name_p (iv->step))
     return false;
 
+  /* If STMT could throw, then do not consider STMT as defining a GIV.  
+     While this will suppress optimizations, we can not safely delete this
+     GIV and associated statements, even if it appears it is not used.  */
+  if (stmt_could_throw_p (stmt))
+    return false;
+
   return true;
 }
 
@@ -2842,7 +2849,7 @@ computation_cost (tree expr, bool speed)
   unsigned cost;
   /* Avoid using hard regs in ways which may be unsupported.  */
   int regno = LAST_VIRTUAL_REGISTER + 1;
-  struct cgraph_node *node = cgraph_node (current_function_decl);
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
   enum node_frequency real_frequency = node->frequency;
 
   node->frequency = NODE_FREQUENCY_NORMAL;
@@ -4027,6 +4034,8 @@ get_computation_cost_at (struct ivopts_data *data,
   STRIP_NOPS (cbase);
   ctype = TREE_TYPE (cbase);
 
+  stmt_is_after_inc = stmt_after_increment (data->current_loop, cand, at);
+
   /* use = ubase + ratio * (var - cbase).  If either cbase is a constant
      or ratio == 1, it is better to handle this like
 
@@ -4045,8 +4054,24 @@ get_computation_cost_at (struct ivopts_data *data,
     }
   else if (ratio == 1)
     {
+      tree real_cbase = cbase;
+
+      /* Check to see if any adjustment is needed.  */
+      if (cstepi == 0 && stmt_is_after_inc)
+        {
+          aff_tree real_cbase_aff;
+          aff_tree cstep_aff;
+
+          tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
+                                   &real_cbase_aff);
+          tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
+
+          aff_combination_add (&real_cbase_aff, &cstep_aff);
+          real_cbase = aff_combination_to_tree (&real_cbase_aff);
+        }
+
       cost = difference_cost (data,
-                             ubase, cbase,
+                             ubase, real_cbase,
                              &symbol_present, &var_present, &offset,
                              depends_on);
       cost.cost /= avg_loop_niter (data->current_loop);
@@ -4088,7 +4113,6 @@ get_computation_cost_at (struct ivopts_data *data,
 
   /* If we are after the increment, the value of the candidate is higher by
      one iteration.  */
-  stmt_is_after_inc = stmt_after_increment (data->current_loop, cand, at);
   if (stmt_is_after_inc)
     offset -= ratio * cstepi;
 
@@ -5869,7 +5893,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
             information.  */
          if (SSA_NAME_PTR_INFO (comp))
            {
-             SSA_NAME_PTR_INFO (comp)->align = BITS_PER_UNIT;
+             SSA_NAME_PTR_INFO (comp)->align = 1;
              SSA_NAME_PTR_INFO (comp)->misalign = 0;
            }
        }
@@ -5934,7 +5958,7 @@ copy_ref_info (tree new_ref, tree old_ref)
            }
          else
            {
-             new_pi->align = BITS_PER_UNIT;
+             new_pi->align = 1;
              new_pi->misalign = 0;
            }
        }
@@ -6230,8 +6254,7 @@ free_loop_data (struct ivopts_data *data)
       struct version_info *info;
 
       info = ver_info (data, i);
-      if (info->iv)
-       free (info->iv);
+      free (info->iv);
       info->iv = NULL;
       info->has_nonlin_use = false;
       info->preserve_biv = false;
@@ -6258,8 +6281,7 @@ free_loop_data (struct ivopts_data *data)
     {
       struct iv_cand *cand = iv_cand (data, i);
 
-      if (cand->iv)
-       free (cand->iv);
+      free (cand->iv);
       if (cand->depends_on)
        BITMAP_FREE (cand->depends_on);
       free (cand);