xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/graphite-poly.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /* Graphite polyhedral representation.
2    Copyright (C) 2009-2015 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 
22 #include "config.h"
23 
24 #ifdef HAVE_isl
25 #include <isl/constraint.h>
26 #include <isl/set.h>
27 #include <isl/map.h>
28 #include <isl/union_map.h>
29 #include <isl/constraint.h>
30 #include <isl/ilp.h>
31 #include <isl/aff.h>
32 #include <isl/val.h>
33 
34 /* Since ISL-0.13, the extern is in val_gmp.h.  */
35 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
36 extern "C" {
37 #endif
38 #include <isl/val_gmp.h>
39 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
40 }
41 #endif
42 #endif
43 
44 #include "system.h"
45 #include "coretypes.h"
46 #include "diagnostic-core.h"
47 #include "hash-set.h"
48 #include "machmode.h"
49 #include "vec.h"
50 #include "double-int.h"
51 #include "input.h"
52 #include "alias.h"
53 #include "symtab.h"
54 #include "options.h"
55 #include "wide-int.h"
56 #include "inchash.h"
57 #include "tree.h"
58 #include "fold-const.h"
59 #include "predict.h"
60 #include "tm.h"
61 #include "hard-reg-set.h"
62 #include "input.h"
63 #include "function.h"
64 #include "dominance.h"
65 #include "cfg.h"
66 #include "basic-block.h"
67 #include "tree-ssa-alias.h"
68 #include "internal-fn.h"
69 #include "gimple-expr.h"
70 #include "is-a.h"
71 #include "gimple.h"
72 #include "gimple-iterator.h"
73 #include "tree-ssa-loop.h"
74 #include "dumpfile.h"
75 #include "gimple-pretty-print.h"
76 #include "cfgloop.h"
77 #include "tree-chrec.h"
78 #include "tree-data-ref.h"
79 #include "tree-scalar-evolution.h"
80 #include "sese.h"
81 
82 #ifdef HAVE_isl
83 #include "graphite-poly.h"
84 
85 #define OPENSCOP_MAX_STRING 256
86 
87 
88 /* Print to STDERR the GMP value VAL.  */
89 
90 DEBUG_FUNCTION void
91 debug_gmp_value (mpz_t val)
92 {
93   gmp_fprintf (stderr, "%Zd", val);
94 }
95 
96 /* Return the maximal loop depth in SCOP.  */
97 
98 int
99 scop_max_loop_depth (scop_p scop)
100 {
101   int i;
102   poly_bb_p pbb;
103   int max_nb_loops = 0;
104 
105   FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
106     {
107       int nb_loops = pbb_dim_iter_domain (pbb);
108       if (max_nb_loops < nb_loops)
109         max_nb_loops = nb_loops;
110     }
111 
112   return max_nb_loops;
113 }
114 
115 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
116    level.  */
117 
118 static void
119 print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
120 {
121   graphite_dim_t i;
122 
123   if (verbosity > 0)
124     {
125       fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
126       fprintf (file, "#eq");
127 
128       for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
129 	fprintf (file, "     s%d", (int) i);
130 
131       for (i = 0; i < pbb_nb_local_vars (pbb); i++)
132 	fprintf (file, "    lv%d", (int) i);
133 
134       for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
135 	fprintf (file, "     i%d", (int) i);
136 
137       for (i = 0; i < pbb_nb_params (pbb); i++)
138 	fprintf (file, "     p%d", (int) i);
139 
140       fprintf (file, "    cst\n");
141     }
142 
143   fprintf (file, "isl\n");
144   print_isl_map (file, pbb->transformed ? pbb->transformed : pbb->schedule);
145 
146   if (verbosity > 0)
147     fprintf (file, "#)\n");
148 }
149 
150 /* Prints to FILE the scattering function of PBB, at some VERBOSITY
151    level.  */
152 
153 void
154 print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity)
155 {
156   if (!PBB_TRANSFORMED (pbb))
157     return;
158 
159   if (pbb->schedule || pbb->transformed)
160     {
161       if (verbosity > 0)
162 	fprintf (file, "# Scattering function is provided\n");
163 
164       fprintf (file, "1\n");
165     }
166   else
167     {
168       if (verbosity > 0)
169 	fprintf (file, "# Scattering function is not provided\n");
170 
171       fprintf (file, "0\n");
172       return;
173     }
174 
175   print_scattering_function_1 (file, pbb, verbosity);
176 
177   if (verbosity > 0)
178     fprintf (file, "# Scattering names are not provided\n");
179 
180   fprintf (file, "0\n");
181 
182 }
183 
184 /* Prints to FILE the iteration domain of PBB, at some VERBOSITY
185    level.  */
186 
187 void
188 print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity)
189 {
190   print_pbb_domain (file, pbb, verbosity);
191 }
192 
193 /* Prints to FILE the scattering functions of every PBB of SCOP.  */
194 
195 void
196 print_scattering_functions (FILE *file, scop_p scop, int verbosity)
197 {
198   int i;
199   poly_bb_p pbb;
200 
201   FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
202     print_scattering_function (file, pbb, verbosity);
203 }
204 
205 /* Prints to FILE the iteration domains of every PBB of SCOP, at some
206    VERBOSITY level.  */
207 
208 void
209 print_iteration_domains (FILE *file, scop_p scop, int verbosity)
210 {
211   int i;
212   poly_bb_p pbb;
213 
214   FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
215     print_iteration_domain (file, pbb, verbosity);
216 }
217 
218 /* Prints to STDERR the scattering function of PBB, at some VERBOSITY
219    level.  */
220 
221 DEBUG_FUNCTION void
222 debug_scattering_function (poly_bb_p pbb, int verbosity)
223 {
224   print_scattering_function (stderr, pbb, verbosity);
225 }
226 
227 /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY
228    level.  */
229 
230 DEBUG_FUNCTION void
231 debug_iteration_domain (poly_bb_p pbb, int verbosity)
232 {
233   print_iteration_domain (stderr, pbb, verbosity);
234 }
235 
236 /* Prints to STDERR the scattering functions of every PBB of SCOP, at
237    some VERBOSITY level.  */
238 
239 DEBUG_FUNCTION void
240 debug_scattering_functions (scop_p scop, int verbosity)
241 {
242   print_scattering_functions (stderr, scop, verbosity);
243 }
244 
245 /* Prints to STDERR the iteration domains of every PBB of SCOP, at
246    some VERBOSITY level.  */
247 
248 DEBUG_FUNCTION void
249 debug_iteration_domains (scop_p scop, int verbosity)
250 {
251   print_iteration_domains (stderr, scop, verbosity);
252 }
253 
254 /* Apply graphite transformations to all the basic blocks of SCOP.  */
255 
256 bool
257 apply_poly_transforms (scop_p scop)
258 {
259   bool transform_done = false;
260 
261   /* Generate code even if we did not apply any real transformation.
262      This also allows to check the performance for the identity
263      transformation: GIMPLE -> GRAPHITE -> GIMPLE
264      Keep in mind that CLooG optimizes in control, so the loop structure
265      may change, even if we only use -fgraphite-identity.  */
266   if (flag_graphite_identity)
267     transform_done = true;
268 
269   if (flag_loop_parallelize_all)
270     transform_done = true;
271 
272   if (flag_loop_block)
273     transform_done |= scop_do_block (scop);
274   else
275     {
276       if (flag_loop_strip_mine)
277 	transform_done |= scop_do_strip_mine (scop, 0);
278 
279       if (flag_loop_interchange)
280 	transform_done |= scop_do_interchange (scop);
281     }
282 
283   /* This pass needs to be run at the final stage, as it does not
284      update the lst.  */
285   if (flag_loop_optimize_isl || flag_loop_unroll_jam)
286     transform_done |= optimize_isl (scop);
287 
288   return transform_done;
289 }
290 
291 /* Create a new polyhedral data reference and add it to PBB.  It is
292    defined by its ACCESSES, its TYPE, and the number of subscripts
293    NB_SUBSCRIPTS.  */
294 
295 void
296 new_poly_dr (poly_bb_p pbb, int dr_base_object_set,
297 	     enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts,
298 	     isl_map *acc, isl_set *extent)
299 {
300   static int id = 0;
301   poly_dr_p pdr = XNEW (struct poly_dr);
302 
303   PDR_ID (pdr) = id++;
304   PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set;
305   PDR_NB_REFS (pdr) = 1;
306   PDR_PBB (pdr) = pbb;
307   pdr->accesses = acc;
308   pdr->extent = extent;
309   PDR_TYPE (pdr) = type;
310   PDR_CDR (pdr) = cdr;
311   PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts;
312   PBB_DRS (pbb).safe_push (pdr);
313 }
314 
315 /* Free polyhedral data reference PDR.  */
316 
317 void
318 free_poly_dr (poly_dr_p pdr)
319 {
320   isl_map_free (pdr->accesses);
321   isl_set_free (pdr->extent);
322   XDELETE (pdr);
323 }
324 
325 /* Create a new polyhedral black box.  */
326 
327 poly_bb_p
328 new_poly_bb (scop_p scop, void *black_box)
329 {
330   poly_bb_p pbb = XNEW (struct poly_bb);
331 
332   pbb->domain = NULL;
333   pbb->schedule = NULL;
334   pbb->transformed = NULL;
335   pbb->saved = NULL;
336   pbb->map_sepclass = NULL;
337   PBB_SCOP (pbb) = scop;
338   pbb_set_black_box (pbb, black_box);
339   PBB_TRANSFORMED (pbb) = NULL;
340   PBB_SAVED (pbb) = NULL;
341   PBB_ORIGINAL (pbb) = NULL;
342   PBB_DRS (pbb).create (3);
343   PBB_IS_REDUCTION (pbb) = false;
344   GBB_PBB ((gimple_bb_p) black_box) = pbb;
345 
346   return pbb;
347 }
348 
349 /* Free polyhedral black box.  */
350 
351 void
352 free_poly_bb (poly_bb_p pbb)
353 {
354   int i;
355   poly_dr_p pdr;
356 
357   isl_set_free (pbb->domain);
358   isl_map_free (pbb->schedule);
359   isl_map_free (pbb->transformed);
360   isl_map_free (pbb->saved);
361 
362   if (PBB_DRS (pbb).exists ())
363     FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
364       free_poly_dr (pdr);
365 
366   PBB_DRS (pbb).release ();
367   XDELETE (pbb);
368 }
369 
370 static void
371 print_pdr_access_layout (FILE *file, poly_bb_p pbb, poly_dr_p pdr)
372 {
373   graphite_dim_t i;
374 
375   fprintf (file, "#  eq");
376 
377   fprintf (file, "   alias");
378 
379   for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++)
380     fprintf (file, "   sub%d", (int) i);
381 
382   for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
383     fprintf (file, "     i%d", (int) i);
384 
385   for (i = 0; i < pbb_nb_params (pbb); i++)
386     fprintf (file, "     p%d", (int) i);
387 
388   fprintf (file, "    cst\n");
389 }
390 
391 /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY
392    level.  */
393 
394 void
395 print_pdr (FILE *file, poly_dr_p pdr, int verbosity)
396 {
397   if (verbosity > 1)
398     {
399       fprintf (file, "# pdr_%d (", PDR_ID (pdr));
400 
401       switch (PDR_TYPE (pdr))
402 	{
403 	case PDR_READ:
404 	  fprintf (file, "read \n");
405 	  break;
406 
407 	case PDR_WRITE:
408 	  fprintf (file, "write \n");
409 	  break;
410 
411 	case PDR_MAY_WRITE:
412 	  fprintf (file, "may_write \n");
413 	  break;
414 
415 	default:
416 	  gcc_unreachable ();
417 	}
418 
419       dump_data_reference (file, (data_reference_p) PDR_CDR (pdr));
420     }
421 
422   if (verbosity > 0)
423     {
424       fprintf (file, "# data accesses (\n");
425       print_pdr_access_layout (file, PDR_PBB (pdr), pdr);
426     }
427 
428   /* XXX isl dump accesses/subscripts */
429 
430   if (verbosity > 0)
431     fprintf (file, "#)\n");
432 
433   if (verbosity > 1)
434     fprintf (file, "#)\n");
435 }
436 
437 /* Prints to STDERR the polyhedral data reference PDR, at some
438    VERBOSITY level.  */
439 
440 DEBUG_FUNCTION void
441 debug_pdr (poly_dr_p pdr, int verbosity)
442 {
443   print_pdr (stderr, pdr, verbosity);
444 }
445 
446 /* Creates a new SCOP containing REGION.  */
447 
448 scop_p
449 new_scop (void *region)
450 {
451   scop_p scop = XNEW (struct scop);
452 
453   scop->context = NULL;
454   scop->must_raw = NULL;
455   scop->may_raw = NULL;
456   scop->must_raw_no_source = NULL;
457   scop->may_raw_no_source = NULL;
458   scop->must_war = NULL;
459   scop->may_war = NULL;
460   scop->must_war_no_source = NULL;
461   scop->may_war_no_source = NULL;
462   scop->must_waw = NULL;
463   scop->may_waw = NULL;
464   scop->must_waw_no_source = NULL;
465   scop->may_waw_no_source = NULL;
466   scop_set_region (scop, region);
467   SCOP_BBS (scop).create (3);
468   SCOP_ORIGINAL_SCHEDULE (scop) = NULL;
469   SCOP_TRANSFORMED_SCHEDULE (scop) = NULL;
470   SCOP_SAVED_SCHEDULE (scop) = NULL;
471   POLY_SCOP_P (scop) = false;
472 
473   return scop;
474 }
475 
476 /* Deletes SCOP.  */
477 
478 void
479 free_scop (scop_p scop)
480 {
481   int i;
482   poly_bb_p pbb;
483 
484   FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
485     free_poly_bb (pbb);
486 
487   SCOP_BBS (scop).release ();
488 
489   isl_set_free (scop->context);
490   isl_union_map_free (scop->must_raw);
491   isl_union_map_free (scop->may_raw);
492   isl_union_map_free (scop->must_raw_no_source);
493   isl_union_map_free (scop->may_raw_no_source);
494   isl_union_map_free (scop->must_war);
495   isl_union_map_free (scop->may_war);
496   isl_union_map_free (scop->must_war_no_source);
497   isl_union_map_free (scop->may_war_no_source);
498   isl_union_map_free (scop->must_waw);
499   isl_union_map_free (scop->may_waw);
500   isl_union_map_free (scop->must_waw_no_source);
501   isl_union_map_free (scop->may_waw_no_source);
502   free_lst (SCOP_ORIGINAL_SCHEDULE (scop));
503   free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
504   free_lst (SCOP_SAVED_SCHEDULE (scop));
505   XDELETE (scop);
506 }
507 
508 /* Print to FILE the domain of PBB in OpenScop format, at some VERBOSITY
509    level.  */
510 
511 static void
512 openscop_print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
513 {
514   graphite_dim_t i;
515   gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
516 
517   if (!pbb->domain)
518     return;
519 
520   if (verbosity > 0)
521     {
522       fprintf (file, "\n# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
523       fprintf (file, "#eq");
524 
525       for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
526 	fprintf (file, "     i%d", (int) i);
527 
528       for (i = 0; i < pbb_nb_params (pbb); i++)
529 	fprintf (file, "     p%d", (int) i);
530 
531       fprintf (file, "    cst\n");
532     }
533 
534   fprintf (file, "XXX isl\n");
535 
536   if (verbosity > 0)
537     fprintf (file, "#)\n");
538 }
539 
540 /* Print to FILE the domain of PBB, at some VERBOSITY level.  */
541 
542 void
543 print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity ATTRIBUTE_UNUSED)
544 {
545   print_isl_set (file, pbb->domain);
546 }
547 
548 /* Dump the cases of a graphite basic block GBB on FILE.  */
549 
550 static void
551 dump_gbb_cases (FILE *file, gimple_bb_p gbb)
552 {
553   int i;
554   gimple stmt;
555   vec<gimple> cases;
556 
557   if (!gbb)
558     return;
559 
560   cases = GBB_CONDITION_CASES (gbb);
561   if (cases.is_empty ())
562     return;
563 
564   fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index);
565 
566   FOR_EACH_VEC_ELT (cases, i, stmt)
567     {
568       fprintf (file, "# ");
569       print_gimple_stmt (file, stmt, 0, 0);
570     }
571 
572   fprintf (file, "#)\n");
573 }
574 
575 /* Dump conditions of a graphite basic block GBB on FILE.  */
576 
577 static void
578 dump_gbb_conditions (FILE *file, gimple_bb_p gbb)
579 {
580   int i;
581   gimple stmt;
582   vec<gimple> conditions;
583 
584   if (!gbb)
585     return;
586 
587   conditions = GBB_CONDITIONS (gbb);
588   if (conditions.is_empty ())
589     return;
590 
591   fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index);
592 
593   FOR_EACH_VEC_ELT (conditions, i, stmt)
594     {
595       fprintf (file, "# ");
596       print_gimple_stmt (file, stmt, 0, 0);
597     }
598 
599   fprintf (file, "#)\n");
600 }
601 
602 /* Print to FILE all the data references of PBB, at some VERBOSITY
603    level.  */
604 
605 void
606 print_pdrs (FILE *file, poly_bb_p pbb, int verbosity)
607 {
608   int i;
609   poly_dr_p pdr;
610   int nb_reads = 0;
611   int nb_writes = 0;
612 
613   if (PBB_DRS (pbb).length () == 0)
614     {
615       if (verbosity > 0)
616 	fprintf (file, "# Access informations are not provided\n");\
617       fprintf (file, "0\n");
618       return;
619     }
620 
621   if (verbosity > 1)
622     fprintf (file, "# Data references (\n");
623 
624   if (verbosity > 0)
625     fprintf (file, "# Access informations are provided\n");
626   fprintf (file, "1\n");
627 
628   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
629     if (PDR_TYPE (pdr) == PDR_READ)
630       nb_reads++;
631     else
632       nb_writes++;
633 
634   if (verbosity > 1)
635     fprintf (file, "# Read data references (\n");
636 
637   if (verbosity > 0)
638     fprintf (file, "# Read access informations\n");
639   fprintf (file, "%d\n", nb_reads);
640 
641   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
642     if (PDR_TYPE (pdr) == PDR_READ)
643       print_pdr (file, pdr, verbosity);
644 
645   if (verbosity > 1)
646     fprintf (file, "#)\n");
647 
648   if (verbosity > 1)
649     fprintf (file, "# Write data references (\n");
650 
651   if (verbosity > 0)
652     fprintf (file, "# Write access informations\n");
653   fprintf (file, "%d\n", nb_writes);
654 
655   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
656     if (PDR_TYPE (pdr) != PDR_READ)
657       print_pdr (file, pdr, verbosity);
658 
659   if (verbosity > 1)
660     fprintf (file, "#)\n");
661 
662   if (verbosity > 1)
663     fprintf (file, "#)\n");
664 }
665 
666 /* Print to STDERR all the data references of PBB.  */
667 
668 DEBUG_FUNCTION void
669 debug_pdrs (poly_bb_p pbb, int verbosity)
670 {
671   print_pdrs (stderr, pbb, verbosity);
672 }
673 
674 /* Print to FILE the body of PBB, at some VERBOSITY level.
675    If statement_body_provided is false statement body is not printed.  */
676 
677 static void
678 print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity,
679 		bool statement_body_provided)
680 {
681   if (verbosity > 1)
682     fprintf (file, "# Body (\n");
683 
684   if (!statement_body_provided)
685     {
686       if (verbosity > 0)
687 	fprintf (file, "# Statement body is not provided\n");
688 
689       fprintf (file, "0\n");
690 
691       if (verbosity > 1)
692 	fprintf (file, "#)\n");
693       return;
694     }
695 
696   if (verbosity > 0)
697     fprintf (file, "# Statement body is provided\n");
698   fprintf (file, "1\n");
699 
700   if (verbosity > 0)
701     fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
702 
703   if (verbosity > 0)
704     fprintf (file, "# Statement body\n");
705 
706   fprintf (file, "{\n");
707   dump_bb (file, pbb_bb (pbb), 0, 0);
708   fprintf (file, "}\n");
709 
710   if (verbosity > 1)
711     fprintf (file, "#)\n");
712 }
713 
714 /* Print to FILE the domain and scattering function of PBB, at some
715    VERBOSITY level.  */
716 
717 void
718 print_pbb (FILE *file, poly_bb_p pbb, int verbosity)
719 {
720   if (verbosity > 1)
721     {
722       fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
723       dump_gbb_conditions (file, PBB_BLACK_BOX (pbb));
724       dump_gbb_cases (file, PBB_BLACK_BOX (pbb));
725     }
726 
727   openscop_print_pbb_domain (file, pbb, verbosity);
728   print_scattering_function (file, pbb, verbosity);
729   print_pdrs (file, pbb, verbosity);
730   print_pbb_body (file, pbb, verbosity, false);
731 
732   if (verbosity > 1)
733     fprintf (file, "#)\n");
734 }
735 
736 /* Print to FILE the parameters of SCOP, at some VERBOSITY level.  */
737 
738 void
739 print_scop_params (FILE *file, scop_p scop, int verbosity)
740 {
741   int i;
742   tree t;
743 
744   if (verbosity > 1)
745     fprintf (file, "# parameters (\n");
746 
747   if (SESE_PARAMS (SCOP_REGION (scop)).length ())
748     {
749       if (verbosity > 0)
750 	fprintf (file, "# Parameter names are provided\n");
751 
752       fprintf (file, "1\n");
753 
754       if (verbosity > 0)
755 	fprintf (file, "# Parameter names\n");
756     }
757   else
758     {
759       if (verbosity > 0)
760 	fprintf (file, "# Parameter names are not provided\n");
761       fprintf (file, "0\n");
762     }
763 
764   FOR_EACH_VEC_ELT (SESE_PARAMS (SCOP_REGION (scop)), i, t)
765     {
766       print_generic_expr (file, t, 0);
767       fprintf (file, " ");
768     }
769 
770   fprintf (file, "\n");
771 
772   if (verbosity > 1)
773     fprintf (file, "#)\n");
774 }
775 
776 /* Print to FILE the context of SCoP in OpenScop format, at some VERBOSITY
777    level.  */
778 
779 static void
780 openscop_print_scop_context (FILE *file, scop_p scop, int verbosity)
781 {
782   graphite_dim_t i;
783 
784   if (verbosity > 0)
785     {
786       fprintf (file, "# Context (\n");
787       fprintf (file, "#eq");
788 
789       for (i = 0; i < scop_nb_params (scop); i++)
790 	fprintf (file, "     p%d", (int) i);
791 
792       fprintf (file, "    cst\n");
793     }
794 
795   if (scop->context)
796     /* XXX isl print context */
797     fprintf (file, "XXX isl\n");
798   else
799     fprintf (file, "0 %d 0 0 0 %d\n", (int) scop_nb_params (scop) + 2,
800 	     (int) scop_nb_params (scop));
801 
802   if (verbosity > 0)
803     fprintf (file, "# )\n");
804 }
805 
806 /* Print to FILE the context of SCoP, at some VERBOSITY level.  */
807 
808 void
809 print_scop_context (FILE *file, scop_p scop, int verbosity)
810 {
811   graphite_dim_t i;
812 
813   if (verbosity > 0)
814     {
815       fprintf (file, "# Context (\n");
816       fprintf (file, "#eq");
817 
818       for (i = 0; i < scop_nb_params (scop); i++)
819 	fprintf (file, "     p%d", (int) i);
820 
821       fprintf (file, "    cst\n");
822     }
823 
824   if (scop->context)
825     print_isl_set (file, scop->context);
826   else
827     fprintf (file, "no isl context %d\n", (int) scop_nb_params (scop) + 2);
828 
829   if (verbosity > 0)
830     fprintf (file, "# )\n");
831 }
832 
833 /* Print to FILE the SCOP, at some VERBOSITY level.  */
834 
835 void
836 print_scop (FILE *file, scop_p scop, int verbosity)
837 {
838   int i;
839   poly_bb_p pbb;
840 
841   fprintf (file, "SCoP 1\n#(\n");
842   fprintf (file, "# Language\nGimple\n");
843   openscop_print_scop_context (file, scop, verbosity);
844   print_scop_params (file, scop, verbosity);
845 
846   if (verbosity > 0)
847     fprintf (file, "# Number of statements\n");
848 
849   fprintf (file, "%d\n", SCOP_BBS (scop).length ());
850 
851   FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
852     print_pbb (file, pbb, verbosity);
853 
854   if (verbosity > 1)
855     {
856       fprintf (file, "# original_lst (\n");
857       print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0);
858       fprintf (file, "\n#)\n");
859 
860       fprintf (file, "# transformed_lst (\n");
861       print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
862       fprintf (file, "\n#)\n");
863     }
864 
865   fprintf (file, "#)\n");
866 }
867 
868 /* Print to STDERR the domain of PBB, at some VERBOSITY level.  */
869 
870 DEBUG_FUNCTION void
871 debug_pbb_domain (poly_bb_p pbb, int verbosity)
872 {
873   print_pbb_domain (stderr, pbb, verbosity);
874 }
875 
876 /* Print to FILE the domain and scattering function of PBB, at some
877    VERBOSITY level.  */
878 
879 DEBUG_FUNCTION void
880 debug_pbb (poly_bb_p pbb, int verbosity)
881 {
882   print_pbb (stderr, pbb, verbosity);
883 }
884 
885 /* Print to STDERR the context of SCOP, at some VERBOSITY level.  */
886 
887 DEBUG_FUNCTION void
888 debug_scop_context (scop_p scop, int verbosity)
889 {
890   print_scop_context (stderr, scop, verbosity);
891 }
892 
893 /* Print to STDERR the SCOP, at some VERBOSITY level.  */
894 
895 DEBUG_FUNCTION void
896 debug_scop (scop_p scop, int verbosity)
897 {
898   print_scop (stderr, scop, verbosity);
899 }
900 
901 /* Print to STDERR the parameters of SCOP, at some VERBOSITY
902    level.  */
903 
904 DEBUG_FUNCTION void
905 debug_scop_params (scop_p scop, int verbosity)
906 {
907   print_scop_params (stderr, scop, verbosity);
908 }
909 
910 extern isl_ctx *the_isl_ctx;
911 void
912 print_isl_set (FILE *f, isl_set *set)
913 {
914   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
915   p = isl_printer_print_set (p, set);
916   isl_printer_free (p);
917 }
918 
919 DEBUG_FUNCTION void
920 debug_isl_set (isl_set *set)
921 {
922   print_isl_set (stderr, set);
923 }
924 
925 void
926 print_isl_map (FILE *f, isl_map *map)
927 {
928   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
929   p = isl_printer_print_map (p, map);
930   isl_printer_free (p);
931 }
932 
933 DEBUG_FUNCTION void
934 debug_isl_map (isl_map *map)
935 {
936   print_isl_map (stderr, map);
937 }
938 
939 void
940 print_isl_aff (FILE *f, isl_aff *aff)
941 {
942   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
943   p = isl_printer_print_aff (p, aff);
944   isl_printer_free (p);
945 }
946 
947 DEBUG_FUNCTION void
948 debug_isl_aff (isl_aff *aff)
949 {
950   print_isl_aff (stderr, aff);
951 }
952 
953 void
954 print_isl_constraint (FILE *f, isl_constraint *c)
955 {
956   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
957   p = isl_printer_print_constraint (p, c);
958   isl_printer_free (p);
959 }
960 
961 DEBUG_FUNCTION void
962 debug_isl_constraint (isl_constraint *c)
963 {
964   print_isl_constraint (stderr, c);
965 }
966 
967 /* Returns the number of iterations RES of the loop around PBB at
968    time(scattering) dimension TIME_DEPTH.  */
969 
970 void
971 pbb_number_of_iterations_at_time (poly_bb_p pbb,
972 				  graphite_dim_t time_depth,
973 				  mpz_t res)
974 {
975   isl_set *transdomain;
976   isl_space *dc;
977   isl_aff *aff;
978   isl_val *isllb, *islub;
979 
980   /* Map the iteration domain through the current scatter, and work
981      on the resulting set.  */
982   transdomain = isl_set_apply (isl_set_copy (pbb->domain),
983 			       isl_map_copy (pbb->transformed));
984 
985   /* Select the time_depth' dimension via an affine expression.  */
986   dc = isl_set_get_space (transdomain);
987   aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
988   aff = isl_aff_set_coefficient_si (aff, isl_dim_in, time_depth, 1);
989 
990   /* And find the min/max for that function.  */
991   /* XXX isl check results?  */
992   isllb = isl_set_min_val (transdomain, aff);
993   islub = isl_set_max_val (transdomain, aff);
994 
995   islub = isl_val_sub (islub, isllb);
996   islub = isl_val_add_ui (islub, 1);
997   isl_val_get_num_gmp (islub, res);
998 
999   isl_val_free (islub);
1000   isl_aff_free (aff);
1001   isl_set_free (transdomain);
1002 }
1003 
1004 /* Translates LOOP to LST.  */
1005 
1006 static lst_p
1007 loop_to_lst (loop_p loop, vec<poly_bb_p> bbs, int *i)
1008 {
1009   poly_bb_p pbb;
1010   vec<lst_p> seq;
1011   seq.create (5);
1012 
1013   for (; bbs.iterate (*i, &pbb); (*i)++)
1014     {
1015       lst_p stmt;
1016       basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb));
1017 
1018       if (bb->loop_father == loop)
1019 	stmt = new_lst_stmt (pbb);
1020       else if (flow_bb_inside_loop_p (loop, bb))
1021 	{
1022 	  loop_p next = loop->inner;
1023 
1024 	  while (next && !flow_bb_inside_loop_p (next, bb))
1025 	    next = next->next;
1026 
1027 	  stmt = loop_to_lst (next, bbs, i);
1028 	}
1029       else
1030 	{
1031 	  (*i)--;
1032 	  return new_lst_loop (seq);
1033 	}
1034 
1035       seq.safe_push (stmt);
1036     }
1037 
1038   return new_lst_loop (seq);
1039 }
1040 
1041 /* Reads the original scattering of the SCOP and returns an LST
1042    representing it.  */
1043 
1044 void
1045 scop_to_lst (scop_p scop)
1046 {
1047   lst_p res;
1048   int i, n = SCOP_BBS (scop).length ();
1049   vec<lst_p> seq;
1050   seq.create (5);
1051   sese region = SCOP_REGION (scop);
1052 
1053   for (i = 0; i < n; i++)
1054     {
1055       poly_bb_p pbb = SCOP_BBS (scop)[i];
1056       loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb)));
1057 
1058       if (loop_in_sese_p (loop, region))
1059 	res = loop_to_lst (loop, SCOP_BBS (scop), &i);
1060       else
1061 	res = new_lst_stmt (pbb);
1062 
1063       seq.safe_push (res);
1064     }
1065 
1066   res = new_lst_loop (seq);
1067   SCOP_ORIGINAL_SCHEDULE (scop) = res;
1068   SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res);
1069 }
1070 
1071 /* Print to FILE on a new line COLUMN white spaces.  */
1072 
1073 static void
1074 lst_indent_to (FILE *file, int column)
1075 {
1076   int i;
1077 
1078   if (column > 0)
1079     fprintf (file, "\n#");
1080 
1081   for (i = 0; i < column; i++)
1082     fprintf (file, " ");
1083 }
1084 
1085 /* Print LST to FILE with INDENT spaces of indentation.  */
1086 
1087 void
1088 print_lst (FILE *file, lst_p lst, int indent)
1089 {
1090   if (!lst)
1091     return;
1092 
1093   lst_indent_to (file, indent);
1094 
1095   if (LST_LOOP_P (lst))
1096     {
1097       int i;
1098       lst_p l;
1099 
1100       if (LST_LOOP_FATHER (lst))
1101 	fprintf (file, "%d (loop", lst_dewey_number (lst));
1102       else
1103 	fprintf (file, "#(root");
1104 
1105       FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
1106 	print_lst (file, l, indent + 2);
1107 
1108       fprintf (file, ")");
1109     }
1110   else
1111     fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst)));
1112 }
1113 
1114 /* Print LST to STDERR.  */
1115 
1116 DEBUG_FUNCTION void
1117 debug_lst (lst_p lst)
1118 {
1119   print_lst (stderr, lst, 0);
1120 }
1121 
1122 /* Pretty print to FILE the loop statement tree LST in DOT format.  */
1123 
1124 static void
1125 dot_lst_1 (FILE *file, lst_p lst)
1126 {
1127   if (!lst)
1128     return;
1129 
1130   if (LST_LOOP_P (lst))
1131     {
1132       int i;
1133       lst_p l;
1134 
1135       if (!LST_LOOP_FATHER (lst))
1136 	fprintf (file, "L -> L_%d_%d\n",
1137 		 lst_depth (lst),
1138 		 lst_dewey_number (lst));
1139       else
1140 	fprintf (file, "L_%d_%d -> L_%d_%d\n",
1141 		 lst_depth (LST_LOOP_FATHER (lst)),
1142 		 lst_dewey_number (LST_LOOP_FATHER (lst)),
1143 		 lst_depth (lst),
1144 		 lst_dewey_number (lst));
1145 
1146       FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
1147 	dot_lst_1 (file, l);
1148     }
1149 
1150   else
1151     fprintf (file, "L_%d_%d -> S_%d\n",
1152 	     lst_depth (LST_LOOP_FATHER (lst)),
1153 	     lst_dewey_number (LST_LOOP_FATHER (lst)),
1154 	     pbb_index (LST_PBB (lst)));
1155 
1156 }
1157 
1158 /* Display the LST using dotty.  */
1159 
1160 DEBUG_FUNCTION void
1161 dot_lst (lst_p lst)
1162 {
1163   /* When debugging, enable the following code.  This cannot be used
1164      in production compilers because it calls "system".  */
1165 #if 0
1166   FILE *stream = fopen ("/tmp/lst.dot", "w");
1167   gcc_assert (stream);
1168 
1169   fputs ("digraph all {\n", stream);
1170   dot_lst_1 (stream, lst);
1171   fputs ("}\n\n", stream);
1172   fclose (stream);
1173 
1174   system ("dotty /tmp/lst.dot &");
1175 #else
1176   fputs ("digraph all {\n", stderr);
1177   dot_lst_1 (stderr, lst);
1178   fputs ("}\n\n", stderr);
1179 
1180 #endif
1181 }
1182 
1183 /* Reverse the loop around PBB at level DEPTH.  */
1184 
1185 isl_map *
1186 reverse_loop_at_level (poly_bb_p pbb, int depth)
1187 {
1188   unsigned i, depth_dim = psct_dynamic_dim (pbb, depth);
1189   isl_space *d = isl_map_get_space (pbb->transformed);
1190   isl_space *d1 = isl_space_range (d);
1191   unsigned n = isl_space_dim (d1, isl_dim_out);
1192   isl_space *d2 = isl_space_add_dims (d1, isl_dim_in, n);
1193   isl_map *x = isl_map_universe (isl_space_copy (d2));
1194   isl_constraint *c = isl_equality_alloc (isl_local_space_from_space (d2));
1195 
1196   for (i = 0; i < n; i++)
1197     if (i != depth_dim)
1198       x = isl_map_equate (x, isl_dim_in, i, isl_dim_out, i);
1199 
1200   c = isl_constraint_set_coefficient_si (c, isl_dim_in, depth_dim, 1);
1201   c = isl_constraint_set_coefficient_si (c, isl_dim_out, depth_dim, 1);
1202   x = isl_map_add_constraint (x, c);
1203   return x;
1204 }
1205 
1206 /* Reverse the loop at level DEPTH for all the PBBS.  */
1207 
1208 isl_union_map *
1209 reverse_loop_for_pbbs (scop_p scop, vec<poly_bb_p> pbbs, int depth)
1210 {
1211   poly_bb_p pbb;
1212   int i;
1213   isl_space *space = isl_space_from_domain (isl_set_get_space (scop->context));
1214   isl_union_map *res = isl_union_map_empty (space);
1215 
1216   for (i = 0; pbbs.iterate (i, &pbb); i++)
1217     res = isl_union_map_add_map (res, reverse_loop_at_level (pbb, depth));
1218 
1219   return res;
1220 }
1221 
1222 
1223 #endif
1224 
1225