toolchain/gcc: fix PR 32044 patch
[avatt.git] / toolchain / gcc / 4.3.2 / 901-backport-fix-for-bug-32044.patch
blob9337bf9eed11e8c8642df2ec48da4cd92219e28f
1 Index: gcc-4.3.2/gcc/tree-scalar-evolution.c
2 ===================================================================
3 --- gcc-4.3.2.orig/gcc/tree-scalar-evolution.c 2009-01-28 10:14:37.000000000 +0100
4 +++ gcc-4.3.2/gcc/tree-scalar-evolution.c 2009-01-28 10:17:50.000000000 +0100
5 @@ -2716,6 +2716,50 @@
6 scalar_evolution_info = NULL;
9 +/* Returns true if the expression EXPR is considered to be too expensive
10 + for scev_const_prop. */
12 +bool
13 +expression_expensive_p (tree expr)
15 + enum tree_code code;
17 + if (is_gimple_val (expr))
18 + return false;
20 + code = TREE_CODE (expr);
21 + if (code == TRUNC_DIV_EXPR
22 + || code == CEIL_DIV_EXPR
23 + || code == FLOOR_DIV_EXPR
24 + || code == ROUND_DIV_EXPR
25 + || code == TRUNC_MOD_EXPR
26 + || code == CEIL_MOD_EXPR
27 + || code == FLOOR_MOD_EXPR
28 + || code == ROUND_MOD_EXPR
29 + || code == EXACT_DIV_EXPR)
30 + {
31 + /* Division by power of two is usually cheap, so we allow it.
32 + Forbid anything else. */
33 + if (!integer_pow2p (TREE_OPERAND (expr, 1)))
34 + return true;
35 + }
37 + switch (TREE_CODE_CLASS (code))
38 + {
39 + case tcc_binary:
40 + case tcc_comparison:
41 + if (expression_expensive_p (TREE_OPERAND (expr, 1)))
42 + return true;
44 + /* Fallthru. */
45 + case tcc_unary:
46 + return expression_expensive_p (TREE_OPERAND (expr, 0));
48 + default:
49 + return true;
50 + }
53 /* Replace ssa names for that scev can prove they are constant by the
54 appropriate constants. Also perform final value replacement in loops,
55 in case the replacement expressions are cheap.
56 @@ -2802,12 +2846,6 @@
57 continue;
59 niter = number_of_latch_executions (loop);
60 - /* We used to check here whether the computation of NITER is expensive,
61 - and avoided final value elimination if that is the case. The problem
62 - is that it is hard to evaluate whether the expression is too
63 - expensive, as we do not know what optimization opportunities the
64 - the elimination of the final value may reveal. Therefore, we now
65 - eliminate the final values of induction variables unconditionally. */
66 if (niter == chrec_dont_know)
67 continue;
69 @@ -2838,7 +2876,15 @@
70 /* Moving the computation from the loop may prolong life range
71 of some ssa names, which may cause problems if they appear
72 on abnormal edges. */
73 - || contains_abnormal_ssa_name_p (def))
74 + || contains_abnormal_ssa_name_p (def)
75 + /* Do not emit expensive expressions. The rationale is that
76 + when someone writes a code like
78 + while (n > 45) n -= 45;
80 + he probably knows that n is not large, and does not want it
81 + to be turned into n %= 45. */
82 + || expression_expensive_p (def))
83 continue;
85 /* Eliminate the PHI node and replace it by a computation outside
86 Index: gcc-4.3.2/gcc/tree-scalar-evolution.h
87 ===================================================================
88 --- gcc-4.3.2.orig/gcc/tree-scalar-evolution.h 2009-01-28 10:22:47.000000000 +0100
89 +++ gcc-4.3.2/gcc/tree-scalar-evolution.h 2009-01-28 10:23:10.000000000 +0100
90 @@ -35,6 +35,7 @@
91 extern void scev_analysis (void);
92 unsigned int scev_const_prop (void);
94 +bool expression_expensive_p (tree);
95 extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
97 /* Returns the loop of the polynomial chrec CHREC. */
98 Index: gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c
99 ===================================================================
100 --- gcc-4.3.2.orig/gcc/testsuite/gcc.dg/pr34027-1.c 2009-01-28 10:24:09.000000000 +0100
101 +++ gcc-4.3.2/gcc/testsuite/gcc.dg/pr34027-1.c 2009-01-28 10:24:43.000000000 +0100
102 @@ -8,5 +8,9 @@
103 return ns;
106 -/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
107 +/* This test was originally introduced to test that we transform
108 + to ns % 10000. See the discussion of PR 32044 why we do not do
109 + that anymore. */
110 +/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */
111 +/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */
112 /* { dg-final { cleanup-tree-dump "optimized" } } */
113 Index: gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c
114 ===================================================================
115 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
116 +++ gcc-4.3.2/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c 2009-01-28 10:25:50.000000000 +0100
117 @@ -0,0 +1,55 @@
118 +/* { dg-do compile } */
119 +/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */
121 +int foo (int n)
123 + while (n >= 45)
124 + n -= 45;
126 + return n;
129 +int bar (int n)
131 + while (n >= 64)
132 + n -= 64;
134 + return n;
137 +int bla (int n)
139 + int i = 0;
141 + while (n >= 45)
143 + i++;
144 + n -= 45;
147 + return i;
150 +int baz (int n)
152 + int i = 0;
154 + while (n >= 64)
156 + i++;
157 + n -= 64;
160 + return i;
163 +/* The loops computing division/modulo by 64 should be eliminated. */
164 +/* { dg-final { scan-tree-dump-times "Removing empty loop" 2 "empty" } } */
166 +/* There should be no division/modulo in the final dump (division and modulo
167 + by 64 are done using bit operations). */
168 +/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */
169 +/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */
171 +/* { dg-final { cleanup-tree-dump "empty" } } */
172 +/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
173 Index: gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c
174 ===================================================================
175 --- gcc-4.3.2.orig/gcc/tree-ssa-loop-ivopts.c 2009-01-28 10:26:04.000000000 +0100
176 +++ gcc-4.3.2/gcc/tree-ssa-loop-ivopts.c 2009-01-28 10:27:09.000000000 +0100
177 @@ -3778,7 +3778,12 @@
178 return false;
180 cand_value_at (loop, cand, use->stmt, nit, &bnd);
182 *bound = aff_combination_to_tree (&bnd);
183 + /* It is unlikely that computing the number of iterations using division
184 + would be more profitable than keeping the original induction variable. */
185 + if (expression_expensive_p (*bound))
186 + return false;
187 return true;