1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This pass converts GIMPLE to GRAPHITE, performs some loop
22 transformations and then converts the resulting representation back
25 An early description of this pass can be found in the GCC Summit'06
26 paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
27 The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
30 One important document to read is CLooG's internal manual:
31 http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
32 that describes the data structure of loops used in this file, and
33 the functions that are used for transforming the code. */
40 #include <isl/options.h>
41 #include <isl/union_map.h>
42 #include <cloog/cloog.h>
43 #include <cloog/isl/domain.h>
44 #include <cloog/isl/cloog.h>
48 #include "coretypes.h"
49 #include "diagnostic-core.h"
51 #include "basic-block.h"
52 #include "tree-ssa-alias.h"
53 #include "internal-fn.h"
54 #include "gimple-expr.h"
57 #include "gimple-iterator.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-dump.h"
62 #include "tree-chrec.h"
63 #include "tree-data-ref.h"
64 #include "tree-scalar-evolution.h"
67 #include "tree-parloops.h"
68 #include "tree-pass.h"
69 #include "tree-cfgcleanup.h"
73 #include "graphite-poly.h"
74 #include "graphite-scop-detection.h"
75 #include "graphite-clast-to-gimple.h"
76 #include "graphite-isl-ast-to-gimple.h"
77 #include "graphite-sese-to-poly.h"
78 #include "graphite-htab.h"
80 CloogState
*cloog_state
;
82 /* Print global statistics to FILE. */
85 print_global_statistics (FILE* file
)
90 long n_conditions
= 0;
94 long n_p_conditions
= 0;
98 FOR_ALL_BB_FN (bb
, cfun
)
100 gimple_stmt_iterator psi
;
103 n_p_bbs
+= bb
->count
;
105 /* Ignore artificial surrounding loop. */
106 if (bb
== bb
->loop_father
->header
110 n_p_loops
+= bb
->count
;
113 if (EDGE_COUNT (bb
->succs
) > 1)
116 n_p_conditions
+= bb
->count
;
119 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
122 n_p_stmts
+= bb
->count
;
126 fprintf (file
, "\nGlobal statistics (");
127 fprintf (file
, "BBS:%ld, ", n_bbs
);
128 fprintf (file
, "LOOPS:%ld, ", n_loops
);
129 fprintf (file
, "CONDITIONS:%ld, ", n_conditions
);
130 fprintf (file
, "STMTS:%ld)\n", n_stmts
);
131 fprintf (file
, "\nGlobal profiling statistics (");
132 fprintf (file
, "BBS:%ld, ", n_p_bbs
);
133 fprintf (file
, "LOOPS:%ld, ", n_p_loops
);
134 fprintf (file
, "CONDITIONS:%ld, ", n_p_conditions
);
135 fprintf (file
, "STMTS:%ld)\n", n_p_stmts
);
138 /* Print statistics for SCOP to FILE. */
141 print_graphite_scop_statistics (FILE* file
, scop_p scop
)
146 long n_conditions
= 0;
150 long n_p_conditions
= 0;
154 FOR_ALL_BB_FN (bb
, cfun
)
156 gimple_stmt_iterator psi
;
157 loop_p loop
= bb
->loop_father
;
159 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
163 n_p_bbs
+= bb
->count
;
165 if (EDGE_COUNT (bb
->succs
) > 1)
168 n_p_conditions
+= bb
->count
;
171 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
174 n_p_stmts
+= bb
->count
;
177 if (loop
->header
== bb
&& loop_in_sese_p (loop
, SCOP_REGION (scop
)))
180 n_p_loops
+= bb
->count
;
184 fprintf (file
, "\nSCoP statistics (");
185 fprintf (file
, "BBS:%ld, ", n_bbs
);
186 fprintf (file
, "LOOPS:%ld, ", n_loops
);
187 fprintf (file
, "CONDITIONS:%ld, ", n_conditions
);
188 fprintf (file
, "STMTS:%ld)\n", n_stmts
);
189 fprintf (file
, "\nSCoP profiling statistics (");
190 fprintf (file
, "BBS:%ld, ", n_p_bbs
);
191 fprintf (file
, "LOOPS:%ld, ", n_p_loops
);
192 fprintf (file
, "CONDITIONS:%ld, ", n_p_conditions
);
193 fprintf (file
, "STMTS:%ld)\n", n_p_stmts
);
196 /* Print statistics for SCOPS to FILE. */
199 print_graphite_statistics (FILE* file
, vec
<scop_p
> scops
)
205 FOR_EACH_VEC_ELT (scops
, i
, scop
)
206 print_graphite_scop_statistics (file
, scop
);
209 /* Initialize graphite: when there are no loops returns false. */
212 graphite_initialize (isl_ctx
*ctx
)
214 if (number_of_loops (cfun
) <= 1
215 /* FIXME: This limit on the number of basic blocks of a function
216 should be removed when the SCOP detection is faster. */
217 || (n_basic_blocks_for_fn (cfun
) >
218 PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION
)))
220 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
221 print_global_statistics (dump_file
);
228 recompute_all_dominators ();
229 initialize_original_copy_tables ();
231 cloog_state
= cloog_isl_state_malloc (ctx
);
233 if (dump_file
&& dump_flags
)
234 dump_function_to_file (current_function_decl
, dump_file
, dump_flags
);
239 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
243 graphite_finalize (bool need_cfg_cleanup_p
)
245 if (need_cfg_cleanup_p
)
249 profile_status_for_fn (cfun
) = PROFILE_ABSENT
;
250 release_recorded_exits ();
251 tree_estimate_probability ();
254 cloog_state_free (cloog_state
);
255 free_original_copy_tables ();
257 if (dump_file
&& dump_flags
)
258 print_loops (dump_file
, 3);
261 isl_ctx
*the_isl_ctx
;
263 /* Perform a set of linear transforms on the loops of the current
267 graphite_transform_loops (void)
271 bool need_cfg_cleanup_p
= false;
272 vec
<scop_p
> scops
= vNULL
;
275 /* If a function is parallel it was most probably already run through graphite
276 once. No need to run again. */
277 if (parallelized_function_p (cfun
->decl
))
280 ctx
= isl_ctx_alloc ();
281 isl_options_set_on_error (ctx
, ISL_ON_ERROR_ABORT
);
282 if (!graphite_initialize (ctx
))
286 build_scops (&scops
);
288 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
290 print_graphite_statistics (dump_file
, scops
);
291 print_global_statistics (dump_file
);
294 bb_pbb_htab_type
bb_pbb_mapping (10);
295 FOR_EACH_VEC_ELT (scops
, i
, scop
)
296 if (dbg_cnt (graphite_scop
))
299 build_poly_scop (scop
);
301 if (POLY_SCOP_P (scop
)
302 && apply_poly_transforms (scop
)
303 && (((flag_graphite_code_gen
== FGRAPHITE_CODE_GEN_ISL
)
304 && graphite_regenerate_ast_isl (scop
))
305 || ((flag_graphite_code_gen
== FGRAPHITE_CODE_GEN_CLOOG
)
306 && graphite_regenerate_ast_cloog (scop
, &bb_pbb_mapping
))))
307 need_cfg_cleanup_p
= true;
311 graphite_finalize (need_cfg_cleanup_p
);
316 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
319 graphite_transform_loops (void)
321 sorry ("Graphite loop optimizations cannot be used");
328 graphite_transforms (struct function
*fun
)
330 if (number_of_loops (fun
) <= 1)
333 graphite_transform_loops ();
339 gate_graphite_transforms (void)
341 /* Enable -fgraphite pass if any one of the graphite optimization flags
344 || flag_loop_interchange
345 || flag_loop_strip_mine
346 || flag_graphite_identity
347 || flag_loop_parallelize_all
348 || flag_loop_optimize_isl
)
351 return flag_graphite
!= 0;
356 const pass_data pass_data_graphite
=
358 GIMPLE_PASS
, /* type */
359 "graphite0", /* name */
360 OPTGROUP_LOOP
, /* optinfo_flags */
361 TV_GRAPHITE
, /* tv_id */
362 ( PROP_cfg
| PROP_ssa
), /* properties_required */
363 0, /* properties_provided */
364 0, /* properties_destroyed */
365 0, /* todo_flags_start */
366 0, /* todo_flags_finish */
369 class pass_graphite
: public gimple_opt_pass
372 pass_graphite (gcc::context
*ctxt
)
373 : gimple_opt_pass (pass_data_graphite
, ctxt
)
376 /* opt_pass methods: */
377 virtual bool gate (function
*) { return gate_graphite_transforms (); }
379 }; // class pass_graphite
384 make_pass_graphite (gcc::context
*ctxt
)
386 return new pass_graphite (ctxt
);
391 const pass_data pass_data_graphite_transforms
=
393 GIMPLE_PASS
, /* type */
394 "graphite", /* name */
395 OPTGROUP_LOOP
, /* optinfo_flags */
396 TV_GRAPHITE_TRANSFORMS
, /* tv_id */
397 ( PROP_cfg
| PROP_ssa
), /* properties_required */
398 0, /* properties_provided */
399 0, /* properties_destroyed */
400 0, /* todo_flags_start */
401 0, /* todo_flags_finish */
404 class pass_graphite_transforms
: public gimple_opt_pass
407 pass_graphite_transforms (gcc::context
*ctxt
)
408 : gimple_opt_pass (pass_data_graphite_transforms
, ctxt
)
411 /* opt_pass methods: */
412 virtual bool gate (function
*) { return gate_graphite_transforms (); }
413 virtual unsigned int execute (function
*fun
) { return graphite_transforms (fun
); }
415 }; // class pass_graphite_transforms
420 make_pass_graphite_transforms (gcc::context
*ctxt
)
422 return new pass_graphite_transforms (ctxt
);