Daily bump.
[gcc.git] / gcc / graphite-poly.c
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>.
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"
24 #include "diagnostic-core.h"
25 #include "tree-flow.h"
26 #include "tree-dump.h"
27 #include "gimple-pretty-print.h"
28 #include "cfgloop.h"
29 #include "tree-chrec.h"
30 #include "tree-data-ref.h"
31 #include "tree-scalar-evolution.h"
32 #include "sese.h"
33
34 #ifdef HAVE_cloog
35 #include "ppl_c.h"
36 #include "graphite-ppl.h"
37 #include "graphite-poly.h"
38 #include "graphite-dependences.h"
39 #include "graphite-cloog-util.h"
40
41 #define OPENSCOP_MAX_STRING 256
42
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
52 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
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;
71 mpz_t one;
72
73 nb_added_dims = max_scattering - pbb_nb_scattering_transform (pbb);
74 mpz_init (one);
75 mpz_set_si (one, 1);
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);
104 mpz_clear (one);
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
117 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
118 max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering);
119
120 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
121 extend_scattering (pbb, max_scattering);
122
123 return max_scattering;
124 }
125
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
141 ppl_new_C_Polyhedron_from_C_Polyhedron (&pph, ph);
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
160 openscop_print_polyhedron_matrix (file, pph, output, input, locals, nb_params);
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));
244 fprintf (file, "#eq");
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
279 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
280 level. */
281
282 static void
283 print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
284 {
285 graphite_dim_t i;
286
287 if (verbosity > 0)
288 {
289 fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
290 fprintf (file, "#eq");
291
292 for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
293 fprintf (file, " s%d", (int) i);
294
295 for (i = 0; i < pbb_nb_local_vars (pbb); i++)
296 fprintf (file, " lv%d", (int) i);
297
298 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
299 fprintf (file, " i%d", (int) i);
300
301 for (i = 0; i < pbb_nb_params (pbb); i++)
302 fprintf (file, " p%d", (int) i);
303
304 fprintf (file, " cst\n");
305 }
306
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));
313
314 if (verbosity > 0)
315 fprintf (file, "#)\n");
316 }
317
318 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
319 level. */
320
321 void
322 print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity)
323 {
324 if (!PBB_TRANSFORMED (pbb))
325 return;
326
327 if (PBB_TRANSFORMED_SCATTERING (pbb)
328 || PBB_ORIGINAL_SCATTERING (pbb))
329 {
330 if (verbosity > 0)
331 fprintf (file, "# Scattering function is provided\n");
332
333 fprintf (file, "1\n");
334 }
335 else
336 {
337 if (verbosity > 0)
338 fprintf (file, "# Scattering function is not provided\n");
339
340 fprintf (file, "0\n");
341 return;
342 }
343
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
351 }
352
353 /* Prints to FILE the iteration domain of PBB, at some VERBOSITY
354 level. */
355
356 void
357 print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity)
358 {
359 print_pbb_domain (file, pbb, verbosity);
360 }
361
362 /* Prints to FILE the scattering functions of every PBB of SCOP. */
363
364 void
365 print_scattering_functions (FILE *file, scop_p scop, int verbosity)
366 {
367 int i;
368 poly_bb_p pbb;
369
370 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
371 print_scattering_function (file, pbb, verbosity);
372 }
373
374 /* Prints to FILE the iteration domains of every PBB of SCOP, at some
375 VERBOSITY level. */
376
377 void
378 print_iteration_domains (FILE *file, scop_p scop, int verbosity)
379 {
380 int i;
381 poly_bb_p pbb;
382
383 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
384 print_iteration_domain (file, pbb, verbosity);
385 }
386
387 /* Prints to STDERR the scattering function of PBB, at some VERBOSITY
388 level. */
389
390 DEBUG_FUNCTION void
391 debug_scattering_function (poly_bb_p pbb, int verbosity)
392 {
393 print_scattering_function (stderr, pbb, verbosity);
394 }
395
396 /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY
397 level. */
398
399 DEBUG_FUNCTION void
400 debug_iteration_domain (poly_bb_p pbb, int verbosity)
401 {
402 print_iteration_domain (stderr, pbb, verbosity);
403 }
404
405 /* Prints to STDERR the scattering functions of every PBB of SCOP, at
406 some VERBOSITY level. */
407
408 DEBUG_FUNCTION void
409 debug_scattering_functions (scop_p scop, int verbosity)
410 {
411 print_scattering_functions (stderr, scop, verbosity);
412 }
413
414 /* Prints to STDERR the iteration domains of every PBB of SCOP, at
415 some VERBOSITY level. */
416
417 DEBUG_FUNCTION void
418 debug_iteration_domains (scop_p scop, int verbosity)
419 {
420 print_iteration_domains (stderr, scop, verbosity);
421 }
422
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, &params);
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;
586 bool transform_done = false;
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 {
593 error ("the file is not in OpenScop format");
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 {
604 error ("the language is not recognized");
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, &params);
612
613 if ((size_t) params != scop->nb_params)
614 {
615 error ("parameters number in the scop file is different from the"
616 " internal scop parameter number");
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 {
628 error ("number of statements in the OpenScop file does not match"
629 " the graphite internal statements number");
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 &params);
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 &params);
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 &params);
661 }
662
663 /* Statement body. */
664 openscop_read_one_int (file);
665 }
666
667 return transform_done;
668 }
669
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
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;
732 FILE *graphite_file;
733 static size_t file_scop_number = 0;
734
735 /* This feature is only enabled in the Graphite branch. */
736 if (0)
737 {
738 graphite_file = init_graphite_in_file (file_scop_number);
739 transform_done |= graphite_read_scop_file (graphite_file, scop);
740
741 /* We cannot check for the legality of the transform here: there
742 are cases where graphite_legal_transform cannot determine the
743 dependence at compile time. For an example, see the
744 explanation of why http://gcc.gnu.org/PR45450 is invalid. */
745 if (0 && !graphite_legal_transform (scop))
746 fatal_error ("the graphite file read for scop %d does not contain a legal transform",
747 (int) file_scop_number);
748
749 file_scop_number++;
750 }
751
752 /* Generate code even if we did not apply any real transformation.
753 This also allows to check the performance for the identity
754 transformation: GIMPLE -> GRAPHITE -> GIMPLE
755 Keep in mind that CLooG optimizes in control, so the loop structure
756 may change, even if we only use -fgraphite-identity. */
757 if (flag_graphite_identity)
758 transform_done = true;
759
760 if (flag_loop_parallelize_all)
761 transform_done = true;
762
763 if (flag_loop_block)
764 transform_done |= scop_do_block (scop);
765 else
766 {
767 if (flag_loop_strip_mine)
768 transform_done |= scop_do_strip_mine (scop, 0);
769
770 if (flag_loop_interchange)
771 transform_done |= scop_do_interchange (scop);
772 }
773
774 /* This feature is only enabled in the Graphite branch. */
775 if (0)
776 {
777 graphite_file = init_graphite_out_file (file_scop_number);
778 print_scop (graphite_file, scop, 1);
779 file_scop_number++;
780 }
781
782 return transform_done;
783 }
784
785 /* Returns true when it PDR1 is a duplicate of PDR2: same PBB, and
786 their ACCESSES, TYPE, and NB_SUBSCRIPTS are the same. */
787
788 static inline bool
789 can_collapse_pdrs (poly_dr_p pdr1, poly_dr_p pdr2)
790 {
791 bool res;
792 ppl_Pointset_Powerset_C_Polyhedron_t af1, af2, diff;
793
794 if (PDR_PBB (pdr1) != PDR_PBB (pdr2)
795 || PDR_NB_SUBSCRIPTS (pdr1) != PDR_NB_SUBSCRIPTS (pdr2)
796 || PDR_TYPE (pdr1) != PDR_TYPE (pdr2))
797 return false;
798
799 af1 = PDR_ACCESSES (pdr1);
800 af2 = PDR_ACCESSES (pdr2);
801 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
802 (&diff, af1);
803 ppl_Pointset_Powerset_C_Polyhedron_difference_assign (diff, af2);
804
805 res = ppl_Pointset_Powerset_C_Polyhedron_is_empty (diff);
806 ppl_delete_Pointset_Powerset_C_Polyhedron (diff);
807 return res;
808 }
809
810 /* Removes duplicated data references in PBB. */
811
812 void
813 pbb_remove_duplicate_pdrs (poly_bb_p pbb)
814 {
815 int i, j;
816 poly_dr_p pdr1, pdr2;
817
818 FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr1)
819 for (j = i + 1; VEC_iterate (poly_dr_p, PBB_DRS (pbb), j, pdr2); j++)
820 if (can_collapse_pdrs (pdr1, pdr2))
821 {
822 PDR_NB_REFS (pdr1) += PDR_NB_REFS (pdr2);
823 free_poly_dr (pdr2);
824 VEC_ordered_remove (poly_dr_p, PBB_DRS (pbb), j);
825 }
826
827 PBB_PDR_DUPLICATES_REMOVED (pbb) = true;
828 }
829
830 /* Create a new polyhedral data reference and add it to PBB. It is
831 defined by its ACCESSES, its TYPE, and the number of subscripts
832 NB_SUBSCRIPTS. */
833
834 void
835 new_poly_dr (poly_bb_p pbb, int dr_base_object_set,
836 ppl_Pointset_Powerset_C_Polyhedron_t accesses,
837 enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts)
838 {
839 static int id = 0;
840 poly_dr_p pdr = XNEW (struct poly_dr);
841
842 PDR_ID (pdr) = id++;
843 PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set;
844 PDR_NB_REFS (pdr) = 1;
845 PDR_PBB (pdr) = pbb;
846 PDR_ACCESSES (pdr) = accesses;
847 PDR_TYPE (pdr) = type;
848 PDR_CDR (pdr) = cdr;
849 PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts;
850 VEC_safe_push (poly_dr_p, heap, PBB_DRS (pbb), pdr);
851 }
852
853 /* Free polyhedral data reference PDR. */
854
855 void
856 free_poly_dr (poly_dr_p pdr)
857 {
858 ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_ACCESSES (pdr));
859 XDELETE (pdr);
860 }
861
862 /* Create a new polyhedral black box. */
863
864 poly_bb_p
865 new_poly_bb (scop_p scop, void *black_box)
866 {
867 poly_bb_p pbb = XNEW (struct poly_bb);
868
869 PBB_DOMAIN (pbb) = NULL;
870 PBB_SCOP (pbb) = scop;
871 pbb_set_black_box (pbb, black_box);
872 PBB_TRANSFORMED (pbb) = NULL;
873 PBB_SAVED (pbb) = NULL;
874 PBB_ORIGINAL (pbb) = NULL;
875 PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3);
876 PBB_IS_REDUCTION (pbb) = false;
877 PBB_PDR_DUPLICATES_REMOVED (pbb) = false;
878 GBB_PBB ((gimple_bb_p) black_box) = pbb;
879
880 return pbb;
881 }
882
883 /* Free polyhedral black box. */
884
885 void
886 free_poly_bb (poly_bb_p pbb)
887 {
888 int i;
889 poly_dr_p pdr;
890
891 ppl_delete_Pointset_Powerset_C_Polyhedron (PBB_DOMAIN (pbb));
892
893 if (PBB_TRANSFORMED (pbb))
894 poly_scattering_free (PBB_TRANSFORMED (pbb));
895
896 if (PBB_SAVED (pbb))
897 poly_scattering_free (PBB_SAVED (pbb));
898
899 if (PBB_ORIGINAL (pbb))
900 poly_scattering_free (PBB_ORIGINAL (pbb));
901
902 if (PBB_DRS (pbb))
903 FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr)
904 free_poly_dr (pdr);
905
906 VEC_free (poly_dr_p, heap, PBB_DRS (pbb));
907 XDELETE (pbb);
908 }
909
910 static void
911 print_pdr_access_layout (FILE *file, poly_bb_p pbb, poly_dr_p pdr)
912 {
913 graphite_dim_t i;
914
915 fprintf (file, "# eq");
916
917 fprintf (file, " alias");
918
919 for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++)
920 fprintf (file, " sub%d", (int) i);
921
922 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
923 fprintf (file, " i%d", (int) i);
924
925 for (i = 0; i < pbb_nb_params (pbb); i++)
926 fprintf (file, " p%d", (int) i);
927
928 fprintf (file, " cst\n");
929 }
930
931 /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY
932 level. */
933
934 void
935 print_pdr (FILE *file, poly_dr_p pdr, int verbosity)
936 {
937 int alias_set_dim;
938
939 if (verbosity > 1)
940 {
941 fprintf (file, "# pdr_%d (", PDR_ID (pdr));
942
943 switch (PDR_TYPE (pdr))
944 {
945 case PDR_READ:
946 fprintf (file, "read \n");
947 break;
948
949 case PDR_WRITE:
950 fprintf (file, "write \n");
951 break;
952
953 case PDR_MAY_WRITE:
954 fprintf (file, "may_write \n");
955 break;
956
957 default:
958 gcc_unreachable ();
959 }
960
961 dump_data_reference (file, (data_reference_p) PDR_CDR (pdr));
962 }
963
964 if (verbosity > 0)
965 {
966 fprintf (file, "# data accesses (\n");
967 print_pdr_access_layout (file, PDR_PBB (pdr), pdr);
968 }
969
970 alias_set_dim = pdr_alias_set_dim (pdr) + 1;
971
972 openscop_print_pdr_powerset (file,
973 PDR_ACCESSES (pdr),
974 PDR_NB_SUBSCRIPTS (pdr),
975 alias_set_dim,
976 pbb_nb_params (PDR_PBB (pdr)));
977
978 if (verbosity > 0)
979 fprintf (file, "#)\n");
980
981 if (verbosity > 1)
982 fprintf (file, "#)\n");
983 }
984
985 /* Prints to STDERR the polyhedral data reference PDR, at some
986 VERBOSITY level. */
987
988 DEBUG_FUNCTION void
989 debug_pdr (poly_dr_p pdr, int verbosity)
990 {
991 print_pdr (stderr, pdr, verbosity);
992 }
993
994 /* Creates a new SCOP containing REGION. */
995
996 scop_p
997 new_scop (void *region)
998 {
999 scop_p scop = XNEW (struct scop);
1000
1001 SCOP_CONTEXT (scop) = NULL;
1002 scop_set_region (scop, region);
1003 SCOP_BBS (scop) = VEC_alloc (poly_bb_p, heap, 3);
1004 SCOP_ORIGINAL_PDDRS (scop) = htab_create (10, hash_poly_ddr_p,
1005 eq_poly_ddr_p, free_poly_ddr);
1006 SCOP_ORIGINAL_SCHEDULE (scop) = NULL;
1007 SCOP_TRANSFORMED_SCHEDULE (scop) = NULL;
1008 SCOP_SAVED_SCHEDULE (scop) = NULL;
1009 POLY_SCOP_P (scop) = false;
1010
1011 return scop;
1012 }
1013
1014 /* Deletes SCOP. */
1015
1016 void
1017 free_scop (scop_p scop)
1018 {
1019 int i;
1020 poly_bb_p pbb;
1021
1022 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1023 free_poly_bb (pbb);
1024
1025 VEC_free (poly_bb_p, heap, SCOP_BBS (scop));
1026
1027 if (SCOP_CONTEXT (scop))
1028 ppl_delete_Pointset_Powerset_C_Polyhedron (SCOP_CONTEXT (scop));
1029
1030 htab_delete (SCOP_ORIGINAL_PDDRS (scop));
1031 free_lst (SCOP_ORIGINAL_SCHEDULE (scop));
1032 free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
1033 free_lst (SCOP_SAVED_SCHEDULE (scop));
1034 XDELETE (scop);
1035 }
1036
1037 /* Print to FILE the domain of PBB in OpenScop format, at some VERBOSITY
1038 level. */
1039
1040 static void
1041 openscop_print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
1042 {
1043 graphite_dim_t i;
1044 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1045
1046 if (!PBB_DOMAIN (pbb))
1047 return;
1048
1049 if (verbosity > 0)
1050 {
1051 fprintf (file, "\n# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
1052 fprintf (file, "#eq");
1053
1054 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
1055 fprintf (file, " i%d", (int) i);
1056
1057 for (i = 0; i < pbb_nb_params (pbb); i++)
1058 fprintf (file, " p%d", (int) i);
1059
1060 fprintf (file, " cst\n");
1061 }
1062
1063 if (PBB_DOMAIN (pbb))
1064 openscop_print_powerset_matrix (file, PBB_DOMAIN (pbb),
1065 pbb_dim_iter_domain (pbb),
1066 0,
1067 0,
1068 pbb_nb_params (pbb));
1069 else
1070 fprintf (file, "0\n");
1071
1072 if (verbosity > 0)
1073 fprintf (file, "#)\n");
1074 }
1075
1076 /* Print to FILE the domain of PBB, at some VERBOSITY level. */
1077
1078 void
1079 print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
1080 {
1081 graphite_dim_t i;
1082 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1083
1084 if (!PBB_DOMAIN (pbb))
1085 return;
1086
1087 if (verbosity > 0)
1088 {
1089 fprintf (file, "# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
1090 fprintf (file, "# eq");
1091
1092 for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
1093 fprintf (file, " i%d", (int) i);
1094
1095 for (i = 0; i < pbb_nb_params (pbb); i++)
1096 fprintf (file, " p%d", (int) i);
1097
1098 fprintf (file, " cst\n");
1099 }
1100
1101 if (PBB_DOMAIN (pbb))
1102 ppl_print_powerset_matrix (file, PBB_DOMAIN (pbb));
1103 else
1104 fprintf (file, "0\n");
1105
1106 if (verbosity > 0)
1107 fprintf (file, "#)\n");
1108 }
1109
1110 /* Dump the cases of a graphite basic block GBB on FILE. */
1111
1112 static void
1113 dump_gbb_cases (FILE *file, gimple_bb_p gbb)
1114 {
1115 int i;
1116 gimple stmt;
1117 VEC (gimple, heap) *cases;
1118
1119 if (!gbb)
1120 return;
1121
1122 cases = GBB_CONDITION_CASES (gbb);
1123 if (VEC_empty (gimple, cases))
1124 return;
1125
1126 fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index);
1127
1128 FOR_EACH_VEC_ELT (gimple, cases, i, stmt)
1129 {
1130 fprintf (file, "# ");
1131 print_gimple_stmt (file, stmt, 0, 0);
1132 }
1133
1134 fprintf (file, "#)\n");
1135 }
1136
1137 /* Dump conditions of a graphite basic block GBB on FILE. */
1138
1139 static void
1140 dump_gbb_conditions (FILE *file, gimple_bb_p gbb)
1141 {
1142 int i;
1143 gimple stmt;
1144 VEC (gimple, heap) *conditions;
1145
1146 if (!gbb)
1147 return;
1148
1149 conditions = GBB_CONDITIONS (gbb);
1150 if (VEC_empty (gimple, conditions))
1151 return;
1152
1153 fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index);
1154
1155 FOR_EACH_VEC_ELT (gimple, conditions, i, stmt)
1156 {
1157 fprintf (file, "# ");
1158 print_gimple_stmt (file, stmt, 0, 0);
1159 }
1160
1161 fprintf (file, "#)\n");
1162 }
1163
1164 /* Print to FILE all the data references of PBB, at some VERBOSITY
1165 level. */
1166
1167 void
1168 print_pdrs (FILE *file, poly_bb_p pbb, int verbosity)
1169 {
1170 int i;
1171 poly_dr_p pdr;
1172 int nb_reads = 0;
1173 int nb_writes = 0;
1174
1175 if (VEC_length (poly_dr_p, PBB_DRS (pbb)) == 0)
1176 {
1177 if (verbosity > 0)
1178 fprintf (file, "# Access informations are not provided\n");\
1179 fprintf (file, "0\n");
1180 return;
1181 }
1182
1183 if (verbosity > 1)
1184 fprintf (file, "# Data references (\n");
1185
1186 if (verbosity > 0)
1187 fprintf (file, "# Access informations are provided\n");
1188 fprintf (file, "1\n");
1189
1190 FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr)
1191 if (PDR_TYPE (pdr) == PDR_READ)
1192 nb_reads++;
1193 else
1194 nb_writes++;
1195
1196 if (verbosity > 1)
1197 fprintf (file, "# Read data references (\n");
1198
1199 if (verbosity > 0)
1200 fprintf (file, "# Read access informations\n");
1201 fprintf (file, "%d\n", nb_reads);
1202
1203 FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr)
1204 if (PDR_TYPE (pdr) == PDR_READ)
1205 print_pdr (file, pdr, verbosity);
1206
1207 if (verbosity > 1)
1208 fprintf (file, "#)\n");
1209
1210 if (verbosity > 1)
1211 fprintf (file, "# Write data references (\n");
1212
1213 if (verbosity > 0)
1214 fprintf (file, "# Write access informations\n");
1215 fprintf (file, "%d\n", nb_writes);
1216
1217 FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb), i, pdr)
1218 if (PDR_TYPE (pdr) != PDR_READ)
1219 print_pdr (file, pdr, verbosity);
1220
1221 if (verbosity > 1)
1222 fprintf (file, "#)\n");
1223
1224 if (verbosity > 1)
1225 fprintf (file, "#)\n");
1226 }
1227
1228 /* Print to STDERR all the data references of PBB. */
1229
1230 DEBUG_FUNCTION void
1231 debug_pdrs (poly_bb_p pbb, int verbosity)
1232 {
1233 print_pdrs (stderr, pbb, verbosity);
1234 }
1235
1236 /* Print to FILE the body of PBB, at some VERBOSITY level.
1237 If statement_body_provided is false statement body is not printed. */
1238
1239 static void
1240 print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity,
1241 bool statement_body_provided)
1242 {
1243 if (verbosity > 1)
1244 fprintf (file, "# Body (\n");
1245
1246 if (!statement_body_provided)
1247 {
1248 if (verbosity > 0)
1249 fprintf (file, "# Statement body is not provided\n");
1250
1251 fprintf (file, "0\n");
1252
1253 if (verbosity > 1)
1254 fprintf (file, "#)\n");
1255 return;
1256 }
1257
1258 if (verbosity > 0)
1259 fprintf (file, "# Statement body is provided\n");
1260 fprintf (file, "1\n");
1261
1262 if (verbosity > 0)
1263 fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
1264
1265 if (verbosity > 0)
1266 fprintf (file, "# Statement body\n");
1267
1268 fprintf (file, "{\n");
1269 dump_bb (pbb_bb (pbb), file, 0);
1270 fprintf (file, "}\n");
1271
1272 if (verbosity > 1)
1273 fprintf (file, "#)\n");
1274 }
1275
1276 /* Print to FILE the domain and scattering function of PBB, at some
1277 VERBOSITY level. */
1278
1279 void
1280 print_pbb (FILE *file, poly_bb_p pbb, int verbosity)
1281 {
1282 if (verbosity > 1)
1283 {
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));
1287 }
1288
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);
1293
1294 if (verbosity > 1)
1295 fprintf (file, "#)\n");
1296 }
1297
1298 /* Print to FILE the parameters of SCOP, at some VERBOSITY level. */
1299
1300 void
1301 print_scop_params (FILE *file, scop_p scop, int verbosity)
1302 {
1303 int i;
1304 tree t;
1305
1306 if (verbosity > 1)
1307 fprintf (file, "# parameters (\n");
1308
1309 if (VEC_length (tree, SESE_PARAMS (SCOP_REGION (scop))))
1310 {
1311 if (verbosity > 0)
1312 fprintf (file, "# Parameter names are provided\n");
1313
1314 fprintf (file, "1\n");
1315
1316 if (verbosity > 0)
1317 fprintf (file, "# Parameter names\n");
1318 }
1319 else
1320 {
1321 if (verbosity > 0)
1322 fprintf (file, "# Parameter names are not provided\n");
1323 fprintf (file, "0\n");
1324 }
1325
1326 FOR_EACH_VEC_ELT (tree, SESE_PARAMS (SCOP_REGION (scop)), i, t)
1327 {
1328 print_generic_expr (file, t, 0);
1329 fprintf (file, " ");
1330 }
1331
1332 fprintf (file, "\n");
1333
1334 if (verbosity > 1)
1335 fprintf (file, "#)\n");
1336 }
1337
1338 /* Print to FILE the context of SCoP in OpenScop format, at some VERBOSITY
1339 level. */
1340
1341 static void
1342 openscop_print_scop_context (FILE *file, scop_p scop, int verbosity)
1343 {
1344 graphite_dim_t i;
1345
1346 if (verbosity > 0)
1347 {
1348 fprintf (file, "# Context (\n");
1349 fprintf (file, "#eq");
1350
1351 for (i = 0; i < scop_nb_params (scop); i++)
1352 fprintf (file, " p%d", (int) i);
1353
1354 fprintf (file, " cst\n");
1355 }
1356
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));
1363
1364 if (verbosity > 0)
1365 fprintf (file, "# )\n");
1366 }
1367
1368 /* Print to FILE the context of SCoP, at some VERBOSITY level. */
1369
1370 void
1371 print_scop_context (FILE *file, scop_p scop, int verbosity)
1372 {
1373 graphite_dim_t i;
1374
1375 if (verbosity > 0)
1376 {
1377 fprintf (file, "# Context (\n");
1378 fprintf (file, "#eq");
1379
1380 for (i = 0; i < scop_nb_params (scop); i++)
1381 fprintf (file, " p%d", (int) i);
1382
1383 fprintf (file, " cst\n");
1384 }
1385
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);
1390
1391 if (verbosity > 0)
1392 fprintf (file, "# )\n");
1393 }
1394
1395 /* Print to FILE the SCOP, at some VERBOSITY level. */
1396
1397 void
1398 print_scop (FILE *file, scop_p scop, int verbosity)
1399 {
1400 int i;
1401 poly_bb_p pbb;
1402
1403 fprintf (file, "SCoP 1\n#(\n");
1404 fprintf (file, "# Language\nGimple\n");
1405 openscop_print_scop_context (file, scop, verbosity);
1406 print_scop_params (file, scop, verbosity);
1407
1408 if (verbosity > 0)
1409 fprintf (file, "# Number of statements\n");
1410
1411 fprintf (file, "%d\n",VEC_length (poly_bb_p, SCOP_BBS (scop)));
1412
1413 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1414 print_pbb (file, pbb, verbosity);
1415
1416 if (verbosity > 1)
1417 {
1418 fprintf (file, "# original_lst (\n");
1419 print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0);
1420 fprintf (file, "\n#)\n");
1421
1422 fprintf (file, "# transformed_lst (\n");
1423 print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
1424 fprintf (file, "\n#)\n");
1425 }
1426
1427 fprintf (file, "#)\n");
1428 }
1429
1430 /* Print to FILE the input file that CLooG would expect as input, at
1431 some VERBOSITY level. */
1432
1433 void
1434 print_cloog (FILE *file, scop_p scop, int verbosity)
1435 {
1436 int i;
1437 poly_bb_p pbb;
1438
1439 fprintf (file, "# SCoP (generated by GCC/Graphite\n");
1440 if (verbosity > 0)
1441 fprintf (file, "# CLooG output language\n");
1442 fprintf (file, "c\n");
1443
1444 print_scop_context (file, scop, verbosity);
1445 print_scop_params (file, scop, verbosity);
1446
1447 if (verbosity > 0)
1448 fprintf (file, "# Number of statements\n");
1449
1450 fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop)));
1451
1452 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1453 {
1454 if (verbosity > 1)
1455 fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
1456
1457 print_pbb_domain (file, pbb, verbosity);
1458 fprintf (file, "0 0 0");
1459
1460 if (verbosity > 0)
1461 fprintf (file, "# For future CLooG options.\n");
1462 else
1463 fprintf (file, "\n");
1464
1465 if (verbosity > 1)
1466 fprintf (file, "#)\n");
1467 }
1468
1469 fprintf (file, "0");
1470 if (verbosity > 0)
1471 fprintf (file, "# Don't set the iterator names.\n");
1472 else
1473 fprintf (file, "\n");
1474
1475 if (verbosity > 0)
1476 fprintf (file, "# Number of scattering functions\n");
1477
1478 fprintf (file, "%d\n", VEC_length (poly_bb_p, SCOP_BBS (scop)));
1479 unify_scattering_dimensions (scop);
1480
1481 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1482 {
1483 if (!PBB_TRANSFORMED (pbb)
1484 || !(PBB_TRANSFORMED_SCATTERING (pbb)
1485 || PBB_ORIGINAL_SCATTERING (pbb)))
1486 continue;
1487
1488 if (verbosity > 1)
1489 fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
1490
1491 print_scattering_function_1 (file, pbb, verbosity);
1492
1493 if (verbosity > 1)
1494 fprintf (file, "#)\n");
1495 }
1496
1497 fprintf (file, "0");
1498 if (verbosity > 0)
1499 fprintf (file, "# Don't set the scattering dimension names.\n");
1500 else
1501 fprintf (file, "\n");
1502
1503 fprintf (file, "#)\n");
1504 }
1505
1506 /* Print to STDERR the domain of PBB, at some VERBOSITY level. */
1507
1508 DEBUG_FUNCTION void
1509 debug_pbb_domain (poly_bb_p pbb, int verbosity)
1510 {
1511 print_pbb_domain (stderr, pbb, verbosity);
1512 }
1513
1514 /* Print to FILE the domain and scattering function of PBB, at some
1515 VERBOSITY level. */
1516
1517 DEBUG_FUNCTION void
1518 debug_pbb (poly_bb_p pbb, int verbosity)
1519 {
1520 print_pbb (stderr, pbb, verbosity);
1521 }
1522
1523 /* Print to STDERR the context of SCOP, at some VERBOSITY level. */
1524
1525 DEBUG_FUNCTION void
1526 debug_scop_context (scop_p scop, int verbosity)
1527 {
1528 print_scop_context (stderr, scop, verbosity);
1529 }
1530
1531 /* Print to STDERR the SCOP, at some VERBOSITY level. */
1532
1533 DEBUG_FUNCTION void
1534 debug_scop (scop_p scop, int verbosity)
1535 {
1536 print_scop (stderr, scop, verbosity);
1537 }
1538
1539 /* Print to STDERR the SCOP under CLooG format, at some VERBOSITY
1540 level. */
1541
1542 DEBUG_FUNCTION void
1543 debug_cloog (scop_p scop, int verbosity)
1544 {
1545 print_cloog (stderr, scop, verbosity);
1546 }
1547
1548 /* Print to STDERR the parameters of SCOP, at some VERBOSITY
1549 level. */
1550
1551 DEBUG_FUNCTION void
1552 debug_scop_params (scop_p scop, int verbosity)
1553 {
1554 print_scop_params (stderr, scop, verbosity);
1555 }
1556
1557
1558 /* The dimension in the transformed scattering polyhedron of PBB
1559 containing the scattering iterator for the loop at depth LOOP_DEPTH. */
1560
1561 ppl_dimension_type
1562 psct_scattering_dim_for_loop_depth (poly_bb_p pbb, graphite_dim_t loop_depth)
1563 {
1564 ppl_const_Constraint_System_t pcs;
1565 ppl_Constraint_System_const_iterator_t cit, cend;
1566 ppl_const_Constraint_t cstr;
1567 ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb);
1568 ppl_dimension_type iter = psct_iterator_dim (pbb, loop_depth);
1569 ppl_Linear_Expression_t expr;
1570 ppl_Coefficient_t coef;
1571 mpz_t val;
1572 graphite_dim_t i;
1573
1574 mpz_init (val);
1575 ppl_new_Coefficient (&coef);
1576 ppl_Polyhedron_get_constraints (ph, &pcs);
1577 ppl_new_Constraint_System_const_iterator (&cit);
1578 ppl_new_Constraint_System_const_iterator (&cend);
1579
1580 for (ppl_Constraint_System_begin (pcs, cit),
1581 ppl_Constraint_System_end (pcs, cend);
1582 !ppl_Constraint_System_const_iterator_equal_test (cit, cend);
1583 ppl_Constraint_System_const_iterator_increment (cit))
1584 {
1585 ppl_Constraint_System_const_iterator_dereference (cit, &cstr);
1586 ppl_new_Linear_Expression_from_Constraint (&expr, cstr);
1587 ppl_Linear_Expression_coefficient (expr, iter, coef);
1588 ppl_Coefficient_to_mpz_t (coef, val);
1589
1590 if (mpz_sgn (val) == 0)
1591 {
1592 ppl_delete_Linear_Expression (expr);
1593 continue;
1594 }
1595
1596 for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
1597 {
1598 ppl_dimension_type scatter = psct_scattering_dim (pbb, i);
1599
1600 ppl_Linear_Expression_coefficient (expr, scatter, coef);
1601 ppl_Coefficient_to_mpz_t (coef, val);
1602
1603 if (mpz_sgn (val) != 0)
1604 {
1605 mpz_clear (val);
1606 ppl_delete_Linear_Expression (expr);
1607 ppl_delete_Coefficient (coef);
1608 ppl_delete_Constraint_System_const_iterator (cit);
1609 ppl_delete_Constraint_System_const_iterator (cend);
1610
1611 return scatter;
1612 }
1613 }
1614 }
1615
1616 gcc_unreachable ();
1617 }
1618
1619 /* Returns the number of iterations RES of the loop around PBB at
1620 time(scattering) dimension TIME_DEPTH. */
1621
1622 void
1623 pbb_number_of_iterations_at_time (poly_bb_p pbb,
1624 graphite_dim_t time_depth,
1625 mpz_t res)
1626 {
1627 ppl_Pointset_Powerset_C_Polyhedron_t domain, sctr_lb, sctr_ub;
1628 ppl_dimension_type domain_dim, sctr_dim;
1629 graphite_dim_t dim_iter_domain = pbb_dim_iter_domain (pbb);
1630 ppl_Linear_Expression_t le;
1631 mpz_t lb, ub, diff, one;
1632 int i;
1633
1634 ppl_Polyhedron_space_dimension (PBB_TRANSFORMED_SCATTERING (pbb), &sctr_dim);
1635
1636 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1637 (&domain, PBB_DOMAIN (pbb));
1638
1639 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (domain, &domain_dim);
1640
1641 mpz_init (diff);
1642 mpz_init (lb);
1643 mpz_init (ub);
1644 mpz_init (one);
1645 mpz_set_si (one, 1);
1646
1647 /* Compute the upper bound on the original iteration domain and add
1648 that upper bound to the scattering. */
1649 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1650 (&sctr_ub, PBB_TRANSFORMED_SCATTERING (pbb));
1651 for (i = 0; i < (int) dim_iter_domain; i++)
1652 {
1653 ppl_Linear_Expression_t eq;
1654 ppl_Constraint_t pc;
1655 ppl_Constraint_System_t cs;
1656 ppl_Polyhedron_t ph;
1657 ppl_Pointset_Powerset_C_Polyhedron_t pph;
1658
1659 ppl_new_Linear_Expression_with_dimension (&le, domain_dim);
1660 ppl_set_coef (le, i, 1);
1661 ppl_min_for_le_pointset (domain, le, lb);
1662 ppl_max_for_le_pointset (domain, le, ub);
1663 mpz_sub (diff, ub, lb);
1664 mpz_add (diff, diff, one);
1665
1666 ppl_new_Linear_Expression_with_dimension (&eq, sctr_dim);
1667 ppl_set_coef (eq, psct_iterator_dim (pbb, i), -1);
1668 ppl_set_inhomogeneous_gmp (eq, diff);
1669
1670 ppl_new_Constraint (&pc, eq, PPL_CONSTRAINT_TYPE_EQUAL);
1671 ppl_new_Constraint_System_from_Constraint (&cs, pc);
1672 ppl_new_C_Polyhedron_from_Constraint_System (&ph, cs);
1673 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&pph, ph);
1674 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr_ub, pph);
1675
1676 ppl_delete_Linear_Expression (le);
1677 ppl_delete_Linear_Expression (eq);
1678 ppl_delete_Polyhedron (ph);
1679 ppl_delete_Pointset_Powerset_C_Polyhedron (pph);
1680 ppl_delete_Constraint (pc);
1681 ppl_delete_Constraint_System (cs);
1682 }
1683
1684 /* Compute the lower bound on the original iteration domain and add
1685 it to the scattering. */
1686 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1687 (&sctr_lb, PBB_TRANSFORMED_SCATTERING (pbb));
1688 for (i = 0; i < (int) dim_iter_domain; i++)
1689 {
1690 ppl_Linear_Expression_t eq;
1691 ppl_Constraint_t pc;
1692 ppl_Constraint_System_t cs;
1693 ppl_Polyhedron_t ph;
1694 ppl_Pointset_Powerset_C_Polyhedron_t pph;
1695
1696 ppl_new_Linear_Expression_with_dimension (&le, domain_dim);
1697 ppl_set_coef (le, i, 1);
1698 ppl_min_for_le_pointset (domain, le, lb);
1699
1700 ppl_new_Linear_Expression_with_dimension (&eq, sctr_dim);
1701 ppl_set_coef (eq, psct_iterator_dim (pbb, i), -1);
1702 ppl_set_inhomogeneous_gmp (eq, lb);
1703
1704 ppl_new_Constraint (&pc, eq, PPL_CONSTRAINT_TYPE_EQUAL);
1705 ppl_new_Constraint_System_from_Constraint (&cs, pc);
1706 ppl_new_C_Polyhedron_from_Constraint_System (&ph, cs);
1707 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&pph, ph);
1708 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr_lb, pph);
1709
1710 ppl_delete_Linear_Expression (le);
1711 ppl_delete_Linear_Expression (eq);
1712 ppl_delete_Polyhedron (ph);
1713 ppl_delete_Pointset_Powerset_C_Polyhedron (pph);
1714 ppl_delete_Constraint (pc);
1715 ppl_delete_Constraint_System (cs);
1716 }
1717
1718 /* Extract the number of iterations. */
1719 ppl_new_Linear_Expression_with_dimension (&le, sctr_dim);
1720 ppl_set_coef (le, time_depth, 1);
1721 ppl_min_for_le_pointset (sctr_lb, le, lb);
1722 ppl_max_for_le_pointset (sctr_ub, le, ub);
1723 mpz_sub (res, ub, lb);
1724
1725 mpz_clear (one);
1726 mpz_clear (diff);
1727 mpz_clear (lb);
1728 mpz_clear (ub);
1729 ppl_delete_Linear_Expression (le);
1730 ppl_delete_Pointset_Powerset_C_Polyhedron (sctr_ub);
1731 ppl_delete_Pointset_Powerset_C_Polyhedron (sctr_lb);
1732 ppl_delete_Pointset_Powerset_C_Polyhedron (domain);
1733 }
1734
1735 /* Translates LOOP to LST. */
1736
1737 static lst_p
1738 loop_to_lst (loop_p loop, VEC (poly_bb_p, heap) *bbs, int *i)
1739 {
1740 poly_bb_p pbb;
1741 VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1742
1743 for (; VEC_iterate (poly_bb_p, bbs, *i, pbb); (*i)++)
1744 {
1745 lst_p stmt;
1746 basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb));
1747
1748 if (bb->loop_father == loop)
1749 stmt = new_lst_stmt (pbb);
1750 else if (flow_bb_inside_loop_p (loop, bb))
1751 {
1752 loop_p next = loop->inner;
1753
1754 while (next && !flow_bb_inside_loop_p (next, bb))
1755 next = next->next;
1756
1757 stmt = loop_to_lst (next, bbs, i);
1758 }
1759 else
1760 {
1761 (*i)--;
1762 return new_lst_loop (seq);
1763 }
1764
1765 VEC_safe_push (lst_p, heap, seq, stmt);
1766 }
1767
1768 return new_lst_loop (seq);
1769 }
1770
1771 /* Reads the original scattering of the SCOP and returns an LST
1772 representing it. */
1773
1774 void
1775 scop_to_lst (scop_p scop)
1776 {
1777 lst_p res;
1778 int i, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
1779 VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1780 sese region = SCOP_REGION (scop);
1781
1782 for (i = 0; i < n; i++)
1783 {
1784 poly_bb_p pbb = VEC_index (poly_bb_p, SCOP_BBS (scop), i);
1785 loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb)));
1786
1787 if (loop_in_sese_p (loop, region))
1788 res = loop_to_lst (loop, SCOP_BBS (scop), &i);
1789 else
1790 res = new_lst_stmt (pbb);
1791
1792 VEC_safe_push (lst_p, heap, seq, res);
1793 }
1794
1795 res = new_lst_loop (seq);
1796 SCOP_ORIGINAL_SCHEDULE (scop) = res;
1797 SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res);
1798 }
1799
1800 /* Print to FILE on a new line COLUMN white spaces. */
1801
1802 static void
1803 lst_indent_to (FILE *file, int column)
1804 {
1805 int i;
1806
1807 if (column > 0)
1808 fprintf (file, "\n#");
1809
1810 for (i = 0; i < column; i++)
1811 fprintf (file, " ");
1812 }
1813
1814 /* Print LST to FILE with INDENT spaces of indentation. */
1815
1816 void
1817 print_lst (FILE *file, lst_p lst, int indent)
1818 {
1819 if (!lst)
1820 return;
1821
1822 lst_indent_to (file, indent);
1823
1824 if (LST_LOOP_P (lst))
1825 {
1826 int i;
1827 lst_p l;
1828
1829 if (LST_LOOP_FATHER (lst))
1830 fprintf (file, "%d (loop", lst_dewey_number (lst));
1831 else
1832 fprintf (file, "#(root");
1833
1834 FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
1835 print_lst (file, l, indent + 2);
1836
1837 fprintf (file, ")");
1838 }
1839 else
1840 fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst)));
1841 }
1842
1843 /* Print LST to STDERR. */
1844
1845 DEBUG_FUNCTION void
1846 debug_lst (lst_p lst)
1847 {
1848 print_lst (stderr, lst, 0);
1849 }
1850
1851 /* Pretty print to FILE the loop statement tree LST in DOT format. */
1852
1853 static void
1854 dot_lst_1 (FILE *file, lst_p lst)
1855 {
1856 if (!lst)
1857 return;
1858
1859 if (LST_LOOP_P (lst))
1860 {
1861 int i;
1862 lst_p l;
1863
1864 if (!LST_LOOP_FATHER (lst))
1865 fprintf (file, "L -> L_%d_%d\n",
1866 lst_depth (lst),
1867 lst_dewey_number (lst));
1868 else
1869 fprintf (file, "L_%d_%d -> L_%d_%d\n",
1870 lst_depth (LST_LOOP_FATHER (lst)),
1871 lst_dewey_number (LST_LOOP_FATHER (lst)),
1872 lst_depth (lst),
1873 lst_dewey_number (lst));
1874
1875 FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
1876 dot_lst_1 (file, l);
1877 }
1878
1879 else
1880 fprintf (file, "L_%d_%d -> S_%d\n",
1881 lst_depth (LST_LOOP_FATHER (lst)),
1882 lst_dewey_number (LST_LOOP_FATHER (lst)),
1883 pbb_index (LST_PBB (lst)));
1884
1885 }
1886
1887 /* Display the LST using dotty. */
1888
1889 DEBUG_FUNCTION void
1890 dot_lst (lst_p lst)
1891 {
1892 /* When debugging, enable the following code. This cannot be used
1893 in production compilers because it calls "system". */
1894 #if 0
1895 FILE *stream = fopen ("/tmp/lst.dot", "w");
1896 gcc_assert (stream);
1897
1898 fputs ("digraph all {\n", stream);
1899 dot_lst_1 (stream, lst);
1900 fputs ("}\n\n", stream);
1901 fclose (stream);
1902
1903 system ("dotty /tmp/lst.dot &");
1904 #else
1905 fputs ("digraph all {\n", stderr);
1906 dot_lst_1 (stderr, lst);
1907 fputs ("}\n\n", stderr);
1908
1909 #endif
1910 }
1911
1912 /* Computes a checksum for the code generated by CLooG for SCOP. */
1913
1914 DEBUG_FUNCTION void
1915 cloog_checksum (scop_p scop ATTRIBUTE_UNUSED)
1916 {
1917 /* When debugging, enable the following code. This cannot be used
1918 in production compilers because it calls "system". */
1919 #if 0
1920 FILE *stream = fopen ("/tmp/scop.cloog", "w");
1921 gcc_assert (stream);
1922 print_cloog (stream, scop, 0);
1923 fclose (stream);
1924
1925 fputs ("\n", stdout);
1926 system ("cloog -compilable 1 /tmp/scop.cloog > /tmp/scop.c ; gcc -O0 -g /tmp/scop.c -lm -o /tmp/scop; /tmp/scop | md5sum ");
1927 #endif
1928 }
1929
1930 #endif
1931