Dump each scop in a separate file.
[official-gcc/graphite-test-results.git] / gcc / graphite-poly.c
blobfc69e7c3fdf41b64a8d6bd54d43d30c2a7542293
1 /* Graphite polyhedral representation.
2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com> and
4 Tobias Grosser <grosser@fim.uni-passau.de>.
6 This file is part of GCC.
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.
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.
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"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "output.h"
29 #include "basic-block.h"
30 #include "diagnostic.h"
31 #include "tree-pretty-print.h"
32 #include "gimple-pretty-print.h"
33 #include "tree-flow.h"
34 #include "toplev.h"
35 #include "tree-dump.h"
36 #include "timevar.h"
37 #include "cfgloop.h"
38 #include "tree-chrec.h"
39 #include "tree-data-ref.h"
40 #include "tree-scalar-evolution.h"
41 #include "tree-pass.h"
42 #include "domwalk.h"
43 #include "value-prof.h"
44 #include "pointer-set.h"
45 #include "gimple.h"
46 #include "params.h"
48 #ifdef HAVE_cloog
49 #include "ppl_c.h"
50 #include "sese.h"
51 #include "graphite-ppl.h"
52 #include "graphite.h"
53 #include "graphite-poly.h"
54 #include "graphite-dependences.h"
55 #include "graphite-cloog-util.h"
57 #define OPENSCOP_MAX_STRING 256
59 /* Return the maximal loop depth in SCOP. */
61 int
62 scop_max_loop_depth (scop_p scop)
64 int i;
65 poly_bb_p pbb;
66 int max_nb_loops = 0;
68 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
70 int nb_loops = pbb_dim_iter_domain (pbb);
71 if (max_nb_loops < nb_loops)
72 max_nb_loops = nb_loops;
75 return max_nb_loops;
78 /* Extend the scattering matrix of PBB to MAX_SCATTERING scattering
79 dimensions. */
81 static void
82 extend_scattering (poly_bb_p pbb, int max_scattering)
84 ppl_dimension_type nb_old_dims, nb_new_dims;
85 int nb_added_dims, i;
86 ppl_Coefficient_t coef;
87 mpz_t one;
89 nb_added_dims = max_scattering - pbb_nb_scattering_transform (pbb);
90 mpz_init (one);
91 mpz_set_si (one, 1);
92 ppl_new_Coefficient (&coef);
93 ppl_assign_Coefficient_from_mpz_t (coef, one);
95 gcc_assert (nb_added_dims >= 0);
97 nb_old_dims = pbb_nb_scattering_transform (pbb) + pbb_dim_iter_domain (pbb)
98 + scop_nb_params (PBB_SCOP (pbb));
99 nb_new_dims = nb_old_dims + nb_added_dims;
101 ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb),
102 pbb_nb_scattering_transform (pbb), nb_added_dims);
103 PBB_NB_SCATTERING_TRANSFORM (pbb) += nb_added_dims;
105 /* Add identity matrix for the added dimensions. */
106 for (i = max_scattering - nb_added_dims; i < max_scattering; i++)
108 ppl_Constraint_t cstr;
109 ppl_Linear_Expression_t expr;
111 ppl_new_Linear_Expression_with_dimension (&expr, nb_new_dims);
112 ppl_Linear_Expression_add_to_coefficient (expr, i, coef);
113 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
114 ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
115 ppl_delete_Constraint (cstr);
116 ppl_delete_Linear_Expression (expr);
119 ppl_delete_Coefficient (coef);
120 mpz_clear (one);
123 /* All scattering matrices in SCOP will have the same number of scattering
124 dimensions. */
127 unify_scattering_dimensions (scop_p scop)
129 int i;
130 poly_bb_p pbb;
131 graphite_dim_t max_scattering = 0;
133 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
134 max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering);
136 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
137 extend_scattering (pbb, max_scattering);
139 return max_scattering;
142 /* Print to FILE the pdr PH in OpenScop format. NB_SUBSCRIPTS is the number
143 of subscripts in PH, ALIAS_SET_DIM is the dimension of the alias set and
144 NB_PARAMS is the number of parameters in PH. */
146 static void
147 openscop_print_pdr_polyhedron (FILE *file, ppl_const_Polyhedron_t ph,
148 int nb_subscripts, int alias_set_dimension,
149 int nb_params)
151 int input, locals, output;
152 ppl_dimension_type alias_set_dim = (ppl_dimension_type) alias_set_dimension;
153 ppl_dimension_type sub_dim_last = alias_set_dim + nb_subscripts;
154 ppl_dimension_type *map, i, ph_space_dim = sub_dim_last + 1;
155 ppl_Polyhedron_t pph;
157 ppl_new_C_Polyhedron_from_C_Polyhedron (&pph, ph);
159 map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, ph_space_dim);
161 for (i = 0; i < alias_set_dim - 1; i++)
162 map[i] = nb_subscripts + 1 + i;
164 for (i = alias_set_dim - 1; i < sub_dim_last; i++)
165 map[i] = i - alias_set_dim + 1;
167 ppl_Polyhedron_map_space_dimensions (pph, map, ph_space_dim - 1);
169 locals = 0;
170 input = alias_set_dim - nb_params - 1;
172 /* According to OpenScop specification, the alias set column is a part of
173 the output columns. */
174 output = nb_subscripts + 1;
176 openscop_print_polyhedron_matrix (file, pph, output, input, locals, nb_params);
179 /* Print to FILE the powerset PDR. NB_SUBSCRIPTS is the number of subscripts
180 in PDR, ALIAS_SET_DIM is the dimension of the alias set in PDR and
181 NB_PARAMS is the number of parameters in PDR. */
183 static void
184 openscop_print_pdr_powerset (FILE *file,
185 ppl_Pointset_Powerset_C_Polyhedron_t ps,
186 int nb_subscripts,
187 int alias_set_dim,
188 int nb_params)
190 size_t nb_disjuncts;
191 ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end;
193 ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it);
194 ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end);
196 ppl_Pointset_Powerset_C_Polyhedron_size (ps, &nb_disjuncts);
197 fprintf (file, "%d\n", (int) nb_disjuncts);
199 for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it),
200 ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end);
201 !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end);
202 ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it))
204 ppl_const_Polyhedron_t ph;
206 ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph);
207 openscop_print_pdr_polyhedron (file, ph, nb_subscripts, alias_set_dim,
208 nb_params);
211 ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it);
212 ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end);
215 /* Print to FILE the powerset PS in its OpenScop matrix form. */
217 static void
218 openscop_print_powerset_matrix (FILE *file,
219 ppl_Pointset_Powerset_C_Polyhedron_t ps,
220 int output, int input, int locals,
221 int params)
223 size_t nb_disjuncts;
224 ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end;
226 ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it);
227 ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end);
229 ppl_Pointset_Powerset_C_Polyhedron_size (ps, &nb_disjuncts);
230 fprintf (file, "%d\n", (int) nb_disjuncts);
232 for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it),
233 ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end);
234 !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end);
235 ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it))
237 ppl_const_Polyhedron_t ph;
239 ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph);
240 openscop_print_polyhedron_matrix (file, ph, output, input, locals,
241 params);
244 ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it);
245 ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end);
248 /* Prints to FILE the scattering function of PBB in OpenScop format, at some
249 VERBOSITY level. */
251 static void
252 openscop_print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
254 graphite_dim_t i;
255 ppl_const_Polyhedron_t ph;
257 if (verbosity > 0)
259 fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
260 fprintf (file, "#eq");
262 for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
263 fprintf (file, " s%d", (int) i);
265 for (i = 0; i < pbb_nb_local_vars (pbb); i++)
266 fprintf (file, " lv%d", (int) i);
268 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
269 fprintf (file, " i%d", (int) i);
271 for (i = 0; i < pbb_nb_params (pbb); i++)
272 fprintf (file, " p%d", (int) i);
274 fprintf (file, " cst\n");
277 /* Number of disjunct components. Remove this when
278 PBB_TRANSFORMED_SCATTERING will be a pointset_powerset. */
279 fprintf (file, "1\n");
281 ph = PBB_TRANSFORMED_SCATTERING (pbb)
282 ? PBB_TRANSFORMED_SCATTERING (pbb)
283 : PBB_ORIGINAL_SCATTERING (pbb);
285 openscop_print_polyhedron_matrix (file, ph,
286 pbb_nb_scattering_transform (pbb),
287 pbb_dim_iter_domain (pbb),
288 pbb_nb_local_vars (pbb),
289 pbb_nb_params (pbb));
291 if (verbosity > 0)
292 fprintf (file, "#)\n");
295 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
296 level. */
298 static void
299 print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
301 graphite_dim_t i;
303 if (verbosity > 0)
305 fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
306 fprintf (file, "#eq");
308 for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
309 fprintf (file, " s%d", (int) i);
311 for (i = 0; i < pbb_nb_local_vars (pbb); i++)
312 fprintf (file, " lv%d", (int) i);
314 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
315 fprintf (file, " i%d", (int) i);
317 for (i = 0; i < pbb_nb_params (pbb); i++)
318 fprintf (file, " p%d", (int) i);
320 fprintf (file, " cst\n");
323 /* Number of disjunct components. Remove this when
324 PBB_TRANSFORMED_SCATTERING will be a pointset_powerset. */
325 fprintf (file, "1\n");
326 ppl_print_polyhedron_matrix (file, PBB_TRANSFORMED_SCATTERING (pbb)
327 ? PBB_TRANSFORMED_SCATTERING (pbb)
328 : PBB_ORIGINAL_SCATTERING (pbb));
330 if (verbosity > 0)
331 fprintf (file, "#)\n");
334 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
335 level. */
337 void
338 print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity)
340 if (!PBB_TRANSFORMED (pbb))
341 return;
343 if (PBB_TRANSFORMED_SCATTERING (pbb)
344 || PBB_ORIGINAL_SCATTERING (pbb))
346 if (verbosity > 0)
347 fprintf (file, "# Scattering function is provided\n");
349 fprintf (file, "1\n");
351 else
353 if (verbosity > 0)
354 fprintf (file, "# Scattering function is not provided\n");
356 fprintf (file, "0\n");
357 return;
360 openscop_print_scattering_function_1 (file, pbb, verbosity);
362 if (verbosity > 0)
363 fprintf (file, "# Scattering names are not provided\n");
365 fprintf (file, "0\n");
369 /* Prints to FILE the iteration domain of PBB, at some VERBOSITY
370 level. */
372 void
373 print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity)
375 print_pbb_domain (file, pbb, verbosity);
378 /* Prints to FILE the scattering functions of every PBB of SCOP. */
380 void
381 print_scattering_functions (FILE *file, scop_p scop, int verbosity)
383 int i;
384 poly_bb_p pbb;
386 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
387 print_scattering_function (file, pbb, verbosity);
390 /* Prints to FILE the iteration domains of every PBB of SCOP, at some
391 VERBOSITY level. */
393 void
394 print_iteration_domains (FILE *file, scop_p scop, int verbosity)
396 int i;
397 poly_bb_p pbb;
399 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
400 print_iteration_domain (file, pbb, verbosity);
403 /* Prints to STDERR the scattering function of PBB, at some VERBOSITY
404 level. */
406 DEBUG_FUNCTION void
407 debug_scattering_function (poly_bb_p pbb, int verbosity)
409 print_scattering_function (stderr, pbb, verbosity);
412 /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY
413 level. */
415 DEBUG_FUNCTION void
416 debug_iteration_domain (poly_bb_p pbb, int verbosity)
418 print_iteration_domain (stderr, pbb, verbosity);
421 /* Prints to STDERR the scattering functions of every PBB of SCOP, at
422 some VERBOSITY level. */
424 DEBUG_FUNCTION void
425 debug_scattering_functions (scop_p scop, int verbosity)
427 print_scattering_functions (stderr, scop, verbosity);
430 /* Prints to STDERR the iteration domains of every PBB of SCOP, at
431 some VERBOSITY level. */
433 DEBUG_FUNCTION void
434 debug_iteration_domains (scop_p scop, int verbosity)
436 print_iteration_domains (stderr, scop, verbosity);
439 /* Read N integer from FILE. */
441 int *
442 openscop_read_N_int (FILE *file, int N)
444 char s[OPENSCOP_MAX_STRING];
445 char *str;
446 int i, *res = (int *) xmalloc (OPENSCOP_MAX_STRING * sizeof (int));
448 /* Skip blank and commented lines. */
449 while (fgets (s, sizeof s, file) == (char *) 0
450 || s[0] == '#'
451 || ISSPACE (s[0]))
454 str = s;
456 for (i = 0; i < N; i++)
458 sscanf (str, "%d", &res[i]);
460 /* Jump the integer that was read. */
461 while ((*str) && !ISSPACE (*str) && (*str != '#'))
462 str++;
464 /* Jump spaces. */
465 while ((*str) && ISSPACE (*str) && (*str != '#'))
466 str++;
469 return res;
472 /* Read one integer from FILE. */
474 static int
475 openscop_read_one_int (FILE *file)
477 int *x = openscop_read_N_int (file, 1);
478 int res = *x;
480 free (x);
481 return res;
484 /* Read N string from FILE. */
486 static char *
487 openscop_read_N_string (FILE *file, int N)
489 int count, i;
490 char str[OPENSCOP_MAX_STRING];
491 char *tmp = (char *) xmalloc (sizeof (char) * OPENSCOP_MAX_STRING);
492 char *s = NULL;
494 /* Skip blank and commented lines. */
495 while (fgets (str, sizeof str, file) == (char *) 0
496 || str[0] == '#'
497 || ISSPACE (str[0]))
500 s = str;
501 count = 0;
503 for (i = 0; i < N; i++)
505 /* Read the first word. */
506 for (; (*s) && (!ISSPACE (*s)) && (*s != '#'); ++count)
507 tmp[count] = *(s++);
509 tmp[count] = ' ';
510 count++;
512 /* Jump spaces. */
513 while ((*s) && ISSPACE (*s) && (*s != '#'))
514 s++;
517 tmp[count-1] = '\0';
519 return tmp;
522 /* Read one string from FILE. */
524 static char *
525 openscop_read_one_string (FILE *file)
527 return openscop_read_N_string (file, 1);
530 /* Read from FILE the powerset PS in its OpenScop matrix form. OUTPUT is the
531 number of output dimensions, INPUT is the number of input dimensions,
532 LOCALS is the number of existentially quantified variables and PARAMS is
533 the number of parameters. */
535 static void
536 openscop_read_powerset_matrix (FILE *file,
537 ppl_Pointset_Powerset_C_Polyhedron_t *ps,
538 int *output, int *input, int *locals,
539 int *params)
541 int nb_disjuncts, i;
543 nb_disjuncts = openscop_read_one_int (file);
545 for (i = 0; i < nb_disjuncts; i++)
547 ppl_Polyhedron_t ph;
549 openscop_read_polyhedron_matrix (file, &ph, output, input, locals,
550 params);
551 if (!ph)
552 *ps = NULL;
553 else if (i == 0)
554 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (ps, ph);
555 else
556 ppl_Pointset_Powerset_C_Polyhedron_add_disjunct (*ps, ph);
560 /* Read a scattering function from FILE and save it to PBB. Return whether
561 the scattering function was provided or not. */
563 static bool
564 graphite_read_scatt (FILE *file, poly_bb_p pbb)
566 bool scattering_provided = false;
567 int output, input, locals, params;
568 ppl_Polyhedron_t newp;
570 if (openscop_read_one_int (file) > 0)
572 /* Read number of disjunct components. */
573 openscop_read_one_int (file);
575 /* Read scattering function. */
576 openscop_read_polyhedron_matrix (file, &newp, &output, &input,
577 &locals, &params);
578 store_scattering (PBB_SCOP (pbb));
579 PBB_TRANSFORMED (pbb) = poly_scattering_new ();
580 PBB_TRANSFORMED_SCATTERING (pbb) = newp;
581 PBB_NB_LOCAL_VARIABLES (pbb) = locals;
583 /* New scattering dimension. */
584 PBB_NB_SCATTERING_TRANSFORM (pbb) = output;
586 scattering_provided = true;
589 return scattering_provided;
592 /* Read a scop file. Return true if the scop is transformed. */
594 static bool
595 graphite_read_scop_file (FILE *file, scop_p scop)
597 char *tmp, *language;
598 size_t i, j, nb_statements, nbr, nbw;
599 int input, output, locals, params;
600 ppl_Pointset_Powerset_C_Polyhedron_t ps;
601 poly_bb_p pbb;
602 bool transform_done;
604 /* Ensure that the file is in OpenScop format. */
605 tmp = openscop_read_N_string (file, 2);
607 if (strcmp (tmp, "SCoP 1"))
609 error ("The file is not in OpenScop format.\n");
610 return false;
613 free (tmp);
615 /* Read the language. */
616 language = openscop_read_one_string (file);
618 if (strcmp (language, "Gimple"))
620 error ("The language is not recognized\n");
621 return false;
624 free (language);
626 /* Read the context but do not use it. */
627 openscop_read_powerset_matrix (file, &ps, &input, &output, &locals, &params);
629 if ((size_t) params != scop->nb_params)
631 error ("Parameters number in the scop file is different from the"
632 " internal scop parameter number.");
633 return false;
636 /* Read parameter names if provided. */
637 if (openscop_read_one_int (file))
638 openscop_read_N_string (file, scop->nb_params);
640 nb_statements = openscop_read_one_int (file);
642 if (nb_statements != VEC_length (poly_bb_p, SCOP_BBS (scop)))
644 error ("Number of statements in the OpenScop file does not match"
645 " the graphite internal statements number.");
646 return false;
649 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
651 /* Read iteration domain. */
652 openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
653 &params);
655 /* Read scattering. */
656 transform_done = graphite_read_scatt (file, pbb);
658 /* Scattering names. */
659 openscop_read_one_int (file);
661 /* Read access functions. */
662 if (openscop_read_one_int (file) > 0)
664 nbr = openscop_read_one_int (file);
666 /* Read access functions. */
667 for (j = 0; j < nbr; j++)
668 openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
669 &params);
671 nbw = openscop_read_one_int (file);
673 /* Write access functions. */
674 for (j = 0; j < nbw; j++)
675 openscop_read_powerset_matrix (file, &ps, &input, &output, &locals,
676 &params);
679 /* Statement body. */
680 openscop_read_one_int (file);
683 return transform_done;
686 /* Initialize and return a file that will be used to write a scop. SCOP_NUMBER
687 is a sequential number (identifier) used to differentiate scop files.
688 Examples of the generated file names: dump_base_name.0.graphite,
689 dump_base_name.1.graphite, dump_base_name.2.graphite, etc. */
691 static FILE *
692 init_graphite_out_file (int scop_number)
694 FILE *graphite_out_file;
695 int len = strlen (dump_base_name);
696 char *dumpname = XNEWVEC (char, len + 25);
697 char *s_scop_number = XNEWVEC (char, 15);
699 memcpy (dumpname, dump_base_name, len + 1);
700 strip_off_ending (dumpname, len);
701 sprintf (s_scop_number, ".%d", scop_number);
702 strcat (dumpname, s_scop_number);
703 strcat (dumpname, ".graphite");
704 graphite_out_file = fopen (dumpname, "w+b");
706 if (graphite_out_file == 0)
707 fatal_error ("can%'t open %s for writing: %m", dumpname);
709 free (dumpname);
711 return graphite_out_file;
714 /* Open and return a file used for scop reading. SCOP_NUMBER is a sequential
715 number (identifier) used to differentiate scop files. Examples of the
716 generated file names: dump_base_name.0.graphite, dump_base_name.1.graphite,
717 dump_base_name.2.graphite, etc. */
719 static FILE *
720 init_graphite_in_file (int scop_number)
722 FILE *graphite_in_file;
723 int len = strlen (dump_base_name);
724 char *dumpname = XNEWVEC (char, len + 25);
725 char *s_scop_number = XNEWVEC (char, 15);
727 memcpy (dumpname, dump_base_name, len + 1);
728 strip_off_ending (dumpname, len);
729 sprintf (s_scop_number, ".%d", scop_number);
730 strcat (dumpname, s_scop_number);
731 strcat (dumpname, ".graphite");
732 graphite_in_file = fopen (dumpname, "r+b");
734 if (graphite_in_file == 0)
735 fatal_error ("can%'t open %s for reading: %m", dumpname);
737 free (dumpname);
739 return graphite_in_file;
742 /* Apply graphite transformations to all the basic blocks of SCOP. */
744 bool
745 apply_poly_transforms (scop_p scop)
747 bool transform_done = false;
748 FILE *graphite_file;
749 static size_t file_scop_number = 0;
751 if (flag_graphite_read)
753 graphite_file = init_graphite_in_file (file_scop_number);
754 transform_done |= graphite_read_scop_file (graphite_file, scop);
755 gcc_assert (graphite_legal_transform (scop));
756 file_scop_number++;
759 /* Generate code even if we did not apply any real transformation.
760 This also allows to check the performance for the identity
761 transformation: GIMPLE -> GRAPHITE -> GIMPLE
762 Keep in mind that CLooG optimizes in control, so the loop structure
763 may change, even if we only use -fgraphite-identity. */
764 if (flag_graphite_identity)
765 transform_done = true;
767 if (flag_loop_parallelize_all)
768 transform_done = true;
770 if (flag_loop_block)
771 transform_done |= scop_do_block (scop);
772 else
774 if (flag_loop_strip_mine)
775 transform_done |= scop_do_strip_mine (scop);
777 if (flag_loop_interchange)
778 transform_done |= scop_do_interchange (scop);
781 if (flag_graphite_write)
783 graphite_file = init_graphite_out_file (file_scop_number);
784 print_scop (graphite_file, scop, 1);
785 file_scop_number++;
788 return transform_done;
791 /* Returns true when it PDR1 is a duplicate of PDR2: same PBB, and
792 their ACCESSES, TYPE, and NB_SUBSCRIPTS are the same. */
794 static inline bool
795 can_collapse_pdrs (poly_dr_p pdr1, poly_dr_p pdr2)
797 bool res;
798 ppl_Pointset_Powerset_C_Polyhedron_t af1, af2, diff;
800 if (PDR_PBB (pdr1) != PDR_PBB (pdr2)
801 || PDR_NB_SUBSCRIPTS (pdr1) != PDR_NB_SUBSCRIPTS (pdr2)
802 || PDR_TYPE (pdr1) != PDR_TYPE (pdr2))
803 return false;
805 af1 = PDR_ACCESSES (pdr1);
806 af2 = PDR_ACCESSES (pdr2);
807 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
808 (&diff, af1);
809 ppl_Pointset_Powerset_C_Polyhedron_difference_assign (diff, af2);
811 res = ppl_Pointset_Powerset_C_Polyhedron_is_empty (diff);
812 ppl_delete_Pointset_Powerset_C_Polyhedron (diff);
813 return res;
816 /* Removes duplicated data references in PBB. */
818 void
819 pbb_remove_duplicate_pdrs (poly_bb_p pbb)
821 int i, j;
822 poly_dr_p pdr1, pdr2;
823 unsigned n = VEC_length (poly_dr_p, PBB_DRS (pbb));
824 VEC (poly_dr_p, heap) *collapsed = VEC_alloc (poly_dr_p, heap, n);
826 for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr1); i++)
827 for (j = 0; VEC_iterate (poly_dr_p, collapsed, j, pdr2); j++)
828 if (!can_collapse_pdrs (pdr1, pdr2))
829 VEC_quick_push (poly_dr_p, collapsed, pdr1);
831 VEC_free (poly_dr_p, heap, collapsed);
832 PBB_PDR_DUPLICATES_REMOVED (pbb) = true;
835 /* Create a new polyhedral data reference and add it to PBB. It is
836 defined by its ACCESSES, its TYPE, and the number of subscripts
837 NB_SUBSCRIPTS. */
839 void
840 new_poly_dr (poly_bb_p pbb, int dr_base_object_set,
841 ppl_Pointset_Powerset_C_Polyhedron_t accesses,
842 enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts)
844 static int id = 0;
845 poly_dr_p pdr = XNEW (struct poly_dr);
847 PDR_ID (pdr) = id++;
848 PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set;
849 PDR_NB_REFS (pdr) = 1;
850 PDR_PBB (pdr) = pbb;
851 PDR_ACCESSES (pdr) = accesses;
852 PDR_TYPE (pdr) = type;
853 PDR_CDR (pdr) = cdr;
854 PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts;
855 VEC_safe_push (poly_dr_p, heap, PBB_DRS (pbb), pdr);
858 /* Free polyhedral data reference PDR. */
860 void
861 free_poly_dr (poly_dr_p pdr)
863 ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_ACCESSES (pdr));
864 XDELETE (pdr);
867 /* Create a new polyhedral black box. */
869 void
870 new_poly_bb (scop_p scop, void *black_box, bool reduction)
872 poly_bb_p pbb = XNEW (struct poly_bb);
874 PBB_DOMAIN (pbb) = NULL;
875 PBB_SCOP (pbb) = scop;
876 pbb_set_black_box (pbb, black_box);
877 PBB_TRANSFORMED (pbb) = NULL;
878 PBB_SAVED (pbb) = NULL;
879 PBB_ORIGINAL (pbb) = NULL;
880 PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3);
881 PBB_IS_REDUCTION (pbb) = reduction;
882 PBB_PDR_DUPLICATES_REMOVED (pbb) = false;
883 VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
886 /* Free polyhedral black box. */
888 void
889 free_poly_bb (poly_bb_p pbb)
891 int i;
892 poly_dr_p pdr;
894 ppl_delete_Pointset_Powerset_C_Polyhedron (PBB_DOMAIN (pbb));
896 if (PBB_TRANSFORMED (pbb))
897 poly_scattering_free (PBB_TRANSFORMED (pbb));
899 if (PBB_SAVED (pbb))
900 poly_scattering_free (PBB_SAVED (pbb));
902 if (PBB_ORIGINAL (pbb))
903 poly_scattering_free (PBB_ORIGINAL (pbb));
905 if (PBB_DRS (pbb))
906 for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
907 free_poly_dr (pdr);
909 VEC_free (poly_dr_p, heap, PBB_DRS (pbb));
910 XDELETE (pbb);
913 static void
914 print_pdr_access_layout (FILE *file, poly_bb_p pbb, poly_dr_p pdr)
916 graphite_dim_t i;
918 fprintf (file, "# eq");
920 fprintf (file, " alias");
922 for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++)
923 fprintf (file, " sub%d", (int) i);
925 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
926 fprintf (file, " i%d", (int) i);
928 for (i = 0; i < pbb_nb_params (pbb); i++)
929 fprintf (file, " p%d", (int) i);
931 fprintf (file, " cst\n");
934 /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY
935 level. */
937 void
938 print_pdr (FILE *file, poly_dr_p pdr, int verbosity)
940 int alias_set_dim;
942 if (verbosity > 1)
944 fprintf (file, "# pdr_%d (", PDR_ID (pdr));
946 switch (PDR_TYPE (pdr))
948 case PDR_READ:
949 fprintf (file, "read \n");
950 break;
952 case PDR_WRITE:
953 fprintf (file, "write \n");
954 break;
956 case PDR_MAY_WRITE:
957 fprintf (file, "may_write \n");
958 break;
960 default:
961 gcc_unreachable ();
964 dump_data_reference (file, (data_reference_p) PDR_CDR (pdr));
967 if (verbosity > 0)
969 fprintf (file, "# data accesses (\n");
970 print_pdr_access_layout (file, PDR_PBB (pdr), pdr);
973 alias_set_dim = pdr_alias_set_dim (pdr) + 1;
975 openscop_print_pdr_powerset (file,
976 PDR_ACCESSES (pdr),
977 PDR_NB_SUBSCRIPTS (pdr),
978 alias_set_dim,
979 pbb_nb_params (PDR_PBB (pdr)));
981 if (verbosity > 0)
982 fprintf (file, "#)\n");
984 if (verbosity > 1)
985 fprintf (file, "#)\n");
988 /* Prints to STDERR the polyhedral data reference PDR, at some
989 VERBOSITY level. */
991 DEBUG_FUNCTION void
992 debug_pdr (poly_dr_p pdr, int verbosity)
994 print_pdr (stderr, pdr, verbosity);
997 /* Creates a new SCOP containing REGION. */
999 scop_p
1000 new_scop (void *region)
1002 scop_p scop = XNEW (struct scop);
1004 SCOP_CONTEXT (scop) = NULL;
1005 scop_set_region (scop, region);
1006 SCOP_BBS (scop) = VEC_alloc (poly_bb_p, heap, 3);
1007 SCOP_ORIGINAL_PDDRS (scop) = htab_create (10, hash_poly_ddr_p,
1008 eq_poly_ddr_p, free_poly_ddr);
1009 SCOP_ORIGINAL_SCHEDULE (scop) = NULL;
1010 SCOP_TRANSFORMED_SCHEDULE (scop) = NULL;
1011 SCOP_SAVED_SCHEDULE (scop) = NULL;
1012 POLY_SCOP_P (scop) = false;
1014 return scop;
1017 /* Deletes SCOP. */
1019 void
1020 free_scop (scop_p scop)
1022 int i;
1023 poly_bb_p pbb;
1025 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1026 free_poly_bb (pbb);
1028 VEC_free (poly_bb_p, heap, SCOP_BBS (scop));
1030 if (SCOP_CONTEXT (scop))
1031 ppl_delete_Pointset_Powerset_C_Polyhedron (SCOP_CONTEXT (scop));
1033 htab_delete (SCOP_ORIGINAL_PDDRS (scop));
1034 free_lst (SCOP_ORIGINAL_SCHEDULE (scop));
1035 free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
1036 free_lst (SCOP_SAVED_SCHEDULE (scop));
1037 XDELETE (scop);
1040 /* Print to FILE the domain of PBB in OpenScop format, at some VERBOSITY
1041 level. */
1043 static void
1044 openscop_print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
1046 graphite_dim_t i;
1047 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1049 if (!PBB_DOMAIN (pbb))
1050 return;
1052 if (verbosity > 0)
1054 fprintf (file, "\n# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
1055 fprintf (file, "#eq");
1057 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
1058 fprintf (file, " i%d", (int) i);
1060 for (i = 0; i < pbb_nb_params (pbb); i++)
1061 fprintf (file, " p%d", (int) i);
1063 fprintf (file, " cst\n");
1066 if (PBB_DOMAIN (pbb))
1067 openscop_print_powerset_matrix (file, PBB_DOMAIN (pbb),
1068 pbb_dim_iter_domain (pbb),
1071 pbb_nb_params (pbb));
1072 else
1073 fprintf (file, "0\n");
1075 if (verbosity > 0)
1076 fprintf (file, "#)\n");
1079 /* Print to FILE the domain of PBB, at some VERBOSITY level. */
1081 void
1082 print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
1084 graphite_dim_t i;
1085 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1087 if (!PBB_DOMAIN (pbb))
1088 return;
1090 if (verbosity > 0)
1092 fprintf (file, "# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
1093 fprintf (file, "# eq");
1095 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
1096 fprintf (file, " i%d", (int) i);
1098 for (i = 0; i < pbb_nb_params (pbb); i++)
1099 fprintf (file, " p%d", (int) i);
1101 fprintf (file, " cst\n");
1104 if (PBB_DOMAIN (pbb))
1105 ppl_print_powerset_matrix (file, PBB_DOMAIN (pbb));
1106 else
1107 fprintf (file, "0\n");
1109 if (verbosity > 0)
1110 fprintf (file, "#)\n");
1113 /* Dump the cases of a graphite basic block GBB on FILE. */
1115 static void
1116 dump_gbb_cases (FILE *file, gimple_bb_p gbb)
1118 int i;
1119 gimple stmt;
1120 VEC (gimple, heap) *cases;
1122 if (!gbb)
1123 return;
1125 cases = GBB_CONDITION_CASES (gbb);
1126 if (VEC_empty (gimple, cases))
1127 return;
1129 fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index);
1131 for (i = 0; VEC_iterate (gimple, cases, i, stmt); i++)
1133 fprintf (file, "# ");
1134 print_gimple_stmt (file, stmt, 0, 0);
1137 fprintf (file, "#)\n");
1140 /* Dump conditions of a graphite basic block GBB on FILE. */
1142 static void
1143 dump_gbb_conditions (FILE *file, gimple_bb_p gbb)
1145 int i;
1146 gimple stmt;
1147 VEC (gimple, heap) *conditions;
1149 if (!gbb)
1150 return;
1152 conditions = GBB_CONDITIONS (gbb);
1153 if (VEC_empty (gimple, conditions))
1154 return;
1156 fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index);
1158 for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
1160 fprintf (file, "# ");
1161 print_gimple_stmt (file, stmt, 0, 0);
1164 fprintf (file, "#)\n");
1167 /* Print to FILE all the data references of PBB, at some VERBOSITY
1168 level. */
1170 void
1171 print_pdrs (FILE *file, poly_bb_p pbb, int verbosity)
1173 int i;
1174 poly_dr_p pdr;
1175 int nb_reads = 0;
1176 int nb_writes = 0;
1178 if (VEC_length (poly_dr_p, PBB_DRS (pbb)) == 0)
1180 if (verbosity > 0)
1181 fprintf (file, "# Access informations are not provided\n");\
1182 fprintf (file, "0\n");
1183 return;
1186 if (verbosity > 1)
1187 fprintf (file, "# Data references (\n");
1189 if (verbosity > 0)
1190 fprintf (file, "# Access informations are provided\n");
1191 fprintf (file, "1\n");
1193 for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
1194 if (PDR_TYPE (pdr) == PDR_READ)
1195 nb_reads++;
1196 else
1197 nb_writes++;
1199 if (verbosity > 1)
1200 fprintf (file, "# Read data references (\n");
1202 if (verbosity > 0)
1203 fprintf (file, "# Read access informations\n");
1204 fprintf (file, "%d\n", nb_reads);
1206 for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
1207 if (PDR_TYPE (pdr) == PDR_READ)
1208 print_pdr (file, pdr, verbosity);
1210 if (verbosity > 1)
1211 fprintf (file, "#)\n");
1213 if (verbosity > 1)
1214 fprintf (file, "# Write data references (\n");
1216 if (verbosity > 0)
1217 fprintf (file, "# Write access informations\n");
1218 fprintf (file, "%d\n", nb_writes);
1220 for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
1221 if (PDR_TYPE (pdr) != PDR_READ)
1222 print_pdr (file, pdr, verbosity);
1224 if (verbosity > 1)
1225 fprintf (file, "#)\n");
1227 if (verbosity > 1)
1228 fprintf (file, "#)\n");
1231 /* Print to STDERR all the data references of PBB. */
1233 DEBUG_FUNCTION void
1234 debug_pdrs (poly_bb_p pbb, int verbosity)
1236 print_pdrs (stderr, pbb, verbosity);
1239 /* Print to FILE the body of PBB, at some VERBOSITY level.
1240 If statement_body_provided is false statement body is not printed. */
1242 static void
1243 print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity,
1244 bool statement_body_provided)
1246 if (verbosity > 1)
1247 fprintf (file, "# Body (\n");
1249 if (!statement_body_provided)
1251 if (verbosity > 0)
1252 fprintf (file, "# Statement body is not provided\n");
1254 fprintf (file, "0\n");
1255 return;
1258 if (verbosity > 0)
1259 fprintf (file, "# Statement body is provided\n");
1260 fprintf (file, "1\n");
1262 if (verbosity > 0)
1263 fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
1265 if (verbosity > 0)
1266 fprintf (file, "# Statement body\n");
1268 fprintf (file, "{\n");
1269 dump_bb (pbb_bb (pbb), file, 0);
1270 fprintf (file, "}\n");
1272 if (verbosity > 1)
1273 fprintf (file, "#)\n");
1276 /* Print to FILE the domain and scattering function of PBB, at some
1277 VERBOSITY level. */
1279 void
1280 print_pbb (FILE *file, poly_bb_p pbb, int verbosity)
1282 if (verbosity > 1)
1284 fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
1285 dump_gbb_conditions (file, PBB_BLACK_BOX (pbb));
1286 dump_gbb_cases (file, PBB_BLACK_BOX (pbb));
1289 openscop_print_pbb_domain (file, pbb, verbosity);
1290 print_scattering_function (file, pbb, verbosity);
1291 print_pdrs (file, pbb, verbosity);
1292 print_pbb_body (file, pbb, verbosity, false);
1294 if (verbosity > 1)
1295 fprintf (file, "#)\n");
1298 /* Print to FILE the parameters of SCOP, at some VERBOSITY level. */
1300 void
1301 print_scop_params (FILE *file, scop_p scop, int verbosity)
1303 int i;
1304 tree t;
1306 if (verbosity > 1)
1307 fprintf (file, "# parameters (\n");
1309 if (VEC_length (tree, SESE_PARAMS (SCOP_REGION (scop))))
1311 if (verbosity > 0)
1312 fprintf (file, "# Parameter names are provided\n");
1314 fprintf (file, "1\n");
1316 if (verbosity > 0)
1317 fprintf (file, "# Parameter names\n");
1319 else
1321 if (verbosity > 0)
1322 fprintf (file, "# Parameter names are not provided\n");
1323 fprintf (file, "0\n");
1326 for (i = 0; VEC_iterate (tree, SESE_PARAMS (SCOP_REGION (scop)), i, t); i++)
1328 print_generic_expr (file, t, 0);
1329 fprintf (file, " ");
1332 fprintf (file, "\n");
1334 if (verbosity > 1)
1335 fprintf (file, "#)\n");
1338 /* Print to FILE the context of SCoP in OpenScop format, at some VERBOSITY
1339 level. */
1341 static void
1342 openscop_print_scop_context (FILE *file, scop_p scop, int verbosity)
1344 graphite_dim_t i;
1346 if (verbosity > 0)
1348 fprintf (file, "# Context (\n");
1349 fprintf (file, "#eq");
1351 for (i = 0; i < scop_nb_params (scop); i++)
1352 fprintf (file, " p%d", (int) i);
1354 fprintf (file, " cst\n");
1357 if (SCOP_CONTEXT (scop))
1358 openscop_print_powerset_matrix (file, SCOP_CONTEXT (scop), 0, 0, 0,
1359 scop_nb_params (scop));
1360 else
1361 fprintf (file, "0 %d 0 0 0 %d\n", (int) scop_nb_params (scop) + 2,
1362 (int) scop_nb_params (scop));
1364 if (verbosity > 0)
1365 fprintf (file, "# )\n");
1368 /* Print to FILE the context of SCoP, at some VERBOSITY level. */
1370 void
1371 print_scop_context (FILE *file, scop_p scop, int verbosity)
1373 graphite_dim_t i;
1375 if (verbosity > 0)
1377 fprintf (file, "# Context (\n");
1378 fprintf (file, "#eq");
1380 for (i = 0; i < scop_nb_params (scop); i++)
1381 fprintf (file, " p%d", (int) i);
1383 fprintf (file, " cst\n");
1386 if (SCOP_CONTEXT (scop))
1387 ppl_print_powerset_matrix (file, SCOP_CONTEXT (scop));
1388 else
1389 fprintf (file, "0 %d\n", (int) scop_nb_params (scop) + 2);
1391 if (verbosity > 0)
1392 fprintf (file, "# )\n");
1395 /* Print to FILE the SCOP header: context, parameters, and statements
1396 number. */
1398 static void
1399 print_scop_header (FILE *file, scop_p scop, int verbosity)
1401 fprintf (file, "SCoP 1\n#(\n");
1402 fprintf (file, "# Language\nGimple\n");
1403 openscop_print_scop_context (file, scop, verbosity);
1404 print_scop_params (file, scop, verbosity);
1406 if (verbosity > 0)
1407 fprintf (file, "# Number of statements\n");
1409 fprintf (file, "%d\n",VEC_length (poly_bb_p, SCOP_BBS (scop)));
1412 /* Print to FILE the SCOP, at some VERBOSITY level. */
1414 void
1415 print_scop (FILE *file, scop_p scop, int verbosity)
1417 int i;
1418 poly_bb_p pbb;
1420 print_scop_header (file, scop, verbosity);
1422 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1423 print_pbb (file, pbb, verbosity);
1425 if (verbosity > 1)
1427 fprintf (file, "# original_lst (\n");
1428 print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0);
1429 fprintf (file, "\n#)\n");
1431 fprintf (file, "# transformed_lst (\n");
1432 print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
1433 fprintf (file, "\n#)\n");
1436 fprintf (file, "#)\n");
1439 /* Print to FILE the input file that CLooG would expect as input, at
1440 some VERBOSITY level. */
1442 void
1443 print_cloog (FILE *file, scop_p scop, int verbosity)
1445 int i;
1446 poly_bb_p pbb;
1448 fprintf (file, "# SCoP (generated by GCC/Graphite\n");
1449 if (verbosity > 0)
1450 fprintf (file, "# CLooG output language\n");
1451 fprintf (file, "c\n");
1453 print_scop_context (file, scop, verbosity);
1454 print_scop_params (file, scop, verbosity);
1456 if (verbosity > 0)
1457 fprintf (file, "# Number of statements\n");
1459 fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop)));
1461 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1463 if (verbosity > 1)
1464 fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
1466 print_pbb_domain (file, pbb, verbosity);
1467 fprintf (file, "0 0 0");
1469 if (verbosity > 0)
1470 fprintf (file, "# For future CLooG options.\n");
1471 else
1472 fprintf (file, "\n");
1474 if (verbosity > 1)
1475 fprintf (file, "#)\n");
1478 fprintf (file, "0");
1479 if (verbosity > 0)
1480 fprintf (file, "# Don't set the iterator names.\n");
1481 else
1482 fprintf (file, "\n");
1484 if (verbosity > 0)
1485 fprintf (file, "# Number of scattering functions\n");
1487 fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop)));
1488 unify_scattering_dimensions (scop);
1490 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1492 if (!PBB_TRANSFORMED (pbb)
1493 || !(PBB_TRANSFORMED_SCATTERING (pbb)
1494 || PBB_ORIGINAL_SCATTERING (pbb)))
1495 continue;
1497 if (verbosity > 1)
1498 fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
1500 print_scattering_function_1 (file, pbb, verbosity);
1502 if (verbosity > 1)
1503 fprintf (file, "#)\n");
1506 fprintf (file, "0");
1507 if (verbosity > 0)
1508 fprintf (file, "# Don't set the scattering dimension names.\n");
1509 else
1510 fprintf (file, "\n");
1512 fprintf (file, "#)\n");
1515 /* Print to STDERR the domain of PBB, at some VERBOSITY level. */
1517 DEBUG_FUNCTION void
1518 debug_pbb_domain (poly_bb_p pbb, int verbosity)
1520 print_pbb_domain (stderr, pbb, verbosity);
1523 /* Print to FILE the domain and scattering function of PBB, at some
1524 VERBOSITY level. */
1526 DEBUG_FUNCTION void
1527 debug_pbb (poly_bb_p pbb, int verbosity)
1529 print_pbb (stderr, pbb, verbosity);
1532 /* Print to STDERR the context of SCOP, at some VERBOSITY level. */
1534 DEBUG_FUNCTION void
1535 debug_scop_context (scop_p scop, int verbosity)
1537 print_scop_context (stderr, scop, verbosity);
1540 /* Print to STDERR the SCOP, at some VERBOSITY level. */
1542 DEBUG_FUNCTION void
1543 debug_scop (scop_p scop, int verbosity)
1545 print_scop (stderr, scop, verbosity);
1548 /* Print to STDERR the SCOP under CLooG format, at some VERBOSITY
1549 level. */
1551 DEBUG_FUNCTION void
1552 debug_cloog (scop_p scop, int verbosity)
1554 print_cloog (stderr, scop, verbosity);
1557 /* Print to STDERR the parameters of SCOP, at some VERBOSITY
1558 level. */
1560 DEBUG_FUNCTION void
1561 debug_scop_params (scop_p scop, int verbosity)
1563 print_scop_params (stderr, scop, verbosity);
1567 /* The dimension in the transformed scattering polyhedron of PBB
1568 containing the scattering iterator for the loop at depth LOOP_DEPTH. */
1570 ppl_dimension_type
1571 psct_scattering_dim_for_loop_depth (poly_bb_p pbb, graphite_dim_t loop_depth)
1573 ppl_const_Constraint_System_t pcs;
1574 ppl_Constraint_System_const_iterator_t cit, cend;
1575 ppl_const_Constraint_t cstr;
1576 ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb);
1577 ppl_dimension_type iter = psct_iterator_dim (pbb, loop_depth);
1578 ppl_Linear_Expression_t expr;
1579 ppl_Coefficient_t coef;
1580 mpz_t val;
1581 graphite_dim_t i;
1583 mpz_init (val);
1584 ppl_new_Coefficient (&coef);
1585 ppl_Polyhedron_get_constraints (ph, &pcs);
1586 ppl_new_Constraint_System_const_iterator (&cit);
1587 ppl_new_Constraint_System_const_iterator (&cend);
1589 for (ppl_Constraint_System_begin (pcs, cit),
1590 ppl_Constraint_System_end (pcs, cend);
1591 !ppl_Constraint_System_const_iterator_equal_test (cit, cend);
1592 ppl_Constraint_System_const_iterator_increment (cit))
1594 ppl_Constraint_System_const_iterator_dereference (cit, &cstr);
1595 ppl_new_Linear_Expression_from_Constraint (&expr, cstr);
1596 ppl_Linear_Expression_coefficient (expr, iter, coef);
1597 ppl_Coefficient_to_mpz_t (coef, val);
1599 if (mpz_sgn (val) == 0)
1601 ppl_delete_Linear_Expression (expr);
1602 continue;
1605 for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
1607 ppl_dimension_type scatter = psct_scattering_dim (pbb, i);
1609 ppl_Linear_Expression_coefficient (expr, scatter, coef);
1610 ppl_Coefficient_to_mpz_t (coef, val);
1612 if (mpz_sgn (val) != 0)
1614 mpz_clear (val);
1615 ppl_delete_Linear_Expression (expr);
1616 ppl_delete_Coefficient (coef);
1617 ppl_delete_Constraint_System_const_iterator (cit);
1618 ppl_delete_Constraint_System_const_iterator (cend);
1620 return scatter;
1625 gcc_unreachable ();
1628 /* Returns the number of iterations NITER of the loop around PBB at
1629 depth LOOP_DEPTH. */
1631 void
1632 pbb_number_of_iterations (poly_bb_p pbb,
1633 graphite_dim_t loop_depth,
1634 mpz_t niter)
1636 ppl_Linear_Expression_t le;
1637 ppl_dimension_type dim;
1639 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), &dim);
1640 ppl_new_Linear_Expression_with_dimension (&le, dim);
1641 ppl_set_coef (le, pbb_iterator_dim (pbb, loop_depth), 1);
1642 mpz_set_si (niter, -1);
1643 ppl_max_for_le_pointset (PBB_DOMAIN (pbb), le, niter);
1644 ppl_delete_Linear_Expression (le);
1647 /* Returns the number of iterations NITER of the loop around PBB at
1648 time(scattering) dimension TIME_DEPTH. */
1650 void
1651 pbb_number_of_iterations_at_time (poly_bb_p pbb,
1652 graphite_dim_t time_depth,
1653 mpz_t niter)
1655 ppl_Pointset_Powerset_C_Polyhedron_t ext_domain, sctr;
1656 ppl_Linear_Expression_t le;
1657 ppl_dimension_type dim;
1659 /* Takes together domain and scattering polyhedrons, and composes
1660 them into the bigger polyhedron that has the following format:
1662 t0..t_{n-1} | l0..l_{nlcl-1} | i0..i_{niter-1} | g0..g_{nparm-1}
1664 where
1665 | t0..t_{n-1} are time dimensions (scattering dimensions)
1666 | l0..l_{nclc-1} are local variables in scattering function
1667 | i0..i_{niter-1} are original iteration variables
1668 | g0..g_{nparam-1} are global parameters. */
1670 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&sctr,
1671 PBB_TRANSFORMED_SCATTERING (pbb));
1673 /* Extend the iteration domain with the scattering dimensions:
1674 0..0 | 0..0 | i0..i_{niter-1} | g0..g_{nparm-1}. */
1675 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1676 (&ext_domain, PBB_DOMAIN (pbb));
1677 ppl_insert_dimensions_pointset (ext_domain, 0,
1678 pbb_nb_scattering_transform (pbb)
1679 + pbb_nb_local_vars (pbb));
1681 /* Add to sctr the extended domain. */
1682 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr, ext_domain);
1684 /* Extract the number of iterations. */
1685 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (sctr, &dim);
1686 ppl_new_Linear_Expression_with_dimension (&le, dim);
1687 ppl_set_coef (le, time_depth, 1);
1688 mpz_set_si (niter, -1);
1689 ppl_max_for_le_pointset (sctr, le, niter);
1691 ppl_delete_Linear_Expression (le);
1692 ppl_delete_Pointset_Powerset_C_Polyhedron (sctr);
1693 ppl_delete_Pointset_Powerset_C_Polyhedron (ext_domain);
1696 /* Translates LOOP to LST. */
1698 static lst_p
1699 loop_to_lst (loop_p loop, VEC (poly_bb_p, heap) *bbs, int *i)
1701 poly_bb_p pbb;
1702 VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1704 for (; VEC_iterate (poly_bb_p, bbs, *i, pbb); (*i)++)
1706 lst_p stmt;
1707 basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb));
1709 if (bb->loop_father == loop)
1710 stmt = new_lst_stmt (pbb);
1711 else if (flow_bb_inside_loop_p (loop, bb))
1713 loop_p next = loop->inner;
1715 while (next && !flow_bb_inside_loop_p (next, bb))
1716 next = next->next;
1718 stmt = loop_to_lst (next, bbs, i);
1720 else
1722 (*i)--;
1723 return new_lst_loop (seq);
1726 VEC_safe_push (lst_p, heap, seq, stmt);
1729 return new_lst_loop (seq);
1732 /* Reads the original scattering of the SCOP and returns an LST
1733 representing it. */
1735 void
1736 scop_to_lst (scop_p scop)
1738 lst_p res;
1739 int i, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
1740 VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1741 sese region = SCOP_REGION (scop);
1743 for (i = 0; i < n; i++)
1745 poly_bb_p pbb = VEC_index (poly_bb_p, SCOP_BBS (scop), i);
1746 loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb)));
1748 if (loop_in_sese_p (loop, region))
1749 res = loop_to_lst (loop, SCOP_BBS (scop), &i);
1750 else
1751 res = new_lst_stmt (pbb);
1753 VEC_safe_push (lst_p, heap, seq, res);
1756 res = new_lst_loop (seq);
1757 SCOP_ORIGINAL_SCHEDULE (scop) = res;
1758 SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res);
1761 /* Print to FILE on a new line COLUMN white spaces. */
1763 static void
1764 lst_indent_to (FILE *file, int column)
1766 int i;
1768 if (column > 0)
1769 fprintf (file, "\n#");
1771 for (i = 0; i < column; i++)
1772 fprintf (file, " ");
1775 /* Print LST to FILE with INDENT spaces of indentation. */
1777 void
1778 print_lst (FILE *file, lst_p lst, int indent)
1780 if (!lst)
1781 return;
1783 lst_indent_to (file, indent);
1785 if (LST_LOOP_P (lst))
1787 int i;
1788 lst_p l;
1790 if (LST_LOOP_FATHER (lst))
1791 fprintf (file, "%d (loop", lst_dewey_number (lst));
1792 else
1793 fprintf (file, "#(root");
1795 for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
1796 print_lst (file, l, indent + 2);
1798 fprintf (file, ")");
1800 else
1801 fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst)));
1804 /* Print LST to STDERR. */
1806 DEBUG_FUNCTION void
1807 debug_lst (lst_p lst)
1809 print_lst (stderr, lst, 0);
1812 /* Pretty print to FILE the loop statement tree LST in DOT format. */
1814 static void
1815 dot_lst_1 (FILE *file, lst_p lst)
1817 if (!lst)
1818 return;
1820 if (LST_LOOP_P (lst))
1822 int i;
1823 lst_p l;
1825 if (!LST_LOOP_FATHER (lst))
1826 fprintf (file, "L -> L_%d_%d\n",
1827 lst_depth (lst),
1828 lst_dewey_number (lst));
1829 else
1830 fprintf (file, "L_%d_%d -> L_%d_%d\n",
1831 lst_depth (LST_LOOP_FATHER (lst)),
1832 lst_dewey_number (LST_LOOP_FATHER (lst)),
1833 lst_depth (lst),
1834 lst_dewey_number (lst));
1836 for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
1837 dot_lst_1 (file, l);
1840 else
1841 fprintf (file, "L_%d_%d -> S_%d\n",
1842 lst_depth (LST_LOOP_FATHER (lst)),
1843 lst_dewey_number (LST_LOOP_FATHER (lst)),
1844 pbb_index (LST_PBB (lst)));
1848 /* Display the LST using dotty. */
1850 void
1851 dot_lst (lst_p lst)
1853 /* When debugging, enable the following code. This cannot be used
1854 in production compilers because it calls "system". */
1855 #if 1
1856 FILE *stream = fopen ("/tmp/lst.dot", "w");
1857 gcc_assert (stream);
1859 fputs ("digraph all {\n", stream);
1860 dot_lst_1 (stream, lst);
1861 fputs ("}\n\n", stream);
1862 fclose (stream);
1864 system ("dotty /tmp/lst.dot &");
1865 #else
1866 fputs ("digraph all {\n", stderr);
1867 dot_lst_1 (stderr, lst);
1868 fputs ("}\n\n", stderr);
1870 #endif
1873 #endif