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 "diagnostic-core.h"
39 #include "tree-flow.h"
40 #include "tree-dump.h"
42 #include "tree-chrec.h"
43 #include "tree-data-ref.h"
44 #include "tree-scalar-evolution.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"
57 /* Print global statistics to FILE. */
60 print_global_statistics (FILE* file
)
65 long n_conditions
= 0;
69 long n_p_conditions
= 0;
75 gimple_stmt_iterator psi
;
80 /* Ignore artificial surrounding loop. */
81 if (bb
== bb
->loop_father
->header
85 n_p_loops
+= bb
->count
;
88 if (VEC_length (edge
, bb
->succs
) > 1)
91 n_p_conditions
+= bb
->count
;
94 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
97 n_p_stmts
+= bb
->count
;
101 fprintf (file
, "\nGlobal statistics (");
102 fprintf (file
, "BBS:%ld, ", n_bbs
);
103 fprintf (file
, "LOOPS:%ld, ", n_loops
);
104 fprintf (file
, "CONDITIONS:%ld, ", n_conditions
);
105 fprintf (file
, "STMTS:%ld)\n", n_stmts
);
106 fprintf (file
, "\nGlobal profiling statistics (");
107 fprintf (file
, "BBS:%ld, ", n_p_bbs
);
108 fprintf (file
, "LOOPS:%ld, ", n_p_loops
);
109 fprintf (file
, "CONDITIONS:%ld, ", n_p_conditions
);
110 fprintf (file
, "STMTS:%ld)\n", n_p_stmts
);
113 /* Print statistics for SCOP to FILE. */
116 print_graphite_scop_statistics (FILE* file
, scop_p scop
)
121 long n_conditions
= 0;
125 long n_p_conditions
= 0;
131 gimple_stmt_iterator psi
;
132 loop_p loop
= bb
->loop_father
;
134 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
138 n_p_bbs
+= bb
->count
;
140 if (VEC_length (edge
, bb
->succs
) > 1)
143 n_p_conditions
+= bb
->count
;
146 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
149 n_p_stmts
+= bb
->count
;
152 if (loop
->header
== bb
&& loop_in_sese_p (loop
, SCOP_REGION (scop
)))
155 n_p_loops
+= bb
->count
;
159 fprintf (file
, "\nSCoP statistics (");
160 fprintf (file
, "BBS:%ld, ", n_bbs
);
161 fprintf (file
, "LOOPS:%ld, ", n_loops
);
162 fprintf (file
, "CONDITIONS:%ld, ", n_conditions
);
163 fprintf (file
, "STMTS:%ld)\n", n_stmts
);
164 fprintf (file
, "\nSCoP profiling statistics (");
165 fprintf (file
, "BBS:%ld, ", n_p_bbs
);
166 fprintf (file
, "LOOPS:%ld, ", n_p_loops
);
167 fprintf (file
, "CONDITIONS:%ld, ", n_p_conditions
);
168 fprintf (file
, "STMTS:%ld)\n", n_p_stmts
);
171 /* Print statistics for SCOPS to FILE. */
174 print_graphite_statistics (FILE* file
, VEC (scop_p
, heap
) *scops
)
180 FOR_EACH_VEC_ELT (scop_p
, scops
, i
, scop
)
181 print_graphite_scop_statistics (file
, scop
);
184 /* Initialize graphite: when there are no loops returns false. */
187 graphite_initialize (void)
191 if (number_of_loops () <= 1
192 /* FIXME: This limit on the number of basic blocks of a function
193 should be removed when the SCOP detection is faster. */
194 || n_basic_blocks
> PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION
))
196 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
197 print_global_statistics (dump_file
);
203 recompute_all_dominators ();
204 initialize_original_copy_tables ();
206 ppl_initialized
= ppl_initialize ();
207 gcc_assert (ppl_initialized
== 0);
211 if (dump_file
&& dump_flags
)
212 dump_function_to_file (current_function_decl
, dump_file
, dump_flags
);
217 /* Finalize graphite: perform CFG cleanup when NEED_CFG_CLEANUP_P is
221 graphite_finalize (bool need_cfg_cleanup_p
)
223 if (need_cfg_cleanup_p
)
227 profile_status
= PROFILE_ABSENT
;
228 release_recorded_exits ();
229 tree_estimate_probability ();
234 free_original_copy_tables ();
236 if (dump_file
&& dump_flags
)
237 print_loops (dump_file
, 3);
240 /* Perform a set of linear transforms on the loops of the current
244 graphite_transform_loops (void)
248 bool need_cfg_cleanup_p
= false;
249 VEC (scop_p
, heap
) *scops
= NULL
;
250 htab_t bb_pbb_mapping
;
252 if (!graphite_initialize ())
255 build_scops (&scops
);
257 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
259 print_graphite_statistics (dump_file
, scops
);
260 print_global_statistics (dump_file
);
263 bb_pbb_mapping
= htab_create (10, bb_pbb_map_hash
, eq_bb_pbb_map
, free
);
265 FOR_EACH_VEC_ELT (scop_p
, scops
, i
, scop
)
266 if (dbg_cnt (graphite_scop
))
268 build_poly_scop (scop
);
270 if (POLY_SCOP_P (scop
)
271 && apply_poly_transforms (scop
)
272 && gloog (scop
, bb_pbb_mapping
))
273 need_cfg_cleanup_p
= true;
276 htab_delete (bb_pbb_mapping
);
278 graphite_finalize (need_cfg_cleanup_p
);
281 #else /* If Cloog is not available: #ifndef HAVE_cloog. */
284 graphite_transform_loops (void)
286 sorry ("Graphite loop optimizations cannot be used");