OSDN Git Service

Make print_scop output the scoplib format.
[pf3gnuchains/gcc-fork.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 "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-flow.h"
32 #include "toplev.h"
33 #include "tree-dump.h"
34 #include "timevar.h"
35 #include "cfgloop.h"
36 #include "tree-chrec.h"
37 #include "tree-data-ref.h"
38 #include "tree-scalar-evolution.h"
39 #include "tree-pass.h"
40 #include "domwalk.h"
41 #include "value-prof.h"
42 #include "pointer-set.h"
43 #include "gimple.h"
44 #include "params.h"
45
46 #ifdef HAVE_cloog
47 #include "cloog/cloog.h"
48 #include "ppl_c.h"
49 #include "sese.h"
50 #include "graphite-ppl.h"
51 #include "graphite.h"
52 #include "graphite-poly.h"
53 #include "graphite-dependences.h"
54
55 /* Return the maximal loop depth in SCOP.  */
56
57 int
58 scop_max_loop_depth (scop_p scop)
59 {
60   int i;
61   poly_bb_p pbb;
62   int max_nb_loops = 0;
63
64   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
65     {
66       int nb_loops = pbb_dim_iter_domain (pbb);
67       if (max_nb_loops < nb_loops)
68         max_nb_loops = nb_loops;
69     }
70
71   return max_nb_loops;
72 }
73
74 /* Extend the scattering matrix of PBB to MAX_SCATTERING scattering
75    dimensions.  */
76
77 static void
78 extend_scattering (poly_bb_p pbb, int max_scattering)
79 {
80   ppl_dimension_type nb_old_dims, nb_new_dims;
81   int nb_added_dims, i;
82   ppl_Coefficient_t coef;
83   mpz_t one;
84
85   nb_added_dims = max_scattering - pbb_nb_scattering_transform (pbb);
86   mpz_init (one);
87   mpz_set_si (one, 1);
88   ppl_new_Coefficient (&coef);
89   ppl_assign_Coefficient_from_mpz_t (coef, one);
90
91   gcc_assert (nb_added_dims >= 0);
92
93   nb_old_dims = pbb_nb_scattering_transform (pbb) + pbb_dim_iter_domain (pbb)
94     + scop_nb_params (PBB_SCOP (pbb));
95   nb_new_dims = nb_old_dims + nb_added_dims;
96
97   ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb),
98                          pbb_nb_scattering_transform (pbb), nb_added_dims);
99   PBB_NB_SCATTERING_TRANSFORM (pbb) += nb_added_dims;
100
101   /* Add identity matrix for the added dimensions.  */
102   for (i = max_scattering - nb_added_dims; i < max_scattering; i++)
103     {
104       ppl_Constraint_t cstr;
105       ppl_Linear_Expression_t expr;
106
107       ppl_new_Linear_Expression_with_dimension (&expr, nb_new_dims);
108       ppl_Linear_Expression_add_to_coefficient (expr, i, coef);
109       ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
110       ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
111       ppl_delete_Constraint (cstr);
112       ppl_delete_Linear_Expression (expr);
113     }
114
115   ppl_delete_Coefficient (coef);
116   mpz_clear (one);
117 }
118
119 /* All scattering matrices in SCOP will have the same number of scattering
120    dimensions.  */
121
122 int
123 unify_scattering_dimensions (scop_p scop)
124 {
125   int i;
126   poly_bb_p pbb;
127   graphite_dim_t max_scattering = 0;
128
129   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
130     max_scattering = MAX (pbb_nb_scattering_transform (pbb), max_scattering);
131
132   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
133     extend_scattering (pbb, max_scattering);
134
135   return max_scattering;
136 }
137
138 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
139    level.  */
140
141 static void
142 print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
143 {
144   graphite_dim_t i;
145
146   if (verbosity > 0)
147     {
148       fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
149       fprintf (file, "#  eq");
150
151   if (PBB_TRANSFORMED_SCATTERING (pbb)
152       || PBB_ORIGINAL_SCATTERING (pbb))
153     fprintf (file, "# Scattering function is provided\n1\n");
154   else
155     {
156       fprintf (file, "# Scattering function is not provided\n0\n");
157       return;
158     }
159
160   fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
161   fprintf (file, "#  eq");
162
163       for (i = 0; i < pbb_nb_local_vars (pbb); i++)
164         fprintf (file, "    lv%d", (int) i);
165
166       for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
167         fprintf (file, "     i%d", (int) i);
168
169       for (i = 0; i < pbb_nb_params (pbb); i++)
170         fprintf (file, "     p%d", (int) i);
171
172       fprintf (file, "    cst\n");
173     }
174
175   /* Number of disjunct components.  Remove this when
176      PBB_TRANSFORMED_SCATTERING will be a pointset_powerset.  */
177   fprintf (file, "1\n");
178   ppl_print_polyhedron_matrix (file, PBB_TRANSFORMED_SCATTERING (pbb)
179                                ? PBB_TRANSFORMED_SCATTERING (pbb)
180                                : PBB_ORIGINAL_SCATTERING (pbb));
181
182   if (verbosity > 0)
183     fprintf (file, "#)\n");
184 }
185
186 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
187    level.  */
188
189 void
190 print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity)
191 {
192   if (!PBB_TRANSFORMED (pbb))
193     return;
194
195   /* Number of disjunct components.  Remove this when
196      PBB_TRANSFORMED_SCATTERING will be a pointset_powerset.  */
197   fprintf (file, "1\n");
198   ppl_print_polyhedron_matrix (file, PBB_TRANSFORMED_SCATTERING (pbb)
199                                ? PBB_TRANSFORMED_SCATTERING (pbb)
200                                : PBB_ORIGINAL_SCATTERING (pbb));
201
202   fprintf (file, "#)\n");
203 }
204
205 /* Prints to FILE the iteration domain of PBB, at some VERBOSITY
206    level.  */
207
208 void
209 print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity)
210 {
211   print_pbb_domain (file, pbb, verbosity);
212 }
213
214 /* Prints to FILE the scattering functions of every PBB of SCOP.  */
215
216 void
217 print_scattering_functions (FILE *file, scop_p scop, int verbosity)
218 {
219   int i;
220   poly_bb_p pbb;
221
222   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
223     print_scattering_function (file, pbb, verbosity);
224 }
225
226 /* Prints to FILE the iteration domains of every PBB of SCOP, at some
227    VERBOSITY level.  */
228
229 void
230 print_iteration_domains (FILE *file, scop_p scop, int verbosity)
231 {
232   int i;
233   poly_bb_p pbb;
234
235   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
236     print_iteration_domain (file, pbb, verbosity);
237 }
238
239 /* Prints to STDERR the scattering function of PBB, at some VERBOSITY
240    level.  */
241
242 void
243 debug_scattering_function (poly_bb_p pbb, int verbosity)
244 {
245   print_scattering_function (stderr, pbb, verbosity);
246 }
247
248 /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY
249    level.  */
250
251 void
252 debug_iteration_domain (poly_bb_p pbb, int verbosity)
253 {
254   print_iteration_domain (stderr, pbb, verbosity);
255 }
256
257 /* Prints to STDERR the scattering functions of every PBB of SCOP, at
258    some VERBOSITY level.  */
259
260 void
261 debug_scattering_functions (scop_p scop, int verbosity)
262 {
263   print_scattering_functions (stderr, scop, verbosity);
264 }
265
266 /* Prints to STDERR the iteration domains of every PBB of SCOP, at
267    some VERBOSITY level.  */
268
269 void
270 debug_iteration_domains (scop_p scop, int verbosity)
271 {
272   print_iteration_domains (stderr, scop, verbosity);
273 }
274
275
276 /* Apply graphite transformations to all the basic blocks of SCOP.  */
277
278 bool
279 apply_poly_transforms (scop_p scop)
280 {
281   bool transform_done = false;
282
283   /* Generate code even if we did not apply any real transformation.
284      This also allows to check the performance for the identity
285      transformation: GIMPLE -> GRAPHITE -> GIMPLE
286      Keep in mind that CLooG optimizes in control, so the loop structure
287      may change, even if we only use -fgraphite-identity.  */
288   if (flag_graphite_identity)
289     transform_done = true;
290
291   if (flag_loop_parallelize_all)
292     transform_done = true;
293
294   if (flag_loop_block)
295     transform_done |= scop_do_block (scop);
296   else
297     {
298       if (flag_loop_strip_mine)
299         transform_done |= scop_do_strip_mine (scop);
300
301       if (flag_loop_interchange)
302         transform_done |= scop_do_interchange (scop);
303     }
304
305   return transform_done;
306 }
307
308 /* Returns true when it PDR1 is a duplicate of PDR2: same PBB, and
309    their ACCESSES, TYPE, and NB_SUBSCRIPTS are the same.  */
310
311 static inline bool
312 can_collapse_pdrs (poly_dr_p pdr1, poly_dr_p pdr2)
313 {
314   bool res;
315   ppl_Pointset_Powerset_C_Polyhedron_t af1, af2, diff;
316
317   if (PDR_PBB (pdr1) != PDR_PBB (pdr2)
318       || PDR_NB_SUBSCRIPTS (pdr1) != PDR_NB_SUBSCRIPTS (pdr2)
319       || PDR_TYPE (pdr1) != PDR_TYPE (pdr2))
320     return false;
321
322   af1 = PDR_ACCESSES (pdr1);
323   af2 = PDR_ACCESSES (pdr2);
324   ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
325     (&diff, af1);
326   ppl_Pointset_Powerset_C_Polyhedron_difference_assign (diff, af2);
327
328   res = ppl_Pointset_Powerset_C_Polyhedron_is_empty (diff);
329   ppl_delete_Pointset_Powerset_C_Polyhedron (diff);
330   return res;
331 }
332
333 /* Removes duplicated data references in PBB.  */
334
335 void
336 pbb_remove_duplicate_pdrs (poly_bb_p pbb)
337 {
338   int i, j;
339   poly_dr_p pdr1, pdr2;
340   unsigned n = VEC_length (poly_dr_p, PBB_DRS (pbb));
341   VEC (poly_dr_p, heap) *collapsed = VEC_alloc (poly_dr_p, heap, n);
342
343   for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr1); i++)
344     for (j = 0; VEC_iterate (poly_dr_p, collapsed, j, pdr2); j++)
345       if (!can_collapse_pdrs (pdr1, pdr2))
346         VEC_quick_push (poly_dr_p, collapsed, pdr1);
347
348   VEC_free (poly_dr_p, heap, collapsed);
349   PBB_PDR_DUPLICATES_REMOVED (pbb) = true;
350 }
351
352 /* Create a new polyhedral data reference and add it to PBB.  It is
353    defined by its ACCESSES, its TYPE, and the number of subscripts
354    NB_SUBSCRIPTS.  */
355
356 void
357 new_poly_dr (poly_bb_p pbb, int dr_base_object_set,
358              ppl_Pointset_Powerset_C_Polyhedron_t accesses,
359              enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts)
360 {
361   static int id = 0;
362   poly_dr_p pdr = XNEW (struct poly_dr);
363
364   PDR_ID (pdr) = id++;
365   PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set;
366   PDR_NB_REFS (pdr) = 1;
367   PDR_PBB (pdr) = pbb;
368   PDR_ACCESSES (pdr) = accesses;
369   PDR_TYPE (pdr) = type;
370   PDR_CDR (pdr) = cdr;
371   PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts;
372   VEC_safe_push (poly_dr_p, heap, PBB_DRS (pbb), pdr);
373 }
374
375 /* Free polyhedral data reference PDR.  */
376
377 void
378 free_poly_dr (poly_dr_p pdr)
379 {
380   ppl_delete_Pointset_Powerset_C_Polyhedron (PDR_ACCESSES (pdr));
381   XDELETE (pdr);
382 }
383
384 /* Create a new polyhedral black box.  */
385
386 void
387 new_poly_bb (scop_p scop, void *black_box, bool reduction)
388 {
389   poly_bb_p pbb = XNEW (struct poly_bb);
390
391   PBB_DOMAIN (pbb) = NULL;
392   PBB_SCOP (pbb) = scop;
393   pbb_set_black_box (pbb, black_box);
394   PBB_TRANSFORMED (pbb) = NULL;
395   PBB_SAVED (pbb) = NULL;
396   PBB_ORIGINAL (pbb) = NULL;
397   PBB_DRS (pbb) = VEC_alloc (poly_dr_p, heap, 3);
398   PBB_IS_REDUCTION (pbb) = reduction;
399   PBB_PDR_DUPLICATES_REMOVED (pbb) = false;
400   VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
401 }
402
403 /* Free polyhedral black box.  */
404
405 void
406 free_poly_bb (poly_bb_p pbb)
407 {
408   int i;
409   poly_dr_p pdr;
410
411   ppl_delete_Pointset_Powerset_C_Polyhedron (PBB_DOMAIN (pbb));
412
413   if (PBB_TRANSFORMED (pbb))
414     poly_scattering_free (PBB_TRANSFORMED (pbb));
415
416   if (PBB_SAVED (pbb))
417     poly_scattering_free (PBB_SAVED (pbb));
418
419   if (PBB_ORIGINAL (pbb))
420     poly_scattering_free (PBB_ORIGINAL (pbb));
421
422   if (PBB_DRS (pbb))
423     for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
424       free_poly_dr (pdr);
425
426   VEC_free (poly_dr_p, heap, PBB_DRS (pbb));
427   XDELETE (pbb);
428 }
429
430 static void
431 print_pdr_access_layout (FILE *file, poly_dr_p pdr)
432 {
433   graphite_dim_t i;
434
435   fprintf (file, "#  eq");
436
437   for (i = 0; i < pdr_dim_iter_domain (pdr); i++)
438     fprintf (file, "     i%d", (int) i);
439
440   for (i = 0; i < pdr_nb_params (pdr); i++)
441     fprintf (file, "     p%d", (int) i);
442
443   fprintf (file, "  alias");
444
445   for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++)
446     fprintf (file, "   sub%d", (int) i);
447
448   fprintf (file, "    cst\n");
449 }
450
451 /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY
452    level.  */
453
454 void
455 print_pdr (FILE *file, poly_dr_p pdr, int verbosity)
456 {
457   fprintf (file, "# pdr_%d (", PDR_ID (pdr));
458
459   switch (PDR_TYPE (pdr))
460     {
461       fprintf (file, "# pdr_%d (", PDR_ID (pdr));
462
463       switch (PDR_TYPE (pdr))
464         {
465         case PDR_READ:
466           fprintf (file, "read \n");
467           break;
468
469         case PDR_WRITE:
470           fprintf (file, "write \n");
471           break;
472
473         case PDR_MAY_WRITE:
474           fprintf (file, "may_write \n");
475           break;
476
477         default:
478           gcc_unreachable ();
479         }
480
481       dump_data_reference (file, (data_reference_p) PDR_CDR (pdr));
482     }
483
484   if (verbosity > 0)
485     {
486       fprintf (file, "# data accesses (\n");
487       print_pdr_access_layout (file, pdr);
488     }
489
490   fprintf (file, "# data accesses (\n");
491   print_pdr_access_layout (file, pdr);
492   ppl_print_powerset_matrix (file, PDR_ACCESSES (pdr));
493   fprintf (file, "#)\n");
494
495   fprintf (file, "#)\n");
496 }
497
498 /* Prints to STDERR the polyhedral data reference PDR, at some
499    VERBOSITY level.  */
500
501 void
502 debug_pdr (poly_dr_p pdr, int verbosity)
503 {
504   print_pdr (stderr, pdr, verbosity);
505 }
506
507 /* Creates a new SCOP containing REGION.  */
508
509 scop_p
510 new_scop (void *region)
511 {
512   scop_p scop = XNEW (struct scop);
513
514   SCOP_CONTEXT (scop) = NULL;
515   scop_set_region (scop, region);
516   SCOP_BBS (scop) = VEC_alloc (poly_bb_p, heap, 3);
517   SCOP_ORIGINAL_PDDRS (scop) = htab_create (10, hash_poly_ddr_p,
518                                             eq_poly_ddr_p, free_poly_ddr);
519   SCOP_ORIGINAL_SCHEDULE (scop) = NULL;
520   SCOP_TRANSFORMED_SCHEDULE (scop) = NULL;
521   SCOP_SAVED_SCHEDULE (scop) = NULL;
522   POLY_SCOP_P (scop) = false;
523
524   return scop;
525 }
526
527 /* Deletes SCOP.  */
528
529 void
530 free_scop (scop_p scop)
531 {
532   int i;
533   poly_bb_p pbb;
534
535   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
536     free_poly_bb (pbb);
537
538   VEC_free (poly_bb_p, heap, SCOP_BBS (scop));
539
540   if (SCOP_CONTEXT (scop))
541     ppl_delete_Pointset_Powerset_C_Polyhedron (SCOP_CONTEXT (scop));
542
543   htab_delete (SCOP_ORIGINAL_PDDRS (scop));
544   free_lst (SCOP_ORIGINAL_SCHEDULE (scop));
545   free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
546   free_lst (SCOP_SAVED_SCHEDULE (scop));
547   XDELETE (scop);
548 }
549
550 /* Print to FILE the domain of PBB, at some VERBOSITY level.  */
551
552 void
553 print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
554 {
555   graphite_dim_t i;
556   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
557
558   if (!PBB_DOMAIN (pbb))
559     return;
560
561   fprintf (file, "# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
562   fprintf (file, "#  eq");
563
564       for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
565         fprintf (file, "     i%d", (int) i);
566
567       for (i = 0; i < pbb_nb_params (pbb); i++)
568         fprintf (file, "     p%d", (int) i);
569
570       fprintf (file, "    cst\n");
571     }
572
573   if (PBB_DOMAIN (pbb))
574     ppl_print_powerset_matrix (file, PBB_DOMAIN (pbb));
575   else
576     fprintf (file, "0\n");
577
578   fprintf (file, "#)\n");
579 }
580
581 /* Dump the cases of a graphite basic block GBB on FILE.  */
582
583 static void
584 dump_gbb_cases (FILE *file, gimple_bb_p gbb)
585 {
586   int i;
587   gimple stmt;
588   VEC (gimple, heap) *cases;
589
590   if (!gbb)
591     return;
592
593   cases = GBB_CONDITION_CASES (gbb);
594   if (VEC_empty (gimple, cases))
595     return;
596
597   fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index);
598
599   for (i = 0; VEC_iterate (gimple, cases, i, stmt); i++)
600     {
601       fprintf (file, "# ");
602       print_gimple_stmt (file, stmt, 0, 0);
603     }
604
605   fprintf (file, "#)\n");
606 }
607
608 /* Dump conditions of a graphite basic block GBB on FILE.  */
609
610 static void
611 dump_gbb_conditions (FILE *file, gimple_bb_p gbb)
612 {
613   int i;
614   gimple stmt;
615   VEC (gimple, heap) *conditions;
616
617   if (!gbb)
618     return;
619
620   conditions = GBB_CONDITIONS (gbb);
621   if (VEC_empty (gimple, conditions))
622     return;
623
624   fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index);
625
626   for (i = 0; VEC_iterate (gimple, conditions, i, stmt); i++)
627     {
628       fprintf (file, "# ");
629       print_gimple_stmt (file, stmt, 0, 0);
630     }
631
632   fprintf (file, "#)\n");
633 }
634
635 /* Print to FILE all the data references of PBB, at some VERBOSITY
636    level.  */
637
638 void
639 print_pdrs (FILE *file, poly_bb_p pbb, int verbosity)
640 {
641   int i;
642   poly_dr_p pdr;
643   int nb_reads = 0;
644   int nb_writes = 0;
645
646   if (VEC_length (poly_dr_p, PBB_DRS (pbb)) == 0)
647     {
648       fprintf (file, "# Access informations are not provided\n0\n");
649       return;
650     }
651
652   fprintf (file, "# Data references (\n");
653   fprintf (file, "# Access informations are provided\n1\n");
654
655   for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
656     if (PDR_TYPE (pdr) == PDR_READ)
657       nb_reads++;
658     else
659       nb_writes++;
660
661   fprintf (file, "# Read data references (\n");
662   fprintf (file, "# Read access informations\n%d\n", nb_reads);
663   for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
664     if (PDR_TYPE (pdr) == PDR_READ)
665       print_pdr (file, pdr);
666   fprintf (file, "#)\n");
667
668   fprintf (file, "# Write data references (\n");
669   fprintf (file, "# Write access informations\n%d\n", nb_writes);
670   for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr); i++)
671     if (PDR_TYPE (pdr) != PDR_READ)
672       print_pdr (file, pdr);
673   fprintf (file, "#)\n");
674   fprintf (file, "#)\n");
675 }
676
677 /* Print to STDERR all the data references of PBB.  */
678
679 void
680 debug_pdrs (poly_bb_p pbb, int verbosity)
681 {
682   print_pdrs (stderr, pbb, verbosity);
683 }
684
685 /* Print to FILE the body of PBB, at some VERBOSITY level.  */
686
687 static void
688 print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity)
689 {
690   if (verbosity > 1)
691     fprintf (file, "# Body (\n");
692
693   if (verbosity > 0)
694     fprintf (file, "# Statement body is provided\n");
695   fprintf (file, "1\n");
696
697   if (verbosity > 0)
698     fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
699
700   if (verbosity > 0)
701     fprintf (file, "# Statement body\n");
702
703   fprintf (file, "{\n");
704   dump_bb (pbb_bb (pbb), file, 0);
705   fprintf (file, "}\n");
706
707   if (verbosity > 1)
708     fprintf (file, "#)\n");
709 }
710
711 /* Print to FILE the body of PBB.  */
712
713 static void
714 print_pbb_body (FILE *file, poly_bb_p pbb)
715 {
716   fprintf (file, "# Body (\n");
717   fprintf (file, "# Statement body is provided\n1\n");
718   fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
719   fprintf (file, "# Statement body\n");
720   fprintf (file, "{\n");
721   dump_bb (pbb_bb (pbb), file, 0);
722   fprintf (file, "}\n");
723   fprintf (file, "#)\n");
724 }
725
726 /* Print to FILE the domain and scattering function of PBB.  */
727
728 void
729 print_pbb (FILE *file, poly_bb_p pbb, int verbosity)
730 {
731   fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
732   dump_gbb_conditions (file, PBB_BLACK_BOX (pbb));
733   dump_gbb_cases (file, PBB_BLACK_BOX (pbb));
734   print_pbb_domain (file, pbb);
735   print_scattering_function (file, pbb);
736   print_pdrs (file, pbb);
737   print_pbb_body (file, pbb);
738   fprintf (file, "#)\n");
739 }
740
741 /* Print to FILE the parameters of SCOP, at some VERBOSITY level.  */
742
743 void
744 print_scop_params (FILE *file, scop_p scop, int verbosity)
745 {
746   int i;
747   tree t;
748
749   fprintf (file, "# parameters (\n");
750
751   if (VEC_length (tree, SESE_PARAMS (SCOP_REGION (scop))))
752     fprintf (file, "# Parameter names are provided\n1\n# Parameter names \n");
753   else
754     fprintf (file, "# Parameter names are not provided\n0\n");
755
756   for (i = 0; VEC_iterate (tree, SESE_PARAMS (SCOP_REGION (scop)), i, t); i++)
757     {
758       print_generic_expr (file, t, 0);
759       fprintf (file, " # p_%d \n", i);
760     }
761   fprintf (file, "#)\n");
762 }
763
764 /* Print to FILE the context of SCoP, at some VERBOSITY level.  */
765
766 void
767 print_scop_context (FILE *file, scop_p scop, int verbosity)
768 {
769   graphite_dim_t i;
770
771   fprintf (file, "# Context (\n");
772   fprintf (file, "#  eq");
773
774       for (i = 0; i < scop_nb_params (scop); i++)
775         fprintf (file, "     p%d", (int) i);
776
777       fprintf (file, "    cst\n");
778     }
779
780   if (SCOP_CONTEXT (scop))
781     ppl_print_powerset_matrix (file, SCOP_CONTEXT (scop));
782   else
783     fprintf (file, "0 %d\n", (int) scop_nb_params (scop) + 2);
784
785   fprintf (file, "# )\n");
786 }
787
788 /* Print to FILE the input file that CLooG would expect as input, at
789    some VERBOSITY level.  */
790
791 void
792 print_cloog (FILE *file, scop_p scop, int verbosity)
793 {
794   int i;
795   poly_bb_p pbb;
796
797   fprintf (file, "SCoP #(\n");
798   fprintf (file, "# Language\nGimple\n");
799   print_scop_context (file, scop);
800   print_scop_params (file, scop);
801   fprintf (file, "# Number of statements\n%d\n",
802            VEC_length (poly_bb_p, SCOP_BBS (scop)));
803
804   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
805     {
806       if (!PBB_TRANSFORMED (pbb)
807           || !(PBB_TRANSFORMED_SCATTERING (pbb)
808                || PBB_ORIGINAL_SCATTERING (pbb)))
809         continue;
810
811       if (verbosity > 1)
812         fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
813
814   fprintf (file, "# original_lst (\n");
815   print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0);
816   fprintf (file, "\n#)\n");
817
818   fprintf (file, "# transformed_lst (\n");
819   print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
820   fprintf (file, "\n#)\n");
821
822   fprintf (file, "#)\n");
823 }
824
825 /* Print to FILE the domain and scattering function of PBB, at some
826    VERBOSITY level.  */
827
828 void
829 debug_pbb (poly_bb_p pbb, int verbosity)
830 {
831   print_pbb (stderr, pbb, verbosity);
832 }
833
834 /* Print to STDERR the context of SCOP, at some VERBOSITY level.  */
835
836 void
837 debug_scop_context (scop_p scop, int verbosity)
838 {
839   print_scop_context (stderr, scop, verbosity);
840 }
841
842 /* Print to STDERR the SCOP, at some VERBOSITY level.  */
843
844 void
845 debug_scop (scop_p scop, int verbosity)
846 {
847   print_scop (stderr, scop, verbosity);
848 }
849
850 /* Print to STDERR the SCOP under CLooG format, at some VERBOSITY
851    level.  */
852
853 void
854 debug_cloog (scop_p scop, int verbosity)
855 {
856   print_cloog (stderr, scop, verbosity);
857 }
858
859 /* Print to STDERR the parameters of SCOP, at some VERBOSITY
860    level.  */
861
862 void
863 debug_scop_params (scop_p scop, int verbosity)
864 {
865   print_scop_params (stderr, scop, verbosity);
866 }
867
868
869 /* The dimension in the transformed scattering polyhedron of PBB
870    containing the scattering iterator for the loop at depth LOOP_DEPTH.  */
871
872 ppl_dimension_type
873 psct_scattering_dim_for_loop_depth (poly_bb_p pbb, graphite_dim_t loop_depth)
874 {
875   ppl_const_Constraint_System_t pcs;
876   ppl_Constraint_System_const_iterator_t cit, cend;
877   ppl_const_Constraint_t cstr;
878   ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb);
879   ppl_dimension_type iter = psct_iterator_dim (pbb, loop_depth);
880   ppl_Linear_Expression_t expr;
881   ppl_Coefficient_t coef;
882   mpz_t val;
883   graphite_dim_t i;
884
885   mpz_init (val);
886   ppl_new_Coefficient (&coef);
887   ppl_Polyhedron_get_constraints (ph, &pcs);
888   ppl_new_Constraint_System_const_iterator (&cit);
889   ppl_new_Constraint_System_const_iterator (&cend);
890
891   for (ppl_Constraint_System_begin (pcs, cit),
892          ppl_Constraint_System_end (pcs, cend);
893        !ppl_Constraint_System_const_iterator_equal_test (cit, cend);
894        ppl_Constraint_System_const_iterator_increment (cit))
895     {
896       ppl_Constraint_System_const_iterator_dereference (cit, &cstr);
897       ppl_new_Linear_Expression_from_Constraint (&expr, cstr);
898       ppl_Linear_Expression_coefficient (expr, iter, coef);
899       ppl_Coefficient_to_mpz_t (coef, val);
900
901       if (mpz_sgn (val))
902         {
903           ppl_delete_Linear_Expression (expr);
904           continue;
905         }
906
907       for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
908         {
909           ppl_dimension_type scatter = psct_scattering_dim (pbb, i);
910
911           ppl_Linear_Expression_coefficient (expr, scatter, coef);
912           ppl_Coefficient_to_mpz_t (coef, val);
913
914           if (value_notzero_p (val))
915             {
916               mpz_clear (val);
917               ppl_delete_Linear_Expression (expr);
918               ppl_delete_Coefficient (coef);
919               ppl_delete_Constraint_System_const_iterator (cit);
920               ppl_delete_Constraint_System_const_iterator (cend);
921
922               return scatter;
923             }
924         }
925     }
926
927   gcc_unreachable ();
928 }
929
930 /* Returns the number of iterations NITER of the loop around PBB at
931    depth LOOP_DEPTH.  */
932
933 void
934 pbb_number_of_iterations (poly_bb_p pbb,
935                           graphite_dim_t loop_depth,
936                           mpz_t niter)
937 {
938   ppl_Linear_Expression_t le;
939   ppl_dimension_type dim;
940
941   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), &dim);
942   ppl_new_Linear_Expression_with_dimension (&le, dim);
943   ppl_set_coef (le, pbb_iterator_dim (pbb, loop_depth), 1);
944   mpz_set_si (niter, -1);
945   ppl_max_for_le_pointset (PBB_DOMAIN (pbb), le, niter);
946   ppl_delete_Linear_Expression (le);
947 }
948
949 /* Returns the number of iterations NITER of the loop around PBB at
950    time(scattering) dimension TIME_DEPTH.  */
951
952 void
953 pbb_number_of_iterations_at_time (poly_bb_p pbb,
954                                   graphite_dim_t time_depth,
955                                   mpz_t niter)
956 {
957   ppl_Pointset_Powerset_C_Polyhedron_t ext_domain, sctr;
958   ppl_Linear_Expression_t le;
959   ppl_dimension_type dim;
960
961   /* Takes together domain and scattering polyhedrons, and composes
962      them into the bigger polyhedron that has the following format:
963
964      t0..t_{n-1} | l0..l_{nlcl-1} | i0..i_{niter-1} | g0..g_{nparm-1}
965
966      where
967      | t0..t_{n-1} are time dimensions (scattering dimensions)
968      | l0..l_{nclc-1} are local variables in scattering function
969      | i0..i_{niter-1} are original iteration variables
970      | g0..g_{nparam-1} are global parameters.  */
971
972   ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&sctr,
973       PBB_TRANSFORMED_SCATTERING (pbb));
974
975   /* Extend the iteration domain with the scattering dimensions:
976      0..0 | 0..0 | i0..i_{niter-1} | g0..g_{nparm-1}.   */
977   ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
978     (&ext_domain, PBB_DOMAIN (pbb));
979   ppl_insert_dimensions_pointset (ext_domain, 0,
980                                   pbb_nb_scattering_transform (pbb)
981                                   + pbb_nb_local_vars (pbb));
982
983   /* Add to sctr the extended domain.  */
984   ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (sctr, ext_domain);
985
986   /* Extract the number of iterations.  */
987   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (sctr, &dim);
988   ppl_new_Linear_Expression_with_dimension (&le, dim);
989   ppl_set_coef (le, time_depth, 1);
990   mpz_set_si (niter, -1);
991   ppl_max_for_le_pointset (sctr, le, niter);
992
993   ppl_delete_Linear_Expression (le);
994   ppl_delete_Pointset_Powerset_C_Polyhedron (sctr);
995   ppl_delete_Pointset_Powerset_C_Polyhedron (ext_domain);
996 }
997
998 /* Translates LOOP to LST.  */
999
1000 static lst_p
1001 loop_to_lst (loop_p loop, VEC (poly_bb_p, heap) *bbs, int *i)
1002 {
1003   poly_bb_p pbb;
1004   VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1005
1006   for (; VEC_iterate (poly_bb_p, bbs, *i, pbb); (*i)++)
1007     {
1008       lst_p stmt;
1009       basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb));
1010
1011       if (bb->loop_father == loop)
1012         stmt = new_lst_stmt (pbb);
1013       else if (flow_bb_inside_loop_p (loop, bb))
1014         {
1015           loop_p next = loop->inner;
1016
1017           while (next && !flow_bb_inside_loop_p (next, bb))
1018             next = next->next;
1019
1020           stmt = loop_to_lst (next, bbs, i);
1021         }
1022       else
1023         {
1024           (*i)--;
1025           return new_lst_loop (seq);
1026         }
1027
1028       VEC_safe_push (lst_p, heap, seq, stmt);
1029     }
1030
1031   return new_lst_loop (seq);
1032 }
1033
1034 /* Reads the original scattering of the SCOP and returns an LST
1035    representing it.  */
1036
1037 void
1038 scop_to_lst (scop_p scop)
1039 {
1040   lst_p res;
1041   int i, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
1042   VEC (lst_p, heap) *seq = VEC_alloc (lst_p, heap, 5);
1043   sese region = SCOP_REGION (scop);
1044
1045   for (i = 0; i < n; i++)
1046     {
1047       poly_bb_p pbb = VEC_index (poly_bb_p, SCOP_BBS (scop), i);
1048       loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb)));
1049
1050       if (loop_in_sese_p (loop, region))
1051         res = loop_to_lst (loop, SCOP_BBS (scop), &i);
1052       else
1053         res = new_lst_stmt (pbb);
1054
1055       VEC_safe_push (lst_p, heap, seq, res);
1056     }
1057
1058   res = new_lst_loop (seq);
1059   SCOP_ORIGINAL_SCHEDULE (scop) = res;
1060   SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res);
1061 }
1062
1063 /* Print to FILE on a new line COLUMN white spaces.  */
1064
1065 static void
1066 lst_indent_to (FILE *file, int column)
1067 {
1068   int i;
1069
1070   if (column > 0)
1071     fprintf (file, "\n#");
1072
1073   for (i = 0; i < column; i++)
1074     fprintf (file, " ");
1075 }
1076
1077 /* Print LST to FILE with INDENT spaces of indentation.  */
1078
1079 void
1080 print_lst (FILE *file, lst_p lst, int indent)
1081 {
1082   if (!lst)
1083     return;
1084
1085   lst_indent_to (file, indent);
1086
1087   if (LST_LOOP_P (lst))
1088     {
1089       int i;
1090       lst_p l;
1091
1092       if (LST_LOOP_FATHER (lst))
1093         fprintf (file, "%d (loop", lst_dewey_number (lst));
1094       else
1095         fprintf (file, "#(root");
1096
1097       for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
1098         print_lst (file, l, indent + 2);
1099
1100       fprintf (file, ")");
1101     }
1102   else
1103     fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst)));
1104 }
1105
1106 /* Print LST to STDERR.  */
1107
1108 void
1109 debug_lst (lst_p lst)
1110 {
1111   print_lst (stderr, lst, 0);
1112 }
1113
1114 /* Pretty print to FILE the loop statement tree LST in DOT format.  */
1115
1116 static void
1117 dot_lst_1 (FILE *file, lst_p lst)
1118 {
1119   if (!lst)
1120     return;
1121
1122   if (LST_LOOP_P (lst))
1123     {
1124       int i;
1125       lst_p l;
1126
1127       if (!LST_LOOP_FATHER (lst))
1128         fprintf (file, "L -> L_%d_%d\n",
1129                  lst_depth (lst),
1130                  lst_dewey_number (lst));
1131       else
1132         fprintf (file, "L_%d_%d -> L_%d_%d\n",
1133                  lst_depth (LST_LOOP_FATHER (lst)),
1134                  lst_dewey_number (LST_LOOP_FATHER (lst)),
1135                  lst_depth (lst),
1136                  lst_dewey_number (lst));
1137
1138       for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
1139         dot_lst_1 (file, l);
1140     }
1141
1142   else
1143     fprintf (file, "L_%d_%d -> S_%d\n",
1144              lst_depth (LST_LOOP_FATHER (lst)),
1145              lst_dewey_number (LST_LOOP_FATHER (lst)),
1146              pbb_index (LST_PBB (lst)));
1147
1148 }
1149
1150 /* Display the LST using dotty.  */
1151
1152 void
1153 dot_lst (lst_p lst)
1154 {
1155   /* When debugging, enable the following code.  This cannot be used
1156      in production compilers because it calls "system".  */
1157 #if 0
1158   int x;
1159   FILE *stream = fopen ("/tmp/lst.dot", "w");
1160   gcc_assert (stream);
1161
1162   fputs ("digraph all {\n", stream);
1163   dot_lst_1 (stream, lst);
1164   fputs ("}\n\n", stream);
1165   fclose (stream);
1166
1167   x = system ("dotty /tmp/lst.dot");
1168 #else
1169   fputs ("digraph all {\n", stderr);
1170   dot_lst_1 (stderr, lst);
1171   fputs ("}\n\n", stderr);
1172
1173 #endif
1174 }
1175
1176 #endif
1177