Backport from GCC mainline.
[platform/upstream/linaro-gcc.git] / gcc / graphite-poly.c
1 /* Graphite polyhedral representation.
2    Copyright (C) 2009-2016 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 #define USES_ISL
23
24 #include "config.h"
25
26 #ifdef HAVE_isl
27
28 #include "system.h"
29 #include "coretypes.h"
30 #include "backend.h"
31 #include "tree.h"
32 #include "gimple.h"
33 #include "cfghooks.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
37 #include "tree-ssa-loop.h"
38 #include "cfgloop.h"
39 #include "tree-data-ref.h"
40 #include "pretty-print.h"
41 #include "gimple-pretty-print.h"
42 #include "tree-dump.h"
43 #include "graphite.h"
44
45 /* Print to STDERR the GMP value VAL.  */
46
47 DEBUG_FUNCTION void
48 debug_gmp_value (mpz_t val)
49 {
50   gmp_fprintf (stderr, "%Zd", val);
51 }
52
53 /* Prints to FILE the iteration domain of PBB.  */
54
55 void
56 print_iteration_domain (FILE *file, poly_bb_p pbb)
57 {
58   print_pbb_domain (file, pbb);
59 }
60
61 /* Prints to FILE the iteration domains of every PBB of SCOP.  */
62
63 void
64 print_iteration_domains (FILE *file, scop_p scop)
65 {
66   int i;
67   poly_bb_p pbb;
68
69   FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
70     print_iteration_domain (file, pbb);
71 }
72
73 /* Prints to STDERR the iteration domain of PBB.  */
74
75 DEBUG_FUNCTION void
76 debug_iteration_domain (poly_bb_p pbb)
77 {
78   print_iteration_domain (stderr, pbb);
79 }
80
81 /* Prints to STDERR the iteration domains of every PBB of SCOP.  */
82
83 DEBUG_FUNCTION void
84 debug_iteration_domains (scop_p scop)
85 {
86   print_iteration_domains (stderr, scop);
87 }
88
89 /* Create a new polyhedral data reference and add it to PBB.  It is
90    defined by its ACCESSES, its TYPE, and the number of subscripts
91    NB_SUBSCRIPTS.  */
92
93 void
94 new_poly_dr (poly_bb_p pbb, gimple *stmt, enum poly_dr_type type,
95              isl_map *acc, isl_set *subscript_sizes)
96 {
97   static int id = 0;
98   poly_dr_p pdr = XNEW (struct poly_dr);
99
100   pdr->stmt = stmt;
101   PDR_ID (pdr) = id++;
102   PDR_NB_REFS (pdr) = 1;
103   PDR_PBB (pdr) = pbb;
104   pdr->accesses = acc;
105   pdr->subscript_sizes = subscript_sizes;
106   PDR_TYPE (pdr) = type;
107   PBB_DRS (pbb).safe_push (pdr);
108
109   if (dump_file)
110     {
111       fprintf (dump_file, "Converting dr: ");
112       print_pdr (dump_file, pdr);
113       fprintf (dump_file, "To polyhedral representation:\n");
114       fprintf (dump_file, "  - access functions: ");
115       print_isl_map (dump_file, acc);
116       fprintf (dump_file, "  - subscripts: ");
117       print_isl_set (dump_file, subscript_sizes);
118     }
119 }
120
121 /* Free polyhedral data reference PDR.  */
122
123 static void
124 free_poly_dr (poly_dr_p pdr)
125 {
126   isl_map_free (pdr->accesses);
127   isl_set_free (pdr->subscript_sizes);
128   XDELETE (pdr);
129 }
130
131 /* Create a new polyhedral black box.  */
132
133 poly_bb_p
134 new_poly_bb (scop_p scop, gimple_poly_bb_p black_box)
135 {
136   poly_bb_p pbb = XNEW (struct poly_bb);
137
138   pbb->domain = NULL;
139 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
140   pbb->iterators = NULL;
141 #else
142   pbb->schedule = NULL;
143   pbb->transformed = NULL;
144   pbb->saved = NULL;
145 #endif
146   PBB_SCOP (pbb) = scop;
147   pbb_set_black_box (pbb, black_box);
148   PBB_DRS (pbb).create (3);
149   GBB_PBB ((gimple_poly_bb_p) black_box) = pbb;
150
151   return pbb;
152 }
153
154 /* Free polyhedral black box.  */
155
156 static void
157 free_poly_bb (poly_bb_p pbb)
158 {
159   int i;
160   poly_dr_p pdr;
161
162   isl_set_free (pbb->domain);
163   pbb->domain = NULL;
164 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
165   isl_set_free (pbb->iterators);
166   pbb->iterators = NULL;
167 #else
168   isl_map_free (pbb->schedule);
169   pbb->schedule = NULL;
170   isl_map_free (pbb->transformed);
171   pbb->transformed = NULL;
172   isl_map_free (pbb->saved);
173   pbb->saved = NULL;
174 #endif
175
176   if (PBB_DRS (pbb).exists ())
177     FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
178       free_poly_dr (pdr);
179
180   PBB_DRS (pbb).release ();
181   XDELETE (pbb);
182 }
183
184 /* Prints to FILE the polyhedral data reference PDR.  */
185
186 void
187 print_pdr (FILE *file, poly_dr_p pdr)
188 {
189   fprintf (file, "pdr_%d (", PDR_ID (pdr));
190
191   switch (PDR_TYPE (pdr))
192     {
193     case PDR_READ:
194       fprintf (file, "read \n");
195       break;
196
197     case PDR_WRITE:
198       fprintf (file, "write \n");
199       break;
200
201     case PDR_MAY_WRITE:
202       fprintf (file, "may_write \n");
203       break;
204
205     default:
206       gcc_unreachable ();
207     }
208
209   fprintf (file, "in gimple stmt: ");
210   print_gimple_stmt (file, pdr->stmt, 0, 0);
211   fprintf (file, "data accesses: ");
212   print_isl_map (file, pdr->accesses);
213   fprintf (file, "subscript sizes: ");
214   print_isl_set (file, pdr->subscript_sizes);
215   fprintf (file, ")\n");
216 }
217
218 /* Prints to STDERR the polyhedral data reference PDR.  */
219
220 DEBUG_FUNCTION void
221 debug_pdr (poly_dr_p pdr)
222 {
223   print_pdr (stderr, pdr);
224 }
225
226 /* Store the GRAPHITE representation of BB.  */
227
228 gimple_poly_bb_p
229 new_gimple_poly_bb (basic_block bb, vec<data_reference_p> drs,
230                     vec<scalar_use> reads, vec<tree> writes)
231 {
232   gimple_poly_bb_p gbb = XNEW (struct gimple_poly_bb);
233   GBB_BB (gbb) = bb;
234   GBB_DATA_REFS (gbb) = drs;
235   gbb->read_scalar_refs = reads;
236   gbb->write_scalar_refs = writes;
237   GBB_CONDITIONS (gbb).create (0);
238   GBB_CONDITION_CASES (gbb).create (0);
239
240   return gbb;
241 }
242
243 /* Frees GBB.  */
244
245 static void
246 free_gimple_poly_bb (gimple_poly_bb_p gbb)
247 {
248   free_data_refs (GBB_DATA_REFS (gbb));
249   GBB_CONDITIONS (gbb).release ();
250   GBB_CONDITION_CASES (gbb).release ();
251   gbb->read_scalar_refs.release ();
252   gbb->write_scalar_refs.release ();
253   XDELETE (gbb);
254 }
255
256 /* Deletes all gimple bbs in SCOP.  */
257
258 static void
259 remove_gbbs_in_scop (scop_p scop)
260 {
261   int i;
262   poly_bb_p pbb;
263
264   FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
265     free_gimple_poly_bb (PBB_BLACK_BOX (pbb));
266 }
267
268 /* Creates a new SCOP containing the region (ENTRY, EXIT).  */
269
270 scop_p
271 new_scop (edge entry, edge exit)
272 {
273   sese_info_p region = new_sese_info (entry, exit);
274   scop_p s = XNEW (struct scop);
275
276 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
277   s->original_schedule = NULL;
278   s->transformed_schedule = NULL;
279 #else
280   s->schedule = NULL;
281 #endif
282   s->param_context = NULL;
283   scop_set_region (s, region);
284   s->pbbs.create (3);
285   s->drs.create (3);
286   s->dependence = NULL;
287   return s;
288 }
289
290 /* Deletes SCOP.  */
291
292 void
293 free_scop (scop_p scop)
294 {
295   int i;
296   poly_bb_p pbb;
297
298   remove_gbbs_in_scop (scop);
299   free_sese_info (scop->scop_info);
300
301   FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
302     free_poly_bb (pbb);
303
304   scop->pbbs.release ();
305   scop->drs.release ();
306
307   isl_set_free (scop->param_context);
308   scop->param_context = NULL;
309   isl_union_map_free (scop->dependence);
310   scop->dependence = NULL;
311 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
312   isl_schedule_free (scop->original_schedule);
313   scop->original_schedule = NULL;
314   isl_schedule_free (scop->transformed_schedule);
315   scop->transformed_schedule = NULL;
316 #else
317
318 #endif
319   XDELETE (scop);
320 }
321
322 /* Print to FILE the domain of PBB.  */
323
324 void
325 print_pbb_domain (FILE *file, poly_bb_p pbb)
326 {
327   print_isl_set (file, pbb->domain);
328 }
329
330 /* Dump the cases of a graphite basic block GBB on FILE.  */
331
332 static void
333 dump_gbb_cases (FILE *file, gimple_poly_bb_p gbb)
334 {
335   int i;
336   gimple *stmt;
337   vec<gimple *> cases;
338
339   if (!gbb)
340     return;
341
342   cases = GBB_CONDITION_CASES (gbb);
343   if (cases.is_empty ())
344     return;
345
346   fprintf (file, "cases bb_%d (\n", GBB_BB (gbb)->index);
347
348   FOR_EACH_VEC_ELT (cases, i, stmt)
349     print_gimple_stmt (file, stmt, 0, 0);
350
351   fprintf (file, ")\n");
352 }
353
354 /* Dump conditions of a graphite basic block GBB on FILE.  */
355
356 static void
357 dump_gbb_conditions (FILE *file, gimple_poly_bb_p gbb)
358 {
359   int i;
360   gimple *stmt;
361   vec<gimple *> conditions;
362
363   if (!gbb)
364     return;
365
366   conditions = GBB_CONDITIONS (gbb);
367   if (conditions.is_empty ())
368     return;
369
370   fprintf (file, "conditions bb_%d (\n", GBB_BB (gbb)->index);
371
372   FOR_EACH_VEC_ELT (conditions, i, stmt)
373     print_gimple_stmt (file, stmt, 0, 0);
374
375   fprintf (file, ")\n");
376 }
377
378 /* Print to FILE all the data references of PBB.  */
379
380 void
381 print_pdrs (FILE *file, poly_bb_p pbb)
382 {
383   int i;
384   poly_dr_p pdr;
385   int nb_reads = 0;
386   int nb_writes = 0;
387
388   if (PBB_DRS (pbb).is_empty ())
389     return;
390
391   fprintf (file, "Data references (\n");
392
393   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
394     if (PDR_TYPE (pdr) == PDR_READ)
395       nb_reads++;
396     else
397       nb_writes++;
398
399   fprintf (file, "Read data references (\n");
400
401   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
402     if (PDR_TYPE (pdr) == PDR_READ)
403       print_pdr (file, pdr);
404
405   fprintf (file, ")\n");
406   fprintf (file, "Write data references (\n");
407   FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
408     if (PDR_TYPE (pdr) != PDR_READ)
409       print_pdr (file, pdr);
410   fprintf (file, ")\n");
411   fprintf (file, ")\n");
412 }
413
414 /* Print to STDERR all the data references of PBB.  */
415
416 DEBUG_FUNCTION void
417 debug_pdrs (poly_bb_p pbb)
418 {
419   print_pdrs (stderr, pbb);
420 }
421
422 /* Print to FILE the body of PBB.  */
423
424 static void
425 print_pbb_body (FILE *file, poly_bb_p pbb)
426 {
427   fprintf (file, "Body (\n");
428   dump_bb (file, pbb_bb (pbb), 0, 0);
429   fprintf (file, ")\n");
430 }
431
432 /* Print to FILE the domain and scattering function of PBB.  */
433
434 void
435 print_pbb (FILE *file, poly_bb_p pbb)
436 {
437   fprintf (file, "pbb_%d (\n", pbb_index (pbb));
438   dump_gbb_conditions (file, PBB_BLACK_BOX (pbb));
439   dump_gbb_cases (file, PBB_BLACK_BOX (pbb));
440
441   print_pbb_domain (file, pbb);
442   print_pdrs (file, pbb);
443   print_pbb_body (file, pbb);
444
445   fprintf (file, ")\n");
446 }
447
448 /* Print to FILE the parameters of SCOP.  */
449
450 void
451 print_scop_params (FILE *file, scop_p scop)
452 {
453   if (scop->scop_info->params.is_empty ())
454     return;
455
456   int i;
457   tree t;
458   fprintf (file, "parameters (");
459   FOR_EACH_VEC_ELT (scop->scop_info->params, i, t)
460     {
461       print_generic_expr (file, t, 0);
462       fprintf (file, ", ");
463     }
464   fprintf (file, ")\n");
465 }
466
467 /* Print to FILE the context of SCoP.  */
468
469 void
470 print_scop_context (FILE *file, scop_p scop)
471 {
472   if (!scop->param_context)
473     return;
474
475   fprintf (file, "Context (\n");
476   print_isl_set (file, scop->param_context);
477   fprintf (file, ")\n");
478 }
479
480 /* Print to FILE the SCOP.  */
481
482 void
483 print_scop (FILE *file, scop_p scop)
484 {
485   int i;
486   poly_bb_p pbb;
487
488   fprintf (file, "SCoP (\n");
489   print_scop_context (file, scop);
490   print_scop_params (file, scop);
491
492   fprintf (file, "Number of statements: ");
493   fprintf (file, "%d\n", scop->pbbs.length ());
494
495   FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
496     print_pbb (file, pbb);
497
498   fprintf (file, ")\n");
499 }
500
501 /* Print to STDERR the domain of PBB.  */
502
503 DEBUG_FUNCTION void
504 debug_pbb_domain (poly_bb_p pbb)
505 {
506   print_pbb_domain (stderr, pbb);
507 }
508
509 /* Print to FILE the domain and scattering function of PBB.  */
510
511 DEBUG_FUNCTION void
512 debug_pbb (poly_bb_p pbb)
513 {
514   print_pbb (stderr, pbb);
515 }
516
517 /* Print to STDERR the context of SCOP.  */
518
519 DEBUG_FUNCTION void
520 debug_scop_context (scop_p scop)
521 {
522   print_scop_context (stderr, scop);
523 }
524
525 /* Print to STDERR the SCOP.  */
526
527 DEBUG_FUNCTION void
528 debug_scop (scop_p scop)
529 {
530   print_scop (stderr, scop);
531 }
532
533 /* Print to STDERR the parameters of SCOP.  */
534
535 DEBUG_FUNCTION void
536 debug_scop_params (scop_p scop)
537 {
538   print_scop_params (stderr, scop);
539 }
540
541 extern isl_ctx *the_isl_ctx;
542 void
543 print_isl_set (FILE *f, __isl_keep isl_set *set)
544 {
545   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
546 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
547   p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
548 #endif
549   p = isl_printer_print_set (p, set);
550   p = isl_printer_print_str (p, "\n");
551   isl_printer_free (p);
552 }
553
554 DEBUG_FUNCTION void
555 debug_isl_set (__isl_keep isl_set *set)
556 {
557   print_isl_set (stderr, set);
558 }
559
560 void
561 print_isl_map (FILE *f, __isl_keep isl_map *map)
562 {
563   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
564 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
565   p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
566 #endif
567   p = isl_printer_print_map (p, map);
568   p = isl_printer_print_str (p, "\n");
569   isl_printer_free (p);
570 }
571
572 DEBUG_FUNCTION void
573 debug_isl_map (__isl_keep isl_map *map)
574 {
575   print_isl_map (stderr, map);
576 }
577
578 void
579 print_isl_union_map (FILE *f, __isl_keep isl_union_map *map)
580 {
581   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
582 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
583   p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
584 #endif
585   p = isl_printer_print_union_map (p, map);
586   p = isl_printer_print_str (p, "\n");
587   isl_printer_free (p);
588 }
589
590 DEBUG_FUNCTION void
591 debug_isl_union_map (__isl_keep isl_union_map *map)
592 {
593   print_isl_union_map (stderr, map);
594 }
595
596 void
597 print_isl_aff (FILE *f, __isl_keep isl_aff *aff)
598 {
599   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
600   p = isl_printer_print_aff (p, aff);
601   p = isl_printer_print_str (p, "\n");
602   isl_printer_free (p);
603 }
604
605 DEBUG_FUNCTION void
606 debug_isl_aff (__isl_keep isl_aff *aff)
607 {
608   print_isl_aff (stderr, aff);
609 }
610
611 void
612 print_isl_constraint (FILE *f, __isl_keep isl_constraint *c)
613 {
614   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
615   p = isl_printer_print_constraint (p, c);
616   p = isl_printer_print_str (p, "\n");
617   isl_printer_free (p);
618 }
619
620 DEBUG_FUNCTION void
621 debug_isl_constraint (__isl_keep isl_constraint *c)
622 {
623   print_isl_constraint (stderr, c);
624 }
625
626 void
627 print_isl_schedule (FILE *f, __isl_keep isl_schedule *s)
628 {
629   isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
630 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
631   p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
632 #endif
633   p = isl_printer_print_schedule (p, s);
634   p = isl_printer_print_str (p, "\n");
635   isl_printer_free (p);
636 }
637
638 DEBUG_FUNCTION void
639 debug_isl_schedule (__isl_keep isl_schedule *s)
640 {
641   print_isl_schedule (stderr, s);
642 }
643
644 void
645 print_isl_ast (FILE *file, __isl_keep isl_ast_node *n)
646 {
647   isl_printer *prn = isl_printer_to_file (the_isl_ctx, file);
648   prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
649   prn = isl_printer_print_ast_node (prn, n);
650   prn = isl_printer_print_str (prn, "\n");
651   isl_printer_free (prn);
652 }
653
654 DEBUG_FUNCTION void
655 debug_isl_ast (isl_ast_node *n)
656 {
657   print_isl_ast (stderr, n);
658 }
659
660 DEBUG_FUNCTION void
661 debug_scop_pbb (scop_p scop, int i)
662 {
663   debug_pbb (scop->pbbs[i]);
664 }
665
666 #endif  /* HAVE_isl */
667