Daily bump.
[gcc.git] / gcc / graphite.c
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>.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 /* This pass converts GIMPLE to GRAPHITE, performs some loop
22 transformations and then converts the resulting representation back
23 to GIMPLE.
24
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.
29
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. */
34
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "diagnostic-core.h"
39 #include "tree-flow.h"
40 #include "tree-dump.h"
41 #include "cfgloop.h"
42 #include "tree-chrec.h"
43 #include "tree-data-ref.h"
44 #include "tree-scalar-evolution.h"
45 #include "sese.h"
46 #include "dbgcnt.h"
47
48 #ifdef HAVE_cloog
49
50 #include "ppl_c.h"
51 #include "graphite-ppl.h"
52 #include "graphite-poly.h"
53 #include "graphite-scop-detection.h"
54 #include "graphite-clast-to-gimple.h"
55 #include "graphite-sese-to-poly.h"
56
57 CloogState *cloog_state;
58
59 /* Print global statistics to FILE. */
60
61 static void
62 print_global_statistics (FILE* file)
63 {
64 long n_bbs = 0;
65 long n_loops = 0;
66 long n_stmts = 0;
67 long n_conditions = 0;
68 long n_p_bbs = 0;
69 long n_p_loops = 0;
70 long n_p_stmts = 0;
71 long n_p_conditions = 0;
72
73 basic_block bb;
74
75 FOR_ALL_BB (bb)
76 {
77 gimple_stmt_iterator psi;
78
79 n_bbs++;
80 n_p_bbs += bb->count;
81
82 /* Ignore artificial surrounding loop. */
83 if (bb == bb->loop_father->header
84 && bb->index != 0)
85 {
86 n_loops++;
87 n_p_loops += bb->count;
88 }
89
90 if (VEC_length (edge, bb->succs) > 1)
91 {
92 n_conditions++;
93 n_p_conditions += bb->count;
94 }
95
96 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
97 {
98 n_stmts++;
99 n_p_stmts += bb->count;
100 }
101 }
102
103 fprintf (file, "\nGlobal statistics (");
104 fprintf (file, "BBS:%ld, ", n_bbs);
105 fprintf (file, "LOOPS:%ld, ", n_loops);
106 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
107 fprintf (file, "STMTS:%ld)\n", n_stmts);
108 fprintf (file, "\nGlobal profiling statistics (");
109 fprintf (file, "BBS:%ld, ", n_p_bbs);
110 fprintf (file, "LOOPS:%ld, ", n_p_loops);
111 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
112 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
113 }
114
115 /* Print statistics for SCOP to FILE. */
116
117 static void
118 print_graphite_scop_statistics (FILE* file, scop_p scop)
119 {
120 long n_bbs = 0;
121 long n_loops = 0;
122 long n_stmts = 0;
123 long n_conditions = 0;
124 long n_p_bbs = 0;
125 long n_p_loops = 0;
126 long n_p_stmts = 0;
127 long n_p_conditions = 0;
128
129 basic_block bb;
130
131 FOR_ALL_BB (bb)
132 {
133 gimple_stmt_iterator psi;
134 loop_p loop = bb->loop_father;
135
136 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
137 continue;
138
139 n_bbs++;
140 n_p_bbs += bb->count;
141
142 if (VEC_length (edge, bb->succs) > 1)
143 {
144 n_conditions++;
145 n_p_conditions += bb->count;
146 }
147
148 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
149 {
150 n_stmts++;
151 n_p_stmts += bb->count;
152 }
153
154 if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
155 {
156 n_loops++;
157 n_p_loops += bb->count;
158 }
159 }
160
161 fprintf (file, "\nSCoP statistics (");
162 fprintf (file, "BBS:%ld, ", n_bbs);
163 fprintf (file, "LOOPS:%ld, ", n_loops);
164 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
165 fprintf (file, "STMTS:%ld)\n", n_stmts);
166 fprintf (file, "\nSCoP profiling statistics (");
167 fprintf (file, "BBS:%ld, ", n_p_bbs);
168 fprintf (file, "LOOPS:%ld, ", n_p_loops);
169 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
170 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
171 }
172
173 /* Print statistics for SCOPS to FILE. */
174
175 static void
176 print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
177 {
178 int i;
179
180 scop_p scop;
181
182 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
183 print_graphite_scop_statistics (file, scop);
184 }
185
186 /* Initialize graphite: when there are no loops returns false. */
187
188 static bool
189 graphite_initialize (void)
190 {
191 int ppl_initialized;
192
193 if (number_of_loops () <= 1
194 /* FIXME: This limit on the number of basic blocks of a function
195 should be removed when the SCOP detection is faster. */
196 || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION))
197 {
198 if (dump_file && (dump_flags & TDF_DETAILS))
199 print_global_statistics (dump_file);
200
201 return false;
202 }
203
204 scev_reset ();
205 recompute_all_dominators ();
206 initialize_original_copy_tables ();
207
208 ppl_initialized = ppl_initialize ();
209 gcc_assert (ppl_initialized == 0);
210
211 cloog_state = cloog_state_malloc ();
212 cloog_initialize ();
213
214 if (dump_file && dump_flags)
215 dump_function_to_file (current_function_decl, dump_file, dump_flags);
216
217 return true;
218 }
219
220 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
221 true. */
222
223 static void
224 graphite_finalize (bool need_cfg_cleanup_p)
225 {
226 if (need_cfg_cleanup_p)
227 {
228 scev_reset ();
229 cleanup_tree_cfg ();
230 profile_status = PROFILE_ABSENT;
231 release_recorded_exits ();
232 tree_estimate_probability ();
233 }
234
235 cloog_state_free (cloog_state);
236 cloog_finalize ();
237 ppl_finalize ();
238 free_original_copy_tables ();
239
240 if (dump_file && dump_flags)
241 print_loops (dump_file, 3);
242 }
243
244 /* Perform a set of linear transforms on the loops of the current
245 function. */
246
247 void
248 graphite_transform_loops (void)
249 {
250 int i;
251 scop_p scop;
252 bool need_cfg_cleanup_p = false;
253 VEC (scop_p, heap) *scops = NULL;
254 htab_t bb_pbb_mapping;
255
256 if (!graphite_initialize ())
257 return;
258
259 build_scops (&scops);
260
261 if (dump_file && (dump_flags & TDF_DETAILS))
262 {
263 print_graphite_statistics (dump_file, scops);
264 print_global_statistics (dump_file);
265 }
266
267 bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
268
269 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
270 if (dbg_cnt (graphite_scop))
271 {
272 build_poly_scop (scop);
273
274 if (POLY_SCOP_P (scop)
275 && apply_poly_transforms (scop)
276 && gloog (scop, bb_pbb_mapping))
277 need_cfg_cleanup_p = true;
278 }
279
280 htab_delete (bb_pbb_mapping);
281 free_scops (scops);
282 graphite_finalize (need_cfg_cleanup_p);
283 }
284
285 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
286
287 void
288 graphite_transform_loops (void)
289 {
290 sorry ("Graphite loop optimizations cannot be used");
291 }
292
293 #endif