patches/gcc/4.3.2/360-fix-expensive-optimize.patch
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
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