OSDN Git Service

PR tree-optimization/20773
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ivopts.c
index ab3247c..fda17f9 100644 (file)
@@ -15,8 +15,8 @@ for more details.
    
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* This pass tries to find the optimal set of induction variables for the loop.
    It optimizes just the basic linear induction variables (although adding
@@ -358,7 +358,7 @@ loop_data (struct loop *loop)
 
 /* The single loop exit if it dominates the latch, NULL otherwise.  */
 
-static edge
+edge
 single_dom_exit (struct loop *loop)
 {
   edge exit = loop->single_exit;
@@ -712,7 +712,8 @@ niter_for_exit (struct ivopts_data *data, edge exit)
       nfe_desc = xmalloc (sizeof (struct nfe_cache_elt));
       nfe_desc->exit = exit;
       nfe_desc->valid_p = number_of_iterations_exit (data->current_loop,
-                                                    exit, &nfe_desc->niter);
+                                                    exit, &nfe_desc->niter,
+                                                    true);
       *slot = nfe_desc;
     }
   else
@@ -1492,7 +1493,7 @@ may_be_unaligned_p (tree ref)
   unsigned base_align;
 
   /* TARGET_MEM_REFs are translated directly to valid MEMs on the target,
-     thus they are not missaligned.  */
+     thus they are not misaligned.  */
   if (TREE_CODE (ref) == TARGET_MEM_REF)
     return false;
 
@@ -2983,6 +2984,7 @@ get_computation_aff (struct loop *loop,
   unsigned HOST_WIDE_INT ustepi, cstepi;
   HOST_WIDE_INT ratioi;
   struct affine_tree_combination cbase_aff, expr_aff;
+  tree cstep_orig = cstep, ustep_orig = ustep;
 
   if (TYPE_PRECISION (utype) > TYPE_PRECISION (ctype))
     {
@@ -3012,13 +3014,18 @@ get_computation_aff (struct loop *loop,
       expr = fold_convert (uutype, expr);
       cbase = fold_convert (uutype, cbase);
       cstep = fold_convert (uutype, cstep);
+
+      /* If the conversion is not noop, we must take it into account when
+        considering the value of the step.  */
+      if (TYPE_PRECISION (utype) < TYPE_PRECISION (ctype))
+       cstep_orig = cstep;
     }
 
-  if (cst_and_fits_in_hwi (cstep)
-      && cst_and_fits_in_hwi (ustep))
+  if (cst_and_fits_in_hwi (cstep_orig)
+      && cst_and_fits_in_hwi (ustep_orig))
     {
-      ustepi = int_cst_value (ustep);
-      cstepi = int_cst_value (cstep);
+      ustepi = int_cst_value (ustep_orig);
+      cstepi = int_cst_value (cstep_orig);
 
       if (!divide (TYPE_PRECISION (uutype), ustepi, cstepi, &ratioi))
        {
@@ -3032,7 +3039,7 @@ get_computation_aff (struct loop *loop,
     }
   else
     {
-      ratio = constant_multiple_of (uutype, ustep, cstep);
+      ratio = constant_multiple_of (uutype, ustep_orig, cstep_orig);
       if (!ratio)
        return false;
 
@@ -3053,7 +3060,7 @@ get_computation_aff (struct loop *loop,
 
   /* We may need to shift the value if we are after the increment.  */
   if (stmt_after_increment (loop, cand, at))
-    cbase = fold (build2 (PLUS_EXPR, uutype, cbase, cstep));
+    cbase = fold_build2 (PLUS_EXPR, uutype, cbase, cstep);
 
   /* use = ubase - ratio * cbase + ratio * var.
 
@@ -3913,9 +3920,9 @@ iv_value (struct iv *iv, tree niter)
   tree type = TREE_TYPE (iv->base);
 
   niter = fold_convert (type, niter);
-  val = fold (build2 (MULT_EXPR, type, iv->step, niter));
+  val = fold_build2 (MULT_EXPR, type, iv->step, niter);
 
-  return fold (build2 (PLUS_EXPR, type, iv->base, val));
+  return fold_build2 (PLUS_EXPR, type, iv->base, val);
 }
 
 /* Computes value of candidate CAND at position AT in iteration NITER.  */
@@ -3927,7 +3934,7 @@ cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter)
   tree type = TREE_TYPE (cand->iv->base);
 
   if (stmt_after_increment (loop, cand, at))
-    val = fold (build2 (PLUS_EXPR, type, val, cand->iv->step));
+    val = fold_build2 (PLUS_EXPR, type, val, cand->iv->step);
 
   return val;
 }
@@ -4026,9 +4033,9 @@ may_eliminate_iv (struct ivopts_data *data,
   else
     wider_type = nit_type;
 
-  if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
-                                      fold_convert (wider_type, period),
-                                      fold_convert (wider_type, nit)))))
+  if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
+                                     fold_convert (wider_type, period),
+                                     fold_convert (wider_type, nit))))
     return false;
 
   *bound = cand_value_at (loop, cand, use->stmt, nit);