OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-scalar-evolution.c
index e3d60e9..f306ab8 100644 (file)
@@ -2805,6 +2805,50 @@ scev_finalize (void)
   scalar_evolution_info = NULL;
 }
 
+/* Returns true if the expression EXPR is considered to be too expensive
+   for scev_const_prop.  */
+
+bool
+expression_expensive_p (tree expr)
+{
+  enum tree_code code;
+
+  if (is_gimple_val (expr))
+    return false;
+
+  code = TREE_CODE (expr);
+  if (code == TRUNC_DIV_EXPR
+      || code == CEIL_DIV_EXPR
+      || code == FLOOR_DIV_EXPR
+      || code == ROUND_DIV_EXPR
+      || code == TRUNC_MOD_EXPR
+      || code == CEIL_MOD_EXPR
+      || code == FLOOR_MOD_EXPR
+      || code == ROUND_MOD_EXPR
+      || code == EXACT_DIV_EXPR)
+    {
+      /* Division by power of two is usually cheap, so we allow it.
+        Forbid anything else.  */
+      if (!integer_pow2p (TREE_OPERAND (expr, 1)))
+       return true;
+    }
+
+  switch (TREE_CODE_CLASS (code))
+    {
+    case tcc_binary:
+    case tcc_comparison:
+      if (expression_expensive_p (TREE_OPERAND (expr, 1)))
+       return true;
+
+      /* Fallthru.  */
+    case tcc_unary:
+      return expression_expensive_p (TREE_OPERAND (expr, 0));
+
+    default:
+      return true;
+    }
+}
+
 /* Replace ssa names for that scev can prove they are constant by the
    appropriate constants.  Also perform final value replacement in loops,
    in case the replacement expressions are cheap.
@@ -2896,12 +2940,6 @@ scev_const_prop (void)
        continue;
 
       niter = number_of_latch_executions (loop);
-      /* We used to check here whether the computation of NITER is expensive,
-        and avoided final value elimination if that is the case.  The problem
-        is that it is hard to evaluate whether the expression is too
-        expensive, as we do not know what optimization opportunities the
-        elimination of the final value may reveal.  Therefore, we now
-        eliminate the final values of induction variables unconditionally.  */
       if (niter == chrec_dont_know)
        continue;
 
@@ -2938,7 +2976,15 @@ scev_const_prop (void)
              /* Moving the computation from the loop may prolong life range
                 of some ssa names, which may cause problems if they appear
                 on abnormal edges.  */
-             || contains_abnormal_ssa_name_p (def))
+             || contains_abnormal_ssa_name_p (def)
+             /* Do not emit expensive expressions.  The rationale is that
+                when someone writes a code like
+
+                while (n > 45) n -= 45;
+
+                he probably knows that n is not large, and does not want it
+                to be turned into n %= 45.  */
+             || expression_expensive_p (def))
            {
              gsi_next (&psi);
              continue;