Support slim switch for cfg graph dump
[official-gcc.git] / gcc / graphite.c
blob7511527de0bf9e845849d2d618f3a6312caf5290
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)
10 any later version.
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
23 to GIMPLE.
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
28 the related work.
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. */
35 #include "config.h"
37 #ifdef HAVE_cloog
38 #include <isl/set.h>
39 #include <isl/map.h>
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>
45 #endif
47 #include "system.h"
48 #include "coretypes.h"
49 #include "diagnostic-core.h"
50 #include "tree-flow.h"
51 #include "tree-dump.h"
52 #include "cfgloop.h"
53 #include "tree-chrec.h"
54 #include "tree-data-ref.h"
55 #include "tree-scalar-evolution.h"
56 #include "sese.h"
57 #include "dbgcnt.h"
59 #ifdef HAVE_cloog
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. */
70 static void
71 print_global_statistics (FILE* file)
73 long n_bbs = 0;
74 long n_loops = 0;
75 long n_stmts = 0;
76 long n_conditions = 0;
77 long n_p_bbs = 0;
78 long n_p_loops = 0;
79 long n_p_stmts = 0;
80 long n_p_conditions = 0;
82 basic_block bb;
84 FOR_ALL_BB (bb)
86 gimple_stmt_iterator psi;
88 n_bbs++;
89 n_p_bbs += bb->count;
91 /* Ignore artificial surrounding loop. */
92 if (bb == bb->loop_father->header
93 && bb->index != 0)
95 n_loops++;
96 n_p_loops += bb->count;
99 if (EDGE_COUNT (bb->succs) > 1)
101 n_conditions++;
102 n_p_conditions += bb->count;
105 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
107 n_stmts++;
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. */
126 static void
127 print_graphite_scop_statistics (FILE* file, scop_p scop)
129 long n_bbs = 0;
130 long n_loops = 0;
131 long n_stmts = 0;
132 long n_conditions = 0;
133 long n_p_bbs = 0;
134 long n_p_loops = 0;
135 long n_p_stmts = 0;
136 long n_p_conditions = 0;
138 basic_block bb;
140 FOR_ALL_BB (bb)
142 gimple_stmt_iterator psi;
143 loop_p loop = bb->loop_father;
145 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
146 continue;
148 n_bbs++;
149 n_p_bbs += bb->count;
151 if (EDGE_COUNT (bb->succs) > 1)
153 n_conditions++;
154 n_p_conditions += bb->count;
157 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
159 n_stmts++;
160 n_p_stmts += bb->count;
163 if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
165 n_loops++;
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. */
184 static void
185 print_graphite_statistics (FILE* file, vec<scop_p> scops)
187 int i;
189 scop_p scop;
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. */
197 static bool
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);
208 isl_ctx_free (ctx);
209 return false;
212 scev_reset ();
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);
221 return true;
224 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
225 true. */
227 static void
228 graphite_finalize (bool need_cfg_cleanup_p)
230 if (need_cfg_cleanup_p)
232 scev_reset ();
233 cleanup_tree_cfg ();
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
249 function. */
251 void
252 graphite_transform_loops (void)
254 int i;
255 scop_p scop;
256 bool need_cfg_cleanup_p = false;
257 vec<scop_p> scops = vNULL;
258 htab_t bb_pbb_mapping;
259 isl_ctx *ctx;
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))
264 return;
266 ctx = isl_ctx_alloc ();
267 isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
268 if (!graphite_initialize (ctx))
269 return;
271 the_isl_ctx = 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))
285 scop->ctx = ctx;
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);
295 free_scops (scops);
296 graphite_finalize (need_cfg_cleanup_p);
297 the_isl_ctx = NULL;
298 isl_ctx_free (ctx);
301 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
303 void
304 graphite_transform_loops (void)
306 sorry ("Graphite loop optimizations cannot be used");
309 #endif