1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006-2013 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"
50 #include "tree-flow.h"
51 #include "tree-dump.h"
53 #include "tree-chrec.h"
54 #include "tree-data-ref.h"
55 #include "tree-scalar-evolution.h"
61 #include "graphite-poly.h"
62 #include "graphite-scop-detection.h"
63 #include "graphite-clast-to-gimple.h"
64 #include "graphite-sese-to-poly.h"
66 CloogState *cloog_state;
68 /* Print global statistics to FILE. */
71 print_global_statistics (FILE* file)
76 long n_conditions = 0;
80 long n_p_conditions = 0;
86 gimple_stmt_iterator psi;
91 /* Ignore artificial surrounding loop. */
92 if (bb == bb->loop_father->header
96 n_p_loops += bb->count;
99 if (EDGE_COUNT (bb->succs) > 1)
102 n_p_conditions += bb->count;
105 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
108 n_p_stmts += bb->count;
112 fprintf (file, "\nGlobal statistics (");
113 fprintf (file, "BBS:%ld, ", n_bbs);
114 fprintf (file, "LOOPS:%ld, ", n_loops);
115 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
116 fprintf (file, "STMTS:%ld)\n", n_stmts);
117 fprintf (file, "\nGlobal profiling statistics (");
118 fprintf (file, "BBS:%ld, ", n_p_bbs);
119 fprintf (file, "LOOPS:%ld, ", n_p_loops);
120 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
121 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
124 /* Print statistics for SCOP to FILE. */
127 print_graphite_scop_statistics (FILE* file, scop_p scop)
132 long n_conditions = 0;
136 long n_p_conditions = 0;
142 gimple_stmt_iterator psi;
143 loop_p loop = bb->loop_father;
145 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
149 n_p_bbs += bb->count;
151 if (EDGE_COUNT (bb->succs) > 1)
154 n_p_conditions += bb->count;
157 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
160 n_p_stmts += bb->count;
163 if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
166 n_p_loops += bb->count;
170 fprintf (file, "\nSCoP statistics (");
171 fprintf (file, "BBS:%ld, ", n_bbs);
172 fprintf (file, "LOOPS:%ld, ", n_loops);
173 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
174 fprintf (file, "STMTS:%ld)\n", n_stmts);
175 fprintf (file, "\nSCoP profiling statistics (");
176 fprintf (file, "BBS:%ld, ", n_p_bbs);
177 fprintf (file, "LOOPS:%ld, ", n_p_loops);
178 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
179 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
182 /* Print statistics for SCOPS to FILE. */
185 print_graphite_statistics (FILE* file, vec<scop_p> scops)
191 FOR_EACH_VEC_ELT (scops, i, scop)
192 print_graphite_scop_statistics (file, scop);
195 /* Initialize graphite: when there are no loops returns false. */
198 graphite_initialize (isl_ctx *ctx)
200 if (number_of_loops () <= 1
201 /* FIXME: This limit on the number of basic blocks of a function
202 should be removed when the SCOP detection is faster. */
203 || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION))
205 if (dump_file && (dump_flags & TDF_DETAILS))
206 print_global_statistics (dump_file);
213 recompute_all_dominators ();
214 initialize_original_copy_tables ();
216 cloog_state = cloog_isl_state_malloc (ctx);
218 if (dump_file && dump_flags)
219 dump_function_to_file (current_function_decl, dump_file, dump_flags);
224 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
228 graphite_finalize (bool need_cfg_cleanup_p)
230 if (need_cfg_cleanup_p)
234 profile_status = PROFILE_ABSENT;
235 release_recorded_exits ();
236 tree_estimate_probability ();
239 cloog_state_free (cloog_state);
240 free_original_copy_tables ();
242 if (dump_file && dump_flags)
243 print_loops (dump_file, 3);
246 isl_ctx *the_isl_ctx;
248 /* Perform a set of linear transforms on the loops of the current
252 graphite_transform_loops (void)
256 bool need_cfg_cleanup_p = false;
257 vec<scop_p> scops = vNULL;
258 htab_t bb_pbb_mapping;
261 /* If a function is parallel it was most probably already run through graphite
262 once. No need to run again. */
263 if (parallelized_function_p (cfun->decl))
266 ctx = isl_ctx_alloc ();
267 isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
268 if (!graphite_initialize (ctx))
272 build_scops (&scops);
274 if (dump_file && (dump_flags & TDF_DETAILS))
276 print_graphite_statistics (dump_file, scops);
277 print_global_statistics (dump_file);
280 bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
282 FOR_EACH_VEC_ELT (scops, i, scop)
283 if (dbg_cnt (graphite_scop))
286 build_poly_scop (scop);
288 if (POLY_SCOP_P (scop)
289 && apply_poly_transforms (scop)
290 && gloog (scop, bb_pbb_mapping))
291 need_cfg_cleanup_p = true;
294 htab_delete (bb_pbb_mapping);
296 graphite_finalize (need_cfg_cleanup_p);
301 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
304 graphite_transform_loops (void)
306 sorry ("Graphite loop optimizations cannot be used");