1 /* Graphite polyhedral representation.
2 Copyright (C) 2009-2014 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/>. */
22 #ifndef GCC_GRAPHITE_POLY_H
23 #define GCC_GRAPHITE_POLY_H
25 typedef struct poly_dr
*poly_dr_p
;
27 typedef struct poly_bb
*poly_bb_p
;
29 typedef struct scop
*scop_p
;
31 typedef unsigned graphite_dim_t
;
33 static inline graphite_dim_t
pbb_dim_iter_domain (const struct poly_bb
*);
34 static inline graphite_dim_t
pbb_nb_params (const struct poly_bb
*);
35 static inline graphite_dim_t
scop_nb_params (scop_p
);
37 /* A data reference can write or read some memory or we
38 just know it may write some memory. */
42 /* PDR_MAY_READs are represented using PDR_READS. This does not
43 limit the expressiveness. */
50 /* An identifier for this PDR. */
53 /* The number of data refs identical to this one in the PBB. */
56 /* A pointer to compiler's data reference description. */
59 /* A pointer to the PBB that contains this data reference. */
62 enum poly_dr_type type
;
64 /* The access polyhedron contains the polyhedral space this data
65 reference will access.
67 The polyhedron contains these dimensions:
70 Every memory access is classified in at least one alias set.
72 - The subscripts (s_0, ..., s_n):
73 The memory is accessed using zero or more subscript dimensions.
75 - The iteration domain (variables and parameters)
77 Do not hardcode the dimensions. Use the following accessor functions:
91 | if (unknown_function ())
98 The data access A[i][j+k] in alias set "5" is described like this:
103 | 0 -1 -1 0 0 1 0 = 0
104 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
105 | 0 0 0 0 0 1 0 >= 0 # array size.
106 | 0 0 0 0 -1 0 1335 >= 0
107 | 0 0 0 0 0 -1 123 >= 0
109 The pointer "*p" in alias set "5" and "7" is described as a union of
123 "*p" accesses all of the object allocated with 'malloc'.
125 The scalar data access "m" is represented as an array with zero subscript
131 The difference between the graphite internal format for access data and
132 the OpenSop format is in the order of columns.
138 | 0 -1 -1 0 0 1 0 = 0
139 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
140 | 0 0 0 0 0 1 0 >= 0 # array size.
141 | 0 0 0 0 -1 0 1335 >= 0
142 | 0 0 0 0 0 -1 123 >= 0
149 | 0 0 1 0 -1 -1 0 = 0
150 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
151 | 0 0 1 0 0 0 0 >= 0 # array size.
152 | 0 -1 0 0 0 0 1335 >= 0
153 | 0 0 -1 0 0 0 123 >= 0
155 The OpenScop access function is printed as follows:
157 | 1 # The number of disjunct components in a union of access functions.
158 | R C O I L P # Described bellow.
162 | 0 0 1 0 -1 -1 0 = 0
163 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
164 | 0 0 1 0 0 0 0 >= 0 # array size.
165 | 0 -1 0 0 0 0 1335 >= 0
166 | 0 0 -1 0 0 0 123 >= 0
170 - C: Number of columns.
171 - O: Number of output dimensions = alias set + number of subscripts.
172 - I: Number of input dimensions (iterators).
173 - L: Number of local (existentially quantified) dimensions.
174 - P: Number of parameters.
176 In the example, the vector "R C O I L P" is "7 7 3 2 0 1". */
180 /* Data reference's base object set number, we must assure 2 pdrs are in the
181 same base object set before dependency checking. */
182 int dr_base_object_set
;
184 /* The number of subscripts. */
185 graphite_dim_t nb_subscripts
;
188 #define PDR_ID(PDR) (PDR->id)
189 #define PDR_NB_REFS(PDR) (PDR->nb_refs)
190 #define PDR_CDR(PDR) (PDR->compiler_dr)
191 #define PDR_PBB(PDR) (PDR->pbb)
192 #define PDR_TYPE(PDR) (PDR->type)
193 #define PDR_ACCESSES(PDR) (NULL)
194 #define PDR_BASE_OBJECT_SET(PDR) (PDR->dr_base_object_set)
195 #define PDR_NB_SUBSCRIPTS(PDR) (PDR->nb_subscripts)
197 void new_poly_dr (poly_bb_p
, int, enum poly_dr_type
, void *,
198 graphite_dim_t
, isl_map
*, isl_set
*);
199 void free_poly_dr (poly_dr_p
);
200 void debug_pdr (poly_dr_p
, int);
201 void print_pdr (FILE *, poly_dr_p
, int);
202 static inline scop_p
pdr_scop (poly_dr_p pdr
);
204 /* The dimension of the iteration domain of the scop of PDR. */
206 static inline graphite_dim_t
207 pdr_dim_iter_domain (poly_dr_p pdr
)
209 return pbb_dim_iter_domain (PDR_PBB (pdr
));
212 /* The number of parameters of the scop of PDR. */
214 static inline graphite_dim_t
215 pdr_nb_params (poly_dr_p pdr
)
217 return scop_nb_params (pdr_scop (pdr
));
220 /* The dimension of the alias set in PDR. */
222 static inline graphite_dim_t
223 pdr_alias_set_dim (poly_dr_p pdr
)
225 poly_bb_p pbb
= PDR_PBB (pdr
);
227 return pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
);
230 /* The dimension in PDR containing subscript S. */
232 static inline graphite_dim_t
233 pdr_subscript_dim (poly_dr_p pdr
, graphite_dim_t s
)
235 poly_bb_p pbb
= PDR_PBB (pdr
);
237 return pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
) + 1 + s
;
240 /* The dimension in PDR containing the loop iterator ITER. */
242 static inline graphite_dim_t
243 pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED
, graphite_dim_t iter
)
248 /* The dimension in PDR containing parameter PARAM. */
250 static inline graphite_dim_t
251 pdr_parameter_dim (poly_dr_p pdr
, graphite_dim_t param
)
253 poly_bb_p pbb
= PDR_PBB (pdr
);
255 return pbb_dim_iter_domain (pbb
) + param
;
258 /* Returns true when PDR is a "read". */
261 pdr_read_p (poly_dr_p pdr
)
263 return PDR_TYPE (pdr
) == PDR_READ
;
266 /* Returns true when PDR is a "write". */
269 pdr_write_p (poly_dr_p pdr
)
271 return PDR_TYPE (pdr
) == PDR_WRITE
;
274 /* Returns true when PDR is a "may write". */
277 pdr_may_write_p (poly_dr_p pdr
)
279 return PDR_TYPE (pdr
) == PDR_MAY_WRITE
;
282 /* Return true when PDR1 and PDR2 are similar data accesses: they have
283 the same base array, and the same access functions. */
286 same_pdr_p (poly_dr_p pdr1
, poly_dr_p pdr2
)
288 return PDR_NB_SUBSCRIPTS (pdr1
) == PDR_NB_SUBSCRIPTS (pdr2
)
289 && PDR_BASE_OBJECT_SET (pdr1
) == PDR_BASE_OBJECT_SET (pdr2
);
292 typedef struct poly_scattering
*poly_scattering_p
;
294 struct poly_scattering
296 /* The number of local variables. */
297 int nb_local_variables
;
299 /* The number of scattering dimensions. */
303 /* POLY_BB represents a blackbox in the polyhedral model. */
307 /* Pointer to a basic block or a statement in the compiler. */
310 /* Pointer to the SCOP containing this PBB. */
313 /* The iteration domain of this bb. The layout of this polyhedron
314 is I|G with I the iteration domain, G the context parameters.
318 for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
319 for (j = 2; j <= 2*i + 5; j++)
320 for (k = 0; k <= 5; k++)
323 Loop iterators: i, j, k
333 The number of variables in the DOMAIN may change and is not
334 related to the number of loops in the original code. */
337 /* The data references we access. */
340 /* The original scattering. */
341 poly_scattering_p _original
;
344 /* The transformed scattering. */
345 poly_scattering_p _transformed
;
346 isl_map
*transformed
;
348 /* A copy of the transformed scattering. */
349 poly_scattering_p _saved
;
352 /* True when this PBB contains only a reduction statement. */
356 #define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box)
357 #define PBB_SCOP(PBB) (PBB->scop)
358 #define PBB_DOMAIN(PBB) (NULL)
359 #define PBB_DRS(PBB) (PBB->drs)
360 #define PBB_ORIGINAL(PBB) (PBB->_original)
361 #define PBB_ORIGINAL_SCATTERING(PBB) (NULL)
362 #define PBB_TRANSFORMED(PBB) (PBB->_transformed)
363 #define PBB_TRANSFORMED_SCATTERING(PBB) (NULL)
364 #define PBB_SAVED(PBB) (PBB->_saved)
365 /* XXX isl if we ever need local vars in the scatter, we can't use the
366 out dimension of transformed to count the scatterting transform dimension.
368 #define PBB_NB_LOCAL_VARIABLES(PBB) (0)
369 #define PBB_NB_SCATTERING_TRANSFORM(PBB) (isl_map_n_out (PBB->transformed))
370 #define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
372 extern poly_bb_p
new_poly_bb (scop_p
, void *);
373 extern void free_poly_bb (poly_bb_p
);
374 extern void debug_loop_vec (poly_bb_p
);
375 extern void schedule_to_scattering (poly_bb_p
, int);
376 extern void print_pbb_domain (FILE *, poly_bb_p
, int);
377 extern void print_pbb (FILE *, poly_bb_p
, int);
378 extern void print_scop_context (FILE *, scop_p
, int);
379 extern void print_scop (FILE *, scop_p
, int);
380 extern void print_cloog (FILE *, scop_p
, int);
381 extern void debug_pbb_domain (poly_bb_p
, int);
382 extern void debug_pbb (poly_bb_p
, int);
383 extern void print_pdrs (FILE *, poly_bb_p
, int);
384 extern void debug_pdrs (poly_bb_p
, int);
385 extern void debug_scop_context (scop_p
, int);
386 extern void debug_scop (scop_p
, int);
387 extern void debug_cloog (scop_p
, int);
388 extern void print_scop_params (FILE *, scop_p
, int);
389 extern void debug_scop_params (scop_p
, int);
390 extern void print_iteration_domain (FILE *, poly_bb_p
, int);
391 extern void print_iteration_domains (FILE *, scop_p
, int);
392 extern void debug_iteration_domain (poly_bb_p
, int);
393 extern void debug_iteration_domains (scop_p
, int);
394 extern void print_isl_set (FILE *, isl_set
*);
395 extern void print_isl_map (FILE *, isl_map
*);
396 extern void print_isl_aff (FILE *, isl_aff
*);
397 extern void print_isl_constraint (FILE *, isl_constraint
*);
398 extern void debug_isl_set (isl_set
*);
399 extern void debug_isl_map (isl_map
*);
400 extern void debug_isl_aff (isl_aff
*);
401 extern void debug_isl_constraint (isl_constraint
*);
402 extern int scop_do_interchange (scop_p
);
403 extern int scop_do_strip_mine (scop_p
, int);
404 extern bool scop_do_block (scop_p
);
405 extern bool flatten_all_loops (scop_p
);
406 extern bool optimize_isl (scop_p
);
407 extern void pbb_number_of_iterations_at_time (poly_bb_p
, graphite_dim_t
, mpz_t
);
408 extern void debug_gmp_value (mpz_t
);
410 /* Return the number of write data references in PBB. */
413 number_of_write_pdrs (poly_bb_p pbb
)
419 for (i
= 0; PBB_DRS (pbb
).iterate (i
, &pdr
); i
++)
420 if (PDR_TYPE (pdr
) == PDR_WRITE
)
426 /* Returns a gimple_bb from BB. */
428 static inline gimple_bb_p
429 gbb_from_bb (basic_block bb
)
431 return (gimple_bb_p
) bb
->aux
;
434 /* The poly_bb of the BB. */
436 static inline poly_bb_p
437 pbb_from_bb (basic_block bb
)
439 return GBB_PBB (gbb_from_bb (bb
));
442 /* The basic block of the PBB. */
444 static inline basic_block
445 pbb_bb (poly_bb_p pbb
)
447 return GBB_BB (PBB_BLACK_BOX (pbb
));
450 /* The index of the PBB. */
453 pbb_index (poly_bb_p pbb
)
455 return pbb_bb (pbb
)->index
;
458 /* The loop of the PBB. */
461 pbb_loop (poly_bb_p pbb
)
463 return gbb_loop (PBB_BLACK_BOX (pbb
));
466 /* The scop that contains the PDR. */
469 pdr_scop (poly_dr_p pdr
)
471 return PBB_SCOP (PDR_PBB (pdr
));
474 /* Set black box of PBB to BLACKBOX. */
477 pbb_set_black_box (poly_bb_p pbb
, void *black_box
)
479 pbb
->black_box
= black_box
;
482 /* The number of loops around PBB: the dimension of the iteration
485 static inline graphite_dim_t
486 pbb_dim_iter_domain (const struct poly_bb
*pbb
)
488 return isl_set_dim (pbb
->domain
, isl_dim_set
);
491 /* The number of params defined in PBB. */
493 static inline graphite_dim_t
494 pbb_nb_params (const struct poly_bb
*pbb
)
496 scop_p scop
= PBB_SCOP (pbb
);
498 return scop_nb_params (scop
);
501 /* The number of scattering dimensions in the SCATTERING polyhedron
502 of a PBB for a given SCOP. */
504 static inline graphite_dim_t
505 pbb_nb_scattering_orig (const struct poly_bb
*pbb
)
507 return 2 * pbb_dim_iter_domain (pbb
) + 1;
510 /* The number of scattering dimensions in PBB. */
512 static inline graphite_dim_t
513 pbb_nb_scattering_transform (const struct poly_bb
*pbb
)
515 return PBB_NB_SCATTERING_TRANSFORM (pbb
);
518 /* The number of dynamic scattering dimensions in PBB. */
520 static inline graphite_dim_t
521 pbb_nb_dynamic_scattering_transform (const struct poly_bb
*pbb
)
523 /* This function requires the 2d + 1 scattering format to be
524 invariant during all transformations. */
525 gcc_assert (PBB_NB_SCATTERING_TRANSFORM (pbb
) % 2);
526 return PBB_NB_SCATTERING_TRANSFORM (pbb
) / 2;
529 /* Returns the number of local variables used in the transformed
530 scattering polyhedron of PBB. */
532 static inline graphite_dim_t
533 pbb_nb_local_vars (const struct poly_bb
*pbb ATTRIBUTE_UNUSED
)
535 /* For now we do not have any local variables, as we do not do strip
536 mining for example. */
537 return PBB_NB_LOCAL_VARIABLES (pbb
);
540 /* The dimension in the domain of PBB containing the iterator ITER. */
542 static inline graphite_dim_t
543 pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t iter
)
548 /* The dimension in the domain of PBB containing the iterator ITER. */
550 static inline graphite_dim_t
551 pbb_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
554 + pbb_dim_iter_domain (pbb
);
557 /* The dimension in the original scattering polyhedron of PBB
558 containing the scattering iterator SCATTER. */
560 static inline graphite_dim_t
561 psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t scatter
)
563 gcc_assert (scatter
< pbb_nb_scattering_orig (pbb
));
567 /* The dimension in the transformed scattering polyhedron of PBB
568 containing the scattering iterator SCATTER. */
570 static inline graphite_dim_t
571 psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t scatter
)
573 gcc_assert (scatter
<= pbb_nb_scattering_transform (pbb
));
577 /* The dimension in the transformed scattering polyhedron of PBB of
578 the local variable LV. */
580 static inline graphite_dim_t
581 psct_local_var_dim (poly_bb_p pbb
, graphite_dim_t lv
)
583 gcc_assert (lv
<= pbb_nb_local_vars (pbb
));
584 return lv
+ pbb_nb_scattering_transform (pbb
);
587 /* The dimension in the original scattering polyhedron of PBB
588 containing the loop iterator ITER. */
590 static inline graphite_dim_t
591 psco_iterator_dim (poly_bb_p pbb
, graphite_dim_t iter
)
593 gcc_assert (iter
< pbb_dim_iter_domain (pbb
));
594 return iter
+ pbb_nb_scattering_orig (pbb
);
597 /* The dimension in the transformed scattering polyhedron of PBB
598 containing the loop iterator ITER. */
600 static inline graphite_dim_t
601 psct_iterator_dim (poly_bb_p pbb
, graphite_dim_t iter
)
603 gcc_assert (iter
< pbb_dim_iter_domain (pbb
));
605 + pbb_nb_scattering_transform (pbb
)
606 + pbb_nb_local_vars (pbb
);
609 /* The dimension in the original scattering polyhedron of PBB
610 containing parameter PARAM. */
612 static inline graphite_dim_t
613 psco_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
615 gcc_assert (param
< pbb_nb_params (pbb
));
617 + pbb_nb_scattering_orig (pbb
)
618 + pbb_dim_iter_domain (pbb
);
621 /* The dimension in the transformed scattering polyhedron of PBB
622 containing parameter PARAM. */
624 static inline graphite_dim_t
625 psct_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
627 gcc_assert (param
< pbb_nb_params (pbb
));
629 + pbb_nb_scattering_transform (pbb
)
630 + pbb_nb_local_vars (pbb
)
631 + pbb_dim_iter_domain (pbb
);
634 /* The scattering dimension of PBB corresponding to the dynamic level
637 static inline graphite_dim_t
638 psct_dynamic_dim (poly_bb_p pbb
, graphite_dim_t level
)
640 graphite_dim_t result
= 1 + 2 * level
;
642 gcc_assert (result
< pbb_nb_scattering_transform (pbb
));
646 /* The scattering dimension of PBB corresponding to the static
647 sequence of the loop level LEVEL. */
649 static inline graphite_dim_t
650 psct_static_dim (poly_bb_p pbb
, graphite_dim_t level
)
652 graphite_dim_t result
= 2 * level
;
654 gcc_assert (result
< pbb_nb_scattering_transform (pbb
));
658 /* Adds to the transformed scattering polyhedron of PBB a new local
659 variable and returns its index. */
661 static inline graphite_dim_t
662 psct_add_local_variable (poly_bb_p pbb ATTRIBUTE_UNUSED
)
668 typedef struct lst
*lst_p
;
670 /* Loops and Statements Tree. */
673 /* LOOP_P is true when an LST node is a loop. */
676 /* A pointer to the loop that contains this node. */
679 /* The sum of all the memory strides for an LST loop. */
680 mpz_t memory_strides
;
682 /* Loop nodes contain a sequence SEQ of LST nodes, statements
683 contain a pointer to their polyhedral representation PBB. */
690 #define LST_LOOP_P(LST) ((LST)->loop_p)
691 #define LST_LOOP_FATHER(LST) ((LST)->loop_father)
692 #define LST_PBB(LST) ((LST)->node.pbb)
693 #define LST_SEQ(LST) ((LST)->node.seq)
694 #define LST_LOOP_MEMORY_STRIDES(LST) ((LST)->memory_strides)
696 void scop_to_lst (scop_p
);
697 void print_lst (FILE *, lst_p
, int);
698 void debug_lst (lst_p
);
699 void dot_lst (lst_p
);
701 /* Creates a new LST loop with SEQ. */
704 new_lst_loop (vec
<lst_p
> seq
)
706 lst_p lst
= XNEW (struct lst
);
710 LST_LOOP_P (lst
) = true;
712 LST_LOOP_FATHER (lst
) = NULL
;
713 mpz_init (LST_LOOP_MEMORY_STRIDES (lst
));
714 mpz_set_si (LST_LOOP_MEMORY_STRIDES (lst
), -1);
716 for (i
= 0; seq
.iterate (i
, &l
); i
++)
717 LST_LOOP_FATHER (l
) = lst
;
722 /* Creates a new LST statement with PBB. */
725 new_lst_stmt (poly_bb_p pbb
)
727 lst_p lst
= XNEW (struct lst
);
729 LST_LOOP_P (lst
) = false;
731 LST_LOOP_FATHER (lst
) = NULL
;
735 /* Frees the memory used by LST. */
743 if (LST_LOOP_P (lst
))
748 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
751 mpz_clear (LST_LOOP_MEMORY_STRIDES (lst
));
752 LST_SEQ (lst
).release ();
758 /* Returns a copy of LST. */
766 if (LST_LOOP_P (lst
))
773 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
774 seq
.safe_push (copy_lst (l
));
776 return new_lst_loop (seq
);
779 return new_lst_stmt (LST_PBB (lst
));
782 /* Adds a new loop under the loop LST. */
785 lst_add_loop_under_loop (lst_p lst
)
789 lst_p l
= new_lst_loop (LST_SEQ (lst
));
791 gcc_assert (LST_LOOP_P (lst
));
793 LST_LOOP_FATHER (l
) = lst
;
798 /* Returns the loop depth of LST. */
801 lst_depth (lst_p lst
)
806 /* The depth of the outermost "fake" loop is -1. This outermost
807 loop does not have a loop father and it is just a container, as
808 in the loop representation of GCC. */
809 if (!LST_LOOP_FATHER (lst
))
812 return lst_depth (LST_LOOP_FATHER (lst
)) + 1;
815 /* Returns the Dewey number for LST. */
818 lst_dewey_number (lst_p lst
)
826 if (!LST_LOOP_FATHER (lst
))
829 FOR_EACH_VEC_ELT (LST_SEQ (LST_LOOP_FATHER (lst
)), i
, l
)
836 /* Returns the Dewey number of LST at depth DEPTH. */
839 lst_dewey_number_at_depth (lst_p lst
, int depth
)
841 gcc_assert (lst
&& depth
>= 0 && lst_depth (lst
) <= depth
);
843 if (lst_depth (lst
) == depth
)
844 return lst_dewey_number (lst
);
846 return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst
), depth
);
849 /* Returns the predecessor of LST in the sequence of its loop father.
850 Returns NULL if LST is the first statement in the sequence. */
858 if (!lst
|| !LST_LOOP_FATHER (lst
))
861 dewey
= lst_dewey_number (lst
);
865 father
= LST_LOOP_FATHER (lst
);
866 return LST_SEQ (father
)[dewey
- 1];
869 /* Returns the successor of LST in the sequence of its loop father.
870 Returns NULL if there is none. */
878 if (!lst
|| !LST_LOOP_FATHER (lst
))
881 dewey
= lst_dewey_number (lst
);
882 father
= LST_LOOP_FATHER (lst
);
884 if (LST_SEQ (father
).length () == (unsigned) dewey
+ 1)
887 return LST_SEQ (father
)[dewey
+ 1];
891 /* Return the LST node corresponding to PBB. */
894 lst_find_pbb (lst_p lst
, poly_bb_p pbb
)
902 if (!LST_LOOP_P (lst
))
903 return (pbb
== LST_PBB (lst
)) ? lst
: NULL
;
905 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
907 lst_p res
= lst_find_pbb (l
, pbb
);
915 /* Return the LST node corresponding to the loop around STMT at depth
919 find_lst_loop (lst_p stmt
, int loop_depth
)
921 lst_p loop
= LST_LOOP_FATHER (stmt
);
923 gcc_assert (loop_depth
>= 0);
925 while (loop_depth
< lst_depth (loop
))
926 loop
= LST_LOOP_FATHER (loop
);
931 /* Return the first LST representing a PBB statement in LST. */
934 lst_find_first_pbb (lst_p lst
)
942 if (!LST_LOOP_P (lst
))
945 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
947 lst_p res
= lst_find_first_pbb (l
);
955 /* Returns true when LST is a loop that does not contain
959 lst_empty_p (lst_p lst
)
961 return !lst_find_first_pbb (lst
);
964 /* Return the last LST representing a PBB statement in LST. */
967 lst_find_last_pbb (lst_p lst
)
975 if (!LST_LOOP_P (lst
))
978 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
980 lst_p last
= lst_find_last_pbb (l
);
990 /* Returns true if LOOP contains LST, in other words, if LST is nested
994 lst_contains_p (lst_p loop
, lst_p lst
)
996 if (!loop
|| !lst
|| !LST_LOOP_P (loop
))
1002 return lst_contains_p (loop
, LST_LOOP_FATHER (lst
));
1005 /* Returns true if LOOP contains PBB, in other words, if PBB is nested
1009 lst_contains_pbb (lst_p loop
, poly_bb_p pbb
)
1011 return lst_find_pbb (loop
, pbb
) ? true : false;
1014 /* Creates a loop nest of depth NB_LOOPS containing LST. */
1017 lst_create_nest (int nb_loops
, lst_p lst
)
1026 loop
= lst_create_nest (nb_loops
- 1, lst
);
1027 seq
.quick_push (loop
);
1028 res
= new_lst_loop (seq
);
1029 LST_LOOP_FATHER (loop
) = res
;
1034 /* Removes LST from the sequence of statements of its loop father. */
1037 lst_remove_from_sequence (lst_p lst
)
1039 lst_p father
= LST_LOOP_FATHER (lst
);
1040 int dewey
= lst_dewey_number (lst
);
1042 gcc_assert (lst
&& father
&& dewey
>= 0);
1044 LST_SEQ (father
).ordered_remove (dewey
);
1045 LST_LOOP_FATHER (lst
) = NULL
;
1048 /* Removes the loop LST and inline its body in the father loop. */
1051 lst_remove_loop_and_inline_stmts_in_loop_father (lst_p lst
)
1053 lst_p l
, father
= LST_LOOP_FATHER (lst
);
1054 int i
, dewey
= lst_dewey_number (lst
);
1056 gcc_assert (lst
&& father
&& dewey
>= 0);
1058 LST_SEQ (father
).ordered_remove (dewey
);
1059 LST_LOOP_FATHER (lst
) = NULL
;
1061 FOR_EACH_VEC_ELT (LST_SEQ (lst
), i
, l
)
1063 LST_SEQ (father
).safe_insert (dewey
+ i
, l
);
1064 LST_LOOP_FATHER (l
) = father
;
1068 /* Sets NITER to the upper bound approximation of the number of
1069 iterations of loop LST. */
1072 lst_niter_for_loop (lst_p lst
, mpz_t niter
)
1074 int depth
= lst_depth (lst
);
1075 poly_bb_p pbb
= LST_PBB (lst_find_first_pbb (lst
));
1077 gcc_assert (LST_LOOP_P (lst
));
1078 pbb_number_of_iterations_at_time (pbb
, psct_dynamic_dim (pbb
, depth
), niter
);
1081 /* Updates the scattering of PBB to be at the DEWEY number in the loop
1085 pbb_update_scattering (poly_bb_p pbb
, graphite_dim_t level
, int dewey
)
1087 graphite_dim_t sched
= psct_static_dim (pbb
, level
);
1088 isl_space
*d
= isl_map_get_space (pbb
->transformed
);
1089 isl_space
*d1
= isl_space_range (d
);
1090 unsigned i
, n
= isl_space_dim (d1
, isl_dim_out
);
1091 isl_space
*d2
= isl_space_add_dims (d1
, isl_dim_in
, n
);
1092 isl_map
*x
= isl_map_universe (d2
);
1094 x
= isl_map_fix_si (x
, isl_dim_out
, sched
, dewey
);
1096 for (i
= 0; i
< n
; i
++)
1098 x
= isl_map_equate (x
, isl_dim_in
, i
, isl_dim_out
, i
);
1100 pbb
->transformed
= isl_map_apply_range (pbb
->transformed
, x
);
1103 /* Updates the scattering of all the PBBs under LST to be at the DEWEY
1104 number in the loop at depth LEVEL. */
1107 lst_update_scattering_under (lst_p lst
, int level
, int dewey
)
1112 gcc_assert (lst
&& level
>= 0 && dewey
>= 0);
1114 if (LST_LOOP_P (lst
))
1115 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
1116 lst_update_scattering_under (l
, level
, dewey
);
1118 pbb_update_scattering (LST_PBB (lst
), level
, dewey
);
1121 /* Updates the all the scattering levels of all the PBBs under
1125 lst_update_scattering (lst_p lst
)
1133 if (LST_LOOP_FATHER (lst
))
1135 lst_p father
= LST_LOOP_FATHER (lst
);
1136 int dewey
= lst_dewey_number (lst
);
1137 int level
= lst_depth (lst
);
1139 gcc_assert (lst
&& father
&& dewey
>= 0 && level
>= 0);
1141 for (i
= dewey
; LST_SEQ (father
).iterate (i
, &l
); i
++)
1142 lst_update_scattering_under (l
, level
, i
);
1145 if (LST_LOOP_P (lst
))
1146 for (i
= 0; LST_SEQ (lst
).iterate (i
, &l
); i
++)
1147 lst_update_scattering (l
);
1150 /* Inserts LST1 before LST2 if BEFORE is true; inserts LST1 after LST2
1151 if BEFORE is false. */
1154 lst_insert_in_sequence (lst_p lst1
, lst_p lst2
, bool before
)
1159 /* Do not insert empty loops. */
1160 if (!lst1
|| lst_empty_p (lst1
))
1163 father
= LST_LOOP_FATHER (lst2
);
1164 dewey
= lst_dewey_number (lst2
);
1166 gcc_assert (lst2
&& father
&& dewey
>= 0);
1168 LST_SEQ (father
).safe_insert (before
? dewey
: dewey
+ 1, lst1
);
1169 LST_LOOP_FATHER (lst1
) = father
;
1172 /* Replaces LST1 with LST2. */
1175 lst_replace (lst_p lst1
, lst_p lst2
)
1180 if (!lst2
|| lst_empty_p (lst2
))
1183 father
= LST_LOOP_FATHER (lst1
);
1184 dewey
= lst_dewey_number (lst1
);
1185 LST_LOOP_FATHER (lst2
) = father
;
1186 LST_SEQ (father
)[dewey
] = lst2
;
1189 /* Returns a copy of ROOT where LST has been replaced by a copy of the
1190 LSTs A B C in this sequence. */
1193 lst_substitute_3 (lst_p root
, lst_p lst
, lst_p a
, lst_p b
, lst_p c
)
1202 gcc_assert (lst
&& root
!= lst
);
1204 if (!LST_LOOP_P (root
))
1205 return new_lst_stmt (LST_PBB (root
));
1209 for (i
= 0; LST_SEQ (root
).iterate (i
, &l
); i
++)
1211 seq
.safe_push (lst_substitute_3 (l
, lst
, a
, b
, c
));
1214 if (!lst_empty_p (a
))
1215 seq
.safe_push (copy_lst (a
));
1216 if (!lst_empty_p (b
))
1217 seq
.safe_push (copy_lst (b
));
1218 if (!lst_empty_p (c
))
1219 seq
.safe_push (copy_lst (c
));
1222 return new_lst_loop (seq
);
1225 /* Moves LST before LOOP if BEFORE is true, and after the LOOP if
1229 lst_distribute_lst (lst_p loop
, lst_p lst
, bool before
)
1231 int loop_depth
= lst_depth (loop
);
1232 int depth
= lst_depth (lst
);
1233 int nb_loops
= depth
- loop_depth
;
1235 gcc_assert (lst
&& loop
&& LST_LOOP_P (loop
) && nb_loops
> 0);
1237 lst_remove_from_sequence (lst
);
1238 lst_insert_in_sequence (lst_create_nest (nb_loops
, lst
), loop
, before
);
1241 /* Removes from LOOP all the statements before/after and including PBB
1242 if BEFORE is true/false. Returns the negation of BEFORE when the
1243 statement PBB has been found. */
1246 lst_remove_all_before_including_pbb (lst_p loop
, poly_bb_p pbb
, bool before
)
1251 if (!loop
|| !LST_LOOP_P (loop
))
1254 for (i
= 0; LST_SEQ (loop
).iterate (i
, &l
);)
1257 before
= lst_remove_all_before_including_pbb (l
, pbb
, before
);
1259 if (LST_SEQ (l
).length () == 0)
1261 LST_SEQ (loop
).ordered_remove (i
);
1271 if (LST_PBB (l
) == pbb
)
1274 LST_SEQ (loop
).ordered_remove (i
);
1277 else if (LST_PBB (l
) == pbb
)
1280 LST_SEQ (loop
).ordered_remove (i
);
1290 /* Removes from LOOP all the statements before/after and excluding PBB
1291 if BEFORE is true/false; Returns the negation of BEFORE when the
1292 statement PBB has been found. */
1295 lst_remove_all_before_excluding_pbb (lst_p loop
, poly_bb_p pbb
, bool before
)
1300 if (!loop
|| !LST_LOOP_P (loop
))
1303 for (i
= 0; LST_SEQ (loop
).iterate (i
, &l
);)
1306 before
= lst_remove_all_before_excluding_pbb (l
, pbb
, before
);
1308 if (LST_SEQ (l
).length () == 0)
1310 LST_SEQ (loop
).ordered_remove (i
);
1319 if (before
&& LST_PBB (l
) != pbb
)
1321 LST_SEQ (loop
).ordered_remove (i
);
1328 if (LST_PBB (l
) == pbb
)
1329 before
= before
? false : true;
1335 /* A SCOP is a Static Control Part of the program, simple enough to be
1336 represented in polyhedral form. */
1339 /* A SCOP is defined as a SESE region. */
1342 /* Number of parameters in SCoP. */
1343 graphite_dim_t nb_params
;
1345 /* All the basic blocks in this scop that contain memory references
1346 and that will be represented as statements in the polyhedral
1350 /* Original, transformed and saved schedules. */
1351 lst_p original_schedule
, transformed_schedule
, saved_schedule
;
1353 /* The context describes known restrictions concerning the parameters
1354 and relations in between the parameters.
1356 void f (int8_t a, uint_16_t b) {
1361 Here we can add these restrictions to the context:
1368 /* The context used internally by ISL. */
1371 /* The original dependence relations:
1372 RAW are read after write dependences,
1373 WAR are write after read dependences,
1374 WAW are write after write dependences. */
1375 isl_union_map
*must_raw
, *may_raw
, *must_raw_no_source
, *may_raw_no_source
,
1376 *must_war
, *may_war
, *must_war_no_source
, *may_war_no_source
,
1377 *must_waw
, *may_waw
, *must_waw_no_source
, *may_waw_no_source
;
1379 /* True when the scop has been converted to its polyhedral
1384 #define SCOP_BBS(S) (S->bbs)
1385 #define SCOP_REGION(S) ((sese) S->region)
1386 #define SCOP_CONTEXT(S) (NULL)
1387 #define SCOP_ORIGINAL_SCHEDULE(S) (S->original_schedule)
1388 #define SCOP_TRANSFORMED_SCHEDULE(S) (S->transformed_schedule)
1389 #define SCOP_SAVED_SCHEDULE(S) (S->saved_schedule)
1390 #define POLY_SCOP_P(S) (S->poly_scop_p)
1392 extern scop_p
new_scop (void *);
1393 extern void free_scop (scop_p
);
1394 extern void free_scops (vec
<scop_p
> );
1395 extern void print_generated_program (FILE *, scop_p
);
1396 extern void debug_generated_program (scop_p
);
1397 extern void print_scattering_function (FILE *, poly_bb_p
, int);
1398 extern void print_scattering_functions (FILE *, scop_p
, int);
1399 extern void debug_scattering_function (poly_bb_p
, int);
1400 extern void debug_scattering_functions (scop_p
, int);
1401 extern int scop_max_loop_depth (scop_p
);
1402 extern int unify_scattering_dimensions (scop_p
);
1403 extern bool apply_poly_transforms (scop_p
);
1404 extern bool graphite_legal_transform (scop_p
);
1405 extern void cloog_checksum (scop_p
);
1407 /* Set the region of SCOP to REGION. */
1410 scop_set_region (scop_p scop
, void *region
)
1412 scop
->region
= region
;
1415 /* Returns the number of parameters for SCOP. */
1417 static inline graphite_dim_t
1418 scop_nb_params (scop_p scop
)
1420 return scop
->nb_params
;
1423 /* Set the number of params of SCOP to NB_PARAMS. */
1426 scop_set_nb_params (scop_p scop
, graphite_dim_t nb_params
)
1428 scop
->nb_params
= nb_params
;
1431 /* Allocates a new empty poly_scattering structure. */
1433 static inline poly_scattering_p
1434 poly_scattering_new (void)
1436 poly_scattering_p res
= XNEW (struct poly_scattering
);
1438 res
->nb_local_variables
= 0;
1439 res
->nb_scattering
= 0;
1443 /* Free a poly_scattering structure. */
1446 poly_scattering_free (poly_scattering_p s
)
1451 /* Copies S and return a new scattering. */
1453 static inline poly_scattering_p
1454 poly_scattering_copy (poly_scattering_p s
)
1456 poly_scattering_p res
= poly_scattering_new ();
1458 res
->nb_local_variables
= s
->nb_local_variables
;
1459 res
->nb_scattering
= s
->nb_scattering
;
1463 /* Saves the transformed scattering of PBB. */
1466 store_scattering_pbb (poly_bb_p pbb
)
1468 isl_map_free (pbb
->saved
);
1469 pbb
->saved
= isl_map_copy (pbb
->transformed
);
1472 /* Stores the SCOP_TRANSFORMED_SCHEDULE to SCOP_SAVED_SCHEDULE. */
1475 store_lst_schedule (scop_p scop
)
1477 if (SCOP_SAVED_SCHEDULE (scop
))
1478 free_lst (SCOP_SAVED_SCHEDULE (scop
));
1480 SCOP_SAVED_SCHEDULE (scop
) = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop
));
1483 /* Restores the SCOP_TRANSFORMED_SCHEDULE from SCOP_SAVED_SCHEDULE. */
1486 restore_lst_schedule (scop_p scop
)
1488 if (SCOP_TRANSFORMED_SCHEDULE (scop
))
1489 free_lst (SCOP_TRANSFORMED_SCHEDULE (scop
));
1491 SCOP_TRANSFORMED_SCHEDULE (scop
) = copy_lst (SCOP_SAVED_SCHEDULE (scop
));
1494 /* Saves the scattering for all the pbbs in the SCOP. */
1497 store_scattering (scop_p scop
)
1502 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1503 store_scattering_pbb (pbb
);
1505 store_lst_schedule (scop
);
1508 /* Restores the scattering of PBB. */
1511 restore_scattering_pbb (poly_bb_p pbb
)
1513 gcc_assert (pbb
->saved
);
1515 isl_map_free (pbb
->transformed
);
1516 pbb
->transformed
= isl_map_copy (pbb
->saved
);
1519 /* Restores the scattering for all the pbbs in the SCOP. */
1522 restore_scattering (scop_p scop
)
1527 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1528 restore_scattering_pbb (pbb
);
1530 restore_lst_schedule (scop
);
1533 bool graphite_legal_transform (scop_p
);
1534 isl_map
*reverse_loop_at_level (poly_bb_p
, int);
1535 isl_union_map
*reverse_loop_for_pbbs (scop_p
, vec
<poly_bb_p
> , int);
1536 __isl_give isl_union_map
*extend_schedule (__isl_take isl_union_map
*);
1540 compute_deps (scop_p scop
, vec
<poly_bb_p
> pbbs
,
1541 isl_union_map
**must_raw
,
1542 isl_union_map
**may_raw
,
1543 isl_union_map
**must_raw_no_source
,
1544 isl_union_map
**may_raw_no_source
,
1545 isl_union_map
**must_war
,
1546 isl_union_map
**may_war
,
1547 isl_union_map
**must_war_no_source
,
1548 isl_union_map
**may_war_no_source
,
1549 isl_union_map
**must_waw
,
1550 isl_union_map
**may_waw
,
1551 isl_union_map
**must_waw_no_source
,
1552 isl_union_map
**may_waw_no_source
);
1555 scop_get_dependences (scop_p scop
);
1558 carries_deps (__isl_keep isl_union_map
*schedule
,
1559 __isl_keep isl_union_map
*deps
,