]>
Commit | Line | Data |
---|---|---|
c6bb733d | 1 | /* Graphite polyhedral representation. |
7cf0dbf3 | 2 | Copyright (C) 2009, 2010 Free Software Foundation, Inc. |
c6bb733d | 3 | Contributed by Sebastian Pop <sebastian.pop@amd.com> and |
4 | Tobias Grosser <grosser@fim.uni-passau.de>. | |
5 | ||
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3, or (at your option) | |
11 | any later version. | |
12 | ||
13 | GCC is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GCC; see the file COPYING3. If not see | |
20 | <http://www.gnu.org/licenses/>. */ | |
21 | #include "config.h" | |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
c6bb733d | 24 | #include "diagnostic.h" |
25 | #include "tree-flow.h" | |
c6bb733d | 26 | #include "tree-dump.h" |
1e5b7b1f | 27 | #include "gimple-pretty-print.h" |
c6bb733d | 28 | #include "cfgloop.h" |
29 | #include "tree-chrec.h" | |
30 | #include "tree-data-ref.h" | |
31 | #include "tree-scalar-evolution.h" | |
1e5b7b1f | 32 | #include "sese.h" |
c6bb733d | 33 | |
34 | #ifdef HAVE_cloog | |
c6bb733d | 35 | #include "ppl_c.h" |
c6bb733d | 36 | #include "graphite-ppl.h" |
c6bb733d | 37 | #include "graphite-poly.h" |
38 | #include "graphite-dependences.h" | |
f2459691 | 39 | #include "graphite-cloog-util.h" |
c6bb733d | 40 | |
63b03ccf | 41 | #define OPENSCOP_MAX_STRING 256 |
42 | ||
c6bb733d | 43 | /* Return the maximal loop depth in SCOP. */ |
44 | ||
45 | int | |
46 | scop_max_loop_depth (scop_p scop) | |
47 | { | |
48 | int i; | |
49 | poly_bb_p pbb; | |
50 | int max_nb_loops = 0; | |
51 | ||
48148244 | 52 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
c6bb733d | 53 | { |
54 | int nb_loops = pbb_dim_iter_domain (pbb); | |
55 | if (max_nb_loops < nb_loops) | |
56 | max_nb_loops = nb_loops; | |
57 | } | |
58 | ||
59 | return max_nb_loops; | |
60 | } | |
61 | ||
62 | /* Extend the scattering matrix of PBB to MAX_SCATTERING scattering | |
63 | dimensions. */ | |
64 | ||
65 | static void | |
66 | extend_scattering (poly_bb_p pbb, int max_scattering) | |
67 | { | |
68 | ppl_dimension_type nb_old_dims, nb_new_dims; | |
69 | int nb_added_dims, i; | |
70 | ppl_Coefficient_t coef; | |
0ef84e3b | 71 | mpz_t one; |
c6bb733d | 72 | |
73 | nb_added_dims = max_scattering - pbb_nb_scattering_transform (pbb); | |
2d6fe479 | 74 | mpz_init (one); |
75 | mpz_set_si (one, 1); | |
c6bb733d | 76 | ppl_new_Coefficient (&coef); |
77 | ppl_assign_Coefficient_from_mpz_t (coef, one); | |
78 | ||
79 | gcc_assert (nb_added_dims >= 0); | |
80 | ||
81 | nb_old_dims = pbb_nb_scattering_transform (pbb) + pbb_dim_iter_domain (pbb) | |
82 | + scop_nb_params (PBB_SCOP (pbb)); | |
83 | nb_new_dims = nb_old_dims + nb_added_dims; | |
84 | ||
85 | ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), | |
86 | pbb_nb_scattering_transform (pbb), nb_added_dims); | |
87 | PBB_NB_SCATTERING_TRANSFORM (pbb) += nb_added_dims; | |
88 | ||
89 | /* Add identity matrix for the added dimensions. */ | |
90 | for (i = max_scattering - nb_added_dims; i < max_scattering; i++) | |
91 | { | |
92 | ppl_Constraint_t cstr; | |
93 | ppl_Linear_Expression_t expr; | |
94 | ||
95 | ppl_new_Linear_Expression_with_dimension (&expr, nb_new_dims); | |
96 | ppl_Linear_Expression_add_to_coefficient (expr, i, coef); | |
97 | ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL); | |
98 | ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr); | |
99 | ppl_delete_Constraint (cstr); | |
100 | ppl_delete_Linear_Expression (expr); | |
101 | } | |
102 | ||
103 | ppl_delete_Coefficient (coef); | |
2d6fe479 | 104 | mpz_clear (one); |
c6bb733d | 105 | } |
106 | ||
107 | /* All scattering matrices in SCOP will have the same number of scattering | |
108 | dimensions. */ | |
109 | ||
110 | int | |
111 | unify_scattering_dimensions (scop_p scop) | |
112 | { | |
113 | int i; | |
114 | poly_bb_p pbb; | |
115 | graphite_dim_t max_scattering = 0; | |
116 | ||
48148244 | 117 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
c6bb733d | 118 | max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering); |
119 | ||
48148244 | 120 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
c6bb733d | 121 | extend_scattering (pbb, max_scattering); |
122 | ||
123 | return max_scattering; | |
124 | } | |
125 | ||
8c4b14b0 | 126 | /* Print to FILE the pdr PH in OpenScop format. NB_SUBSCRIPTS is the number |
127 | of subscripts in PH, ALIAS_SET_DIM is the dimension of the alias set and | |
128 | NB_PARAMS is the number of parameters in PH. */ | |
129 | ||
130 | static void | |
131 | openscop_print_pdr_polyhedron (FILE *file, ppl_const_Polyhedron_t ph, | |
132 | int nb_subscripts, int alias_set_dimension, | |
133 | int nb_params) | |
134 | { | |
135 | int input, locals, output; | |
136 | ppl_dimension_type alias_set_dim = (ppl_dimension_type) alias_set_dimension; | |
137 | ppl_dimension_type sub_dim_last = alias_set_dim + nb_subscripts; | |
138 | ppl_dimension_type *map, i, ph_space_dim = sub_dim_last + 1; | |
139 | ppl_Polyhedron_t pph; | |
140 | ||
c8f5df71 | 141 | ppl_new_C_Polyhedron_from_C_Polyhedron (&pph, ph); |
8c4b14b0 | 142 | |
143 | map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, ph_space_dim); | |
144 | ||
145 | for (i = 0; i < alias_set_dim - 1; i++) | |
146 | map[i] = nb_subscripts + 1 + i; | |
147 | ||
148 | for (i = alias_set_dim - 1; i < sub_dim_last; i++) | |
149 | map[i] = i - alias_set_dim + 1; | |
150 | ||
151 | ppl_Polyhedron_map_space_dimensions (pph, map, ph_space_dim - 1); | |
152 | ||
153 | locals = 0; | |
154 | input = alias_set_dim - nb_params - 1; | |
155 | ||
156 | /* According to OpenScop specification, the alias set column is a part of | |
157 | the output columns. */ | |
158 | output = nb_subscripts + 1; | |
159 | ||
c8f5df71 | 160 | openscop_print_polyhedron_matrix (file, pph, output, input, locals, nb_params); |
8c4b14b0 | 161 | } |
162 | ||
163 | /* Print to FILE the powerset PDR. NB_SUBSCRIPTS is the number of subscripts | |
164 | in PDR, ALIAS_SET_DIM is the dimension of the alias set in PDR and | |
165 | NB_PARAMS is the number of parameters in PDR. */ | |
166 | ||
167 | static void | |
168 | openscop_print_pdr_powerset (FILE *file, | |
169 | ppl_Pointset_Powerset_C_Polyhedron_t ps, | |
170 | int nb_subscripts, | |
171 | int alias_set_dim, | |
172 | int nb_params) | |
173 | { | |
174 | size_t nb_disjuncts; | |
175 | ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; | |
176 | ||
177 | ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); | |
178 | ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); | |
179 | ||
180 | ppl_Pointset_Powerset_C_Polyhedron_size (ps, &nb_disjuncts); | |
181 | fprintf (file, "%d\n", (int) nb_disjuncts); | |
182 | ||
183 | for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it), | |
184 | ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end); | |
185 | !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); | |
186 | ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) | |
187 | { | |
188 | ppl_const_Polyhedron_t ph; | |
189 | ||
190 | ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); | |
191 | openscop_print_pdr_polyhedron (file, ph, nb_subscripts, alias_set_dim, | |
192 | nb_params); | |
193 | } | |
194 | ||
195 | ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); | |
196 | ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); | |
197 | } | |
198 | ||
199 | /* Print to FILE the powerset PS in its OpenScop matrix form. */ | |
200 | ||
201 | static void | |
202 | openscop_print_powerset_matrix (FILE *file, | |
203 | ppl_Pointset_Powerset_C_Polyhedron_t ps, | |
204 | int output, int input, int locals, | |
205 | int params) | |
206 | { | |
207 | size_t nb_disjuncts; | |
208 | ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end; | |
209 | ||
210 | ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it); | |
211 | ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end); | |
212 | ||
213 | ppl_Pointset_Powerset_C_Polyhedron_size (ps, &nb_disjuncts); | |
214 | fprintf (file, "%d\n", (int) nb_disjuncts); | |
215 | ||
216 | for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it), | |
217 | ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end); | |
218 | !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end); | |
219 | ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it)) | |
220 | { | |
221 | ppl_const_Polyhedron_t ph; | |
222 | ||
223 | ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph); | |
224 | openscop_print_polyhedron_matrix (file, ph, output, input, locals, | |
225 | params); | |
226 | } | |
227 | ||
228 | ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it); | |
229 | ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end); | |
230 | } | |
231 | ||
232 | /* Prints to FILE the scattering function of PBB in OpenScop format, at some | |
233 | VERBOSITY level. */ | |
234 | ||
235 | static void | |
236 | openscop_print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity) | |
237 | { | |
238 | graphite_dim_t i; | |
239 | ppl_const_Polyhedron_t ph; | |
240 | ||
241 | if (verbosity > 0) | |
242 | { | |
243 | fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb)); | |
086610eb | 244 | fprintf (file, "#eq"); |
8c4b14b0 | 245 | |
246 | for (i = 0; i < pbb_nb_scattering_transform (pbb); i++) | |
247 | fprintf (file, " s%d", (int) i); | |
248 | ||
249 | for (i = 0; i < pbb_nb_local_vars (pbb); i++) | |
250 | fprintf (file, " lv%d", (int) i); | |
251 | ||
252 | for (i = 0; i < pbb_dim_iter_domain (pbb); i++) | |
253 | fprintf (file, " i%d", (int) i); | |
254 | ||
255 | for (i = 0; i < pbb_nb_params (pbb); i++) | |
256 | fprintf (file, " p%d", (int) i); | |
257 | ||
258 | fprintf (file, " cst\n"); | |
259 | } | |
260 | ||
261 | /* Number of disjunct components. Remove this when | |
262 | PBB_TRANSFORMED_SCATTERING will be a pointset_powerset. */ | |
263 | fprintf (file, "1\n"); | |
264 | ||
265 | ph = PBB_TRANSFORMED_SCATTERING (pbb) | |
266 | ? PBB_TRANSFORMED_SCATTERING (pbb) | |
267 | : PBB_ORIGINAL_SCATTERING (pbb); | |
268 | ||
269 | openscop_print_polyhedron_matrix (file, ph, | |
270 | pbb_nb_scattering_transform (pbb), | |
271 | pbb_dim_iter_domain (pbb), | |
272 | pbb_nb_local_vars (pbb), | |
273 | pbb_nb_params (pbb)); | |
274 | ||
275 | if (verbosity > 0) | |
276 | fprintf (file, "#)\n"); | |
277 | } | |
278 | ||
ff4c7a5a | 279 | /* Prints to FILE the scattering function of PBB, at some VERBOSITY |
280 | level. */ | |
c6bb733d | 281 | |
1f8d6d4d | 282 | static void |
ff4c7a5a | 283 | print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity) |
c6bb733d | 284 | { |
285 | graphite_dim_t i; | |
286 | ||
ff4c7a5a | 287 | if (verbosity > 0) |
288 | { | |
289 | fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb)); | |
086610eb | 290 | fprintf (file, "#eq"); |
c6bb733d | 291 | |
ff4c7a5a | 292 | for (i = 0; i < pbb_nb_scattering_transform (pbb); i++) |
293 | fprintf (file, " s%d", (int) i); | |
c6bb733d | 294 | |
ff4c7a5a | 295 | for (i = 0; i < pbb_nb_local_vars (pbb); i++) |
296 | fprintf (file, " lv%d", (int) i); | |
c6bb733d | 297 | |
ff4c7a5a | 298 | for (i = 0; i < pbb_dim_iter_domain (pbb); i++) |
299 | fprintf (file, " i%d", (int) i); | |
c6bb733d | 300 | |
ff4c7a5a | 301 | for (i = 0; i < pbb_nb_params (pbb); i++) |
302 | fprintf (file, " p%d", (int) i); | |
c6bb733d | 303 | |
ff4c7a5a | 304 | fprintf (file, " cst\n"); |
305 | } | |
c6bb733d | 306 | |
5dc5fe13 | 307 | /* Number of disjunct components. Remove this when |
308 | PBB_TRANSFORMED_SCATTERING will be a pointset_powerset. */ | |
309 | fprintf (file, "1\n"); | |
310 | ppl_print_polyhedron_matrix (file, PBB_TRANSFORMED_SCATTERING (pbb) | |
311 | ? PBB_TRANSFORMED_SCATTERING (pbb) | |
312 | : PBB_ORIGINAL_SCATTERING (pbb)); | |
c6bb733d | 313 | |
ff4c7a5a | 314 | if (verbosity > 0) |
315 | fprintf (file, "#)\n"); | |
c6bb733d | 316 | } |
317 | ||
ff4c7a5a | 318 | /* Prints to FILE the scattering function of PBB, at some VERBOSITY |
319 | level. */ | |
1f8d6d4d | 320 | |
321 | void | |
ff4c7a5a | 322 | print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity) |
1f8d6d4d | 323 | { |
324 | if (!PBB_TRANSFORMED (pbb)) | |
325 | return; | |
326 | ||
327 | if (PBB_TRANSFORMED_SCATTERING (pbb) | |
328 | || PBB_ORIGINAL_SCATTERING (pbb)) | |
ff4c7a5a | 329 | { |
330 | if (verbosity > 0) | |
331 | fprintf (file, "# Scattering function is provided\n"); | |
332 | ||
333 | fprintf (file, "1\n"); | |
334 | } | |
1f8d6d4d | 335 | else |
336 | { | |
ff4c7a5a | 337 | if (verbosity > 0) |
338 | fprintf (file, "# Scattering function is not provided\n"); | |
339 | ||
340 | fprintf (file, "0\n"); | |
1f8d6d4d | 341 | return; |
342 | } | |
343 | ||
8c4b14b0 | 344 | openscop_print_scattering_function_1 (file, pbb, verbosity); |
345 | ||
346 | if (verbosity > 0) | |
347 | fprintf (file, "# Scattering names are not provided\n"); | |
348 | ||
349 | fprintf (file, "0\n"); | |
350 | ||
1f8d6d4d | 351 | } |
352 | ||
ff4c7a5a | 353 | /* Prints to FILE the iteration domain of PBB, at some VERBOSITY |
354 | level. */ | |
c6bb733d | 355 | |
356 | void | |
ff4c7a5a | 357 | print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity) |
c6bb733d | 358 | { |
ff4c7a5a | 359 | print_pbb_domain (file, pbb, verbosity); |
c6bb733d | 360 | } |
361 | ||
362 | /* Prints to FILE the scattering functions of every PBB of SCOP. */ | |
363 | ||
364 | void | |
ff4c7a5a | 365 | print_scattering_functions (FILE *file, scop_p scop, int verbosity) |
c6bb733d | 366 | { |
367 | int i; | |
368 | poly_bb_p pbb; | |
369 | ||
48148244 | 370 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
ff4c7a5a | 371 | print_scattering_function (file, pbb, verbosity); |
c6bb733d | 372 | } |
373 | ||
ff4c7a5a | 374 | /* Prints to FILE the iteration domains of every PBB of SCOP, at some |
375 | VERBOSITY level. */ | |
c6bb733d | 376 | |
377 | void | |
ff4c7a5a | 378 | print_iteration_domains (FILE *file, scop_p scop, int verbosity) |
c6bb733d | 379 | { |
380 | int i; | |
381 | poly_bb_p pbb; | |
382 | ||
48148244 | 383 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
ff4c7a5a | 384 | print_iteration_domain (file, pbb, verbosity); |
c6bb733d | 385 | } |
386 | ||
ff4c7a5a | 387 | /* Prints to STDERR the scattering function of PBB, at some VERBOSITY |
388 | level. */ | |
c6bb733d | 389 | |
4b987fac | 390 | DEBUG_FUNCTION void |
ff4c7a5a | 391 | debug_scattering_function (poly_bb_p pbb, int verbosity) |
c6bb733d | 392 | { |
ff4c7a5a | 393 | print_scattering_function (stderr, pbb, verbosity); |
c6bb733d | 394 | } |
395 | ||
ff4c7a5a | 396 | /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY |
397 | level. */ | |
c6bb733d | 398 | |
4b987fac | 399 | DEBUG_FUNCTION void |
ff4c7a5a | 400 | debug_iteration_domain (poly_bb_p pbb, int verbosity) |
c6bb733d | 401 | { |
ff4c7a5a | 402 | print_iteration_domain (stderr, pbb, verbosity); |
c6bb733d | 403 | } |
404 | ||
ff4c7a5a | 405 | /* Prints to STDERR the scattering functions of every PBB of SCOP, at |
406 | some VERBOSITY level. */ | |
c6bb733d | 407 | |
4b987fac | 408 | DEBUG_FUNCTION void |
ff4c7a5a | 409 | debug_scattering_functions (scop_p scop, int verbosity) |
c6bb733d | 410 | { |
ff4c7a5a | 411 | print_scattering_functions (stderr, scop, verbosity); |
c6bb733d | 412 | } |
413 | ||
ff4c7a5a | 414 | /* Prints to STDERR the iteration domains of every PBB of SCOP, at |
415 | some VERBOSITY level. */ | |
c6bb733d | 416 | |
4b987fac | 417 | DEBUG_FUNCTION void |
ff4c7a5a | 418 | debug_iteration_domains (scop_p scop, int verbosity) |
c6bb733d | 419 | { |
ff4c7a5a | 420 | print_iteration_domains (stderr, scop, verbosity); |
c6bb733d | 421 | } |
422 | ||
63b03ccf | 423 | /* Read N integer from FILE. */ |
424 | ||
425 | int * | |
426 | openscop_read_N_int (FILE *file, int N) | |
427 | { | |
428 | char s[OPENSCOP_MAX_STRING]; | |
429 | char *str; | |
430 | int i, *res = (int *) xmalloc (OPENSCOP_MAX_STRING * sizeof (int)); | |
431 | ||
432 | /* Skip blank and commented lines. */ | |
433 | while (fgets (s, sizeof s, file) == (char *) 0 | |
434 | || s[0] == '#' | |
435 | || ISSPACE (s[0])) | |
436 | ; | |
437 | ||
438 | str = s; | |
439 | ||
440 | for (i = 0; i < N; i++) | |
441 | { | |
442 | sscanf (str, "%d", &res[i]); | |
443 | ||
444 | /* Jump the integer that was read. */ | |
445 | while ((*str) && !ISSPACE (*str) && (*str != '#')) | |
446 | str++; | |
447 | ||
448 | /* Jump spaces. */ | |
449 | while ((*str) && ISSPACE (*str) && (*str != '#')) | |
450 | str++; | |
451 | } | |
452 | ||
453 | return res; | |
454 | } | |
455 | ||
456 | /* Read one integer from FILE. */ | |
457 | ||
458 | static int | |
459 | openscop_read_one_int (FILE *file) | |
460 | { | |
461 | int *x = openscop_read_N_int (file, 1); | |
462 | int res = *x; | |
463 | ||
464 | free (x); | |
465 | return res; | |
466 | } | |
467 | ||
468 | /* Read N string from FILE. */ | |
469 | ||
470 | static char * | |
471 | openscop_read_N_string (FILE *file, int N) | |
472 | { | |
473 | int count, i; | |
474 | char str[OPENSCOP_MAX_STRING]; | |
475 | char *tmp = (char *) xmalloc (sizeof (char) * OPENSCOP_MAX_STRING); | |
476 | char *s = NULL; | |
477 | ||
478 | /* Skip blank and commented lines. */ | |
479 | while (fgets (str, sizeof str, file) == (char *) 0 | |
480 | || str[0] == '#' | |
481 | || ISSPACE (str[0])) | |
482 | ; | |
483 | ||
484 | s = str; | |
485 | count = 0; | |
486 | ||
487 | for (i = 0; i < N; i++) | |
488 | { | |
489 | /* Read the first word. */ | |
490 | for (; (*s) && (!ISSPACE (*s)) && (*s != '#'); ++count) | |
491 | tmp[count] = *(s++); | |
492 | ||
493 | tmp[count] = ' '; | |
494 | count++; | |
495 | ||
496 | /* Jump spaces. */ | |
497 | while ((*s) && ISSPACE (*s) && (*s != '#')) | |
498 | s++; | |
499 | } | |
500 | ||
501 | tmp[count-1] = '\0'; | |
502 | ||
503 | return tmp; | |
504 | } | |
505 | ||
506 | /* Read one string from FILE. */ | |
507 | ||
508 | static char * | |
509 | openscop_read_one_string (FILE *file) | |
510 | { | |
511 | return openscop_read_N_string (file, 1); | |
512 | } | |
513 | ||
514 | /* Read from FILE the powerset PS in its OpenScop matrix form. OUTPUT is the | |
515 | number of output dimensions, INPUT is the number of input dimensions, | |
516 | LOCALS is the number of existentially quantified variables and PARAMS is | |
517 | the number of parameters. */ | |
518 | ||
519 | static void | |
520 | openscop_read_powerset_matrix (FILE *file, | |
521 | ppl_Pointset_Powerset_C_Polyhedron_t *ps, | |
522 | int *output, int *input, int *locals, | |
523 | int *params) | |
524 | { | |
525 | int nb_disjuncts, i; | |
526 | ||
527 | nb_disjuncts = openscop_read_one_int (file); | |
528 | ||
529 | for (i = 0; i < nb_disjuncts; i++) | |
530 | { | |
531 | ppl_Polyhedron_t ph; | |
532 | ||
533 | openscop_read_polyhedron_matrix (file, &ph, output, input, locals, | |
534 | params); | |
535 | if (!ph) | |
536 | *ps = NULL; | |
537 | else if (i == 0) | |
538 | ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (ps, ph); | |
539 | else | |
540 | ppl_Pointset_Powerset_C_Polyhedron_add_disjunct (*ps, ph); | |
541 | } | |
542 | } | |
543 | ||
544 | /* Read a scattering function from FILE and save it to PBB. Return whether | |
545 | the scattering function was provided or not. */ | |
546 | ||
547 | static bool | |
548 | graphite_read_scatt (FILE *file, poly_bb_p pbb) | |
549 | { | |
550 | bool scattering_provided = false; | |
551 | int output, input, locals, params; | |
552 | ppl_Polyhedron_t newp; | |
553 | ||
554 | if (openscop_read_one_int (file) > 0) | |
555 | { | |
556 | /* Read number of disjunct components. */ | |
557 | openscop_read_one_int (file); | |
558 | ||
559 | /* Read scattering function. */ | |
560 | openscop_read_polyhedron_matrix (file, &newp, &output, &input, | |
561 | &locals, ¶ms); | |
562 | store_scattering (PBB_SCOP (pbb)); | |
563 | PBB_TRANSFORMED (pbb) = poly_scattering_new (); | |
564 | PBB_TRANSFORMED_SCATTERING (pbb) = newp; | |
565 | PBB_NB_LOCAL_VARIABLES (pbb) = locals; | |
566 | ||
567 | /* New scattering dimension. */ | |
568 | PBB_NB_SCATTERING_TRANSFORM (pbb) = output; | |
569 | ||
570 | scattering_provided = true; | |
571 | } | |
572 | ||
573 | return scattering_provided; | |
574 | } | |
575 | ||
576 | /* Read a scop file. Return true if the scop is transformed. */ | |
577 | ||
578 | static bool | |
579 | graphite_read_scop_file (FILE *file, scop_p scop) | |
580 | { | |
581 | char *tmp, *language; | |
582 | size_t i, j, nb_statements, nbr, nbw; | |
583 | int input, output, locals, params; | |
584 | ppl_Pointset_Powerset_C_Polyhedron_t ps; | |
585 | poly_bb_p pbb; | |
e7560952 | 586 | bool transform_done = false; |
63b03ccf | 587 | |
588 | /* Ensure that the file is in OpenScop format. */ | |
589 | tmp = openscop_read_N_string (file, 2); | |
590 | ||
591 | if (strcmp (tmp, "SCoP 1")) | |
592 | { | |
bf776685 | 593 | error ("the file is not in OpenScop format"); |
63b03ccf | 594 | return false; |
595 | } | |
596 | ||
597 | free (tmp); | |
598 | ||
599 | /* Read the language. */ | |
600 | language = openscop_read_one_string (file); | |
601 | ||
602 | if (strcmp (language, "Gimple")) | |
603 | { | |
bf776685 | 604 | error ("the language is not recognized"); |
63b03ccf | 605 | return false; |
606 | } | |
607 | ||
608 | free (language); | |
609 | ||
610 | /* Read the context but do not use it. */ | |
611 | openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, ¶ms); | |
612 | ||
613 | if ((size_t) params != scop->nb_params) | |
614 | { | |
bf776685 | 615 | error ("parameters number in the scop file is different from the" |
616 | " internal scop parameter number"); | |
63b03ccf | 617 | return false; |
618 | } | |
619 | ||
620 | /* Read parameter names if provided. */ | |
621 | if (openscop_read_one_int (file)) | |
622 | openscop_read_N_string (file, scop->nb_params); | |
623 | ||
624 | nb_statements = openscop_read_one_int (file); | |
625 | ||
626 | if (nb_statements != VEC_length (poly_bb_p, SCOP_BBS (scop))) | |
627 | { | |
bf776685 | 628 | error ("number of statements in the OpenScop file does not match" |
629 | " the graphite internal statements number"); | |
63b03ccf | 630 | return false; |
631 | } | |
632 | ||
633 | for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++) | |
634 | { | |
635 | /* Read iteration domain. */ | |
636 | openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, | |
637 | ¶ms); | |
638 | ||
639 | /* Read scattering. */ | |
640 | transform_done = graphite_read_scatt (file, pbb); | |
641 | ||
642 | /* Scattering names. */ | |
643 | openscop_read_one_int (file); | |
644 | ||
645 | /* Read access functions. */ | |
646 | if (openscop_read_one_int (file) > 0) | |
647 | { | |
648 | nbr = openscop_read_one_int (file); | |
649 | ||
650 | /* Read access functions. */ | |
651 | for (j = 0; j < nbr; j++) | |
652 | openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, | |
653 | ¶ms); | |
654 | ||
655 | nbw = openscop_read_one_int (file); | |
656 | ||
657 | /* Write access functions. */ | |
658 | for (j = 0; j < nbw; j++) | |
659 | openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, | |
660 | ¶ms); | |
661 | } | |
662 | ||
663 | /* Statement body. */ | |
664 | openscop_read_one_int (file); | |
665 | } | |
666 | ||
667 | return transform_done; | |
668 | } | |
ff4c7a5a | 669 | |
c64f5631 | 670 | /* Initialize and return a file that will be used to write a scop. SCOP_NUMBER |
671 | is a sequential number (identifier) used to differentiate scop files. | |
672 | Examples of the generated file names: dump_base_name.0.graphite, | |
673 | dump_base_name.1.graphite, dump_base_name.2.graphite, etc. */ | |
674 | ||
675 | static FILE * | |
676 | init_graphite_out_file (int scop_number) | |
677 | { | |
678 | FILE *graphite_out_file; | |
679 | int len = strlen (dump_base_name); | |
680 | char *dumpname = XNEWVEC (char, len + 25); | |
681 | char *s_scop_number = XNEWVEC (char, 15); | |
682 | ||
683 | memcpy (dumpname, dump_base_name, len + 1); | |
684 | strip_off_ending (dumpname, len); | |
685 | sprintf (s_scop_number, ".%d", scop_number); | |
686 | strcat (dumpname, s_scop_number); | |
687 | strcat (dumpname, ".graphite"); | |
688 | graphite_out_file = fopen (dumpname, "w+b"); | |
689 | ||
690 | if (graphite_out_file == 0) | |
691 | fatal_error ("can%'t open %s for writing: %m", dumpname); | |
692 | ||
693 | free (dumpname); | |
694 | ||
695 | return graphite_out_file; | |
696 | } | |
697 | ||
698 | /* Open and return a file used for scop reading. SCOP_NUMBER is a sequential | |
699 | number (identifier) used to differentiate scop files. Examples of the | |
700 | generated file names: dump_base_name.0.graphite, dump_base_name.1.graphite, | |
701 | dump_base_name.2.graphite, etc. */ | |
702 | ||
703 | static FILE * | |
704 | init_graphite_in_file (int scop_number) | |
705 | { | |
706 | FILE *graphite_in_file; | |
707 | int len = strlen (dump_base_name); | |
708 | char *dumpname = XNEWVEC (char, len + 25); | |
709 | char *s_scop_number = XNEWVEC (char, 15); | |
710 | ||
711 | memcpy (dumpname, dump_base_name, len + 1); | |
712 | strip_off_ending (dumpname, len); | |
713 | sprintf (s_scop_number, ".%d", scop_number); | |
714 | strcat (dumpname, s_scop_number); | |
715 | strcat (dumpname, ".graphite"); | |
716 | graphite_in_file = fopen (dumpname, "r+b"); | |
717 | ||
718 | if (graphite_in_file == 0) | |
719 | fatal_error ("can%'t open %s for reading: %m", dumpname); | |
720 | ||
721 | free (dumpname); | |
722 | ||
723 | return graphite_in_file; | |
724 | } | |
725 | ||
c6bb733d | 726 | /* Apply graphite transformations to all the basic blocks of SCOP. */ |
727 | ||
728 | bool | |
729 | apply_poly_transforms (scop_p scop) | |
730 | { | |
731 | bool transform_done = false; | |
c64f5631 | 732 | FILE *graphite_file; |
733 | static size_t file_scop_number = 0; | |
c6bb733d | 734 | |
63b03ccf | 735 | /* This feature is only enabled in the Graphite branch. */ |
736 | if (0) | |
737 | { | |
c64f5631 | 738 | graphite_file = init_graphite_in_file (file_scop_number); |
739 | transform_done |= graphite_read_scop_file (graphite_file, scop); | |
416d9c24 | 740 | |
741 | if (!graphite_legal_transform (scop)) | |
742 | fatal_error ("the graphite file read for scop %d does not contain a legal transform", | |
743 | (int) file_scop_number); | |
744 | ||
c64f5631 | 745 | file_scop_number++; |
63b03ccf | 746 | } |
747 | ||
c6bb733d | 748 | /* Generate code even if we did not apply any real transformation. |
749 | This also allows to check the performance for the identity | |
750 | transformation: GIMPLE -> GRAPHITE -> GIMPLE | |
751 | Keep in mind that CLooG optimizes in control, so the loop structure | |
752 | may change, even if we only use -fgraphite-identity. */ | |
753 | if (flag_graphite_identity) | |
754 | transform_done = true; | |
755 | ||
16848556 | 756 | if (flag_loop_parallelize_all) |
c6bb733d | 757 | transform_done = true; |
758 | ||
759 | if (flag_loop_block) | |
64d8f27a | 760 | transform_done |= scop_do_block (scop); |
dbe2e816 | 761 | else |
762 | { | |
763 | if (flag_loop_strip_mine) | |
68f6634f | 764 | transform_done |= scop_do_strip_mine (scop, 0); |
c6bb733d | 765 | |
dbe2e816 | 766 | if (flag_loop_interchange) |
767 | transform_done |= scop_do_interchange (scop); | |
768 | } | |
c6bb733d | 769 | |
d60a90cc | 770 | if (flag_loop_flatten) |
771 | transform_done |= flatten_all_loops (scop); | |
772 | ||
63b03ccf | 773 | /* This feature is only enabled in the Graphite branch. */ |
774 | if (0) | |
c64f5631 | 775 | { |
776 | graphite_file = init_graphite_out_file (file_scop_number); | |
777 | print_scop (graphite_file, scop, 1); | |
778 | file_scop_number++; | |
779 | } | |
63b03ccf | 780 | |
c6bb733d | 781 | return transform_done; |
782 | } | |
783 | ||
9e3531b5 | 784 | /* Returns true when it PDR1 is a duplicate of PDR2: same PBB, and |
785 | their ACCESSES, TYPE, and NB_SUBSCRIPTS are the same. */ | |
11b2102e | 786 | |
787 | static inline bool | |
9e3531b5 | 788 | can_collapse_pdrs (poly_dr_p pdr1, poly_dr_p pdr2) |
11b2102e | 789 | { |
9e3531b5 | 790 | bool res; |
791 | ppl_Pointset_Powerset_C_Polyhedron_t af1, af2, diff; | |
11b2102e | 792 | |
9e3531b5 | 793 | if (PDR_PBB (pdr1) != PDR_PBB (pdr2) |
794 | || PDR_NB_SUBSCRIPTS (pdr1) != PDR_NB_SUBSCRIPTS (pdr2) | |
795 | || PDR_TYPE (pdr1) != PDR_TYPE (pdr2)) | |
11b2102e | 796 | return false; |
797 | ||
9e3531b5 | 798 | af1 = PDR_ACCESSES (pdr1); |
799 | af2 = PDR_ACCESSES (pdr2); | |
11b2102e | 800 | ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron |
9e3531b5 | 801 | (&diff, af1); |
802 | ppl_Pointset_Powerset_C_Polyhedron_difference_assign (diff, af2); | |
11b2102e | 803 | |
9e3531b5 | 804 | res = ppl_Pointset_Powerset_C_Polyhedron_is_empty (diff); |
11b2102e | 805 | ppl_delete_Pointset_Powerset_C_Polyhedron (diff); |
806 | return res; | |
807 | } | |
808 | ||
9e3531b5 | 809 | /* Removes duplicated data references in PBB. */ |
11b2102e | 810 | |
9e3531b5 | 811 | void |
812 | pbb_remove_duplicate_pdrs (poly_bb_p pbb) | |
11b2102e | 813 | { |
9e3531b5 | 814 | int i, j; |
815 | poly_dr_p pdr1, pdr2; | |
816 | unsigned n = VEC_length (poly_dr_p, PBB_DRS (pbb)); | |
817 | VEC (poly_dr_p, heap) *collapsed = VEC_alloc (poly_dr_p, heap, n); | |
818 | ||
48148244 | 819 | FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr1) |
820 | FOR_EACH_VEC_ELT (poly_dr_p, collapsed, j, pdr2) | |
9e3531b5 | 821 | if (!can_collapse_pdrs (pdr1, pdr2)) |
822 | VEC_quick_push (poly_dr_p, collapsed, pdr1); | |
13d0cae2 | 823 | |
06b1d38c | 824 | VEC_free (poly_dr_p, heap, collapsed); |
13d0cae2 | 825 | PBB_PDR_DUPLICATES_REMOVED (pbb) = true; |
11b2102e | 826 | } |
827 | ||
85f74b79 | 828 | /* Create a new polyhedral data reference and add it to PBB. It is |
829 | defined by its ACCESSES, its TYPE, and the number of subscripts | |
830 | NB_SUBSCRIPTS. */ | |
c6bb733d | 831 | |
832 | void | |
ae11f03b | 833 | new_poly_dr (poly_bb_p pbb, int dr_base_object_set, |
c6bb733d | 834 | ppl_Pointset_Powerset_C_Polyhedron_t accesses, |
11b2102e | 835 | enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts) |
c6bb733d | 836 | { |
96b6d5d7 | 837 | static int id = 0; |
9e3531b5 | 838 | poly_dr_p pdr = XNEW (struct poly_dr); |
c6bb733d | 839 | |
96b6d5d7 | 840 | PDR_ID (pdr) = id++; |
ae11f03b | 841 | PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set; |
11b2102e | 842 | PDR_NB_REFS (pdr) = 1; |
c6bb733d | 843 | PDR_PBB (pdr) = pbb; |
844 | PDR_ACCESSES (pdr) = accesses; | |
c6bb733d | 845 | PDR_TYPE (pdr) = type; |
846 | PDR_CDR (pdr) = cdr; | |
85f74b79 | 847 | PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts; |
c6bb733d | 848 | VEC_safe_push (poly_dr_p, heap, PBB_DRS (pbb), pdr); |
849 | } | |
850 | ||
851 | /* Free polyhedral data reference PDR. */ | |
852 | ||
853 | void | |
854 | free_poly_dr (poly_dr_p pdr) | |
855 | { | |
856 | ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_ACCESSES (pdr)); | |
c6bb733d | 857 | XDELETE (pdr); |
858 | } | |
859 | ||
860 | /* Create a new polyhedral black box. */ | |
861 | ||
8c6b3774 | 862 | poly_bb_p |
863 | new_poly_bb (scop_p scop, void *black_box) | |
c6bb733d | 864 | { |
865 | poly_bb_p pbb = XNEW (struct poly_bb); | |
866 | ||
867 | PBB_DOMAIN (pbb) = NULL; | |
868 | PBB_SCOP (pbb) = scop; | |
869 | pbb_set_black_box (pbb, black_box); | |
a741358d | 870 | PBB_TRANSFORMED (pbb) = NULL; |
871 | PBB_SAVED (pbb) = NULL; | |
872 | PBB_ORIGINAL (pbb) = NULL; | |
c6bb733d | 873 | PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3); |
8c6b3774 | 874 | PBB_IS_REDUCTION (pbb) = false; |
13d0cae2 | 875 | PBB_PDR_DUPLICATES_REMOVED (pbb) = false; |
8c6b3774 | 876 | GBB_PBB ((gimple_bb_p) black_box) = pbb; |
877 | ||
878 | return pbb; | |
c6bb733d | 879 | } |
880 | ||
881 | /* Free polyhedral black box. */ | |
882 | ||
883 | void | |
884 | free_poly_bb (poly_bb_p pbb) | |
885 | { | |
886 | int i; | |
887 | poly_dr_p pdr; | |
888 | ||
889 | ppl_delete_Pointset_Powerset_C_Polyhedron (PBB_DOMAIN (pbb)); | |
890 | ||
a741358d | 891 | if (PBB_TRANSFORMED (pbb)) |
892 | poly_scattering_free (PBB_TRANSFORMED (pbb)); | |
893 | ||
894 | if (PBB_SAVED (pbb)) | |
895 | poly_scattering_free (PBB_SAVED (pbb)); | |
c6bb733d | 896 | |
a741358d | 897 | if (PBB_ORIGINAL (pbb)) |
898 | poly_scattering_free (PBB_ORIGINAL (pbb)); | |
c6bb733d | 899 | |
900 | if (PBB_DRS (pbb)) | |
48148244 | 901 | FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr) |
c6bb733d | 902 | free_poly_dr (pdr); |
903 | ||
904 | VEC_free (poly_dr_p, heap, PBB_DRS (pbb)); | |
905 | XDELETE (pbb); | |
906 | } | |
907 | ||
908 | static void | |
8c4b14b0 | 909 | print_pdr_access_layout (FILE *file, poly_bb_p pbb, poly_dr_p pdr) |
c6bb733d | 910 | { |
911 | graphite_dim_t i; | |
912 | ||
913 | fprintf (file, "# eq"); | |
914 | ||
8c4b14b0 | 915 | fprintf (file, " alias"); |
c6bb733d | 916 | |
85f74b79 | 917 | for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++) |
c6bb733d | 918 | fprintf (file, " sub%d", (int) i); |
919 | ||
8c4b14b0 | 920 | for (i = 0; i < pbb_dim_iter_domain (pbb); i++) |
921 | fprintf (file, " i%d", (int) i); | |
922 | ||
923 | for (i = 0; i < pbb_nb_params (pbb); i++) | |
924 | fprintf (file, " p%d", (int) i); | |
925 | ||
c6bb733d | 926 | fprintf (file, " cst\n"); |
927 | } | |
928 | ||
ff4c7a5a | 929 | /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY |
930 | level. */ | |
c6bb733d | 931 | |
932 | void | |
ff4c7a5a | 933 | print_pdr (FILE *file, poly_dr_p pdr, int verbosity) |
c6bb733d | 934 | { |
8c4b14b0 | 935 | int alias_set_dim; |
936 | ||
ff4c7a5a | 937 | if (verbosity > 1) |
c6bb733d | 938 | { |
ff4c7a5a | 939 | fprintf (file, "# pdr_%d (", PDR_ID (pdr)); |
940 | ||
941 | switch (PDR_TYPE (pdr)) | |
942 | { | |
943 | case PDR_READ: | |
944 | fprintf (file, "read \n"); | |
945 | break; | |
c6bb733d | 946 | |
ff4c7a5a | 947 | case PDR_WRITE: |
948 | fprintf (file, "write \n"); | |
949 | break; | |
c6bb733d | 950 | |
ff4c7a5a | 951 | case PDR_MAY_WRITE: |
952 | fprintf (file, "may_write \n"); | |
953 | break; | |
c6bb733d | 954 | |
ff4c7a5a | 955 | default: |
956 | gcc_unreachable (); | |
957 | } | |
958 | ||
959 | dump_data_reference (file, (data_reference_p) PDR_CDR (pdr)); | |
c6bb733d | 960 | } |
961 | ||
ff4c7a5a | 962 | if (verbosity > 0) |
963 | { | |
964 | fprintf (file, "# data accesses (\n"); | |
8c4b14b0 | 965 | print_pdr_access_layout (file, PDR_PBB (pdr), pdr); |
ff4c7a5a | 966 | } |
c6bb733d | 967 | |
8c4b14b0 | 968 | alias_set_dim = pdr_alias_set_dim (pdr) + 1; |
969 | ||
970 | openscop_print_pdr_powerset (file, | |
971 | PDR_ACCESSES (pdr), | |
972 | PDR_NB_SUBSCRIPTS (pdr), | |
973 | alias_set_dim, | |
974 | pbb_nb_params (PDR_PBB (pdr))); | |
c6bb733d | 975 | |
ff4c7a5a | 976 | if (verbosity > 0) |
977 | fprintf (file, "#)\n"); | |
978 | ||
979 | if (verbosity > 1) | |
980 | fprintf (file, "#)\n"); | |
c6bb733d | 981 | } |
982 | ||
ff4c7a5a | 983 | /* Prints to STDERR the polyhedral data reference PDR, at some |
984 | VERBOSITY level. */ | |
c6bb733d | 985 | |
4b987fac | 986 | DEBUG_FUNCTION void |
ff4c7a5a | 987 | debug_pdr (poly_dr_p pdr, int verbosity) |
c6bb733d | 988 | { |
ff4c7a5a | 989 | print_pdr (stderr, pdr, verbosity); |
c6bb733d | 990 | } |
991 | ||
992 | /* Creates a new SCOP containing REGION. */ | |
993 | ||
994 | scop_p | |
995 | new_scop (void *region) | |
996 | { | |
997 | scop_p scop = XNEW (struct scop); | |
998 | ||
c6bb733d | 999 | SCOP_CONTEXT (scop) = NULL; |
1000 | scop_set_region (scop, region); | |
1001 | SCOP_BBS (scop) = VEC_alloc (poly_bb_p, heap, 3); | |
0d6b5db2 | 1002 | SCOP_ORIGINAL_PDDRS (scop) = htab_create (10, hash_poly_ddr_p, |
1003 | eq_poly_ddr_p, free_poly_ddr); | |
7e7ffe19 | 1004 | SCOP_ORIGINAL_SCHEDULE (scop) = NULL; |
1005 | SCOP_TRANSFORMED_SCHEDULE (scop) = NULL; | |
1006 | SCOP_SAVED_SCHEDULE (scop) = NULL; | |
94bdcd77 | 1007 | POLY_SCOP_P (scop) = false; |
1008 | ||
c6bb733d | 1009 | return scop; |
1010 | } | |
1011 | ||
1012 | /* Deletes SCOP. */ | |
1013 | ||
1014 | void | |
1015 | free_scop (scop_p scop) | |
1016 | { | |
1017 | int i; | |
1018 | poly_bb_p pbb; | |
1019 | ||
48148244 | 1020 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
c6bb733d | 1021 | free_poly_bb (pbb); |
1022 | ||
1023 | VEC_free (poly_bb_p, heap, SCOP_BBS (scop)); | |
1024 | ||
1025 | if (SCOP_CONTEXT (scop)) | |
1026 | ppl_delete_Pointset_Powerset_C_Polyhedron (SCOP_CONTEXT (scop)); | |
1027 | ||
0d6b5db2 | 1028 | htab_delete (SCOP_ORIGINAL_PDDRS (scop)); |
7e7ffe19 | 1029 | free_lst (SCOP_ORIGINAL_SCHEDULE (scop)); |
1030 | free_lst (SCOP_TRANSFORMED_SCHEDULE (scop)); | |
1031 | free_lst (SCOP_SAVED_SCHEDULE (scop)); | |
c6bb733d | 1032 | XDELETE (scop); |
1033 | } | |
1034 | ||
8c4b14b0 | 1035 | /* Print to FILE the domain of PBB in OpenScop format, at some VERBOSITY |
1036 | level. */ | |
1037 | ||
1038 | static void | |
1039 | openscop_print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity) | |
1040 | { | |
1041 | graphite_dim_t i; | |
1042 | gimple_bb_p gbb = PBB_BLACK_BOX (pbb); | |
1043 | ||
1044 | if (!PBB_DOMAIN (pbb)) | |
1045 | return; | |
1046 | ||
1047 | if (verbosity > 0) | |
1048 | { | |
1049 | fprintf (file, "\n# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index); | |
086610eb | 1050 | fprintf (file, "#eq"); |
8c4b14b0 | 1051 | |
1052 | for (i = 0; i < pbb_dim_iter_domain (pbb); i++) | |
1053 | fprintf (file, " i%d", (int) i); | |
1054 | ||
1055 | for (i = 0; i < pbb_nb_params (pbb); i++) | |
1056 | fprintf (file, " p%d", (int) i); | |
1057 | ||
1058 | fprintf (file, " cst\n"); | |
1059 | } | |
1060 | ||
1061 | if (PBB_DOMAIN (pbb)) | |
1062 | openscop_print_powerset_matrix (file, PBB_DOMAIN (pbb), | |
1063 | pbb_dim_iter_domain (pbb), | |
1064 | 0, | |
1065 | 0, | |
1066 | pbb_nb_params (pbb)); | |
1067 | else | |
1068 | fprintf (file, "0\n"); | |
1069 | ||
1070 | if (verbosity > 0) | |
1071 | fprintf (file, "#)\n"); | |
1072 | } | |
1073 | ||
ff4c7a5a | 1074 | /* Print to FILE the domain of PBB, at some VERBOSITY level. */ |
c6bb733d | 1075 | |
1076 | void | |
ff4c7a5a | 1077 | print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity) |
c6bb733d | 1078 | { |
1079 | graphite_dim_t i; | |
1080 | gimple_bb_p gbb = PBB_BLACK_BOX (pbb); | |
1081 | ||
1082 | if (!PBB_DOMAIN (pbb)) | |
1083 | return; | |
1084 | ||
ff4c7a5a | 1085 | if (verbosity > 0) |
1086 | { | |
1087 | fprintf (file, "# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index); | |
1088 | fprintf (file, "# eq"); | |
c6bb733d | 1089 | |
ff4c7a5a | 1090 | for (i = 0; i < pbb_dim_iter_domain (pbb); i++) |
1091 | fprintf (file, " i%d", (int) i); | |
c6bb733d | 1092 | |
ff4c7a5a | 1093 | for (i = 0; i < pbb_nb_params (pbb); i++) |
1094 | fprintf (file, " p%d", (int) i); | |
c6bb733d | 1095 | |
ff4c7a5a | 1096 | fprintf (file, " cst\n"); |
1097 | } | |
c6bb733d | 1098 | |
1099 | if (PBB_DOMAIN (pbb)) | |
1100 | ppl_print_powerset_matrix (file, PBB_DOMAIN (pbb)); | |
5dc5fe13 | 1101 | else |
1102 | fprintf (file, "0\n"); | |
c6bb733d | 1103 | |
ff4c7a5a | 1104 | if (verbosity > 0) |
1105 | fprintf (file, "#)\n"); | |
c6bb733d | 1106 | } |
1107 | ||
1108 | /* Dump the cases of a graphite basic block GBB on FILE. */ | |
1109 | ||
1110 | static void | |
1111 | dump_gbb_cases (FILE *file, gimple_bb_p gbb) | |
1112 | { | |
1113 | int i; | |
1114 | gimple stmt; | |
1115 | VEC (gimple, heap) *cases; | |
1116 | ||
1117 | if (!gbb) | |
1118 | return; | |
1119 | ||
1120 | cases = GBB_CONDITION_CASES (gbb); | |
1121 | if (VEC_empty (gimple, cases)) | |
1122 | return; | |
1123 | ||
5dc5fe13 | 1124 | fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index); |
c6bb733d | 1125 | |
48148244 | 1126 | FOR_EACH_VEC_ELT (gimple, cases, i, stmt) |
5dc5fe13 | 1127 | { |
1128 | fprintf (file, "# "); | |
1129 | print_gimple_stmt (file, stmt, 0, 0); | |
1130 | } | |
c6bb733d | 1131 | |
5dc5fe13 | 1132 | fprintf (file, "#)\n"); |
c6bb733d | 1133 | } |
1134 | ||
1135 | /* Dump conditions of a graphite basic block GBB on FILE. */ | |
1136 | ||
1137 | static void | |
1138 | dump_gbb_conditions (FILE *file, gimple_bb_p gbb) | |
1139 | { | |
1140 | int i; | |
1141 | gimple stmt; | |
1142 | VEC (gimple, heap) *conditions; | |
1143 | ||
1144 | if (!gbb) | |
1145 | return; | |
1146 | ||
1147 | conditions = GBB_CONDITIONS (gbb); | |
1148 | if (VEC_empty (gimple, conditions)) | |
1149 | return; | |
1150 | ||
5dc5fe13 | 1151 | fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index); |
c6bb733d | 1152 | |
48148244 | 1153 | FOR_EACH_VEC_ELT (gimple, conditions, i, stmt) |
5dc5fe13 | 1154 | { |
1155 | fprintf (file, "# "); | |
1156 | print_gimple_stmt (file, stmt, 0, 0); | |
1157 | } | |
c6bb733d | 1158 | |
5dc5fe13 | 1159 | fprintf (file, "#)\n"); |
c6bb733d | 1160 | } |
1161 | ||
ff4c7a5a | 1162 | /* Print to FILE all the data references of PBB, at some VERBOSITY |
1163 | level. */ | |
c6bb733d | 1164 | |
1165 | void | |
ff4c7a5a | 1166 | print_pdrs (FILE *file, poly_bb_p pbb, int verbosity) |
c6bb733d | 1167 | { |
1168 | int i; | |
1169 | poly_dr_p pdr; | |
5dc5fe13 | 1170 | int nb_reads = 0; |
1171 | int nb_writes = 0; | |
c6bb733d | 1172 | |
5dc5fe13 | 1173 | if (VEC_length (poly_dr_p, PBB_DRS (pbb)) == 0) |
1174 | { | |
ff4c7a5a | 1175 | if (verbosity > 0) |
1176 | fprintf (file, "# Access informations are not provided\n");\ | |
1177 | fprintf (file, "0\n"); | |
5dc5fe13 | 1178 | return; |
1179 | } | |
1180 | ||
ff4c7a5a | 1181 | if (verbosity > 1) |
1182 | fprintf (file, "# Data references (\n"); | |
1183 | ||
1184 | if (verbosity > 0) | |
1185 | fprintf (file, "# Access informations are provided\n"); | |
1186 | fprintf (file, "1\n"); | |
5dc5fe13 | 1187 | |
48148244 | 1188 | FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr) |
5dc5fe13 | 1189 | if (PDR_TYPE (pdr) == PDR_READ) |
1190 | nb_reads++; | |
1191 | else | |
1192 | nb_writes++; | |
1193 | ||
ff4c7a5a | 1194 | if (verbosity > 1) |
1195 | fprintf (file, "# Read data references (\n"); | |
1196 | ||
1197 | if (verbosity > 0) | |
1198 | fprintf (file, "# Read access informations\n"); | |
1199 | fprintf (file, "%d\n", nb_reads); | |
1200 | ||
48148244 | 1201 | FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr) |
5dc5fe13 | 1202 | if (PDR_TYPE (pdr) == PDR_READ) |
ff4c7a5a | 1203 | print_pdr (file, pdr, verbosity); |
1204 | ||
1205 | if (verbosity > 1) | |
1206 | fprintf (file, "#)\n"); | |
1207 | ||
1208 | if (verbosity > 1) | |
1209 | fprintf (file, "# Write data references (\n"); | |
1210 | ||
1211 | if (verbosity > 0) | |
1212 | fprintf (file, "# Write access informations\n"); | |
1213 | fprintf (file, "%d\n", nb_writes); | |
5dc5fe13 | 1214 | |
48148244 | 1215 | FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr) |
5dc5fe13 | 1216 | if (PDR_TYPE (pdr) != PDR_READ) |
ff4c7a5a | 1217 | print_pdr (file, pdr, verbosity); |
1218 | ||
1219 | if (verbosity > 1) | |
1220 | fprintf (file, "#)\n"); | |
1221 | ||
1222 | if (verbosity > 1) | |
1223 | fprintf (file, "#)\n"); | |
c6bb733d | 1224 | } |
1225 | ||
1226 | /* Print to STDERR all the data references of PBB. */ | |
1227 | ||
4b987fac | 1228 | DEBUG_FUNCTION void |
ff4c7a5a | 1229 | debug_pdrs (poly_bb_p pbb, int verbosity) |
c6bb733d | 1230 | { |
ff4c7a5a | 1231 | print_pdrs (stderr, pbb, verbosity); |
c6bb733d | 1232 | } |
1233 | ||
8c4b14b0 | 1234 | /* Print to FILE the body of PBB, at some VERBOSITY level. |
1235 | If statement_body_provided is false statement body is not printed. */ | |
5dc5fe13 | 1236 | |
1237 | static void | |
8c4b14b0 | 1238 | print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity, |
1239 | bool statement_body_provided) | |
5dc5fe13 | 1240 | { |
ff4c7a5a | 1241 | if (verbosity > 1) |
1242 | fprintf (file, "# Body (\n"); | |
1243 | ||
8c4b14b0 | 1244 | if (!statement_body_provided) |
d2cd543b | 1245 | { |
1246 | if (verbosity > 0) | |
1247 | fprintf (file, "# Statement body is not provided\n"); | |
1248 | ||
1249 | fprintf (file, "0\n"); | |
8c4b14b0 | 1250 | |
d2cd543b | 1251 | if (verbosity > 1) |
1252 | fprintf (file, "#)\n"); | |
1253 | return; | |
1254 | } | |
8c4b14b0 | 1255 | |
ff4c7a5a | 1256 | if (verbosity > 0) |
1257 | fprintf (file, "# Statement body is provided\n"); | |
1258 | fprintf (file, "1\n"); | |
1259 | ||
1260 | if (verbosity > 0) | |
1261 | fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n"); | |
1262 | ||
1263 | if (verbosity > 0) | |
1264 | fprintf (file, "# Statement body\n"); | |
1265 | ||
5dc5fe13 | 1266 | fprintf (file, "{\n"); |
1267 | dump_bb (pbb_bb (pbb), file, 0); | |
1268 | fprintf (file, "}\n"); | |
ff4c7a5a | 1269 | |
1270 | if (verbosity > 1) | |
1271 | fprintf (file, "#)\n"); | |
5dc5fe13 | 1272 | } |
1273 | ||
ff4c7a5a | 1274 | /* Print to FILE the domain and scattering function of PBB, at some |
1275 | VERBOSITY level. */ | |
c6bb733d | 1276 | |
1277 | void | |
ff4c7a5a | 1278 | print_pbb (FILE *file, poly_bb_p pbb, int verbosity) |
1279 | { | |
1280 | if (verbosity > 1) | |
1281 | { | |
1282 | fprintf (file, "# pbb_%d (\n", pbb_index (pbb)); | |
1283 | dump_gbb_conditions (file, PBB_BLACK_BOX (pbb)); | |
1284 | dump_gbb_cases (file, PBB_BLACK_BOX (pbb)); | |
1285 | } | |
1286 | ||
8c4b14b0 | 1287 | openscop_print_pbb_domain (file, pbb, verbosity); |
ff4c7a5a | 1288 | print_scattering_function (file, pbb, verbosity); |
1289 | print_pdrs (file, pbb, verbosity); | |
8c4b14b0 | 1290 | print_pbb_body (file, pbb, verbosity, false); |
ff4c7a5a | 1291 | |
1292 | if (verbosity > 1) | |
1293 | fprintf (file, "#)\n"); | |
c6bb733d | 1294 | } |
1295 | ||
ff4c7a5a | 1296 | /* Print to FILE the parameters of SCOP, at some VERBOSITY level. */ |
c6bb733d | 1297 | |
1298 | void | |
ff4c7a5a | 1299 | print_scop_params (FILE *file, scop_p scop, int verbosity) |
c6bb733d | 1300 | { |
1301 | int i; | |
1302 | tree t; | |
1303 | ||
ff4c7a5a | 1304 | if (verbosity > 1) |
1305 | fprintf (file, "# parameters (\n"); | |
5dc5fe13 | 1306 | |
1307 | if (VEC_length (tree, SESE_PARAMS (SCOP_REGION (scop)))) | |
ff4c7a5a | 1308 | { |
1309 | if (verbosity > 0) | |
1310 | fprintf (file, "# Parameter names are provided\n"); | |
1311 | ||
1312 | fprintf (file, "1\n"); | |
1313 | ||
1314 | if (verbosity > 0) | |
1315 | fprintf (file, "# Parameter names\n"); | |
1316 | } | |
5dc5fe13 | 1317 | else |
ff4c7a5a | 1318 | { |
1319 | if (verbosity > 0) | |
1320 | fprintf (file, "# Parameter names are not provided\n"); | |
1321 | fprintf (file, "0\n"); | |
1322 | } | |
5dc5fe13 | 1323 | |
48148244 | 1324 | FOR_EACH_VEC_ELT (tree, SESE_PARAMS (SCOP_REGION (scop)), i, t) |
c6bb733d | 1325 | { |
c6bb733d | 1326 | print_generic_expr (file, t, 0); |
1f8d6d4d | 1327 | fprintf (file, " "); |
c6bb733d | 1328 | } |
ff4c7a5a | 1329 | |
1330 | fprintf (file, "\n"); | |
1331 | ||
1332 | if (verbosity > 1) | |
1333 | fprintf (file, "#)\n"); | |
c6bb733d | 1334 | } |
1335 | ||
8c4b14b0 | 1336 | /* Print to FILE the context of SCoP in OpenScop format, at some VERBOSITY |
1337 | level. */ | |
1338 | ||
1339 | static void | |
1340 | openscop_print_scop_context (FILE *file, scop_p scop, int verbosity) | |
1341 | { | |
1342 | graphite_dim_t i; | |
1343 | ||
1344 | if (verbosity > 0) | |
1345 | { | |
1346 | fprintf (file, "# Context (\n"); | |
086610eb | 1347 | fprintf (file, "#eq"); |
8c4b14b0 | 1348 | |
1349 | for (i = 0; i < scop_nb_params (scop); i++) | |
1350 | fprintf (file, " p%d", (int) i); | |
1351 | ||
1352 | fprintf (file, " cst\n"); | |
1353 | } | |
1354 | ||
1355 | if (SCOP_CONTEXT (scop)) | |
1356 | openscop_print_powerset_matrix (file, SCOP_CONTEXT (scop), 0, 0, 0, | |
1357 | scop_nb_params (scop)); | |
1358 | else | |
1359 | fprintf (file, "0 %d 0 0 0 %d\n", (int) scop_nb_params (scop) + 2, | |
1360 | (int) scop_nb_params (scop)); | |
1361 | ||
1362 | if (verbosity > 0) | |
1363 | fprintf (file, "# )\n"); | |
1364 | } | |
1365 | ||
ff4c7a5a | 1366 | /* Print to FILE the context of SCoP, at some VERBOSITY level. */ |
1367 | ||
c6bb733d | 1368 | void |
ff4c7a5a | 1369 | print_scop_context (FILE *file, scop_p scop, int verbosity) |
c6bb733d | 1370 | { |
1371 | graphite_dim_t i; | |
1372 | ||
ff4c7a5a | 1373 | if (verbosity > 0) |
1374 | { | |
1375 | fprintf (file, "# Context (\n"); | |
086610eb | 1376 | fprintf (file, "#eq"); |
c6bb733d | 1377 | |
ff4c7a5a | 1378 | for (i = 0; i < scop_nb_params (scop); i++) |
1379 | fprintf (file, " p%d", (int) i); | |
c6bb733d | 1380 | |
ff4c7a5a | 1381 | fprintf (file, " cst\n"); |
1382 | } | |
c6bb733d | 1383 | |
1384 | if (SCOP_CONTEXT (scop)) | |
1385 | ppl_print_powerset_matrix (file, SCOP_CONTEXT (scop)); | |
5dc5fe13 | 1386 | else |
1387 | fprintf (file, "0 %d\n", (int) scop_nb_params (scop) + 2); | |
c6bb733d | 1388 | |
ff4c7a5a | 1389 | if (verbosity > 0) |
1390 | fprintf (file, "# )\n"); | |
c6bb733d | 1391 | } |
1392 | ||
d2cd543b | 1393 | /* Print to FILE the SCOP, at some VERBOSITY level. */ |
c6bb733d | 1394 | |
d2cd543b | 1395 | void |
1396 | print_scop (FILE *file, scop_p scop, int verbosity) | |
c6bb733d | 1397 | { |
d2cd543b | 1398 | int i; |
1399 | poly_bb_p pbb; | |
1400 | ||
8c4b14b0 | 1401 | fprintf (file, "SCoP 1\n#(\n"); |
5dc5fe13 | 1402 | fprintf (file, "# Language\nGimple\n"); |
8c4b14b0 | 1403 | openscop_print_scop_context (file, scop, verbosity); |
ff4c7a5a | 1404 | print_scop_params (file, scop, verbosity); |
1405 | ||
1406 | if (verbosity > 0) | |
1407 | fprintf (file, "# Number of statements\n"); | |
1408 | ||
1409 | fprintf (file, "%d\n",VEC_length (poly_bb_p, SCOP_BBS (scop))); | |
c6bb733d | 1410 | |
48148244 | 1411 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
ff4c7a5a | 1412 | print_pbb (file, pbb, verbosity); |
95b2e0d3 | 1413 | |
ff4c7a5a | 1414 | if (verbosity > 1) |
1415 | { | |
1416 | fprintf (file, "# original_lst (\n"); | |
1417 | print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0); | |
1418 | fprintf (file, "\n#)\n"); | |
f77385d3 | 1419 | |
ff4c7a5a | 1420 | fprintf (file, "# transformed_lst (\n"); |
1421 | print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0); | |
1422 | fprintf (file, "\n#)\n"); | |
1423 | } | |
9b6c835c | 1424 | |
5dc5fe13 | 1425 | fprintf (file, "#)\n"); |
c6bb733d | 1426 | } |
1427 | ||
ff4c7a5a | 1428 | /* Print to FILE the input file that CLooG would expect as input, at |
1429 | some VERBOSITY level. */ | |
1f8d6d4d | 1430 | |
1431 | void | |
ff4c7a5a | 1432 | print_cloog (FILE *file, scop_p scop, int verbosity) |
1f8d6d4d | 1433 | { |
1434 | int i; | |
1435 | poly_bb_p pbb; | |
1436 | ||
1437 | fprintf (file, "# SCoP (generated by GCC/Graphite\n"); | |
ff4c7a5a | 1438 | if (verbosity > 0) |
1439 | fprintf (file, "# CLooG output language\n"); | |
1440 | fprintf (file, "c\n"); | |
1441 | ||
1442 | print_scop_context (file, scop, verbosity); | |
1443 | print_scop_params (file, scop, verbosity); | |
1444 | ||
1445 | if (verbosity > 0) | |
1446 | fprintf (file, "# Number of statements\n"); | |
1447 | ||
1448 | fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop))); | |
1f8d6d4d | 1449 | |
48148244 | 1450 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
1f8d6d4d | 1451 | { |
ff4c7a5a | 1452 | if (verbosity > 1) |
1453 | fprintf (file, "# pbb_%d (\n", pbb_index (pbb)); | |
1454 | ||
1455 | print_pbb_domain (file, pbb, verbosity); | |
1456 | fprintf (file, "0 0 0"); | |
1457 | ||
1458 | if (verbosity > 0) | |
1459 | fprintf (file, "# For future CLooG options.\n"); | |
1460 | else | |
1461 | fprintf (file, "\n"); | |
1462 | ||
1463 | if (verbosity > 1) | |
1464 | fprintf (file, "#)\n"); | |
1f8d6d4d | 1465 | } |
1466 | ||
ff4c7a5a | 1467 | fprintf (file, "0"); |
1468 | if (verbosity > 0) | |
1469 | fprintf (file, "# Don't set the iterator names.\n"); | |
1470 | else | |
1471 | fprintf (file, "\n"); | |
1472 | ||
1473 | if (verbosity > 0) | |
1474 | fprintf (file, "# Number of scattering functions\n"); | |
1f8d6d4d | 1475 | |
ff4c7a5a | 1476 | fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop))); |
1f8d6d4d | 1477 | unify_scattering_dimensions (scop); |
1478 | ||
48148244 | 1479 | FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb) |
1f8d6d4d | 1480 | { |
1481 | if (!PBB_TRANSFORMED (pbb) | |
1482 | || !(PBB_TRANSFORMED_SCATTERING (pbb) | |
1483 | || PBB_ORIGINAL_SCATTERING (pbb))) | |
1484 | continue; | |
1485 | ||
ff4c7a5a | 1486 | if (verbosity > 1) |
1487 | fprintf (file, "# pbb_%d (\n", pbb_index (pbb)); | |
1488 | ||
1489 | print_scattering_function_1 (file, pbb, verbosity); | |
1490 | ||
1491 | if (verbosity > 1) | |
1492 | fprintf (file, "#)\n"); | |
1f8d6d4d | 1493 | } |
1494 | ||
ff4c7a5a | 1495 | fprintf (file, "0"); |
1496 | if (verbosity > 0) | |
1497 | fprintf (file, "# Don't set the scattering dimension names.\n"); | |
1498 | else | |
1499 | fprintf (file, "\n"); | |
1500 | ||
1f8d6d4d | 1501 | fprintf (file, "#)\n"); |
1502 | } | |
1503 | ||
ff4c7a5a | 1504 | /* Print to STDERR the domain of PBB, at some VERBOSITY level. */ |
c6bb733d | 1505 | |
4b987fac | 1506 | DEBUG_FUNCTION void |
ff4c7a5a | 1507 | debug_pbb_domain (poly_bb_p pbb, int verbosity) |
c6bb733d | 1508 | { |
ff4c7a5a | 1509 | print_pbb_domain (stderr, pbb, verbosity); |
c6bb733d | 1510 | } |
1511 | ||
ff4c7a5a | 1512 | /* Print to FILE the domain and scattering function of PBB, at some |
1513 | VERBOSITY level. */ | |
c6bb733d | 1514 | |
4b987fac | 1515 | DEBUG_FUNCTION void |
ff4c7a5a | 1516 | debug_pbb (poly_bb_p pbb, int verbosity) |
c6bb733d | 1517 | { |
ff4c7a5a | 1518 | print_pbb (stderr, pbb, verbosity); |
c6bb733d | 1519 | } |
1520 | ||
ff4c7a5a | 1521 | /* Print to STDERR the context of SCOP, at some VERBOSITY level. */ |
c6bb733d | 1522 | |
4b987fac | 1523 | DEBUG_FUNCTION void |
ff4c7a5a | 1524 | debug_scop_context (scop_p scop, int verbosity) |
c6bb733d | 1525 | { |
ff4c7a5a | 1526 | print_scop_context (stderr, scop, verbosity); |
c6bb733d | 1527 | } |
1528 | ||
ff4c7a5a | 1529 | /* Print to STDERR the SCOP, at some VERBOSITY level. */ |
c6bb733d | 1530 | |
4b987fac | 1531 | DEBUG_FUNCTION void |
ff4c7a5a | 1532 | debug_scop (scop_p scop, int verbosity) |
c6bb733d | 1533 | { |
ff4c7a5a | 1534 | print_scop (stderr, scop, verbosity); |
c6bb733d | 1535 | } |
1536 | ||
ff4c7a5a | 1537 | /* Print to STDERR the SCOP under CLooG format, at some VERBOSITY |
1538 | level. */ | |
1f8d6d4d | 1539 | |
4b987fac | 1540 | DEBUG_FUNCTION void |
ff4c7a5a | 1541 | debug_cloog (scop_p scop, int verbosity) |
1f8d6d4d | 1542 | { |
ff4c7a5a | 1543 | print_cloog (stderr, scop, verbosity); |
1f8d6d4d | 1544 | } |
1545 | ||
ff4c7a5a | 1546 | /* Print to STDERR the parameters of SCOP, at some VERBOSITY |
1547 | level. */ | |
c6bb733d | 1548 | |
4b987fac | 1549 | DEBUG_FUNCTION void |
ff4c7a5a | 1550 | debug_scop_params (scop_p scop, int verbosity) |
c6bb733d | 1551 | { |
ff4c7a5a | 1552 | print_scop_params (stderr, scop, verbosity); |
c6bb733d | 1553 | } |
1554 | ||
1555 | ||
1556 | /* The dimension in the transformed scattering polyhedron of PBB | |
1557 | containing the scattering iterator for the loop at depth LOOP_DEPTH. */ | |
1558 | ||
1559 | ppl_dimension_type | |
1560 | psct_scattering_dim_for_loop_depth (poly_bb_p pbb, graphite_dim_t loop_depth) | |
1561 | { | |
1562 | ppl_const_Constraint_System_t pcs; | |
1563 | ppl_Constraint_System_const_iterator_t cit, cend; | |
1564 | ppl_const_Constraint_t cstr; | |
1565 | ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb); | |
1566 | ppl_dimension_type iter = psct_iterator_dim (pbb, loop_depth); | |
1567 | ppl_Linear_Expression_t expr; | |
1568 | ppl_Coefficient_t coef; | |
0ef84e3b | 1569 | mpz_t val; |
c6bb733d | 1570 | graphite_dim_t i; |
1571 | ||
2d6fe479 | 1572 | mpz_init (val); |
c6bb733d | 1573 | ppl_new_Coefficient (&coef); |
1574 | ppl_Polyhedron_get_constraints (ph, &pcs); | |
1575 | ppl_new_Constraint_System_const_iterator (&cit); | |
1576 | ppl_new_Constraint_System_const_iterator (&cend); | |
1577 | ||
1578 | for (ppl_Constraint_System_begin (pcs, cit), | |
1579 | ppl_Constraint_System_end (pcs, cend); | |
1580 | !ppl_Constraint_System_const_iterator_equal_test (cit, cend); | |
1581 | ppl_Constraint_System_const_iterator_increment (cit)) | |
1582 | { | |
1583 | ppl_Constraint_System_const_iterator_dereference (cit, &cstr); | |
1584 | ppl_new_Linear_Expression_from_Constraint (&expr, cstr); | |
1585 | ppl_Linear_Expression_coefficient (expr, iter, coef); | |
1586 | ppl_Coefficient_to_mpz_t (coef, val); | |
1587 | ||
2c4340a8 | 1588 | if (mpz_sgn (val) == 0) |
c6bb733d | 1589 | { |
1590 | ppl_delete_Linear_Expression (expr); | |
1591 | continue; | |
1592 | } | |
1593 | ||
1594 | for (i = 0; i < pbb_nb_scattering_transform (pbb); i++) | |
1595 | { | |
1596 | ppl_dimension_type scatter = psct_scattering_dim (pbb, i); | |
1597 | ||
1598 | ppl_Linear_Expression_coefficient (expr, scatter, coef); | |
1599 | ppl_Coefficient_to_mpz_t (coef, val); | |
1600 | ||
6955599b | 1601 | if (mpz_sgn (val) != 0) |
c6bb733d | 1602 | { |
2d6fe479 | 1603 | mpz_clear (val); |
c6bb733d | 1604 | ppl_delete_Linear_Expression (expr); |
1605 | ppl_delete_Coefficient (coef); | |
1606 | ppl_delete_Constraint_System_const_iterator (cit); | |
1607 | ppl_delete_Constraint_System_const_iterator (cend); | |
1608 | ||
1609 | return scatter; | |
1610 | } | |
1611 | } | |
1612 | } | |
1613 | ||
1614 | gcc_unreachable (); | |
1615 | } | |
1616 | ||
bd432164 | 1617 | /* Returns the number of iterations RES of the loop around PBB at |
ee0d08ad | 1618 | time(scattering) dimension TIME_DEPTH. */ |
1619 | ||
1620 | void | |
1621 | pbb_number_of_iterations_at_time (poly_bb_p pbb, | |
1622 | graphite_dim_t time_depth, | |
bd432164 | 1623 | mpz_t res) |
ee0d08ad | 1624 | { |
bd432164 | 1625 | ppl_Pointset_Powerset_C_Polyhedron_t domain, sctr_lb, sctr_ub; |
1626 | ppl_dimension_type domain_dim, sctr_dim; | |
dd37d9f7 | 1627 | graphite_dim_t dim_iter_domain = pbb_dim_iter_domain (pbb); |
ee0d08ad | 1628 | ppl_Linear_Expression_t le; |
bd432164 | 1629 | mpz_t lb, ub, diff, one; |
1630 | int i; | |
ee0d08ad | 1631 | |
bd432164 | 1632 | ppl_Polyhedron_space_dimension (PBB_TRANSFORMED_SCATTERING (pbb), &sctr_dim); |
d9e94834 | 1633 | |
bd432164 | 1634 | ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron |
1635 | (&domain, PBB_DOMAIN (pbb)); | |
d9e94834 | 1636 | |
bd432164 | 1637 | ppl_Pointset_Powerset_C_Polyhedron_space_dimension (domain, &domain_dim); |
dd37d9f7 | 1638 | |
bd432164 | 1639 | mpz_init (diff); |
1640 | mpz_init (lb); | |
1641 | mpz_init (ub); | |
1642 | mpz_init (one); | |
1643 | mpz_set_si (one, 1); | |
d9e94834 | 1644 | |
bd432164 | 1645 | /* Compute the upper bound on the original iteration domain and add |
1646 | that upper bound to the scattering. */ | |
1647 | ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron | |
1648 | (&sctr_ub, PBB_TRANSFORMED_SCATTERING (pbb)); | |
dd37d9f7 | 1649 | for (i = 0; i < (int) dim_iter_domain; i++) |
bd432164 | 1650 | { |
1651 | ppl_Linear_Expression_t eq; | |
1652 | ppl_Constraint_t pc; | |
1653 | ppl_Constraint_System_t cs; | |
1654 | ppl_Polyhedron_t ph; | |
1655 | ppl_Pointset_Powerset_C_Polyhedron_t pph; | |
1656 | ||
1657 | ppl_new_Linear_Expression_with_dimension (&le, domain_dim); | |
1658 | ppl_set_coef (le, i, 1); | |
1659 | ppl_min_for_le_pointset (domain, le, lb); | |
1660 | ppl_max_for_le_pointset (domain, le, ub); | |
1661 | mpz_sub (diff, ub, lb); | |
1662 | mpz_add (diff, diff, one); | |
1663 | ||
1664 | ppl_new_Linear_Expression_with_dimension (&eq, sctr_dim); | |
1665 | ppl_set_coef (eq, psct_iterator_dim (pbb, i), -1); | |
1666 | ppl_set_inhomogeneous_gmp (eq, diff); | |
1667 | ||
1668 | ppl_new_Constraint (&pc, eq, PPL_CONSTRAINT_TYPE_EQUAL); | |
1669 | ppl_new_Constraint_System_from_Constraint (&cs, pc); | |
1670 | ppl_new_C_Polyhedron_from_Constraint_System (&ph, cs); | |
1671 | ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&pph, ph); | |
1672 | ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr_ub, pph); | |
1673 | ||
1674 | ppl_delete_Linear_Expression (le); | |
1675 | ppl_delete_Linear_Expression (eq); | |
1676 | ppl_delete_Polyhedron (ph); | |
1677 | ppl_delete_Pointset_Powerset_C_Polyhedron (pph); | |
1678 | ppl_delete_Constraint (pc); | |
1679 | ppl_delete_Constraint_System (cs); | |
1680 | } | |
d9e94834 | 1681 | |
d60a90cc | 1682 | /* Compute the lower bound on the original iteration domain and add |
1683 | it to the scattering. */ | |
bd432164 | 1684 | ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron |
1685 | (&sctr_lb, PBB_TRANSFORMED_SCATTERING (pbb)); | |
dd37d9f7 | 1686 | for (i = 0; i < (int) dim_iter_domain; i++) |
bd432164 | 1687 | { |
1688 | ppl_Linear_Expression_t eq; | |
1689 | ppl_Constraint_t pc; | |
1690 | ppl_Constraint_System_t cs; | |
1691 | ppl_Polyhedron_t ph; | |
1692 | ppl_Pointset_Powerset_C_Polyhedron_t pph; | |
1693 | ||
1694 | ppl_new_Linear_Expression_with_dimension (&le, domain_dim); | |
1695 | ppl_set_coef (le, i, 1); | |
1696 | ppl_min_for_le_pointset (domain, le, lb); | |
1697 | ||
1698 | ppl_new_Linear_Expression_with_dimension (&eq, sctr_dim); | |
1699 | ppl_set_coef (eq, psct_iterator_dim (pbb, i), -1); | |
1700 | ppl_set_inhomogeneous_gmp (eq, lb); | |
1701 | ||
1702 | ppl_new_Constraint (&pc, eq, PPL_CONSTRAINT_TYPE_EQUAL); | |
1703 | ppl_new_Constraint_System_from_Constraint (&cs, pc); | |
1704 | ppl_new_C_Polyhedron_from_Constraint_System (&ph, cs); | |
1705 | ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&pph, ph); | |
1706 | ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr_lb, pph); | |
1707 | ||
1708 | ppl_delete_Linear_Expression (le); | |
1709 | ppl_delete_Linear_Expression (eq); | |
1710 | ppl_delete_Polyhedron (ph); | |
1711 | ppl_delete_Pointset_Powerset_C_Polyhedron (pph); | |
1712 | ppl_delete_Constraint (pc); | |
1713 | ppl_delete_Constraint_System (cs); | |
1714 | } | |
ee0d08ad | 1715 | |
d9e94834 | 1716 | /* Extract the number of iterations. */ |
bd432164 | 1717 | ppl_new_Linear_Expression_with_dimension (&le, sctr_dim); |
ee0d08ad | 1718 | ppl_set_coef (le, time_depth, 1); |
bd432164 | 1719 | ppl_min_for_le_pointset (sctr_lb, le, lb); |
1720 | ppl_max_for_le_pointset (sctr_ub, le, ub); | |
1721 | mpz_sub (res, ub, lb); | |
ee0d08ad | 1722 | |
bd432164 | 1723 | mpz_clear (one); |
1724 | mpz_clear (diff); | |
1725 | mpz_clear (lb); | |
1726 | mpz_clear (ub); | |
27ac41fd | 1727 | ppl_delete_Linear_Expression (le); |
bd432164 | 1728 | ppl_delete_Pointset_Powerset_C_Polyhedron (sctr_ub); |
1729 | ppl_delete_Pointset_Powerset_C_Polyhedron (sctr_lb); | |
27ac41fd | 1730 | ppl_delete_Pointset_Powerset_C_Polyhedron (domain); |
ee0d08ad | 1731 | } |
1732 | ||
f77385d3 | 1733 | /* Translates LOOP to LST. */ |
1734 | ||
1735 | static lst_p | |
1736 | loop_to_lst (loop_p loop, VEC (poly_bb_p, heap) *bbs, int *i) | |
1737 | { | |
1738 | poly_bb_p pbb; | |
1739 | VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5); | |
1740 | ||
1741 | for (; VEC_iterate (poly_bb_p, bbs, *i, pbb); (*i)++) | |
1742 | { | |
1743 | lst_p stmt; | |
1744 | basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb)); | |
1745 | ||
1746 | if (bb->loop_father == loop) | |
1747 | stmt = new_lst_stmt (pbb); | |
71b90bc3 | 1748 | else if (flow_bb_inside_loop_p (loop, bb)) |
f77385d3 | 1749 | { |
71b90bc3 | 1750 | loop_p next = loop->inner; |
f77385d3 | 1751 | |
71b90bc3 | 1752 | while (next && !flow_bb_inside_loop_p (next, bb)) |
1753 | next = next->next; | |
f77385d3 | 1754 | |
71b90bc3 | 1755 | stmt = loop_to_lst (next, bbs, i); |
1756 | } | |
1757 | else | |
1758 | { | |
1759 | (*i)--; | |
1760 | return new_lst_loop (seq); | |
f77385d3 | 1761 | } |
1762 | ||
1763 | VEC_safe_push (lst_p, heap, seq, stmt); | |
1764 | } | |
1765 | ||
1766 | return new_lst_loop (seq); | |
1767 | } | |
1768 | ||
1769 | /* Reads the original scattering of the SCOP and returns an LST | |
1770 | representing it. */ | |
1771 | ||
1772 | void | |
1773 | scop_to_lst (scop_p scop) | |
1774 | { | |
43217ce9 | 1775 | lst_p res; |
1776 | int i, n = VEC_length (poly_bb_p, SCOP_BBS (scop)); | |
1777 | VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5); | |
1778 | sese region = SCOP_REGION (scop); | |
1779 | ||
1780 | for (i = 0; i < n; i++) | |
1781 | { | |
1782 | poly_bb_p pbb = VEC_index (poly_bb_p, SCOP_BBS (scop), i); | |
1783 | loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb))); | |
1784 | ||
1785 | if (loop_in_sese_p (loop, region)) | |
1786 | res = loop_to_lst (loop, SCOP_BBS (scop), &i); | |
1787 | else | |
1788 | res = new_lst_stmt (pbb); | |
1789 | ||
1790 | VEC_safe_push (lst_p, heap, seq, res); | |
1791 | } | |
f77385d3 | 1792 | |
43217ce9 | 1793 | res = new_lst_loop (seq); |
1794 | SCOP_ORIGINAL_SCHEDULE (scop) = res; | |
1795 | SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res); | |
f77385d3 | 1796 | } |
1797 | ||
5dc5fe13 | 1798 | /* Print to FILE on a new line COLUMN white spaces. */ |
1799 | ||
1800 | static void | |
1801 | lst_indent_to (FILE *file, int column) | |
1802 | { | |
1803 | int i; | |
1804 | ||
1805 | if (column > 0) | |
1806 | fprintf (file, "\n#"); | |
1807 | ||
1808 | for (i = 0; i < column; i++) | |
1809 | fprintf (file, " "); | |
1810 | } | |
1811 | ||
f77385d3 | 1812 | /* Print LST to FILE with INDENT spaces of indentation. */ |
1813 | ||
1814 | void | |
1815 | print_lst (FILE *file, lst_p lst, int indent) | |
1816 | { | |
1817 | if (!lst) | |
1818 | return; | |
1819 | ||
5dc5fe13 | 1820 | lst_indent_to (file, indent); |
f77385d3 | 1821 | |
1822 | if (LST_LOOP_P (lst)) | |
1823 | { | |
1824 | int i; | |
1825 | lst_p l; | |
1826 | ||
43217ce9 | 1827 | if (LST_LOOP_FATHER (lst)) |
1828 | fprintf (file, "%d (loop", lst_dewey_number (lst)); | |
1829 | else | |
5dc5fe13 | 1830 | fprintf (file, "#(root"); |
f77385d3 | 1831 | |
48148244 | 1832 | FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l) |
f77385d3 | 1833 | print_lst (file, l, indent + 2); |
1834 | ||
1835 | fprintf (file, ")"); | |
1836 | } | |
1837 | else | |
1838 | fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst))); | |
1839 | } | |
1840 | ||
1841 | /* Print LST to STDERR. */ | |
1842 | ||
4b987fac | 1843 | DEBUG_FUNCTION void |
f77385d3 | 1844 | debug_lst (lst_p lst) |
1845 | { | |
1846 | print_lst (stderr, lst, 0); | |
1847 | } | |
1848 | ||
4938b827 | 1849 | /* Pretty print to FILE the loop statement tree LST in DOT format. */ |
1850 | ||
1851 | static void | |
1852 | dot_lst_1 (FILE *file, lst_p lst) | |
1853 | { | |
1854 | if (!lst) | |
1855 | return; | |
1856 | ||
1857 | if (LST_LOOP_P (lst)) | |
1858 | { | |
1859 | int i; | |
1860 | lst_p l; | |
1861 | ||
1862 | if (!LST_LOOP_FATHER (lst)) | |
1863 | fprintf (file, "L -> L_%d_%d\n", | |
1864 | lst_depth (lst), | |
1865 | lst_dewey_number (lst)); | |
1866 | else | |
1867 | fprintf (file, "L_%d_%d -> L_%d_%d\n", | |
1868 | lst_depth (LST_LOOP_FATHER (lst)), | |
1869 | lst_dewey_number (LST_LOOP_FATHER (lst)), | |
1870 | lst_depth (lst), | |
1871 | lst_dewey_number (lst)); | |
1872 | ||
48148244 | 1873 | FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l) |
4938b827 | 1874 | dot_lst_1 (file, l); |
1875 | } | |
1876 | ||
1877 | else | |
1878 | fprintf (file, "L_%d_%d -> S_%d\n", | |
1879 | lst_depth (LST_LOOP_FATHER (lst)), | |
1880 | lst_dewey_number (LST_LOOP_FATHER (lst)), | |
1881 | pbb_index (LST_PBB (lst))); | |
1882 | ||
1883 | } | |
1884 | ||
1885 | /* Display the LST using dotty. */ | |
1886 | ||
6b5822fe | 1887 | DEBUG_FUNCTION void |
4938b827 | 1888 | dot_lst (lst_p lst) |
1889 | { | |
1890 | /* When debugging, enable the following code. This cannot be used | |
1891 | in production compilers because it calls "system". */ | |
1892 | #if 0 | |
4938b827 | 1893 | FILE *stream = fopen ("/tmp/lst.dot", "w"); |
1894 | gcc_assert (stream); | |
1895 | ||
1896 | fputs ("digraph all {\n", stream); | |
1897 | dot_lst_1 (stream, lst); | |
1898 | fputs ("}\n\n", stream); | |
1899 | fclose (stream); | |
1900 | ||
97b0e4df | 1901 | system ("dotty /tmp/lst.dot &"); |
4938b827 | 1902 | #else |
1903 | fputs ("digraph all {\n", stderr); | |
1904 | dot_lst_1 (stderr, lst); | |
1905 | fputs ("}\n\n", stderr); | |
1906 | ||
1907 | #endif | |
1908 | } | |
1909 | ||
079f4f8c | 1910 | /* Computes a checksum for the code generated by CLooG for SCOP. */ |
1911 | ||
1912 | DEBUG_FUNCTION void | |
1913 | cloog_checksum (scop_p scop ATTRIBUTE_UNUSED) | |
1914 | { | |
1915 | /* When debugging, enable the following code. This cannot be used | |
1916 | in production compilers because it calls "system". */ | |
1917 | #if 0 | |
1918 | FILE *stream = fopen ("/tmp/scop.cloog", "w"); | |
1919 | gcc_assert (stream); | |
1920 | print_cloog (stream, scop, 0); | |
1921 | fclose (stream); | |
1922 | ||
1923 | fputs ("\n", stdout); | |
1924 | system ("cloog -compilable 1 /tmp/scop.cloog > /tmp/scop.c ; gcc -O0 -g /tmp/scop.c -lm -o /tmp/scop; /tmp/scop | md5sum "); | |
1925 | #endif | |
1926 | } | |
1927 | ||
c6bb733d | 1928 | #endif |
1929 |