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>.
6 This file is part of GCC.
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)
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.
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/>. */
29 #include "coretypes.h"
34 #include "gimple-pretty-print.h"
35 #include "diagnostic-core.h"
36 #include "fold-const.h"
37 #include "gimple-iterator.h"
38 #include "tree-ssa-loop.h"
40 #include "tree-data-ref.h"
42 #include <isl/constraint.h>
45 #include <isl/union_map.h>
46 #include <isl/constraint.h>
51 /* Since ISL-0.13, the extern is in val_gmp.h. */
52 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
55 #include <isl/val_gmp.h>
56 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
62 #define OPENSCOP_MAX_STRING 256
65 /* Print to STDERR the GMP value VAL. */
68 debug_gmp_value (mpz_t val
)
70 gmp_fprintf (stderr
, "%Zd", val
);
73 /* Prints to FILE the iteration domain of PBB. */
76 print_iteration_domain (FILE *file
, poly_bb_p pbb
)
78 print_pbb_domain (file
, pbb
);
81 /* Prints to FILE the iteration domains of every PBB of SCOP. */
84 print_iteration_domains (FILE *file
, scop_p scop
)
89 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
90 print_iteration_domain (file
, pbb
);
93 /* Prints to STDERR the iteration domain of PBB. */
96 debug_iteration_domain (poly_bb_p pbb
)
98 print_iteration_domain (stderr
, pbb
);
101 /* Prints to STDERR the iteration domains of every PBB of SCOP. */
104 debug_iteration_domains (scop_p scop
)
106 print_iteration_domains (stderr
, scop
);
109 /* Apply graphite transformations to all the basic blocks of SCOP. */
112 apply_poly_transforms (scop_p scop
)
114 bool transform_done
= false;
116 /* Generate code even if we did not apply any real transformation.
117 This also allows to check the performance for the identity
118 transformation: GIMPLE -> GRAPHITE -> GIMPLE. */
119 if (flag_graphite_identity
)
120 transform_done
= true;
122 if (flag_loop_parallelize_all
)
123 transform_done
= true;
125 if (flag_loop_nest_optimize
)
126 transform_done
|= optimize_isl (scop
);
128 return transform_done
;
131 /* Create a new polyhedral data reference and add it to PBB. It is
132 defined by its ACCESSES, its TYPE, and the number of subscripts
136 new_poly_dr (poly_bb_p pbb
, gimple
*stmt
, enum poly_dr_type type
,
137 isl_map
*acc
, isl_set
*subscript_sizes
)
140 poly_dr_p pdr
= XNEW (struct poly_dr
);
144 PDR_NB_REFS (pdr
) = 1;
147 pdr
->subscript_sizes
= subscript_sizes
;
148 PDR_TYPE (pdr
) = type
;
149 PBB_DRS (pbb
).safe_push (pdr
);
152 /* Free polyhedral data reference PDR. */
155 free_poly_dr (poly_dr_p pdr
)
157 isl_map_free (pdr
->accesses
);
158 isl_set_free (pdr
->subscript_sizes
);
162 /* Create a new polyhedral black box. */
165 new_poly_bb (scop_p scop
, gimple_poly_bb_p black_box
)
167 poly_bb_p pbb
= XNEW (struct poly_bb
);
170 pbb
->schedule
= NULL
;
171 pbb
->transformed
= NULL
;
173 PBB_SCOP (pbb
) = scop
;
174 pbb_set_black_box (pbb
, black_box
);
175 PBB_DRS (pbb
).create (3);
176 PBB_IS_REDUCTION (pbb
) = false;
177 GBB_PBB ((gimple_poly_bb_p
) black_box
) = pbb
;
182 /* Free polyhedral black box. */
185 free_poly_bb (poly_bb_p pbb
)
190 isl_set_free (pbb
->domain
);
191 isl_map_free (pbb
->schedule
);
192 isl_map_free (pbb
->transformed
);
193 isl_map_free (pbb
->saved
);
195 if (PBB_DRS (pbb
).exists ())
196 FOR_EACH_VEC_ELT (PBB_DRS (pbb
), i
, pdr
)
199 PBB_DRS (pbb
).release ();
203 /* Prints to FILE the polyhedral data reference PDR. */
206 print_pdr (FILE *file
, poly_dr_p pdr
)
208 fprintf (file
, "pdr_%d (", PDR_ID (pdr
));
210 switch (PDR_TYPE (pdr
))
213 fprintf (file
, "read \n");
217 fprintf (file
, "write \n");
221 fprintf (file
, "may_write \n");
228 fprintf (file
, "in gimple stmt: ");
229 print_gimple_stmt (file
, pdr
->stmt
, 0, 0);
230 fprintf (file
, "data accesses: ");
231 print_isl_map (file
, pdr
->accesses
);
232 fprintf (file
, "subscript sizes: ");
233 print_isl_set (file
, pdr
->subscript_sizes
);
234 fprintf (file
, ")\n");
237 /* Prints to STDERR the polyhedral data reference PDR. */
240 debug_pdr (poly_dr_p pdr
)
242 print_pdr (stderr
, pdr
);
245 /* Store the GRAPHITE representation of BB. */
248 new_gimple_poly_bb (basic_block bb
, vec
<data_reference_p
> drs
,
249 vec
<scalar_use
> reads
, vec
<tree
> writes
)
251 gimple_poly_bb_p gbb
= XNEW (struct gimple_poly_bb
);
253 GBB_DATA_REFS (gbb
) = drs
;
254 gbb
->read_scalar_refs
= reads
;
255 gbb
->write_scalar_refs
= writes
;
256 GBB_CONDITIONS (gbb
).create (0);
257 GBB_CONDITION_CASES (gbb
).create (0);
265 free_gimple_poly_bb (gimple_poly_bb_p gbb
)
267 free_data_refs (GBB_DATA_REFS (gbb
));
268 GBB_CONDITIONS (gbb
).release ();
269 GBB_CONDITION_CASES (gbb
).release ();
270 gbb
->read_scalar_refs
.release ();
271 gbb
->write_scalar_refs
.release ();
275 /* Deletes all gimple bbs in SCOP. */
278 remove_gbbs_in_scop (scop_p scop
)
283 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
284 free_gimple_poly_bb (PBB_BLACK_BOX (pbb
));
287 /* Creates a new SCOP containing the region (ENTRY, EXIT). */
290 new_scop (edge entry
, edge exit
)
292 sese_info_p region
= new_sese_info (entry
, exit
);
293 scop_p scop
= XNEW (struct scop
);
295 scop
->param_context
= NULL
;
296 scop
->must_raw
= NULL
;
297 scop
->may_raw
= NULL
;
298 scop
->must_raw_no_source
= NULL
;
299 scop
->may_raw_no_source
= NULL
;
300 scop
->must_war
= NULL
;
301 scop
->may_war
= NULL
;
302 scop
->must_war_no_source
= NULL
;
303 scop
->may_war_no_source
= NULL
;
304 scop
->must_waw
= NULL
;
305 scop
->may_waw
= NULL
;
306 scop
->must_waw_no_source
= NULL
;
307 scop
->may_waw_no_source
= NULL
;
308 scop_set_region (scop
, region
);
309 scop
->pbbs
.create (3);
310 scop
->drs
.create (3);
318 free_scop (scop_p scop
)
323 remove_gbbs_in_scop (scop
);
324 free_sese_info (scop
->scop_info
);
326 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
329 scop
->pbbs
.release ();
330 scop
->drs
.release ();
332 isl_set_free (scop
->param_context
);
333 isl_union_map_free (scop
->must_raw
);
334 isl_union_map_free (scop
->may_raw
);
335 isl_union_map_free (scop
->must_raw_no_source
);
336 isl_union_map_free (scop
->may_raw_no_source
);
337 isl_union_map_free (scop
->must_war
);
338 isl_union_map_free (scop
->may_war
);
339 isl_union_map_free (scop
->must_war_no_source
);
340 isl_union_map_free (scop
->may_war_no_source
);
341 isl_union_map_free (scop
->must_waw
);
342 isl_union_map_free (scop
->may_waw
);
343 isl_union_map_free (scop
->must_waw_no_source
);
344 isl_union_map_free (scop
->may_waw_no_source
);
348 /* Print to FILE the domain of PBB. */
351 print_pbb_domain (FILE *file
, poly_bb_p pbb
)
353 print_isl_set (file
, pbb
->domain
);
356 /* Dump the cases of a graphite basic block GBB on FILE. */
359 dump_gbb_cases (FILE *file
, gimple_poly_bb_p gbb
)
368 cases
= GBB_CONDITION_CASES (gbb
);
369 if (cases
.is_empty ())
372 fprintf (file
, "cases bb_%d (\n", GBB_BB (gbb
)->index
);
374 FOR_EACH_VEC_ELT (cases
, i
, stmt
)
375 print_gimple_stmt (file
, stmt
, 0, 0);
377 fprintf (file
, ")\n");
380 /* Dump conditions of a graphite basic block GBB on FILE. */
383 dump_gbb_conditions (FILE *file
, gimple_poly_bb_p gbb
)
387 vec
<gimple
*> conditions
;
392 conditions
= GBB_CONDITIONS (gbb
);
393 if (conditions
.is_empty ())
396 fprintf (file
, "conditions bb_%d (\n", GBB_BB (gbb
)->index
);
398 FOR_EACH_VEC_ELT (conditions
, i
, stmt
)
399 print_gimple_stmt (file
, stmt
, 0, 0);
401 fprintf (file
, ")\n");
404 /* Print to FILE all the data references of PBB. */
407 print_pdrs (FILE *file
, poly_bb_p pbb
)
414 if (PBB_DRS (pbb
).is_empty ())
417 fprintf (file
, "Data references (\n");
419 FOR_EACH_VEC_ELT (PBB_DRS (pbb
), i
, pdr
)
420 if (PDR_TYPE (pdr
) == PDR_READ
)
425 fprintf (file
, "Read data references (\n");
427 FOR_EACH_VEC_ELT (PBB_DRS (pbb
), i
, pdr
)
428 if (PDR_TYPE (pdr
) == PDR_READ
)
429 print_pdr (file
, pdr
);
431 fprintf (file
, ")\n");
432 fprintf (file
, "Write data references (\n");
433 FOR_EACH_VEC_ELT (PBB_DRS (pbb
), i
, pdr
)
434 if (PDR_TYPE (pdr
) != PDR_READ
)
435 print_pdr (file
, pdr
);
436 fprintf (file
, ")\n");
437 fprintf (file
, ")\n");
440 /* Print to STDERR all the data references of PBB. */
443 debug_pdrs (poly_bb_p pbb
)
445 print_pdrs (stderr
, pbb
);
448 /* Print to FILE the body of PBB. */
451 print_pbb_body (FILE *file
, poly_bb_p pbb
)
453 fprintf (file
, "Body (\n");
454 dump_bb (file
, pbb_bb (pbb
), 0, 0);
455 fprintf (file
, ")\n");
458 /* Print to FILE the domain and scattering function of PBB. */
461 print_pbb (FILE *file
, poly_bb_p pbb
)
463 fprintf (file
, "pbb_%d (\n", pbb_index (pbb
));
464 dump_gbb_conditions (file
, PBB_BLACK_BOX (pbb
));
465 dump_gbb_cases (file
, PBB_BLACK_BOX (pbb
));
467 print_pbb_domain (file
, pbb
);
468 print_pdrs (file
, pbb
);
469 print_pbb_body (file
, pbb
);
471 fprintf (file
, ")\n");
474 /* Print to FILE the parameters of SCOP. */
477 print_scop_params (FILE *file
, scop_p scop
)
479 if (scop
->scop_info
->params
.is_empty ())
484 fprintf (file
, "parameters (");
485 FOR_EACH_VEC_ELT (scop
->scop_info
->params
, i
, t
)
487 print_generic_expr (file
, t
, 0);
488 fprintf (file
, ", ");
490 fprintf (file
, ")\n");
493 /* Print to FILE the context of SCoP. */
496 print_scop_context (FILE *file
, scop_p scop
)
498 if (!scop
->param_context
)
501 fprintf (file
, "Context (\n");
502 print_isl_set (file
, scop
->param_context
);
503 fprintf (file
, ")\n");
506 /* Print to FILE the SCOP. */
509 print_scop (FILE *file
, scop_p scop
)
514 fprintf (file
, "SCoP (\n");
515 print_scop_context (file
, scop
);
516 print_scop_params (file
, scop
);
518 fprintf (file
, "Number of statements: ");
519 fprintf (file
, "%d\n", scop
->pbbs
.length ());
521 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
522 print_pbb (file
, pbb
);
524 fprintf (file
, ")\n");
527 /* Print to STDERR the domain of PBB. */
530 debug_pbb_domain (poly_bb_p pbb
)
532 print_pbb_domain (stderr
, pbb
);
535 /* Print to FILE the domain and scattering function of PBB. */
538 debug_pbb (poly_bb_p pbb
)
540 print_pbb (stderr
, pbb
);
543 /* Print to STDERR the context of SCOP. */
546 debug_scop_context (scop_p scop
)
548 print_scop_context (stderr
, scop
);
551 /* Print to STDERR the SCOP. */
554 debug_scop (scop_p scop
)
556 print_scop (stderr
, scop
);
559 /* Print to STDERR the parameters of SCOP. */
562 debug_scop_params (scop_p scop
)
564 print_scop_params (stderr
, scop
);
567 extern isl_ctx
*the_isl_ctx
;
569 print_isl_set (FILE *f
, isl_set
*set
)
571 isl_printer
*p
= isl_printer_to_file (the_isl_ctx
, f
);
572 p
= isl_printer_print_set (p
, set
);
573 p
= isl_printer_print_str (p
, "\n");
574 isl_printer_free (p
);
578 debug_isl_set (isl_set
*set
)
580 print_isl_set (stderr
, set
);
584 print_isl_map (FILE *f
, isl_map
*map
)
586 isl_printer
*p
= isl_printer_to_file (the_isl_ctx
, f
);
587 p
= isl_printer_print_map (p
, map
);
588 p
= isl_printer_print_str (p
, "\n");
589 isl_printer_free (p
);
593 debug_isl_map (isl_map
*map
)
595 print_isl_map (stderr
, map
);
599 print_isl_union_map (FILE *f
, isl_union_map
*map
)
601 isl_printer
*p
= isl_printer_to_file (the_isl_ctx
, f
);
602 p
= isl_printer_print_union_map (p
, map
);
603 p
= isl_printer_print_str (p
, "\n");
604 isl_printer_free (p
);
608 debug_isl_union_map (isl_union_map
*map
)
610 print_isl_union_map (stderr
, map
);
615 print_isl_aff (FILE *f
, isl_aff
*aff
)
617 isl_printer
*p
= isl_printer_to_file (the_isl_ctx
, f
);
618 p
= isl_printer_print_aff (p
, aff
);
619 p
= isl_printer_print_str (p
, "\n");
620 isl_printer_free (p
);
624 debug_isl_aff (isl_aff
*aff
)
626 print_isl_aff (stderr
, aff
);
630 print_isl_constraint (FILE *f
, isl_constraint
*c
)
632 isl_printer
*p
= isl_printer_to_file (the_isl_ctx
, f
);
633 p
= isl_printer_print_constraint (p
, c
);
634 p
= isl_printer_print_str (p
, "\n");
635 isl_printer_free (p
);
639 debug_isl_constraint (isl_constraint
*c
)
641 print_isl_constraint (stderr
, c
);
644 /* Returns the number of iterations RES of the loop around PBB at
645 time(scattering) dimension TIME_DEPTH. */
648 pbb_number_of_iterations_at_time (poly_bb_p pbb
,
649 graphite_dim_t time_depth
,
652 isl_set
*transdomain
;
655 isl_val
*isllb
, *islub
;
657 /* Map the iteration domain through the current scatter, and work
658 on the resulting set. */
659 transdomain
= isl_set_apply (isl_set_copy (pbb
->domain
),
660 isl_map_copy (pbb
->transformed
));
662 /* Select the time_depth' dimension via an affine expression. */
663 dc
= isl_set_get_space (transdomain
);
664 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
665 aff
= isl_aff_set_coefficient_si (aff
, isl_dim_in
, time_depth
, 1);
667 /* And find the min/max for that function. */
668 /* XXX isl check results? */
669 isllb
= isl_set_min_val (transdomain
, aff
);
670 islub
= isl_set_max_val (transdomain
, aff
);
672 islub
= isl_val_sub (islub
, isllb
);
673 islub
= isl_val_add_ui (islub
, 1);
674 isl_val_get_num_gmp (islub
, res
);
676 isl_val_free (islub
);
678 isl_set_free (transdomain
);
681 #endif /* HAVE_isl */