patches/gcc/4.3.2/360-fix-expensive-optimize.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Jan 12 19:24:03 2010 +0100 (2010-01-12)
changeset 1761 88020b2c3246
permissions -rw-r--r--
scripts/functions: change handling of nochdir

- 'nochdir' must be the first option
- have systematic pushd/popd, even if nochdir
yann@1183
     1
PR tree-optimization/32044
yann@1183
     2
yann@1183
     3
From: rakdver
yann@1183
     4
Date: 2008-12-12 21:32:47 +0100
yann@1183
     5
yann@1183
     6
* tree-scalar-evolution.h (expression_expensive_p): Declare.
yann@1183
     7
* tree-scalar-evolution.c (expression_expensive_p): New function.
yann@1183
     8
(scev_const_prop): Avoid introducing expensive expressions.
yann@1183
     9
* tree-ssa-loop-ivopts.c (may_eliminate_iv): Ditto.
yann@1183
    10
yann@1183
    11
* gcc.dg/pr34027-1.c: Change outcome.
yann@1183
    12
* gcc.dg/tree-ssa/pr32044.c: New test.
yann@1183
    13
yann@1183
    14
cherry picked from svn://gcc.gnu.org/svn/gcc/trunk, rev 142719 and adapted to
yann@1183
    15
apply on gcc 4.3.2
yann@1183
    16
yann@1183
    17
------------------------------------------------------------------------
yann@1183
    18
Index: gcc-4.3.2/gcc/tree-scalar-evolution.c
yann@1183
    19
===================================================================
yann@1183
    20
--- gcc-4.3.2.orig/gcc/tree-scalar-evolution.c	2009-01-28 10:14:37.000000000 +0100
yann@1183
    21
+++ gcc-4.3.2/gcc/tree-scalar-evolution.c	2009-01-28 10:17:50.000000000 +0100
yann@1183
    22
@@ -2716,6 +2716,50 @@
yann@1183
    23
   scalar_evolution_info = NULL;
yann@1183
    24
 }
yann@1183
    25
 
yann@1183
    26
+/* Returns true if the expression EXPR is considered to be too expensive
yann@1183
    27
+   for scev_const_prop.  */
yann@1183
    28
+
yann@1183
    29
+bool
yann@1183
    30
+expression_expensive_p (tree expr)
yann@1183
    31
+{
yann@1183
    32
+  enum tree_code code;
yann@1183
    33
+
yann@1183
    34
+  if (is_gimple_val (expr))
yann@1183
    35
+    return false;
yann@1183
    36
+
yann@1183
    37
+  code = TREE_CODE (expr);
yann@1183
    38
+  if (code == TRUNC_DIV_EXPR
yann@1183
    39
+      || code == CEIL_DIV_EXPR
yann@1183
    40
+      || code == FLOOR_DIV_EXPR
yann@1183
    41
+      || code == ROUND_DIV_EXPR
yann@1183
    42
+      || code == TRUNC_MOD_EXPR
yann@1183
    43
+      || code == CEIL_MOD_EXPR
yann@1183
    44
+      || code == FLOOR_MOD_EXPR
yann@1183
    45
+      || code == ROUND_MOD_EXPR
yann@1183
    46
+      || code == EXACT_DIV_EXPR)
yann@1183
    47
+    {
yann@1183
    48
+      /* Division by power of two is usually cheap, so we allow it.
yann@1183
    49
+	 Forbid anything else.  */
yann@1183
    50
+      if (!integer_pow2p (TREE_OPERAND (expr, 1)))
yann@1183
    51
+	return true;
yann@1183
    52
+    }
yann@1183
    53
+
yann@1183
    54
+  switch (TREE_CODE_CLASS (code))
yann@1183
    55
+    {
yann@1183
    56
+    case tcc_binary:
yann@1183
    57
+    case tcc_comparison:
yann@1183
    58
+      if (expression_expensive_p (TREE_OPERAND (expr, 1)))
yann@1183
    59
+	return true;
yann@1183
    60
+
yann@1183
    61
+      /* Fallthru.  */
yann@1183
    62
+    case tcc_unary:
yann@1183
    63
+      return expression_expensive_p (TREE_OPERAND (expr, 0));
yann@1183
    64
+
yann@1183
    65
+    default:
yann@1183
    66
+      return true;
yann@1183
    67
+    }
yann@1183
    68
+}
yann@1183
    69
+
yann@1183
    70
 /* Replace ssa names for that scev can prove they are constant by the
yann@1183
    71
    appropriate constants.  Also perform final value replacement in loops,
yann@1183
    72
    in case the replacement expressions are cheap.
yann@1183
    73
@@ -2802,12 +2846,6 @@
yann@1183
    74
 	continue;
yann@1183
    75
 
yann@1183
    76
       niter = number_of_latch_executions (loop);
yann@1183
    77
-      /* We used to check here whether the computation of NITER is expensive,
yann@1183
    78
-	 and avoided final value elimination if that is the case.  The problem
yann@1183
    79
-	 is that it is hard to evaluate whether the expression is too
yann@1183
    80
-	 expensive, as we do not know what optimization opportunities the
yann@1183
    81
-	 the elimination of the final value may reveal.  Therefore, we now
yann@1183
    82
-	 eliminate the final values of induction variables unconditionally.  */
yann@1183
    83
       if (niter == chrec_dont_know)
yann@1183
    84
 	continue;
yann@1183
    85
 
yann@1183
    86
@@ -2838,7 +2876,15 @@
yann@1183
    87
 	      /* Moving the computation from the loop may prolong life range
yann@1183
    88
 		 of some ssa names, which may cause problems if they appear
yann@1183
    89
 		 on abnormal edges.  */
yann@1183
    90
-	      || contains_abnormal_ssa_name_p (def))
yann@1183
    91
+	      || contains_abnormal_ssa_name_p (def)
yann@1183
    92
+	      /* Do not emit expensive expressions.  The rationale is that
yann@1183
    93
+		 when someone writes a code like
yann@1183
    94
+
yann@1183
    95
+		 while (n > 45) n -= 45;
yann@1183
    96
+
yann@1183
    97
+		 he probably knows that n is not large, and does not want it
yann@1183
    98
+		 to be turned into n %= 45.  */
yann@1183
    99
+	      || expression_expensive_p (def))
yann@1183
   100
 	    continue;
yann@1183
   101
 
yann@1183
   102
 	  /* Eliminate the PHI node and replace it by a computation outside
yann@1183
   103
Index: gcc-4.3.2/gcc/tree-scalar-evolution.h
yann@1183
   104
===================================================================
yann@1183
   105
--- gcc-4.3.2.orig/gcc/tree-scalar-evolution.h	2009-01-28 10:22:47.000000000 +0100
yann@1183
   106
+++ gcc-4.3.2/gcc/tree-scalar-evolution.h	2009-01-28 10:23:10.000000000 +0100
yann@1183
   107
@@ -35,6 +35,7 @@
yann@1183
   108
 extern void scev_analysis (void);
yann@1183
   109
 unsigned int scev_const_prop (void);
yann@1183
   110
 
yann@1183
   111
+bool expression_expensive_p (tree);
yann@1183
   112
 extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
yann@1183
   113
 
yann@1183
   114
 /* Returns the loop of the polynomial chrec CHREC.  */
yann@1183
   115
Index: gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c
yann@1183
   116
===================================================================
yann@1183
   117
--- gcc-4.3.2.orig/gcc/testsuite/gcc.dg/pr34027-1.c	2009-01-28 10:24:09.000000000 +0100
yann@1183
   118
+++ gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c	2009-01-28 10:24:43.000000000 +0100
yann@1183
   119
@@ -8,5 +8,9 @@
yann@1183
   120
   return ns;
yann@1183
   121
 }
yann@1183
   122
 
yann@1183
   123
-/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
yann@1183
   124
+/* This test was originally introduced to test that we transform
yann@1183
   125
+   to ns % 10000.  See the discussion of PR 32044 why we do not do
yann@1183
   126
+   that anymore.  */
yann@1183
   127
+/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
yann@1183
   128
+/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
yann@1183
   129
 /* { dg-final { cleanup-tree-dump "optimized" } } */
yann@1183
   130
Index: gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c
yann@1183
   131
===================================================================
yann@1183
   132
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
yann@1183
   133
+++ gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c	2009-01-28 10:25:50.000000000 +0100
yann@1183
   134
@@ -0,0 +1,55 @@
yann@1183
   135
+/* { dg-do compile } */
yann@1183
   136
+/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */
yann@1183
   137
+
yann@1183
   138
+int foo (int n)
yann@1183
   139
+{
yann@1183
   140
+  while (n >= 45)
yann@1183
   141
+    n -= 45;
yann@1183
   142
+
yann@1183
   143
+  return n;
yann@1183
   144
+}
yann@1183
   145
+
yann@1183
   146
+int bar (int n)
yann@1183
   147
+{
yann@1183
   148
+  while (n >= 64)
yann@1183
   149
+    n -= 64;
yann@1183
   150
+
yann@1183
   151
+  return n;
yann@1183
   152
+}
yann@1183
   153
+
yann@1183
   154
+int bla (int n)
yann@1183
   155
+{
yann@1183
   156
+  int i = 0;
yann@1183
   157
+
yann@1183
   158
+  while (n >= 45)
yann@1183
   159
+    {
yann@1183
   160
+      i++;
yann@1183
   161
+      n -= 45;
yann@1183
   162
+    }
yann@1183
   163
+
yann@1183
   164
+  return i;
yann@1183
   165
+}
yann@1183
   166
+
yann@1183
   167
+int baz (int n)
yann@1183
   168
+{
yann@1183
   169
+  int i = 0;
yann@1183
   170
+
yann@1183
   171
+  while (n >= 64)
yann@1183
   172
+    {
yann@1183
   173
+      i++;
yann@1183
   174
+      n -= 64;
yann@1183
   175
+    }
yann@1183
   176
+
yann@1183
   177
+  return i;
yann@1183
   178
+}
yann@1183
   179
+
yann@1183
   180
+/* The loops computing division/modulo by 64 should be eliminated.  */
yann@1183
   181
+/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */
yann@1183
   182
+
yann@1183
   183
+/* There should be no division/modulo in the final dump (division and modulo
yann@1183
   184
+   by 64 are done using bit operations).  */
yann@1183
   185
+/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */
yann@1183
   186
+/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */
yann@1183
   187
+
yann@1183
   188
+/* { dg-final { cleanup-tree-dump "empty" } } */
yann@1183
   189
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
yann@1183
   190
Index: gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c
yann@1183
   191
===================================================================
yann@1183
   192
--- gcc-4.3.2.orig/gcc/tree-ssa-loop-ivopts.c	2009-01-28 10:26:04.000000000 +0100
yann@1183
   193
+++ gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c	2009-01-28 10:27:09.000000000 +0100
yann@1183
   194
@@ -3778,7 +3778,12 @@
yann@1183
   195
     return false;
yann@1183
   196
 
yann@1183
   197
   cand_value_at (loop, cand, use->stmt, nit, &bnd);
yann@1183
   198
+
yann@1183
   199
   *bound = aff_combination_to_tree (&bnd);
yann@1183
   200
+  /* It is unlikely that computing the number of iterations using division
yann@1183
   201
+     would be more profitable than keeping the original induction variable.  */
yann@1183
   202
+  if (expression_expensive_p (*bound))
yann@1183
   203
+    return false;
yann@1183
   204
   return true;
yann@1183
   205
 }
yann@1183
   206
 
yann@1183
   207