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)
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
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
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. */
37 #include "coretypes.h"
42 #include "basic-block.h"
43 #include "diagnostic.h"
44 #include "tree-flow.h"
46 #include "tree-dump.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"
62 #include "cloog/cloog.h"
64 #include "graphite-cloog-compat.h"
65 #include "graphite-ppl.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. */
75 print_global_statistics (FILE* file
)
80 long n_conditions
= 0;
84 long n_p_conditions
= 0;
90 gimple_stmt_iterator psi
;
95 /* Ignore artificial surrounding loop. */
96 if (bb
== bb
->loop_father
->header
100 n_p_loops
+= bb
->count
;
103 if (VEC_length (edge
, bb
->succs
) > 1)
106 n_p_conditions
+= bb
->count
;
109 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
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. */
131 print_graphite_scop_statistics (FILE* file
, scop_p scop
)
136 long n_conditions
= 0;
140 long n_p_conditions
= 0;
146 gimple_stmt_iterator psi
;
147 loop_p loop
= bb
->loop_father
;
149 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
153 n_p_bbs
+= bb
->count
;
155 if (VEC_length (edge
, bb
->succs
) > 1)
158 n_p_conditions
+= bb
->count
;
161 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
164 n_p_stmts
+= bb
->count
;
167 if (loop
->header
== bb
&& loop_in_sese_p (loop
, SCOP_REGION (scop
)))
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. */
189 print_graphite_statistics (FILE* file
, VEC (scop_p
, heap
) *scops
)
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. */
202 graphite_initialize (void)
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
);
218 recompute_all_dominators ();
219 initialize_original_copy_tables ();
221 ppl_initialized
= ppl_initialize ();
222 gcc_assert (ppl_initialized
== 0);
226 if (dump_file
&& dump_flags
)
227 dump_function_to_file (current_function_decl
, dump_file
, dump_flags
);
232 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
236 graphite_finalize (bool need_cfg_cleanup_p
)
238 if (need_cfg_cleanup_p
)
242 profile_status
= PROFILE_ABSENT
;
243 release_recorded_exits ();
244 tree_estimate_probability ();
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
259 graphite_transform_loops (void)
263 bool need_cfg_cleanup_p
= false;
264 VEC (scop_p
, heap
) *scops
= NULL
;
265 htab_t bb_pbb_mapping
;
268 if (!graphite_initialize ())
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
),
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
);
310 graphite_finalize (need_cfg_cleanup_p
);
313 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
316 graphite_transform_loops (void)
318 sorry ("Graphite loop optimizations cannot be used");