1*38fd1498Szrj /* Gimple Represented as Polyhedra.
2*38fd1498Szrj Copyright (C) 2006-2018 Free Software Foundation, Inc.
3*38fd1498Szrj Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify
8*38fd1498Szrj it under the terms of the GNU General Public License as published by
9*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
10*38fd1498Szrj any later version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful,
13*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
14*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*38fd1498Szrj GNU General Public License for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3. If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>. */
20*38fd1498Szrj
21*38fd1498Szrj /* This pass converts GIMPLE to GRAPHITE, performs some loop
22*38fd1498Szrj transformations and then converts the resulting representation back
23*38fd1498Szrj to GIMPLE.
24*38fd1498Szrj
25*38fd1498Szrj An early description of this pass can be found in the GCC Summit'06
26*38fd1498Szrj paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
27*38fd1498Szrj The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
28*38fd1498Szrj the related work. */
29*38fd1498Szrj
30*38fd1498Szrj #define USES_ISL
31*38fd1498Szrj
32*38fd1498Szrj #include "config.h"
33*38fd1498Szrj #include "system.h"
34*38fd1498Szrj #include "coretypes.h"
35*38fd1498Szrj #include "backend.h"
36*38fd1498Szrj #include "diagnostic-core.h"
37*38fd1498Szrj #include "cfgloop.h"
38*38fd1498Szrj #include "tree-pass.h"
39*38fd1498Szrj #include "params.h"
40*38fd1498Szrj #include "pretty-print.h"
41*38fd1498Szrj #include "cfganal.h"
42*38fd1498Szrj
43*38fd1498Szrj #ifdef HAVE_isl
44*38fd1498Szrj #include "cfghooks.h"
45*38fd1498Szrj #include "tree.h"
46*38fd1498Szrj #include "gimple.h"
47*38fd1498Szrj #include "ssa.h"
48*38fd1498Szrj #include "fold-const.h"
49*38fd1498Szrj #include "gimple-iterator.h"
50*38fd1498Szrj #include "tree-cfg.h"
51*38fd1498Szrj #include "tree-ssa-loop.h"
52*38fd1498Szrj #include "tree-data-ref.h"
53*38fd1498Szrj #include "tree-scalar-evolution.h"
54*38fd1498Szrj #include "dbgcnt.h"
55*38fd1498Szrj #include "tree-parloops.h"
56*38fd1498Szrj #include "tree-cfgcleanup.h"
57*38fd1498Szrj #include "tree-vectorizer.h"
58*38fd1498Szrj #include "tree-ssa-loop-manip.h"
59*38fd1498Szrj #include "tree-ssa.h"
60*38fd1498Szrj #include "tree-into-ssa.h"
61*38fd1498Szrj #include "graphite.h"
62*38fd1498Szrj
63*38fd1498Szrj /* Print global statistics to FILE. */
64*38fd1498Szrj
65*38fd1498Szrj static void
print_global_statistics(FILE * file)66*38fd1498Szrj print_global_statistics (FILE* file)
67*38fd1498Szrj {
68*38fd1498Szrj long n_bbs = 0;
69*38fd1498Szrj long n_loops = 0;
70*38fd1498Szrj long n_stmts = 0;
71*38fd1498Szrj long n_conditions = 0;
72*38fd1498Szrj profile_count n_p_bbs = profile_count::zero ();
73*38fd1498Szrj profile_count n_p_loops = profile_count::zero ();
74*38fd1498Szrj profile_count n_p_stmts = profile_count::zero ();
75*38fd1498Szrj profile_count n_p_conditions = profile_count::zero ();
76*38fd1498Szrj
77*38fd1498Szrj basic_block bb;
78*38fd1498Szrj
79*38fd1498Szrj FOR_ALL_BB_FN (bb, cfun)
80*38fd1498Szrj {
81*38fd1498Szrj gimple_stmt_iterator psi;
82*38fd1498Szrj
83*38fd1498Szrj n_bbs++;
84*38fd1498Szrj if (bb->count.initialized_p ())
85*38fd1498Szrj n_p_bbs += bb->count;
86*38fd1498Szrj
87*38fd1498Szrj /* Ignore artificial surrounding loop. */
88*38fd1498Szrj if (bb == bb->loop_father->header
89*38fd1498Szrj && bb->index != 0)
90*38fd1498Szrj {
91*38fd1498Szrj n_loops++;
92*38fd1498Szrj n_p_loops += bb->count;
93*38fd1498Szrj }
94*38fd1498Szrj
95*38fd1498Szrj if (EDGE_COUNT (bb->succs) > 1)
96*38fd1498Szrj {
97*38fd1498Szrj n_conditions++;
98*38fd1498Szrj if (bb->count.initialized_p ())
99*38fd1498Szrj n_p_conditions += bb->count;
100*38fd1498Szrj }
101*38fd1498Szrj
102*38fd1498Szrj for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
103*38fd1498Szrj {
104*38fd1498Szrj n_stmts++;
105*38fd1498Szrj if (bb->count.initialized_p ())
106*38fd1498Szrj n_p_stmts += bb->count;
107*38fd1498Szrj }
108*38fd1498Szrj }
109*38fd1498Szrj
110*38fd1498Szrj fprintf (file, "\nGlobal statistics (");
111*38fd1498Szrj fprintf (file, "BBS:%ld, ", n_bbs);
112*38fd1498Szrj fprintf (file, "LOOPS:%ld, ", n_loops);
113*38fd1498Szrj fprintf (file, "CONDITIONS:%ld, ", n_conditions);
114*38fd1498Szrj fprintf (file, "STMTS:%ld)\n", n_stmts);
115*38fd1498Szrj fprintf (file, "Global profiling statistics (");
116*38fd1498Szrj fprintf (file, "BBS:");
117*38fd1498Szrj n_p_bbs.dump (file);
118*38fd1498Szrj fprintf (file, ", LOOPS:");
119*38fd1498Szrj n_p_loops.dump (file);
120*38fd1498Szrj fprintf (file, ", CONDITIONS:");
121*38fd1498Szrj n_p_conditions.dump (file);
122*38fd1498Szrj fprintf (file, ", STMTS:");
123*38fd1498Szrj n_p_stmts.dump (file);
124*38fd1498Szrj fprintf (file, ")\n\n");
125*38fd1498Szrj }
126*38fd1498Szrj
127*38fd1498Szrj /* Print statistics for SCOP to FILE. */
128*38fd1498Szrj
129*38fd1498Szrj static void
print_graphite_scop_statistics(FILE * file,scop_p scop)130*38fd1498Szrj print_graphite_scop_statistics (FILE* file, scop_p scop)
131*38fd1498Szrj {
132*38fd1498Szrj long n_bbs = 0;
133*38fd1498Szrj long n_loops = 0;
134*38fd1498Szrj long n_stmts = 0;
135*38fd1498Szrj long n_conditions = 0;
136*38fd1498Szrj profile_count n_p_bbs = profile_count::zero ();
137*38fd1498Szrj profile_count n_p_loops = profile_count::zero ();
138*38fd1498Szrj profile_count n_p_stmts = profile_count::zero ();
139*38fd1498Szrj profile_count n_p_conditions = profile_count::zero ();
140*38fd1498Szrj
141*38fd1498Szrj basic_block bb;
142*38fd1498Szrj
143*38fd1498Szrj FOR_ALL_BB_FN (bb, cfun)
144*38fd1498Szrj {
145*38fd1498Szrj gimple_stmt_iterator psi;
146*38fd1498Szrj loop_p loop = bb->loop_father;
147*38fd1498Szrj
148*38fd1498Szrj if (!bb_in_sese_p (bb, scop->scop_info->region))
149*38fd1498Szrj continue;
150*38fd1498Szrj
151*38fd1498Szrj n_bbs++;
152*38fd1498Szrj if (bb->count.initialized_p ())
153*38fd1498Szrj n_p_bbs += bb->count;
154*38fd1498Szrj
155*38fd1498Szrj if (EDGE_COUNT (bb->succs) > 1)
156*38fd1498Szrj {
157*38fd1498Szrj n_conditions++;
158*38fd1498Szrj n_p_conditions += bb->count;
159*38fd1498Szrj }
160*38fd1498Szrj
161*38fd1498Szrj for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
162*38fd1498Szrj {
163*38fd1498Szrj n_stmts++;
164*38fd1498Szrj n_p_stmts += bb->count;
165*38fd1498Szrj }
166*38fd1498Szrj
167*38fd1498Szrj if (loop->header == bb && loop_in_sese_p (loop, scop->scop_info->region))
168*38fd1498Szrj {
169*38fd1498Szrj n_loops++;
170*38fd1498Szrj n_p_loops += bb->count;
171*38fd1498Szrj }
172*38fd1498Szrj }
173*38fd1498Szrj
174*38fd1498Szrj fprintf (file, "\nFunction Name: %s\n", current_function_name ());
175*38fd1498Szrj
176*38fd1498Szrj edge scop_begin = scop->scop_info->region.entry;
177*38fd1498Szrj edge scop_end = scop->scop_info->region.exit;
178*38fd1498Szrj
179*38fd1498Szrj fprintf (file, "\nSCoP (entry_edge (bb_%d, bb_%d), ",
180*38fd1498Szrj scop_begin->src->index, scop_begin->dest->index);
181*38fd1498Szrj fprintf (file, "exit_edge (bb_%d, bb_%d))",
182*38fd1498Szrj scop_end->src->index, scop_end->dest->index);
183*38fd1498Szrj
184*38fd1498Szrj fprintf (file, "\nSCoP statistics (");
185*38fd1498Szrj fprintf (file, "BBS:%ld, ", n_bbs);
186*38fd1498Szrj fprintf (file, "LOOPS:%ld, ", n_loops);
187*38fd1498Szrj fprintf (file, "CONDITIONS:%ld, ", n_conditions);
188*38fd1498Szrj fprintf (file, "STMTS:%ld)\n", n_stmts);
189*38fd1498Szrj fprintf (file, "SCoP profiling statistics (");
190*38fd1498Szrj fprintf (file, "BBS:");
191*38fd1498Szrj n_p_bbs.dump (file);
192*38fd1498Szrj fprintf (file, ", LOOPS:");
193*38fd1498Szrj n_p_loops.dump (file);
194*38fd1498Szrj fprintf (file, ", CONDITIONS:");
195*38fd1498Szrj n_p_conditions.dump (file);
196*38fd1498Szrj fprintf (file, ", STMTS:");
197*38fd1498Szrj n_p_stmts.dump (file);
198*38fd1498Szrj fprintf (file, ")\n\n");
199*38fd1498Szrj }
200*38fd1498Szrj
201*38fd1498Szrj /* Print statistics for SCOPS to FILE. */
202*38fd1498Szrj
203*38fd1498Szrj static void
print_graphite_statistics(FILE * file,vec<scop_p> scops)204*38fd1498Szrj print_graphite_statistics (FILE* file, vec<scop_p> scops)
205*38fd1498Szrj {
206*38fd1498Szrj int i;
207*38fd1498Szrj scop_p scop;
208*38fd1498Szrj
209*38fd1498Szrj FOR_EACH_VEC_ELT (scops, i, scop)
210*38fd1498Szrj print_graphite_scop_statistics (file, scop);
211*38fd1498Szrj }
212*38fd1498Szrj
213*38fd1498Szrj /* Deletes all scops in SCOPS. */
214*38fd1498Szrj
215*38fd1498Szrj static void
free_scops(vec<scop_p> scops)216*38fd1498Szrj free_scops (vec<scop_p> scops)
217*38fd1498Szrj {
218*38fd1498Szrj int i;
219*38fd1498Szrj scop_p scop;
220*38fd1498Szrj
221*38fd1498Szrj FOR_EACH_VEC_ELT (scops, i, scop)
222*38fd1498Szrj free_scop (scop);
223*38fd1498Szrj
224*38fd1498Szrj scops.release ();
225*38fd1498Szrj }
226*38fd1498Szrj
227*38fd1498Szrj /* Transforms LOOP to the canonical loop closed SSA form. */
228*38fd1498Szrj
229*38fd1498Szrj static void
canonicalize_loop_closed_ssa(loop_p loop,edge e)230*38fd1498Szrj canonicalize_loop_closed_ssa (loop_p loop, edge e)
231*38fd1498Szrj {
232*38fd1498Szrj basic_block bb;
233*38fd1498Szrj gphi_iterator psi;
234*38fd1498Szrj
235*38fd1498Szrj bb = e->dest;
236*38fd1498Szrj
237*38fd1498Szrj /* Make the loop-close PHI node BB contain only PHIs and have a
238*38fd1498Szrj single predecessor. */
239*38fd1498Szrj if (single_pred_p (bb))
240*38fd1498Szrj {
241*38fd1498Szrj e = split_block_after_labels (bb);
242*38fd1498Szrj bb = e->src;
243*38fd1498Szrj }
244*38fd1498Szrj else
245*38fd1498Szrj {
246*38fd1498Szrj basic_block close = split_edge (e);
247*38fd1498Szrj e = single_succ_edge (close);
248*38fd1498Szrj for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
249*38fd1498Szrj {
250*38fd1498Szrj gphi *phi = psi.phi ();
251*38fd1498Szrj use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
252*38fd1498Szrj tree arg = USE_FROM_PTR (use_p);
253*38fd1498Szrj
254*38fd1498Szrj /* Only add close phi nodes for SSA_NAMEs defined in LOOP. */
255*38fd1498Szrj if (TREE_CODE (arg) != SSA_NAME
256*38fd1498Szrj || SSA_NAME_IS_DEFAULT_DEF (arg)
257*38fd1498Szrj || ! flow_bb_inside_loop_p (loop,
258*38fd1498Szrj gimple_bb (SSA_NAME_DEF_STMT (arg))))
259*38fd1498Szrj continue;
260*38fd1498Szrj
261*38fd1498Szrj tree res = copy_ssa_name (arg);
262*38fd1498Szrj gphi *close_phi = create_phi_node (res, close);
263*38fd1498Szrj add_phi_arg (close_phi, arg, gimple_phi_arg_edge (close_phi, 0),
264*38fd1498Szrj UNKNOWN_LOCATION);
265*38fd1498Szrj SET_USE (use_p, res);
266*38fd1498Szrj }
267*38fd1498Szrj bb = close;
268*38fd1498Szrj }
269*38fd1498Szrj
270*38fd1498Szrj /* Eliminate duplicates. This relies on processing loops from
271*38fd1498Szrj innermost to outer. */
272*38fd1498Szrj for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
273*38fd1498Szrj {
274*38fd1498Szrj gphi_iterator gsi = psi;
275*38fd1498Szrj gphi *phi = psi.phi ();
276*38fd1498Szrj
277*38fd1498Szrj /* At this point, PHI should be a close phi in normal form. */
278*38fd1498Szrj gcc_assert (gimple_phi_num_args (phi) == 1);
279*38fd1498Szrj
280*38fd1498Szrj /* Iterate over the next phis and remove duplicates. */
281*38fd1498Szrj gsi_next (&gsi);
282*38fd1498Szrj while (!gsi_end_p (gsi))
283*38fd1498Szrj if (gimple_phi_arg_def (phi, 0) == gimple_phi_arg_def (gsi.phi (), 0))
284*38fd1498Szrj {
285*38fd1498Szrj replace_uses_by (gimple_phi_result (gsi.phi ()),
286*38fd1498Szrj gimple_phi_result (phi));
287*38fd1498Szrj remove_phi_node (&gsi, true);
288*38fd1498Szrj }
289*38fd1498Szrj else
290*38fd1498Szrj gsi_next (&gsi);
291*38fd1498Szrj }
292*38fd1498Szrj }
293*38fd1498Szrj
294*38fd1498Szrj /* Converts the current loop closed SSA form to a canonical form
295*38fd1498Szrj expected by the Graphite code generation.
296*38fd1498Szrj
297*38fd1498Szrj The loop closed SSA form has the following invariant: a variable
298*38fd1498Szrj defined in a loop that is used outside the loop appears only in the
299*38fd1498Szrj phi nodes in the destination of the loop exit. These phi nodes are
300*38fd1498Szrj called close phi nodes.
301*38fd1498Szrj
302*38fd1498Szrj The canonical loop closed SSA form contains the extra invariants:
303*38fd1498Szrj
304*38fd1498Szrj - when the loop contains only one exit, the close phi nodes contain
305*38fd1498Szrj only one argument. That implies that the basic block that contains
306*38fd1498Szrj the close phi nodes has only one predecessor, that is a basic block
307*38fd1498Szrj in the loop.
308*38fd1498Szrj
309*38fd1498Szrj - the basic block containing the close phi nodes does not contain
310*38fd1498Szrj other statements.
311*38fd1498Szrj
312*38fd1498Szrj - there exist only one phi node per definition in the loop.
313*38fd1498Szrj
314*38fd1498Szrj In addition to that we also make sure that loop exit edges are
315*38fd1498Szrj first in the successor edge vector. This is to make RPO order
316*38fd1498Szrj as computed by pre_and_rev_post_order_compute be consistent with
317*38fd1498Szrj what initial schedule generation expects.
318*38fd1498Szrj */
319*38fd1498Szrj
320*38fd1498Szrj static void
canonicalize_loop_form(void)321*38fd1498Szrj canonicalize_loop_form (void)
322*38fd1498Szrj {
323*38fd1498Szrj loop_p loop;
324*38fd1498Szrj FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
325*38fd1498Szrj {
326*38fd1498Szrj edge e = single_exit (loop);
327*38fd1498Szrj if (!e || (e->flags & (EDGE_COMPLEX|EDGE_FAKE)))
328*38fd1498Szrj continue;
329*38fd1498Szrj
330*38fd1498Szrj canonicalize_loop_closed_ssa (loop, e);
331*38fd1498Szrj
332*38fd1498Szrj /* If the exit is not first in the edge vector make it so. */
333*38fd1498Szrj if (e != EDGE_SUCC (e->src, 0))
334*38fd1498Szrj {
335*38fd1498Szrj unsigned ei;
336*38fd1498Szrj for (ei = 0; EDGE_SUCC (e->src, ei) != e; ++ei)
337*38fd1498Szrj ;
338*38fd1498Szrj std::swap (EDGE_SUCC (e->src, ei), EDGE_SUCC (e->src, 0));
339*38fd1498Szrj }
340*38fd1498Szrj }
341*38fd1498Szrj
342*38fd1498Szrj /* We can end up releasing duplicate exit PHIs and also introduce
343*38fd1498Szrj additional copies so the cached information isn't correct anymore. */
344*38fd1498Szrj scev_reset ();
345*38fd1498Szrj
346*38fd1498Szrj checking_verify_loop_closed_ssa (true);
347*38fd1498Szrj }
348*38fd1498Szrj
349*38fd1498Szrj isl_ctx *the_isl_ctx;
350*38fd1498Szrj
351*38fd1498Szrj /* Perform a set of linear transforms on the loops of the current
352*38fd1498Szrj function. */
353*38fd1498Szrj
354*38fd1498Szrj void
graphite_transform_loops(void)355*38fd1498Szrj graphite_transform_loops (void)
356*38fd1498Szrj {
357*38fd1498Szrj int i;
358*38fd1498Szrj scop_p scop;
359*38fd1498Szrj bool changed = false;
360*38fd1498Szrj vec<scop_p> scops = vNULL;
361*38fd1498Szrj isl_ctx *ctx;
362*38fd1498Szrj
363*38fd1498Szrj /* If a function is parallel it was most probably already run through graphite
364*38fd1498Szrj once. No need to run again. */
365*38fd1498Szrj if (parallelized_function_p (cfun->decl))
366*38fd1498Szrj return;
367*38fd1498Szrj
368*38fd1498Szrj calculate_dominance_info (CDI_DOMINATORS);
369*38fd1498Szrj
370*38fd1498Szrj /* We rely on post-dominators during merging of SESE regions so those
371*38fd1498Szrj have to be meaningful. */
372*38fd1498Szrj connect_infinite_loops_to_exit ();
373*38fd1498Szrj
374*38fd1498Szrj ctx = isl_ctx_alloc ();
375*38fd1498Szrj isl_options_set_on_error (ctx, ISL_ON_ERROR_ABORT);
376*38fd1498Szrj the_isl_ctx = ctx;
377*38fd1498Szrj
378*38fd1498Szrj sort_sibling_loops (cfun);
379*38fd1498Szrj canonicalize_loop_form ();
380*38fd1498Szrj
381*38fd1498Szrj /* Print the loop structure. */
382*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
383*38fd1498Szrj {
384*38fd1498Szrj print_loops (dump_file, 2);
385*38fd1498Szrj print_loops (dump_file, 3);
386*38fd1498Szrj }
387*38fd1498Szrj
388*38fd1498Szrj calculate_dominance_info (CDI_POST_DOMINATORS);
389*38fd1498Szrj build_scops (&scops);
390*38fd1498Szrj free_dominance_info (CDI_POST_DOMINATORS);
391*38fd1498Szrj
392*38fd1498Szrj /* Remove the fake exits before transform given they are not reflected
393*38fd1498Szrj in loop structures we end up verifying. */
394*38fd1498Szrj remove_fake_exit_edges ();
395*38fd1498Szrj
396*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
397*38fd1498Szrj {
398*38fd1498Szrj print_graphite_statistics (dump_file, scops);
399*38fd1498Szrj print_global_statistics (dump_file);
400*38fd1498Szrj }
401*38fd1498Szrj
402*38fd1498Szrj FOR_EACH_VEC_ELT (scops, i, scop)
403*38fd1498Szrj if (dbg_cnt (graphite_scop))
404*38fd1498Szrj {
405*38fd1498Szrj scop->isl_context = ctx;
406*38fd1498Szrj if (!build_poly_scop (scop))
407*38fd1498Szrj continue;
408*38fd1498Szrj
409*38fd1498Szrj if (!apply_poly_transforms (scop))
410*38fd1498Szrj continue;
411*38fd1498Szrj
412*38fd1498Szrj changed = true;
413*38fd1498Szrj if (graphite_regenerate_ast_isl (scop))
414*38fd1498Szrj {
415*38fd1498Szrj location_t loc = find_loop_location
416*38fd1498Szrj (scops[i]->scop_info->region.entry->dest->loop_father);
417*38fd1498Szrj dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
418*38fd1498Szrj "loop nest optimized\n");
419*38fd1498Szrj }
420*38fd1498Szrj }
421*38fd1498Szrj
422*38fd1498Szrj if (changed)
423*38fd1498Szrj {
424*38fd1498Szrj mark_virtual_operands_for_renaming (cfun);
425*38fd1498Szrj update_ssa (TODO_update_ssa);
426*38fd1498Szrj checking_verify_ssa (true, true);
427*38fd1498Szrj rewrite_into_loop_closed_ssa (NULL, 0);
428*38fd1498Szrj scev_reset ();
429*38fd1498Szrj checking_verify_loop_structure ();
430*38fd1498Szrj }
431*38fd1498Szrj
432*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS))
433*38fd1498Szrj {
434*38fd1498Szrj loop_p loop;
435*38fd1498Szrj int num_no_dependency = 0;
436*38fd1498Szrj
437*38fd1498Szrj FOR_EACH_LOOP (loop, 0)
438*38fd1498Szrj if (loop->can_be_parallel)
439*38fd1498Szrj num_no_dependency++;
440*38fd1498Szrj
441*38fd1498Szrj fprintf (dump_file, "%d loops carried no dependency.\n",
442*38fd1498Szrj num_no_dependency);
443*38fd1498Szrj }
444*38fd1498Szrj
445*38fd1498Szrj free_scops (scops);
446*38fd1498Szrj the_isl_ctx = NULL;
447*38fd1498Szrj isl_ctx_free (ctx);
448*38fd1498Szrj
449*38fd1498Szrj if (changed)
450*38fd1498Szrj {
451*38fd1498Szrj cleanup_tree_cfg ();
452*38fd1498Szrj profile_status_for_fn (cfun) = PROFILE_ABSENT;
453*38fd1498Szrj release_recorded_exits (cfun);
454*38fd1498Szrj tree_estimate_probability (false);
455*38fd1498Szrj }
456*38fd1498Szrj }
457*38fd1498Szrj
458*38fd1498Szrj #else /* If isl is not available: #ifndef HAVE_isl. */
459*38fd1498Szrj
460*38fd1498Szrj static void
graphite_transform_loops(void)461*38fd1498Szrj graphite_transform_loops (void)
462*38fd1498Szrj {
463*38fd1498Szrj sorry ("Graphite loop optimizations cannot be used (isl is not available).");
464*38fd1498Szrj }
465*38fd1498Szrj
466*38fd1498Szrj #endif
467*38fd1498Szrj
468*38fd1498Szrj
469*38fd1498Szrj static unsigned int
graphite_transforms(struct function * fun)470*38fd1498Szrj graphite_transforms (struct function *fun)
471*38fd1498Szrj {
472*38fd1498Szrj if (number_of_loops (fun) <= 1)
473*38fd1498Szrj return 0;
474*38fd1498Szrj
475*38fd1498Szrj graphite_transform_loops ();
476*38fd1498Szrj
477*38fd1498Szrj return 0;
478*38fd1498Szrj }
479*38fd1498Szrj
480*38fd1498Szrj static bool
gate_graphite_transforms(void)481*38fd1498Szrj gate_graphite_transforms (void)
482*38fd1498Szrj {
483*38fd1498Szrj /* Enable -fgraphite pass if any one of the graphite optimization flags
484*38fd1498Szrj is turned on. */
485*38fd1498Szrj if (flag_graphite_identity
486*38fd1498Szrj || flag_loop_parallelize_all
487*38fd1498Szrj || flag_loop_nest_optimize)
488*38fd1498Szrj flag_graphite = 1;
489*38fd1498Szrj
490*38fd1498Szrj return flag_graphite != 0;
491*38fd1498Szrj }
492*38fd1498Szrj
493*38fd1498Szrj namespace {
494*38fd1498Szrj
495*38fd1498Szrj const pass_data pass_data_graphite =
496*38fd1498Szrj {
497*38fd1498Szrj GIMPLE_PASS, /* type */
498*38fd1498Szrj "graphite0", /* name */
499*38fd1498Szrj OPTGROUP_LOOP, /* optinfo_flags */
500*38fd1498Szrj TV_GRAPHITE, /* tv_id */
501*38fd1498Szrj ( PROP_cfg | PROP_ssa ), /* properties_required */
502*38fd1498Szrj 0, /* properties_provided */
503*38fd1498Szrj 0, /* properties_destroyed */
504*38fd1498Szrj 0, /* todo_flags_start */
505*38fd1498Szrj 0, /* todo_flags_finish */
506*38fd1498Szrj };
507*38fd1498Szrj
508*38fd1498Szrj class pass_graphite : public gimple_opt_pass
509*38fd1498Szrj {
510*38fd1498Szrj public:
pass_graphite(gcc::context * ctxt)511*38fd1498Szrj pass_graphite (gcc::context *ctxt)
512*38fd1498Szrj : gimple_opt_pass (pass_data_graphite, ctxt)
513*38fd1498Szrj {}
514*38fd1498Szrj
515*38fd1498Szrj /* opt_pass methods: */
gate(function *)516*38fd1498Szrj virtual bool gate (function *) { return gate_graphite_transforms (); }
517*38fd1498Szrj
518*38fd1498Szrj }; // class pass_graphite
519*38fd1498Szrj
520*38fd1498Szrj } // anon namespace
521*38fd1498Szrj
522*38fd1498Szrj gimple_opt_pass *
make_pass_graphite(gcc::context * ctxt)523*38fd1498Szrj make_pass_graphite (gcc::context *ctxt)
524*38fd1498Szrj {
525*38fd1498Szrj return new pass_graphite (ctxt);
526*38fd1498Szrj }
527*38fd1498Szrj
528*38fd1498Szrj namespace {
529*38fd1498Szrj
530*38fd1498Szrj const pass_data pass_data_graphite_transforms =
531*38fd1498Szrj {
532*38fd1498Szrj GIMPLE_PASS, /* type */
533*38fd1498Szrj "graphite", /* name */
534*38fd1498Szrj OPTGROUP_LOOP, /* optinfo_flags */
535*38fd1498Szrj TV_GRAPHITE_TRANSFORMS, /* tv_id */
536*38fd1498Szrj ( PROP_cfg | PROP_ssa ), /* properties_required */
537*38fd1498Szrj 0, /* properties_provided */
538*38fd1498Szrj 0, /* properties_destroyed */
539*38fd1498Szrj 0, /* todo_flags_start */
540*38fd1498Szrj 0, /* todo_flags_finish */
541*38fd1498Szrj };
542*38fd1498Szrj
543*38fd1498Szrj class pass_graphite_transforms : public gimple_opt_pass
544*38fd1498Szrj {
545*38fd1498Szrj public:
pass_graphite_transforms(gcc::context * ctxt)546*38fd1498Szrj pass_graphite_transforms (gcc::context *ctxt)
547*38fd1498Szrj : gimple_opt_pass (pass_data_graphite_transforms, ctxt)
548*38fd1498Szrj {}
549*38fd1498Szrj
550*38fd1498Szrj /* opt_pass methods: */
gate(function *)551*38fd1498Szrj virtual bool gate (function *) { return gate_graphite_transforms (); }
execute(function * fun)552*38fd1498Szrj virtual unsigned int execute (function *fun) { return graphite_transforms (fun); }
553*38fd1498Szrj
554*38fd1498Szrj }; // class pass_graphite_transforms
555*38fd1498Szrj
556*38fd1498Szrj } // anon namespace
557*38fd1498Szrj
558*38fd1498Szrj gimple_opt_pass *
make_pass_graphite_transforms(gcc::context * ctxt)559*38fd1498Szrj make_pass_graphite_transforms (gcc::context *ctxt)
560*38fd1498Szrj {
561*38fd1498Szrj return new pass_graphite_transforms (ctxt);
562*38fd1498Szrj }
563*38fd1498Szrj
564*38fd1498Szrj
565