xref: /dragonfly/contrib/gcc-8.0/gcc/graphite.c (revision 38fd1498)
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