]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/32044 (final value replacement too aggressive for...
authorRichard Guenther <rguenther@suse.de>
Tue, 26 May 2009 10:17:19 +0000 (10:17 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 26 May 2009 10:17:19 +0000 (10:17 +0000)
2009-05-26  Richard Guenther  <rguenther@suse.de>

Backport from mainline
2008-12-12  Zdenek Dvorak  <ook@ucw.cz>

PR tree-optimization/32044
* tree-scalar-evolution.h (expression_expensive_p): Declare.
* tree-scalar-evolution.c (expression_expensive_p): New function.
(scev_const_prop): Avoid introducing expensive expressions.
* tree-ssa-loop-ivopts.c (may_eliminate_iv): Ditto.

* gcc.dg/pr34027-1.c: Change outcome.
* gcc.dg/tree-ssa/pr32044.c: New test.

From-SVN: r147865

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr34027-1.c
gcc/testsuite/gcc.dg/tree-ssa/pr32044.c [new file with mode: 0644]
gcc/tree-scalar-evolution.c
gcc/tree-scalar-evolution.h
gcc/tree-ssa-loop-ivopts.c

index 6d89a32f93c75adbf556d1727f0cff8be8ce32fc..417bc039f494185b19374492db95aa413fb55d0b 100644 (file)
@@ -1,3 +1,14 @@
+2009-05-26  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2008-12-12  Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/32044
+       * tree-scalar-evolution.h (expression_expensive_p): Declare.
+       * tree-scalar-evolution.c (expression_expensive_p): New function.
+       (scev_const_prop): Avoid introducing expensive expressions.
+       * tree-ssa-loop-ivopts.c (may_eliminate_iv): Ditto.
+
 2009-05-23  Eric Botcazou  <ebotcazou@adacore.com>
 
        * doc/passes.texi: Standardize spelling of RTL, Tree and Tree SSA.
index e8da9b3c7b4efdd68d7f35d0622fd96fc6d491b5..f82b286b9f08296009e760ff2eb7de9b80cc1a77 100644 (file)
@@ -1,3 +1,12 @@
+2009-05-26  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2008-12-12  Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/32044
+       * gcc.dg/pr34027-1.c: Change outcome.
+       * gcc.dg/tree-ssa/pr32044.c: New test.
+
 2009-05-18  Dodji Seketeli  <dodji@redhat.com>
 
        PR debug/40109
index 532e4976dc37eb3de322662580a60973131860d6..8e8872a51332c0dcd076ba4f142ec881f7ce8a70 100644 (file)
@@ -8,5 +8,9 @@ unsigned long foobar(unsigned long ns)
   return ns;
 }
 
-/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
+/* This test was originally introduced to test that we transform
+   to ns % 10000.  See the discussion of PR 32044 why we do not do
+   that anymore.  */
+/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c b/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c
new file mode 100644 (file)
index 0000000..0c1a582
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */
+
+int foo (int n)
+{
+  while (n >= 45)
+    n -= 45;
+
+  return n;
+}
+
+int bar (int n)
+{
+  while (n >= 64)
+    n -= 64;
+
+  return n;
+}
+
+int bla (int n)
+{
+  int i = 0;
+
+  while (n >= 45)
+    {
+      i++;
+      n -= 45;
+    }
+
+  return i;
+}
+
+int baz (int n)
+{
+  int i = 0;
+
+  while (n >= 64)
+    {
+      i++;
+      n -= 64;
+    }
+
+  return i;
+}
+
+/* The loops computing division/modulo by 64 should be eliminated.  */
+/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */
+
+/* There should be no division/modulo in the final dump (division and modulo
+   by 64 are done using bit operations).  */
+/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */
+/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */
+
+/* { dg-final { cleanup-tree-dump "empty" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
index 83728fce324aa6bbfc5714a04f45bcc1f134edf9..e7563784742cb0746d9a2f3aa5a7b6b4c931ce4f 100644 (file)
@@ -2714,6 +2714,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.
@@ -2800,12 +2844,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
-        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;
 
@@ -2836,7 +2874,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))
            continue;
 
          /* Eliminate the PHI node and replace it by a computation outside
index a2ba5848046480ffd1abf728124da44556d3f86b..3dd928aee9ca3c2e118f2050a04058ea94118312 100644 (file)
@@ -35,6 +35,7 @@ extern void gather_stats_on_scev_database (void);
 extern void scev_analysis (void);
 unsigned int scev_const_prop (void);
 
+bool expression_expensive_p (tree);
 extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
 
 /* Returns the loop of the polynomial chrec CHREC.  */
index 5936e2b7ec768bebcb74b0d7d818ed69242f714c..78b440906929d1c13955a554f3b1f7fa2c1990e5 100644 (file)
@@ -3776,7 +3776,12 @@ may_eliminate_iv (struct ivopts_data *data,
     return false;
 
   cand_value_at (loop, cand, use->stmt, nit, &bnd);
+
   *bound = aff_combination_to_tree (&bnd);
+  /* It is unlikely that computing the number of iterations using division
+     would be more profitable than keeping the original induction variable.  */
+  if (expression_expensive_p (*bound))
+    return false;
   return true;
 }