Merge from mainline (160224:163495).
[official-gcc/graphite-test-results.git] / gcc / graphite.c
bloba5fcc4a0f2e96d493b74b49f4b3547d7820917bf
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 recompute_all_dominators ();
218 initialize_original_copy_tables ();
220 ppl_initialized = ppl_initialize ();
221 gcc_assert (ppl_initialized == 0);
223 cloog_initialize ();
225 if (dump_file && dump_flags)
226 dump_function_to_file (current_function_decl, dump_file, dump_flags);
228 return true;
231 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
232 true. */
234 static void
235 graphite_finalize (bool need_cfg_cleanup_p)
237 if (need_cfg_cleanup_p)
239 scev_reset ();
240 cleanup_tree_cfg ();
241 profile_status = PROFILE_ABSENT;
242 release_recorded_exits ();
243 tree_estimate_probability ();
246 cloog_finalize ();
247 ppl_finalize ();
248 free_original_copy_tables ();
250 if (dump_file && dump_flags)
251 print_loops (dump_file, 3);
254 /* Perform a set of linear transforms on the loops of the current
255 function. */
257 void
258 graphite_transform_loops (void)
260 int i;
261 scop_p scop;
262 bool need_cfg_cleanup_p = false;
263 VEC (scop_p, heap) *scops = NULL;
264 htab_t bb_pbb_mapping;
265 sbitmap reductions;
267 if (!graphite_initialize ())
268 return;
270 build_scops (&scops);
272 if (dump_file && (dump_flags & TDF_DETAILS))
274 print_graphite_statistics (dump_file, scops);
275 print_global_statistics (dump_file);
278 bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
279 reductions = sbitmap_alloc (last_basic_block * 2);
280 sbitmap_zero (reductions);
282 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
283 if (dbg_cnt (graphite_scop))
284 rewrite_commutative_reductions_out_of_ssa (SCOP_REGION (scop),
285 reductions);
287 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
288 if (dbg_cnt (graphite_scop))
290 rewrite_reductions_out_of_ssa (scop);
291 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
292 build_scop_bbs (scop, reductions);
295 sbitmap_free (reductions);
297 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
298 if (dbg_cnt (graphite_scop))
299 build_poly_scop (scop);
301 for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
302 if (POLY_SCOP_P (scop)
303 && apply_poly_transforms (scop)
304 && gloog (scop, bb_pbb_mapping))
305 need_cfg_cleanup_p = true;
307 htab_delete (bb_pbb_mapping);
308 free_scops (scops);
309 graphite_finalize (need_cfg_cleanup_p);
312 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
314 void
315 graphite_transform_loops (void)
317 sorry ("Graphite loop optimizations cannot be used");
320 #endif