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"
38 #include "tree-flow.h"
39 #include "tree-dump.h"
41 #include "tree-chrec.h"
42 #include "tree-data-ref.h"
43 #include "tree-scalar-evolution.h"
50 #include "graphite-ppl.h"
51 #include "graphite-poly.h"
52 #include "graphite-scop-detection.h"
53 #include "graphite-clast-to-gimple.h"
54 #include "graphite-sese-to-poly.h"
56 /* Print global statistics to FILE. */
59 print_global_statistics (FILE* file)
64 long n_conditions = 0;
68 long n_p_conditions = 0;
74 gimple_stmt_iterator psi;
79 /* Ignore artificial surrounding loop. */
80 if (bb == bb->loop_father->header
84 n_p_loops += bb->count;
87 if (VEC_length (edge, bb->succs) > 1)
90 n_p_conditions += bb->count;
93 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
96 n_p_stmts += bb->count;
100 fprintf (file, "\nGlobal statistics (");
101 fprintf (file, "BBS:%ld, ", n_bbs);
102 fprintf (file, "LOOPS:%ld, ", n_loops);
103 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
104 fprintf (file, "STMTS:%ld)\n", n_stmts);
105 fprintf (file, "\nGlobal profiling statistics (");
106 fprintf (file, "BBS:%ld, ", n_p_bbs);
107 fprintf (file, "LOOPS:%ld, ", n_p_loops);
108 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
109 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
112 /* Print statistics for SCOP to FILE. */
115 print_graphite_scop_statistics (FILE* file, scop_p scop)
120 long n_conditions = 0;
124 long n_p_conditions = 0;
130 gimple_stmt_iterator psi;
131 loop_p loop = bb->loop_father;
133 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
137 n_p_bbs += bb->count;
139 if (VEC_length (edge, bb->succs) > 1)
142 n_p_conditions += bb->count;
145 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
148 n_p_stmts += bb->count;
151 if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
154 n_p_loops += bb->count;
158 fprintf (file, "\nSCoP statistics (");
159 fprintf (file, "BBS:%ld, ", n_bbs);
160 fprintf (file, "LOOPS:%ld, ", n_loops);
161 fprintf (file, "CONDITIONS:%ld, ", n_conditions);
162 fprintf (file, "STMTS:%ld)\n", n_stmts);
163 fprintf (file, "\nSCoP profiling statistics (");
164 fprintf (file, "BBS:%ld, ", n_p_bbs);
165 fprintf (file, "LOOPS:%ld, ", n_p_loops);
166 fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
167 fprintf (file, "STMTS:%ld)\n", n_p_stmts);
170 /* Print statistics for SCOPS to FILE. */
173 print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
179 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
180 print_graphite_scop_statistics (file, scop);
183 /* Initialize graphite: when there are no loops returns false. */
186 graphite_initialize (void)
190 if (number_of_loops () <= 1
191 /* FIXME: This limit on the number of basic blocks of a function
192 should be removed when the SCOP detection is faster. */
193 || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION))
195 if (dump_file && (dump_flags & TDF_DETAILS))
196 print_global_statistics (dump_file);
202 recompute_all_dominators ();
203 initialize_original_copy_tables ();
205 ppl_initialized = ppl_initialize ();
206 gcc_assert (ppl_initialized == 0);
210 if (dump_file && dump_flags)
211 dump_function_to_file (current_function_decl, dump_file, dump_flags);
216 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
220 graphite_finalize (bool need_cfg_cleanup_p)
222 if (need_cfg_cleanup_p)
226 profile_status = PROFILE_ABSENT;
227 release_recorded_exits ();
228 tree_estimate_probability ();
233 free_original_copy_tables ();
235 if (dump_file && dump_flags)
236 print_loops (dump_file, 3);
239 /* Perform a set of linear transforms on the loops of the current
243 graphite_transform_loops (void)
247 bool need_cfg_cleanup_p = false;
248 VEC (scop_p, heap) *scops = NULL;
249 htab_t bb_pbb_mapping;
251 if (!graphite_initialize ())
254 build_scops (&scops);
256 if (dump_file && (dump_flags & TDF_DETAILS))
258 print_graphite_statistics (dump_file, scops);
259 print_global_statistics (dump_file);
262 bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
264 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
265 if (dbg_cnt (graphite_scop))
267 build_poly_scop (scop);
269 if (POLY_SCOP_P (scop)
270 && apply_poly_transforms (scop)
271 && gloog (scop, bb_pbb_mapping))
272 need_cfg_cleanup_p = true;
275 htab_delete (bb_pbb_mapping);
277 graphite_finalize (need_cfg_cleanup_p);
280 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
283 graphite_transform_loops (void)
285 sorry ("Graphite loop optimizations cannot be used");