gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / gcc / graphite-poly.c
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