1*e4b17023SJohn Marino /* Induction variable canonicalization.
2*e4b17023SJohn Marino Copyright (C) 2004, 2005, 2007, 2008, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
8*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
10*e4b17023SJohn Marino later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
13*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino /* This pass detects the loops that iterate a constant number of times,
22*e4b17023SJohn Marino adds a canonical induction variable (step -1, tested against 0)
23*e4b17023SJohn Marino and replaces the exit test. This enables the less powerful rtl
24*e4b17023SJohn Marino level analysis to use this information.
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino This might spoil the code in some cases (by increasing register pressure).
27*e4b17023SJohn Marino Note that in the case the new variable is not needed, ivopts will get rid
28*e4b17023SJohn Marino of it, so it might only be a problem when there are no other linear induction
29*e4b17023SJohn Marino variables. In that case the created optimization possibilities are likely
30*e4b17023SJohn Marino to pay up.
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino Additionally in case we detect that it is beneficial to unroll the
33*e4b17023SJohn Marino loop completely, we do it right here to expose the optimization
34*e4b17023SJohn Marino possibilities to the following passes. */
35*e4b17023SJohn Marino
36*e4b17023SJohn Marino #include "config.h"
37*e4b17023SJohn Marino #include "system.h"
38*e4b17023SJohn Marino #include "coretypes.h"
39*e4b17023SJohn Marino #include "tm.h"
40*e4b17023SJohn Marino #include "tree.h"
41*e4b17023SJohn Marino #include "tm_p.h"
42*e4b17023SJohn Marino #include "basic-block.h"
43*e4b17023SJohn Marino #include "tree-pretty-print.h"
44*e4b17023SJohn Marino #include "gimple-pretty-print.h"
45*e4b17023SJohn Marino #include "tree-flow.h"
46*e4b17023SJohn Marino #include "tree-dump.h"
47*e4b17023SJohn Marino #include "cfgloop.h"
48*e4b17023SJohn Marino #include "tree-pass.h"
49*e4b17023SJohn Marino #include "tree-chrec.h"
50*e4b17023SJohn Marino #include "tree-scalar-evolution.h"
51*e4b17023SJohn Marino #include "params.h"
52*e4b17023SJohn Marino #include "flags.h"
53*e4b17023SJohn Marino #include "tree-inline.h"
54*e4b17023SJohn Marino #include "target.h"
55*e4b17023SJohn Marino
56*e4b17023SJohn Marino /* Specifies types of loops that may be unrolled. */
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino enum unroll_level
59*e4b17023SJohn Marino {
60*e4b17023SJohn Marino UL_SINGLE_ITER, /* Only loops that exit immediately in the first
61*e4b17023SJohn Marino iteration. */
62*e4b17023SJohn Marino UL_NO_GROWTH, /* Only loops whose unrolling will not cause increase
63*e4b17023SJohn Marino of code size. */
64*e4b17023SJohn Marino UL_ALL /* All suitable loops. */
65*e4b17023SJohn Marino };
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino /* Adds a canonical induction variable to LOOP iterating NITER times. EXIT
68*e4b17023SJohn Marino is the exit edge whose condition is replaced. */
69*e4b17023SJohn Marino
70*e4b17023SJohn Marino static void
create_canonical_iv(struct loop * loop,edge exit,tree niter)71*e4b17023SJohn Marino create_canonical_iv (struct loop *loop, edge exit, tree niter)
72*e4b17023SJohn Marino {
73*e4b17023SJohn Marino edge in;
74*e4b17023SJohn Marino tree type, var;
75*e4b17023SJohn Marino gimple cond;
76*e4b17023SJohn Marino gimple_stmt_iterator incr_at;
77*e4b17023SJohn Marino enum tree_code cmp;
78*e4b17023SJohn Marino
79*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
80*e4b17023SJohn Marino {
81*e4b17023SJohn Marino fprintf (dump_file, "Added canonical iv to loop %d, ", loop->num);
82*e4b17023SJohn Marino print_generic_expr (dump_file, niter, TDF_SLIM);
83*e4b17023SJohn Marino fprintf (dump_file, " iterations.\n");
84*e4b17023SJohn Marino }
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino cond = last_stmt (exit->src);
87*e4b17023SJohn Marino in = EDGE_SUCC (exit->src, 0);
88*e4b17023SJohn Marino if (in == exit)
89*e4b17023SJohn Marino in = EDGE_SUCC (exit->src, 1);
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino /* Note that we do not need to worry about overflows, since
92*e4b17023SJohn Marino type of niter is always unsigned and all comparisons are
93*e4b17023SJohn Marino just for equality/nonequality -- i.e. everything works
94*e4b17023SJohn Marino with a modulo arithmetics. */
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino type = TREE_TYPE (niter);
97*e4b17023SJohn Marino niter = fold_build2 (PLUS_EXPR, type,
98*e4b17023SJohn Marino niter,
99*e4b17023SJohn Marino build_int_cst (type, 1));
100*e4b17023SJohn Marino incr_at = gsi_last_bb (in->src);
101*e4b17023SJohn Marino create_iv (niter,
102*e4b17023SJohn Marino build_int_cst (type, -1),
103*e4b17023SJohn Marino NULL_TREE, loop,
104*e4b17023SJohn Marino &incr_at, false, NULL, &var);
105*e4b17023SJohn Marino
106*e4b17023SJohn Marino cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
107*e4b17023SJohn Marino gimple_cond_set_code (cond, cmp);
108*e4b17023SJohn Marino gimple_cond_set_lhs (cond, var);
109*e4b17023SJohn Marino gimple_cond_set_rhs (cond, build_int_cst (type, 0));
110*e4b17023SJohn Marino update_stmt (cond);
111*e4b17023SJohn Marino }
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino unsigned
tree_num_loop_insns(struct loop * loop,eni_weights * weights)116*e4b17023SJohn Marino tree_num_loop_insns (struct loop *loop, eni_weights *weights)
117*e4b17023SJohn Marino {
118*e4b17023SJohn Marino basic_block *body = get_loop_body (loop);
119*e4b17023SJohn Marino gimple_stmt_iterator gsi;
120*e4b17023SJohn Marino unsigned size = 0, i;
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
123*e4b17023SJohn Marino for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
124*e4b17023SJohn Marino size += estimate_num_insns (gsi_stmt (gsi), weights);
125*e4b17023SJohn Marino free (body);
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino return size;
128*e4b17023SJohn Marino }
129*e4b17023SJohn Marino
130*e4b17023SJohn Marino /* Describe size of loop as detected by tree_estimate_loop_size. */
131*e4b17023SJohn Marino struct loop_size
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino /* Number of instructions in the loop. */
134*e4b17023SJohn Marino int overall;
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino /* Number of instructions that will be likely optimized out in
137*e4b17023SJohn Marino peeled iterations of loop (i.e. computation based on induction
138*e4b17023SJohn Marino variable where induction variable starts at known constant.) */
139*e4b17023SJohn Marino int eliminated_by_peeling;
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino /* Same statistics for last iteration of loop: it is smaller because
142*e4b17023SJohn Marino instructions after exit are not executed. */
143*e4b17023SJohn Marino int last_iteration;
144*e4b17023SJohn Marino int last_iteration_eliminated_by_peeling;
145*e4b17023SJohn Marino };
146*e4b17023SJohn Marino
147*e4b17023SJohn Marino /* Return true if OP in STMT will be constant after peeling LOOP. */
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino static bool
constant_after_peeling(tree op,gimple stmt,struct loop * loop)150*e4b17023SJohn Marino constant_after_peeling (tree op, gimple stmt, struct loop *loop)
151*e4b17023SJohn Marino {
152*e4b17023SJohn Marino affine_iv iv;
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino if (is_gimple_min_invariant (op))
155*e4b17023SJohn Marino return true;
156*e4b17023SJohn Marino
157*e4b17023SJohn Marino /* We can still fold accesses to constant arrays when index is known. */
158*e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
159*e4b17023SJohn Marino {
160*e4b17023SJohn Marino tree base = op;
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino /* First make fast look if we see constant array inside. */
163*e4b17023SJohn Marino while (handled_component_p (base))
164*e4b17023SJohn Marino base = TREE_OPERAND (base, 0);
165*e4b17023SJohn Marino if ((DECL_P (base) == VAR_DECL
166*e4b17023SJohn Marino && const_value_known_p (base))
167*e4b17023SJohn Marino || CONSTANT_CLASS_P (base))
168*e4b17023SJohn Marino {
169*e4b17023SJohn Marino /* If so, see if we understand all the indices. */
170*e4b17023SJohn Marino base = op;
171*e4b17023SJohn Marino while (handled_component_p (base))
172*e4b17023SJohn Marino {
173*e4b17023SJohn Marino if (TREE_CODE (base) == ARRAY_REF
174*e4b17023SJohn Marino && !constant_after_peeling (TREE_OPERAND (base, 1), stmt, loop))
175*e4b17023SJohn Marino return false;
176*e4b17023SJohn Marino base = TREE_OPERAND (base, 0);
177*e4b17023SJohn Marino }
178*e4b17023SJohn Marino return true;
179*e4b17023SJohn Marino }
180*e4b17023SJohn Marino return false;
181*e4b17023SJohn Marino }
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino /* Induction variables are constants. */
184*e4b17023SJohn Marino if (!simple_iv (loop, loop_containing_stmt (stmt), op, &iv, false))
185*e4b17023SJohn Marino return false;
186*e4b17023SJohn Marino if (!is_gimple_min_invariant (iv.base))
187*e4b17023SJohn Marino return false;
188*e4b17023SJohn Marino if (!is_gimple_min_invariant (iv.step))
189*e4b17023SJohn Marino return false;
190*e4b17023SJohn Marino return true;
191*e4b17023SJohn Marino }
192*e4b17023SJohn Marino
193*e4b17023SJohn Marino /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.
194*e4b17023SJohn Marino Return results in SIZE, estimate benefits for complete unrolling exiting by EXIT. */
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino static void
tree_estimate_loop_size(struct loop * loop,edge exit,struct loop_size * size)197*e4b17023SJohn Marino tree_estimate_loop_size (struct loop *loop, edge exit, struct loop_size *size)
198*e4b17023SJohn Marino {
199*e4b17023SJohn Marino basic_block *body = get_loop_body (loop);
200*e4b17023SJohn Marino gimple_stmt_iterator gsi;
201*e4b17023SJohn Marino unsigned int i;
202*e4b17023SJohn Marino bool after_exit;
203*e4b17023SJohn Marino
204*e4b17023SJohn Marino size->overall = 0;
205*e4b17023SJohn Marino size->eliminated_by_peeling = 0;
206*e4b17023SJohn Marino size->last_iteration = 0;
207*e4b17023SJohn Marino size->last_iteration_eliminated_by_peeling = 0;
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
210*e4b17023SJohn Marino fprintf (dump_file, "Estimating sizes for loop %i\n", loop->num);
211*e4b17023SJohn Marino for (i = 0; i < loop->num_nodes; i++)
212*e4b17023SJohn Marino {
213*e4b17023SJohn Marino if (exit && body[i] != exit->src
214*e4b17023SJohn Marino && dominated_by_p (CDI_DOMINATORS, body[i], exit->src))
215*e4b17023SJohn Marino after_exit = true;
216*e4b17023SJohn Marino else
217*e4b17023SJohn Marino after_exit = false;
218*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
219*e4b17023SJohn Marino fprintf (dump_file, " BB: %i, after_exit: %i\n", body[i]->index, after_exit);
220*e4b17023SJohn Marino
221*e4b17023SJohn Marino for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
222*e4b17023SJohn Marino {
223*e4b17023SJohn Marino gimple stmt = gsi_stmt (gsi);
224*e4b17023SJohn Marino int num = estimate_num_insns (stmt, &eni_size_weights);
225*e4b17023SJohn Marino bool likely_eliminated = false;
226*e4b17023SJohn Marino
227*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
228*e4b17023SJohn Marino {
229*e4b17023SJohn Marino fprintf (dump_file, " size: %3i ", num);
230*e4b17023SJohn Marino print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
231*e4b17023SJohn Marino }
232*e4b17023SJohn Marino
233*e4b17023SJohn Marino /* Look for reasons why we might optimize this stmt away. */
234*e4b17023SJohn Marino
235*e4b17023SJohn Marino /* Exit conditional. */
236*e4b17023SJohn Marino if (body[i] == exit->src && stmt == last_stmt (exit->src))
237*e4b17023SJohn Marino {
238*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
239*e4b17023SJohn Marino fprintf (dump_file, " Exit condition will be eliminated.\n");
240*e4b17023SJohn Marino likely_eliminated = true;
241*e4b17023SJohn Marino }
242*e4b17023SJohn Marino /* Sets of IV variables */
243*e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_ASSIGN
244*e4b17023SJohn Marino && constant_after_peeling (gimple_assign_lhs (stmt), stmt, loop))
245*e4b17023SJohn Marino {
246*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
247*e4b17023SJohn Marino fprintf (dump_file, " Induction variable computation will"
248*e4b17023SJohn Marino " be folded away.\n");
249*e4b17023SJohn Marino likely_eliminated = true;
250*e4b17023SJohn Marino }
251*e4b17023SJohn Marino /* Assignments of IV variables. */
252*e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_ASSIGN
253*e4b17023SJohn Marino && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
254*e4b17023SJohn Marino && constant_after_peeling (gimple_assign_rhs1 (stmt), stmt,loop)
255*e4b17023SJohn Marino && (gimple_assign_rhs_class (stmt) != GIMPLE_BINARY_RHS
256*e4b17023SJohn Marino || constant_after_peeling (gimple_assign_rhs2 (stmt),
257*e4b17023SJohn Marino stmt, loop)))
258*e4b17023SJohn Marino {
259*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
260*e4b17023SJohn Marino fprintf (dump_file, " Constant expression will be folded away.\n");
261*e4b17023SJohn Marino likely_eliminated = true;
262*e4b17023SJohn Marino }
263*e4b17023SJohn Marino /* Conditionals. */
264*e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_COND
265*e4b17023SJohn Marino && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
266*e4b17023SJohn Marino && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
267*e4b17023SJohn Marino {
268*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
269*e4b17023SJohn Marino fprintf (dump_file, " Constant conditional.\n");
270*e4b17023SJohn Marino likely_eliminated = true;
271*e4b17023SJohn Marino }
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino size->overall += num;
274*e4b17023SJohn Marino if (likely_eliminated)
275*e4b17023SJohn Marino size->eliminated_by_peeling += num;
276*e4b17023SJohn Marino if (!after_exit)
277*e4b17023SJohn Marino {
278*e4b17023SJohn Marino size->last_iteration += num;
279*e4b17023SJohn Marino if (likely_eliminated)
280*e4b17023SJohn Marino size->last_iteration_eliminated_by_peeling += num;
281*e4b17023SJohn Marino }
282*e4b17023SJohn Marino }
283*e4b17023SJohn Marino }
284*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
285*e4b17023SJohn Marino fprintf (dump_file, "size: %i-%i, last_iteration: %i-%i\n", size->overall,
286*e4b17023SJohn Marino size->eliminated_by_peeling, size->last_iteration,
287*e4b17023SJohn Marino size->last_iteration_eliminated_by_peeling);
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino free (body);
290*e4b17023SJohn Marino }
291*e4b17023SJohn Marino
292*e4b17023SJohn Marino /* Estimate number of insns of completely unrolled loop.
293*e4b17023SJohn Marino It is (NUNROLL + 1) * size of loop body with taking into account
294*e4b17023SJohn Marino the fact that in last copy everything after exit conditional
295*e4b17023SJohn Marino is dead and that some instructions will be eliminated after
296*e4b17023SJohn Marino peeling.
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino Loop body is likely going to simplify futher, this is difficult
299*e4b17023SJohn Marino to guess, we just decrease the result by 1/3. */
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino static unsigned HOST_WIDE_INT
estimated_unrolled_size(struct loop_size * size,unsigned HOST_WIDE_INT nunroll)302*e4b17023SJohn Marino estimated_unrolled_size (struct loop_size *size,
303*e4b17023SJohn Marino unsigned HOST_WIDE_INT nunroll)
304*e4b17023SJohn Marino {
305*e4b17023SJohn Marino HOST_WIDE_INT unr_insns = ((nunroll)
306*e4b17023SJohn Marino * (HOST_WIDE_INT) (size->overall
307*e4b17023SJohn Marino - size->eliminated_by_peeling));
308*e4b17023SJohn Marino if (!nunroll)
309*e4b17023SJohn Marino unr_insns = 0;
310*e4b17023SJohn Marino unr_insns += size->last_iteration - size->last_iteration_eliminated_by_peeling;
311*e4b17023SJohn Marino
312*e4b17023SJohn Marino unr_insns = unr_insns * 2 / 3;
313*e4b17023SJohn Marino if (unr_insns <= 0)
314*e4b17023SJohn Marino unr_insns = 1;
315*e4b17023SJohn Marino
316*e4b17023SJohn Marino return unr_insns;
317*e4b17023SJohn Marino }
318*e4b17023SJohn Marino
319*e4b17023SJohn Marino /* Tries to unroll LOOP completely, i.e. NITER times.
320*e4b17023SJohn Marino UL determines which loops we are allowed to unroll.
321*e4b17023SJohn Marino EXIT is the exit of the loop that should be eliminated. */
322*e4b17023SJohn Marino
323*e4b17023SJohn Marino static bool
try_unroll_loop_completely(struct loop * loop,edge exit,tree niter,enum unroll_level ul)324*e4b17023SJohn Marino try_unroll_loop_completely (struct loop *loop,
325*e4b17023SJohn Marino edge exit, tree niter,
326*e4b17023SJohn Marino enum unroll_level ul)
327*e4b17023SJohn Marino {
328*e4b17023SJohn Marino unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
329*e4b17023SJohn Marino gimple cond;
330*e4b17023SJohn Marino struct loop_size size;
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino if (loop->inner)
333*e4b17023SJohn Marino return false;
334*e4b17023SJohn Marino
335*e4b17023SJohn Marino if (!host_integerp (niter, 1))
336*e4b17023SJohn Marino return false;
337*e4b17023SJohn Marino n_unroll = tree_low_cst (niter, 1);
338*e4b17023SJohn Marino
339*e4b17023SJohn Marino max_unroll = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES);
340*e4b17023SJohn Marino if (n_unroll > max_unroll)
341*e4b17023SJohn Marino return false;
342*e4b17023SJohn Marino
343*e4b17023SJohn Marino if (n_unroll)
344*e4b17023SJohn Marino {
345*e4b17023SJohn Marino if (ul == UL_SINGLE_ITER)
346*e4b17023SJohn Marino return false;
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino tree_estimate_loop_size (loop, exit, &size);
349*e4b17023SJohn Marino ninsns = size.overall;
350*e4b17023SJohn Marino
351*e4b17023SJohn Marino unr_insns = estimated_unrolled_size (&size, n_unroll);
352*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
353*e4b17023SJohn Marino {
354*e4b17023SJohn Marino fprintf (dump_file, " Loop size: %d\n", (int) ninsns);
355*e4b17023SJohn Marino fprintf (dump_file, " Estimated size after unrolling: %d\n",
356*e4b17023SJohn Marino (int) unr_insns);
357*e4b17023SJohn Marino }
358*e4b17023SJohn Marino
359*e4b17023SJohn Marino if (unr_insns > ninsns
360*e4b17023SJohn Marino && (unr_insns
361*e4b17023SJohn Marino > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)))
362*e4b17023SJohn Marino {
363*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
364*e4b17023SJohn Marino fprintf (dump_file, "Not unrolling loop %d "
365*e4b17023SJohn Marino "(--param max-completely-peeled-insns limit reached).\n",
366*e4b17023SJohn Marino loop->num);
367*e4b17023SJohn Marino return false;
368*e4b17023SJohn Marino }
369*e4b17023SJohn Marino
370*e4b17023SJohn Marino if (ul == UL_NO_GROWTH
371*e4b17023SJohn Marino && unr_insns > ninsns)
372*e4b17023SJohn Marino {
373*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
374*e4b17023SJohn Marino fprintf (dump_file, "Not unrolling loop %d.\n", loop->num);
375*e4b17023SJohn Marino return false;
376*e4b17023SJohn Marino }
377*e4b17023SJohn Marino }
378*e4b17023SJohn Marino
379*e4b17023SJohn Marino if (n_unroll)
380*e4b17023SJohn Marino {
381*e4b17023SJohn Marino sbitmap wont_exit;
382*e4b17023SJohn Marino edge e;
383*e4b17023SJohn Marino unsigned i;
384*e4b17023SJohn Marino VEC (edge, heap) *to_remove = NULL;
385*e4b17023SJohn Marino
386*e4b17023SJohn Marino initialize_original_copy_tables ();
387*e4b17023SJohn Marino wont_exit = sbitmap_alloc (n_unroll + 1);
388*e4b17023SJohn Marino sbitmap_ones (wont_exit);
389*e4b17023SJohn Marino RESET_BIT (wont_exit, 0);
390*e4b17023SJohn Marino
391*e4b17023SJohn Marino if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
392*e4b17023SJohn Marino n_unroll, wont_exit,
393*e4b17023SJohn Marino exit, &to_remove,
394*e4b17023SJohn Marino DLTHE_FLAG_UPDATE_FREQ
395*e4b17023SJohn Marino | DLTHE_FLAG_COMPLETTE_PEEL))
396*e4b17023SJohn Marino {
397*e4b17023SJohn Marino free_original_copy_tables ();
398*e4b17023SJohn Marino free (wont_exit);
399*e4b17023SJohn Marino return false;
400*e4b17023SJohn Marino }
401*e4b17023SJohn Marino
402*e4b17023SJohn Marino FOR_EACH_VEC_ELT (edge, to_remove, i, e)
403*e4b17023SJohn Marino {
404*e4b17023SJohn Marino bool ok = remove_path (e);
405*e4b17023SJohn Marino gcc_assert (ok);
406*e4b17023SJohn Marino }
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino VEC_free (edge, heap, to_remove);
409*e4b17023SJohn Marino free (wont_exit);
410*e4b17023SJohn Marino free_original_copy_tables ();
411*e4b17023SJohn Marino }
412*e4b17023SJohn Marino
413*e4b17023SJohn Marino cond = last_stmt (exit->src);
414*e4b17023SJohn Marino if (exit->flags & EDGE_TRUE_VALUE)
415*e4b17023SJohn Marino gimple_cond_make_true (cond);
416*e4b17023SJohn Marino else
417*e4b17023SJohn Marino gimple_cond_make_false (cond);
418*e4b17023SJohn Marino update_stmt (cond);
419*e4b17023SJohn Marino update_ssa (TODO_update_ssa);
420*e4b17023SJohn Marino
421*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
422*e4b17023SJohn Marino fprintf (dump_file, "Unrolled loop %d completely.\n", loop->num);
423*e4b17023SJohn Marino
424*e4b17023SJohn Marino return true;
425*e4b17023SJohn Marino }
426*e4b17023SJohn Marino
427*e4b17023SJohn Marino /* Adds a canonical induction variable to LOOP if suitable.
428*e4b17023SJohn Marino CREATE_IV is true if we may create a new iv. UL determines
429*e4b17023SJohn Marino which loops we are allowed to completely unroll. If TRY_EVAL is true, we try
430*e4b17023SJohn Marino to determine the number of iterations of a loop by direct evaluation.
431*e4b17023SJohn Marino Returns true if cfg is changed. */
432*e4b17023SJohn Marino
433*e4b17023SJohn Marino static bool
canonicalize_loop_induction_variables(struct loop * loop,bool create_iv,enum unroll_level ul,bool try_eval)434*e4b17023SJohn Marino canonicalize_loop_induction_variables (struct loop *loop,
435*e4b17023SJohn Marino bool create_iv, enum unroll_level ul,
436*e4b17023SJohn Marino bool try_eval)
437*e4b17023SJohn Marino {
438*e4b17023SJohn Marino edge exit = NULL;
439*e4b17023SJohn Marino tree niter;
440*e4b17023SJohn Marino
441*e4b17023SJohn Marino niter = number_of_latch_executions (loop);
442*e4b17023SJohn Marino if (TREE_CODE (niter) == INTEGER_CST)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino exit = single_exit (loop);
445*e4b17023SJohn Marino if (!just_once_each_iteration_p (loop, exit->src))
446*e4b17023SJohn Marino return false;
447*e4b17023SJohn Marino }
448*e4b17023SJohn Marino else
449*e4b17023SJohn Marino {
450*e4b17023SJohn Marino /* If the loop has more than one exit, try checking all of them
451*e4b17023SJohn Marino for # of iterations determinable through scev. */
452*e4b17023SJohn Marino if (!single_exit (loop))
453*e4b17023SJohn Marino niter = find_loop_niter (loop, &exit);
454*e4b17023SJohn Marino
455*e4b17023SJohn Marino /* Finally if everything else fails, try brute force evaluation. */
456*e4b17023SJohn Marino if (try_eval
457*e4b17023SJohn Marino && (chrec_contains_undetermined (niter)
458*e4b17023SJohn Marino || TREE_CODE (niter) != INTEGER_CST))
459*e4b17023SJohn Marino niter = find_loop_niter_by_eval (loop, &exit);
460*e4b17023SJohn Marino
461*e4b17023SJohn Marino if (chrec_contains_undetermined (niter)
462*e4b17023SJohn Marino || TREE_CODE (niter) != INTEGER_CST)
463*e4b17023SJohn Marino return false;
464*e4b17023SJohn Marino }
465*e4b17023SJohn Marino
466*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
467*e4b17023SJohn Marino {
468*e4b17023SJohn Marino fprintf (dump_file, "Loop %d iterates ", loop->num);
469*e4b17023SJohn Marino print_generic_expr (dump_file, niter, TDF_SLIM);
470*e4b17023SJohn Marino fprintf (dump_file, " times.\n");
471*e4b17023SJohn Marino }
472*e4b17023SJohn Marino
473*e4b17023SJohn Marino if (try_unroll_loop_completely (loop, exit, niter, ul))
474*e4b17023SJohn Marino return true;
475*e4b17023SJohn Marino
476*e4b17023SJohn Marino if (create_iv)
477*e4b17023SJohn Marino create_canonical_iv (loop, exit, niter);
478*e4b17023SJohn Marino
479*e4b17023SJohn Marino return false;
480*e4b17023SJohn Marino }
481*e4b17023SJohn Marino
482*e4b17023SJohn Marino /* The main entry point of the pass. Adds canonical induction variables
483*e4b17023SJohn Marino to the suitable loops. */
484*e4b17023SJohn Marino
485*e4b17023SJohn Marino unsigned int
canonicalize_induction_variables(void)486*e4b17023SJohn Marino canonicalize_induction_variables (void)
487*e4b17023SJohn Marino {
488*e4b17023SJohn Marino loop_iterator li;
489*e4b17023SJohn Marino struct loop *loop;
490*e4b17023SJohn Marino bool changed = false;
491*e4b17023SJohn Marino
492*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, 0)
493*e4b17023SJohn Marino {
494*e4b17023SJohn Marino changed |= canonicalize_loop_induction_variables (loop,
495*e4b17023SJohn Marino true, UL_SINGLE_ITER,
496*e4b17023SJohn Marino true);
497*e4b17023SJohn Marino }
498*e4b17023SJohn Marino
499*e4b17023SJohn Marino /* Clean up the information about numbers of iterations, since brute force
500*e4b17023SJohn Marino evaluation could reveal new information. */
501*e4b17023SJohn Marino scev_reset ();
502*e4b17023SJohn Marino
503*e4b17023SJohn Marino if (changed)
504*e4b17023SJohn Marino return TODO_cleanup_cfg;
505*e4b17023SJohn Marino return 0;
506*e4b17023SJohn Marino }
507*e4b17023SJohn Marino
508*e4b17023SJohn Marino /* Unroll LOOPS completely if they iterate just few times. Unless
509*e4b17023SJohn Marino MAY_INCREASE_SIZE is true, perform the unrolling only if the
510*e4b17023SJohn Marino size of the code does not increase. */
511*e4b17023SJohn Marino
512*e4b17023SJohn Marino unsigned int
tree_unroll_loops_completely(bool may_increase_size,bool unroll_outer)513*e4b17023SJohn Marino tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
514*e4b17023SJohn Marino {
515*e4b17023SJohn Marino loop_iterator li;
516*e4b17023SJohn Marino struct loop *loop;
517*e4b17023SJohn Marino bool changed;
518*e4b17023SJohn Marino enum unroll_level ul;
519*e4b17023SJohn Marino int iteration = 0;
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino do
522*e4b17023SJohn Marino {
523*e4b17023SJohn Marino changed = false;
524*e4b17023SJohn Marino
525*e4b17023SJohn Marino FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
526*e4b17023SJohn Marino {
527*e4b17023SJohn Marino if (may_increase_size && optimize_loop_for_speed_p (loop)
528*e4b17023SJohn Marino /* Unroll outermost loops only if asked to do so or they do
529*e4b17023SJohn Marino not cause code growth. */
530*e4b17023SJohn Marino && (unroll_outer
531*e4b17023SJohn Marino || loop_outer (loop_outer (loop))))
532*e4b17023SJohn Marino ul = UL_ALL;
533*e4b17023SJohn Marino else
534*e4b17023SJohn Marino ul = UL_NO_GROWTH;
535*e4b17023SJohn Marino changed |= canonicalize_loop_induction_variables
536*e4b17023SJohn Marino (loop, false, ul, !flag_tree_loop_ivcanon);
537*e4b17023SJohn Marino }
538*e4b17023SJohn Marino
539*e4b17023SJohn Marino if (changed)
540*e4b17023SJohn Marino {
541*e4b17023SJohn Marino /* This will take care of removing completely unrolled loops
542*e4b17023SJohn Marino from the loop structures so we can continue unrolling now
543*e4b17023SJohn Marino innermost loops. */
544*e4b17023SJohn Marino if (cleanup_tree_cfg ())
545*e4b17023SJohn Marino update_ssa (TODO_update_ssa_only_virtuals);
546*e4b17023SJohn Marino
547*e4b17023SJohn Marino /* Clean up the information about numbers of iterations, since
548*e4b17023SJohn Marino complete unrolling might have invalidated it. */
549*e4b17023SJohn Marino scev_reset ();
550*e4b17023SJohn Marino }
551*e4b17023SJohn Marino }
552*e4b17023SJohn Marino while (changed
553*e4b17023SJohn Marino && ++iteration <= PARAM_VALUE (PARAM_MAX_UNROLL_ITERATIONS));
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino return 0;
556*e4b17023SJohn Marino }
557