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 |
|