OSDN Git Service

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