Fix PR/46316
[official-gcc.git] / gcc / graphite.c
blob6b393d65736f3102d7d291e89ce0a469852860a5
1 /* Gimple Represented as Polyhedra.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010 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"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "ggc.h"
40 #include "tree.h"
41 #include "rtl.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
45 #include "toplev.h"
46 #include "tree-dump.h"
47 #include "timevar.h"
48 #include "cfgloop.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "tree-pass.h"
53 #include "value-prof.h"
54 #include "pointer-set.h"
55 #include "gimple.h"
56 #include "sese.h"
57 #include "predict.h"
58 #include "dbgcnt.h"
60 #ifdef HAVE_cloog
62 #include "cloog/cloog.h"
63 #include "ppl_c.h"
64 #include "graphite-cloog-compat.h"
65 #include "graphite-ppl.h"
66 #include "graphite.h"
67 #include "graphite-poly.h"
68 #include "graphite-scop-detection.h"
69 #include "graphite-clast-to-gimple.h"
70 #include "graphite-sese-to-poly.h"
72 /* Print global statistics to FILE. */
74 static void
75 print_global_statistics (FILE* file)
77 long n_bbs = 0;
78 long n_loops = 0;
79 long n_stmts = 0;
80 long n_conditions = 0;
81 long n_p_bbs = 0;
82 long n_p_loops = 0;
83 long n_p_stmts = 0;
84 long n_p_conditions = 0;
86 basic_block bb;
88 FOR_ALL_BB (bb)
90 gimple_stmt_iterator psi;
92 n_bbs++;
93 n_p_bbs += bb->count;
95 /* Ignore artificial surrounding loop. */
96 if (bb == bb->loop_father->header
97 && bb->index != 0)
99 n_loops++;
100 n_p_loops += bb->count;
103 if (VEC_length (edge, bb->succs) > 1)
105 n_conditions++;
106 n_p_conditions += bb->count;
109 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
111 n_stmts++;
112 n_p_stmts += bb->count;
116 fprintf (file, "\nGlobal statistics (");
117 fprintf (file, "BBS:%ld, ", n_bbs);
118 fprintf (file, "LOOPS:%ld, ", n_loops);
119 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
120 fprintf (file, "STMTS:%ld)\n", n_stmts);
121 fprintf (file, "\nGlobal profiling statistics (");
122 fprintf (file, "BBS:%ld, ", n_p_bbs);
123 fprintf (file, "LOOPS:%ld, ", n_p_loops);
124 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
125 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
128 /* Print statistics for SCOP to FILE. */
130 static void
131 print_graphite_scop_statistics (FILE* file, scop_p scop)
133 long n_bbs = 0;
134 long n_loops = 0;
135 long n_stmts = 0;
136 long n_conditions = 0;
137 long n_p_bbs = 0;
138 long n_p_loops = 0;
139 long n_p_stmts = 0;
140 long n_p_conditions = 0;
142 basic_block bb;
144 FOR_ALL_BB (bb)
146 gimple_stmt_iterator psi;
147 loop_p loop = bb->loop_father;
149 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
150 continue;
152 n_bbs++;
153 n_p_bbs += bb->count;
155 if (VEC_length (edge, bb->succs) > 1)
157 n_conditions++;
158 n_p_conditions += bb->count;
161 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
163 n_stmts++;
164 n_p_stmts += bb->count;
167 if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
169 n_loops++;
170 n_p_loops += bb->count;
174 fprintf (file, "\nSCoP statistics (");
175 fprintf (file, "BBS:%ld, ", n_bbs);
176 fprintf (file, "LOOPS:%ld, ", n_loops);
177 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
178 fprintf (file, "STMTS:%ld)\n", n_stmts);
179 fprintf (file, "\nSCoP profiling statistics (");
180 fprintf (file, "BBS:%ld, ", n_p_bbs);
181 fprintf (file, "LOOPS:%ld, ", n_p_loops);
182 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
183 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
186 /* Print statistics for SCOPS to FILE. */
188 static void
189 print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
191 int i;
193 scop_p scop;
195 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
196 print_graphite_scop_statistics (file, scop);
199 /* Initialize graphite: when there are no loops returns false. */
201 static bool
202 graphite_initialize (void)
204 int ppl_initialized;
206 if (number_of_loops () <= 1
207 /* FIXME: This limit on the number of basic blocks of a function
208 should be removed when the SCOP detection is faster. */
209 || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION))
211 if (dump_file && (dump_flags & TDF_DETAILS))
212 print_global_statistics (dump_file);
214 return false;
217 scev_reset ();
218 recompute_all_dominators ();
219 initialize_original_copy_tables ();
221 ppl_initialized = ppl_initialize ();
222 gcc_assert (ppl_initialized == 0);
224 cloog_initialize ();
226 if (dump_file && dump_flags)
227 dump_function_to_file (current_function_decl, dump_file, dump_flags);
229 return true;
232 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
233 true. */
235 static void
236 graphite_finalize (bool need_cfg_cleanup_p)
238 if (need_cfg_cleanup_p)
240 scev_reset ();
241 cleanup_tree_cfg ();
242 profile_status = PROFILE_ABSENT;
243 release_recorded_exits ();
244 tree_estimate_probability ();
247 cloog_finalize ();
248 ppl_finalize ();
249 free_original_copy_tables ();
251 if (dump_file && dump_flags)
252 print_loops (dump_file, 3);
255 /* Perform a set of linear transforms on the loops of the current
256 function. */
258 void
259 graphite_transform_loops (void)
261 int i;
262 scop_p scop;
263 bool need_cfg_cleanup_p = false;
264 VEC (scop_p, heap) *scops = NULL;
265 htab_t bb_pbb_mapping;
266 sbitmap reductions;
268 if (!graphite_initialize ())
269 return;
271 build_scops (&scops);
273 if (dump_file && (dump_flags & TDF_DETAILS))
275 print_graphite_statistics (dump_file, scops);
276 print_global_statistics (dump_file);
279 bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
280 reductions = sbitmap_alloc (last_basic_block * 2);
281 sbitmap_zero (reductions);
283 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
284 if (dbg_cnt (graphite_scop))
285 rewrite_commutative_reductions_out_of_ssa (SCOP_REGION (scop),
286 reductions);
288 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
289 if (dbg_cnt (graphite_scop))
291 rewrite_reductions_out_of_ssa (scop);
292 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
293 build_scop_bbs (scop, reductions);
296 sbitmap_free (reductions);
298 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
299 if (dbg_cnt (graphite_scop))
300 build_poly_scop (scop);
302 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
303 if (POLY_SCOP_P (scop)
304 && apply_poly_transforms (scop)
305 && gloog (scop, bb_pbb_mapping))
306 need_cfg_cleanup_p = true;
308 htab_delete (bb_pbb_mapping);
309 free_scops (scops);
310 graphite_finalize (need_cfg_cleanup_p);
313 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
315 void
316 graphite_transform_loops (void)
318 sorry ("Graphite loop optimizations cannot be used");
321 #endif