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
debug_gmp_value(mpz_t val)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
print_iteration_domain(FILE * file,poly_bb_p pbb)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
print_iteration_domains(FILE * file,scop_p scop)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
debug_iteration_domain(poly_bb_p pbb)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
debug_iteration_domains(scop_p scop)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
new_poly_dr(poly_bb_p pbb,gimple * stmt,enum poly_dr_type type,isl_map * acc,isl_set * subscript_sizes)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
free_poly_dr(poly_dr_p pdr)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
new_poly_bb(scop_p scop,gimple_poly_bb_p black_box)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
free_poly_bb(poly_bb_p pbb)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
print_pdr(FILE * file,poly_dr_p pdr)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
debug_pdr(poly_dr_p pdr)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
new_gimple_poly_bb(basic_block bb,vec<data_reference_p> drs,vec<scalar_use> reads,vec<tree> writes)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
free_gimple_poly_bb(gimple_poly_bb_p gbb)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
remove_gbbs_in_scop(scop_p scop)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
new_scop(edge entry,edge exit)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
free_scop(scop_p scop)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
print_pbb_domain(FILE * file,poly_bb_p pbb)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
dump_gbb_cases(FILE * file,gimple_poly_bb_p gbb)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
dump_gbb_conditions(FILE * file,gimple_poly_bb_p gbb)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
print_pdrs(FILE * file,poly_bb_p pbb)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
debug_pdrs(poly_bb_p pbb)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
print_pbb_body(FILE * file,poly_bb_p pbb)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
print_pbb(FILE * file,poly_bb_p pbb)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
print_scop_params(FILE * file,scop_p scop)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
print_scop_context(FILE * file,scop_p scop)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
print_scop(FILE * file,scop_p scop)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
debug_pbb_domain(poly_bb_p pbb)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
debug_pbb(poly_bb_p pbb)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
debug_scop_context(scop_p scop)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
debug_scop(scop_p scop)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
debug_scop_params(scop_p scop)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
print_isl_set(FILE * f,__isl_keep isl_set * set)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
debug_isl_set(__isl_keep isl_set * set)555 debug_isl_set (__isl_keep isl_set *set)
556 {
557   print_isl_set (stderr, set);
558 }
559 
560 void
print_isl_map(FILE * f,__isl_keep isl_map * map)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
debug_isl_map(__isl_keep isl_map * map)573 debug_isl_map (__isl_keep isl_map *map)
574 {
575   print_isl_map (stderr, map);
576 }
577 
578 void
print_isl_union_map(FILE * f,__isl_keep isl_union_map * map)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
debug_isl_union_map(__isl_keep isl_union_map * map)591 debug_isl_union_map (__isl_keep isl_union_map *map)
592 {
593   print_isl_union_map (stderr, map);
594 }
595 
596 void
print_isl_aff(FILE * f,__isl_keep isl_aff * aff)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
debug_isl_aff(__isl_keep isl_aff * aff)606 debug_isl_aff (__isl_keep isl_aff *aff)
607 {
608   print_isl_aff (stderr, aff);
609 }
610 
611 void
print_isl_constraint(FILE * f,__isl_keep isl_constraint * c)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
debug_isl_constraint(__isl_keep isl_constraint * c)621 debug_isl_constraint (__isl_keep isl_constraint *c)
622 {
623   print_isl_constraint (stderr, c);
624 }
625 
626 void
print_isl_schedule(FILE * f,__isl_keep isl_schedule * s)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
debug_isl_schedule(__isl_keep isl_schedule * s)639 debug_isl_schedule (__isl_keep isl_schedule *s)
640 {
641   print_isl_schedule (stderr, s);
642 }
643 
644 void
print_isl_ast(FILE * file,__isl_keep isl_ast_node * n)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
debug_isl_ast(isl_ast_node * n)655 debug_isl_ast (isl_ast_node *n)
656 {
657   print_isl_ast (stderr, n);
658 }
659 
660 DEBUG_FUNCTION void
debug_scop_pbb(scop_p scop,int i)661 debug_scop_pbb (scop_p scop, int i)
662 {
663   debug_pbb (scop->pbbs[i]);
664 }
665 
666 #endif  /* HAVE_isl */
667 
668