1 /* Graphite polyhedral representation.
2 Copyright (C) 2009, 2010 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 DEF_VEC_ALLOC_P (poly_dr_p
, heap
);
29 typedef struct poly_bb
*poly_bb_p
;
31 DEF_VEC_ALLOC_P (poly_bb_p
, heap
);
33 typedef struct scop
*scop_p
;
35 DEF_VEC_ALLOC_P (scop_p
, heap
);
37 typedef ppl_dimension_type graphite_dim_t
;
39 static inline graphite_dim_t
pbb_dim_iter_domain (const struct poly_bb
*);
40 static inline graphite_dim_t
pbb_nb_params (const struct poly_bb
*);
41 static inline graphite_dim_t
scop_nb_params (scop_p
);
43 /* A data reference can write or read some memory or we
44 just know it may write some memory. */
48 /* PDR_MAY_READs are represented using PDR_READS. This does not
49 limit the expressiveness. */
56 /* An identifier for this PDR. */
59 /* The number of data refs identical to this one in the PBB. */
62 /* A pointer to compiler's data reference description. */
65 /* A pointer to the PBB that contains this data reference. */
68 enum poly_dr_type type
;
70 /* The access polyhedron contains the polyhedral space this data
71 reference will access.
73 The polyhedron contains these dimensions:
76 Every memory access is classified in at least one alias set.
78 - The subscripts (s_0, ..., s_n):
79 The memory is accessed using zero or more subscript dimensions.
81 - The iteration domain (variables and parameters)
83 Do not hardcode the dimensions. Use the following accessor functions:
97 | if (unknown_function ())
104 The data access A[i][j+k] in alias set "5" is described like this:
109 | 0 -1 -1 0 0 1 0 = 0
110 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
111 | 0 0 0 0 0 1 0 >= 0 # array size.
112 | 0 0 0 0 -1 0 1335 >= 0
113 | 0 0 0 0 0 -1 123 >= 0
115 The pointer "*p" in alias set "5" and "7" is described as a union of
129 "*p" accesses all of the object allocated with 'malloc'.
131 The scalar data access "m" is represented as an array with zero subscript
137 The difference between the graphite internal format for access data and
138 the OpenSop format is in the order of columns.
144 | 0 -1 -1 0 0 1 0 = 0
145 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
146 | 0 0 0 0 0 1 0 >= 0 # array size.
147 | 0 0 0 0 -1 0 1335 >= 0
148 | 0 0 0 0 0 -1 123 >= 0
155 | 0 0 1 0 -1 -1 0 = 0
156 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
157 | 0 0 1 0 0 0 0 >= 0 # array size.
158 | 0 -1 0 0 0 0 1335 >= 0
159 | 0 0 -1 0 0 0 123 >= 0
161 The OpenScop access function is printed as follows:
163 | 1 # The number of disjunct components in a union of access functions.
164 | R C O I L P # Described bellow.
168 | 0 0 1 0 -1 -1 0 = 0
169 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
170 | 0 0 1 0 0 0 0 >= 0 # array size.
171 | 0 -1 0 0 0 0 1335 >= 0
172 | 0 0 -1 0 0 0 123 >= 0
176 - C: Number of columns.
177 - O: Number of output dimensions = alias set + number of subscripts.
178 - I: Number of input dimensions (iterators).
179 - L: Number of local (existentially quantified) dimensions.
180 - P: Number of parameters.
182 In the example, the vector "R C O I L P" is "7 7 3 2 0 1". */
183 ppl_Pointset_Powerset_C_Polyhedron_t accesses
;
185 /* Data reference's base object set number, we must assure 2 pdrs are in the
186 same base object set before dependency checking. */
187 int dr_base_object_set
;
189 /* The number of subscripts. */
190 graphite_dim_t nb_subscripts
;
193 #define PDR_ID(PDR) (PDR->id)
194 #define PDR_NB_REFS(PDR) (PDR->nb_refs)
195 #define PDR_CDR(PDR) (PDR->compiler_dr)
196 #define PDR_PBB(PDR) (PDR->pbb)
197 #define PDR_TYPE(PDR) (PDR->type)
198 #define PDR_ACCESSES(PDR) (PDR->accesses)
199 #define PDR_BASE_OBJECT_SET(PDR) (PDR->dr_base_object_set)
200 #define PDR_NB_SUBSCRIPTS(PDR) (PDR->nb_subscripts)
202 void new_poly_dr (poly_bb_p
, int, ppl_Pointset_Powerset_C_Polyhedron_t
,
203 enum poly_dr_type
, void *, graphite_dim_t
);
204 void free_poly_dr (poly_dr_p
);
205 void debug_pdr (poly_dr_p
, int);
206 void print_pdr (FILE *, poly_dr_p
, int);
207 static inline scop_p
pdr_scop (poly_dr_p pdr
);
209 /* The dimension of the PDR_ACCESSES polyhedron of PDR. */
211 static inline ppl_dimension_type
212 pdr_dim (poly_dr_p pdr
)
214 ppl_dimension_type dim
;
215 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PDR_ACCESSES (pdr
),
220 /* The dimension of the iteration domain of the scop of PDR. */
222 static inline ppl_dimension_type
223 pdr_dim_iter_domain (poly_dr_p pdr
)
225 return pbb_dim_iter_domain (PDR_PBB (pdr
));
228 /* The number of parameters of the scop of PDR. */
230 static inline ppl_dimension_type
231 pdr_nb_params (poly_dr_p pdr
)
233 return scop_nb_params (pdr_scop (pdr
));
236 /* The dimension of the alias set in PDR. */
238 static inline ppl_dimension_type
239 pdr_alias_set_dim (poly_dr_p pdr
)
241 poly_bb_p pbb
= PDR_PBB (pdr
);
243 return pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
);
246 /* The dimension in PDR containing subscript S. */
248 static inline ppl_dimension_type
249 pdr_subscript_dim (poly_dr_p pdr
, graphite_dim_t s
)
251 poly_bb_p pbb
= PDR_PBB (pdr
);
253 return pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
) + 1 + s
;
256 /* The dimension in PDR containing the loop iterator ITER. */
258 static inline ppl_dimension_type
259 pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED
, graphite_dim_t iter
)
264 /* The dimension in PDR containing parameter PARAM. */
266 static inline ppl_dimension_type
267 pdr_parameter_dim (poly_dr_p pdr
, graphite_dim_t param
)
269 poly_bb_p pbb
= PDR_PBB (pdr
);
271 return pbb_dim_iter_domain (pbb
) + param
;
274 /* Returns true when PDR is a "read". */
277 pdr_read_p (poly_dr_p pdr
)
279 return PDR_TYPE (pdr
) == PDR_READ
;
282 /* Returns true when PDR is a "write". */
285 pdr_write_p (poly_dr_p pdr
)
287 return PDR_TYPE (pdr
) == PDR_WRITE
;
290 /* Returns true when PDR is a "may write". */
293 pdr_may_write_p (poly_dr_p pdr
)
295 return PDR_TYPE (pdr
) == PDR_MAY_WRITE
;
298 /* Return true when PDR1 and PDR2 are similar data accesses: they have
299 the same base array, and the same access functions. */
302 same_pdr_p (poly_dr_p pdr1
, poly_dr_p pdr2
)
304 return PDR_NB_SUBSCRIPTS (pdr1
) == PDR_NB_SUBSCRIPTS (pdr2
)
305 && PDR_BASE_OBJECT_SET (pdr1
) == PDR_BASE_OBJECT_SET (pdr2
);
308 typedef struct poly_scattering
*poly_scattering_p
;
310 struct poly_scattering
312 /* The scattering function containing the transformations: the
313 layout of this polyhedron is: T|I|G with T the transform
314 scattering, I the iteration domain, G the context parameters. */
315 ppl_Polyhedron_t scattering
;
317 /* The number of local variables. */
318 int nb_local_variables
;
320 /* The number of scattering dimensions. */
324 /* POLY_BB represents a blackbox in the polyhedral model. */
328 /* Pointer to a basic block or a statement in the compiler. */
331 /* Pointer to the SCOP containing this PBB. */
334 /* The iteration domain of this bb. The layout of this polyhedron
335 is I|G with I the iteration domain, G the context parameters.
339 for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
340 for (j = 2; j <= 2*i + 5; j++)
341 for (k = 0; k <= 5; k++)
344 Loop iterators: i, j, k
354 The number of variables in the DOMAIN may change and is not
355 related to the number of loops in the original code. */
356 ppl_Pointset_Powerset_C_Polyhedron_t domain
;
358 /* The data references we access. */
359 VEC (poly_dr_p
, heap
) *drs
;
361 /* The original scattering. */
362 poly_scattering_p original
;
364 /* The transformed scattering. */
365 poly_scattering_p transformed
;
367 /* A copy of the transformed scattering. */
368 poly_scattering_p saved
;
370 /* True when the PDR duplicates have already been removed. */
371 bool pdr_duplicates_removed
;
373 /* True when this PBB contains only a reduction statement. */
377 #define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box)
378 #define PBB_SCOP(PBB) (PBB->scop)
379 #define PBB_DOMAIN(PBB) (PBB->domain)
380 #define PBB_DRS(PBB) (PBB->drs)
381 #define PBB_ORIGINAL(PBB) (PBB->original)
382 #define PBB_ORIGINAL_SCATTERING(PBB) (PBB->original->scattering)
383 #define PBB_TRANSFORMED(PBB) (PBB->transformed)
384 #define PBB_TRANSFORMED_SCATTERING(PBB) (PBB->transformed->scattering)
385 #define PBB_SAVED(PBB) (PBB->saved)
386 #define PBB_NB_LOCAL_VARIABLES(PBB) (PBB->transformed->nb_local_variables)
387 #define PBB_NB_SCATTERING_TRANSFORM(PBB) (PBB->transformed->nb_scattering)
388 #define PBB_PDR_DUPLICATES_REMOVED(PBB) (PBB->pdr_duplicates_removed)
389 #define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
391 extern poly_bb_p
new_poly_bb (scop_p
, void *);
392 extern void free_poly_bb (poly_bb_p
);
393 extern void debug_loop_vec (poly_bb_p
);
394 extern void schedule_to_scattering (poly_bb_p
, int);
395 extern void print_pbb_domain (FILE *, poly_bb_p
, int);
396 extern void print_pbb (FILE *, poly_bb_p
, int);
397 extern void print_scop_context (FILE *, scop_p
, int);
398 extern void print_scop (FILE *, scop_p
, int);
399 extern void print_cloog (FILE *, scop_p
, int);
400 extern void debug_pbb_domain (poly_bb_p
, int);
401 extern void debug_pbb (poly_bb_p
, int);
402 extern void print_pdrs (FILE *, poly_bb_p
, int);
403 extern void debug_pdrs (poly_bb_p
, int);
404 extern void debug_scop_context (scop_p
, int);
405 extern void debug_scop (scop_p
, int);
406 extern void debug_cloog (scop_p
, int);
407 extern void print_scop_params (FILE *, scop_p
, int);
408 extern void debug_scop_params (scop_p
, int);
409 extern void print_iteration_domain (FILE *, poly_bb_p
, int);
410 extern void print_iteration_domains (FILE *, scop_p
, int);
411 extern void debug_iteration_domain (poly_bb_p
, int);
412 extern void debug_iteration_domains (scop_p
, int);
413 extern bool scop_do_interchange (scop_p
);
414 extern bool scop_do_strip_mine (scop_p
, int);
415 extern bool scop_do_block (scop_p
);
416 extern bool flatten_all_loops (scop_p
);
417 extern void pbb_number_of_iterations_at_time (poly_bb_p
, graphite_dim_t
, mpz_t
);
418 extern void pbb_remove_duplicate_pdrs (poly_bb_p
);
420 /* Return the number of write data references in PBB. */
423 number_of_write_pdrs (poly_bb_p pbb
)
429 for (i
= 0; VEC_iterate (poly_dr_p
, PBB_DRS (pbb
), i
, pdr
); i
++)
430 if (PDR_TYPE (pdr
) == PDR_WRITE
)
436 /* Returns a gimple_bb from BB. */
438 static inline gimple_bb_p
439 gbb_from_bb (basic_block bb
)
441 return (gimple_bb_p
) bb
->aux
;
444 /* The poly_bb of the BB. */
446 static inline poly_bb_p
447 pbb_from_bb (basic_block bb
)
449 return GBB_PBB (gbb_from_bb (bb
));
452 /* The basic block of the PBB. */
454 static inline basic_block
455 pbb_bb (poly_bb_p pbb
)
457 return GBB_BB (PBB_BLACK_BOX (pbb
));
460 /* The index of the PBB. */
463 pbb_index (poly_bb_p pbb
)
465 return pbb_bb (pbb
)->index
;
468 /* The loop of the PBB. */
471 pbb_loop (poly_bb_p pbb
)
473 return gbb_loop (PBB_BLACK_BOX (pbb
));
476 /* The scop that contains the PDR. */
479 pdr_scop (poly_dr_p pdr
)
481 return PBB_SCOP (PDR_PBB (pdr
));
484 /* Set black box of PBB to BLACKBOX. */
487 pbb_set_black_box (poly_bb_p pbb
, void *black_box
)
489 pbb
->black_box
= black_box
;
492 /* The number of loops around PBB: the dimension of the iteration
495 static inline graphite_dim_t
496 pbb_dim_iter_domain (const struct poly_bb
*pbb
)
498 scop_p scop
= PBB_SCOP (pbb
);
499 ppl_dimension_type dim
;
501 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb
), &dim
);
502 return dim
- scop_nb_params (scop
);
505 /* The number of params defined in PBB. */
507 static inline graphite_dim_t
508 pbb_nb_params (const struct poly_bb
*pbb
)
510 scop_p scop
= PBB_SCOP (pbb
);
512 return scop_nb_params (scop
);
515 /* The number of scattering dimensions in the SCATTERING polyhedron
516 of a PBB for a given SCOP. */
518 static inline graphite_dim_t
519 pbb_nb_scattering_orig (const struct poly_bb
*pbb
)
521 return 2 * pbb_dim_iter_domain (pbb
) + 1;
524 /* The number of scattering dimensions in PBB. */
526 static inline graphite_dim_t
527 pbb_nb_scattering_transform (const struct poly_bb
*pbb
)
529 return PBB_NB_SCATTERING_TRANSFORM (pbb
);
532 /* The number of dynamic scattering dimensions in PBB. */
534 static inline graphite_dim_t
535 pbb_nb_dynamic_scattering_transform (const struct poly_bb
*pbb
)
537 /* This function requires the 2d + 1 scattering format to be
538 invariant during all transformations. */
539 gcc_assert (PBB_NB_SCATTERING_TRANSFORM (pbb
) % 2);
540 return PBB_NB_SCATTERING_TRANSFORM (pbb
) / 2;
543 /* Returns the number of local variables used in the transformed
544 scattering polyhedron of PBB. */
546 static inline graphite_dim_t
547 pbb_nb_local_vars (const struct poly_bb
*pbb
)
549 /* For now we do not have any local variables, as we do not do strip
550 mining for example. */
551 return PBB_NB_LOCAL_VARIABLES (pbb
);
554 /* The dimension in the domain of PBB containing the iterator ITER. */
556 static inline ppl_dimension_type
557 pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t iter
)
562 /* The dimension in the domain of PBB containing the iterator ITER. */
564 static inline ppl_dimension_type
565 pbb_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
568 + pbb_dim_iter_domain (pbb
);
571 /* The dimension in the original scattering polyhedron of PBB
572 containing the scattering iterator SCATTER. */
574 static inline ppl_dimension_type
575 psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t scatter
)
577 gcc_assert (scatter
< pbb_nb_scattering_orig (pbb
));
581 /* The dimension in the transformed scattering polyhedron of PBB
582 containing the scattering iterator SCATTER. */
584 static inline ppl_dimension_type
585 psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED
, graphite_dim_t scatter
)
587 gcc_assert (scatter
<= pbb_nb_scattering_transform (pbb
));
591 ppl_dimension_type
psct_scattering_dim_for_loop_depth (poly_bb_p
,
594 /* The dimension in the transformed scattering polyhedron of PBB of
595 the local variable LV. */
597 static inline ppl_dimension_type
598 psct_local_var_dim (poly_bb_p pbb
, graphite_dim_t lv
)
600 gcc_assert (lv
<= pbb_nb_local_vars (pbb
));
601 return lv
+ pbb_nb_scattering_transform (pbb
);
604 /* The dimension in the original scattering polyhedron of PBB
605 containing the loop iterator ITER. */
607 static inline ppl_dimension_type
608 psco_iterator_dim (poly_bb_p pbb
, graphite_dim_t iter
)
610 gcc_assert (iter
< pbb_dim_iter_domain (pbb
));
611 return iter
+ pbb_nb_scattering_orig (pbb
);
614 /* The dimension in the transformed scattering polyhedron of PBB
615 containing the loop iterator ITER. */
617 static inline ppl_dimension_type
618 psct_iterator_dim (poly_bb_p pbb
, graphite_dim_t iter
)
620 gcc_assert (iter
< pbb_dim_iter_domain (pbb
));
622 + pbb_nb_scattering_transform (pbb
)
623 + pbb_nb_local_vars (pbb
);
626 /* The dimension in the original scattering polyhedron of PBB
627 containing parameter PARAM. */
629 static inline ppl_dimension_type
630 psco_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
632 gcc_assert (param
< pbb_nb_params (pbb
));
634 + pbb_nb_scattering_orig (pbb
)
635 + pbb_dim_iter_domain (pbb
);
638 /* The dimension in the transformed scattering polyhedron of PBB
639 containing parameter PARAM. */
641 static inline ppl_dimension_type
642 psct_parameter_dim (poly_bb_p pbb
, graphite_dim_t param
)
644 gcc_assert (param
< pbb_nb_params (pbb
));
646 + pbb_nb_scattering_transform (pbb
)
647 + pbb_nb_local_vars (pbb
)
648 + pbb_dim_iter_domain (pbb
);
651 /* The scattering dimension of PBB corresponding to the dynamic level
654 static inline ppl_dimension_type
655 psct_dynamic_dim (poly_bb_p pbb
, graphite_dim_t level
)
657 graphite_dim_t result
= 1 + 2 * level
;
659 gcc_assert (result
< pbb_nb_scattering_transform (pbb
));
663 /* The scattering dimension of PBB corresponding to the static
664 sequence of the loop level LEVEL. */
666 static inline ppl_dimension_type
667 psct_static_dim (poly_bb_p pbb
, graphite_dim_t level
)
669 graphite_dim_t result
= 2 * level
;
671 gcc_assert (result
< pbb_nb_scattering_transform (pbb
));
675 /* Adds to the transformed scattering polyhedron of PBB a new local
676 variable and returns its index. */
678 static inline graphite_dim_t
679 psct_add_local_variable (poly_bb_p pbb
)
681 graphite_dim_t nlv
= pbb_nb_local_vars (pbb
);
682 ppl_dimension_type lv_column
= psct_local_var_dim (pbb
, nlv
);
683 ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb
), lv_column
, 1);
684 PBB_NB_LOCAL_VARIABLES (pbb
) += 1;
688 /* Adds a dimension to the transformed scattering polyhedron of PBB at
692 psct_add_scattering_dimension (poly_bb_p pbb
, ppl_dimension_type index
)
694 gcc_assert (index
< pbb_nb_scattering_transform (pbb
));
696 ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb
), index
, 1);
697 PBB_NB_SCATTERING_TRANSFORM (pbb
) += 1;
700 typedef struct lst
*lst_p
;
702 DEF_VEC_ALLOC_P (lst_p
, heap
);
704 /* Loops and Statements Tree. */
707 /* LOOP_P is true when an LST node is a loop. */
710 /* A pointer to the loop that contains this node. */
713 /* The sum of all the memory strides for an LST loop. */
714 mpz_t memory_strides
;
716 /* Loop nodes contain a sequence SEQ of LST nodes, statements
717 contain a pointer to their polyhedral representation PBB. */
720 VEC (lst_p
, heap
) *seq
;
724 #define LST_LOOP_P(LST) ((LST)->loop_p)
725 #define LST_LOOP_FATHER(LST) ((LST)->loop_father)
726 #define LST_PBB(LST) ((LST)->node.pbb)
727 #define LST_SEQ(LST) ((LST)->node.seq)
728 #define LST_LOOP_MEMORY_STRIDES(LST) ((LST)->memory_strides)
730 void scop_to_lst (scop_p
);
731 void print_lst (FILE *, lst_p
, int);
732 void debug_lst (lst_p
);
733 void dot_lst (lst_p
);
735 /* Creates a new LST loop with SEQ. */
738 new_lst_loop (VEC (lst_p
, heap
) *seq
)
740 lst_p lst
= XNEW (struct lst
);
744 LST_LOOP_P (lst
) = true;
746 LST_LOOP_FATHER (lst
) = NULL
;
747 mpz_init (LST_LOOP_MEMORY_STRIDES (lst
));
748 mpz_set_si (LST_LOOP_MEMORY_STRIDES (lst
), -1);
750 for (i
= 0; VEC_iterate (lst_p
, seq
, i
, l
); i
++)
751 LST_LOOP_FATHER (l
) = lst
;
756 /* Creates a new LST statement with PBB. */
759 new_lst_stmt (poly_bb_p pbb
)
761 lst_p lst
= XNEW (struct lst
);
763 LST_LOOP_P (lst
) = false;
765 LST_LOOP_FATHER (lst
) = NULL
;
769 /* Frees the memory used by LST. */
777 if (LST_LOOP_P (lst
))
782 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
785 mpz_clear (LST_LOOP_MEMORY_STRIDES (lst
));
786 VEC_free (lst_p
, heap
, LST_SEQ (lst
));
792 /* Returns a copy of LST. */
800 if (LST_LOOP_P (lst
))
804 VEC (lst_p
, heap
) *seq
= VEC_alloc (lst_p
, heap
, 5);
806 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
807 VEC_safe_push (lst_p
, heap
, seq
, copy_lst (l
));
809 return new_lst_loop (seq
);
812 return new_lst_stmt (LST_PBB (lst
));
815 /* Adds a new loop under the loop LST. */
818 lst_add_loop_under_loop (lst_p lst
)
820 VEC (lst_p
, heap
) *seq
= VEC_alloc (lst_p
, heap
, 1);
821 lst_p l
= new_lst_loop (LST_SEQ (lst
));
823 gcc_assert (LST_LOOP_P (lst
));
825 LST_LOOP_FATHER (l
) = lst
;
826 VEC_quick_push (lst_p
, seq
, l
);
830 /* Returns the loop depth of LST. */
833 lst_depth (lst_p lst
)
838 /* The depth of the outermost "fake" loop is -1. This outermost
839 loop does not have a loop father and it is just a container, as
840 in the loop representation of GCC. */
841 if (!LST_LOOP_FATHER (lst
))
844 return lst_depth (LST_LOOP_FATHER (lst
)) + 1;
847 /* Returns the Dewey number for LST. */
850 lst_dewey_number (lst_p lst
)
858 if (!LST_LOOP_FATHER (lst
))
861 FOR_EACH_VEC_ELT (lst_p
, LST_SEQ (LST_LOOP_FATHER (lst
)), i
, l
)
868 /* Returns the Dewey number of LST at depth DEPTH. */
871 lst_dewey_number_at_depth (lst_p lst
, int depth
)
873 gcc_assert (lst
&& depth
>= 0 && lst_depth (lst
) <= depth
);
875 if (lst_depth (lst
) == depth
)
876 return lst_dewey_number (lst
);
878 return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst
), depth
);
881 /* Returns the predecessor of LST in the sequence of its loop father.
882 Returns NULL if LST is the first statement in the sequence. */
890 if (!lst
|| !LST_LOOP_FATHER (lst
))
893 dewey
= lst_dewey_number (lst
);
897 father
= LST_LOOP_FATHER (lst
);
898 return VEC_index (lst_p
, LST_SEQ (father
), dewey
- 1);
901 /* Returns the successor of LST in the sequence of its loop father.
902 Returns NULL if there is none. */
910 if (!lst
|| !LST_LOOP_FATHER (lst
))
913 dewey
= lst_dewey_number (lst
);
914 father
= LST_LOOP_FATHER (lst
);
916 if (VEC_length (lst_p
, LST_SEQ (father
)) == (unsigned) dewey
+ 1)
919 return VEC_index (lst_p
, LST_SEQ (father
), dewey
+ 1);
923 /* Return the LST node corresponding to PBB. */
926 lst_find_pbb (lst_p lst
, poly_bb_p pbb
)
934 if (!LST_LOOP_P (lst
))
935 return (pbb
== LST_PBB (lst
)) ? lst
: NULL
;
937 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
939 lst_p res
= lst_find_pbb (l
, pbb
);
947 /* Return the LST node corresponding to the loop around STMT at depth
951 find_lst_loop (lst_p stmt
, int loop_depth
)
953 lst_p loop
= LST_LOOP_FATHER (stmt
);
955 gcc_assert (loop_depth
>= 0);
957 while (loop_depth
< lst_depth (loop
))
958 loop
= LST_LOOP_FATHER (loop
);
963 /* Return the first LST representing a PBB statement in LST. */
966 lst_find_first_pbb (lst_p lst
)
974 if (!LST_LOOP_P (lst
))
977 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
979 lst_p res
= lst_find_first_pbb (l
);
987 /* Returns true when LST is a loop that does not contain
991 lst_empty_p (lst_p lst
)
993 return !lst_find_first_pbb (lst
);
996 /* Return the last LST representing a PBB statement in LST. */
999 lst_find_last_pbb (lst_p lst
)
1002 lst_p l
, res
= NULL
;
1007 if (!LST_LOOP_P (lst
))
1010 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
1012 lst_p last
= lst_find_last_pbb (l
);
1022 /* Returns true if LOOP contains LST, in other words, if LST is nested
1026 lst_contains_p (lst_p loop
, lst_p lst
)
1028 if (!loop
|| !lst
|| !LST_LOOP_P (loop
))
1034 return lst_contains_p (loop
, LST_LOOP_FATHER (lst
));
1037 /* Returns true if LOOP contains PBB, in other words, if PBB is nested
1041 lst_contains_pbb (lst_p loop
, poly_bb_p pbb
)
1043 return lst_find_pbb (loop
, pbb
) ? true : false;
1046 /* Creates a loop nest of depth NB_LOOPS containing LST. */
1049 lst_create_nest (int nb_loops
, lst_p lst
)
1052 VEC (lst_p
, heap
) *seq
;
1057 seq
= VEC_alloc (lst_p
, heap
, 1);
1058 loop
= lst_create_nest (nb_loops
- 1, lst
);
1059 VEC_quick_push (lst_p
, seq
, loop
);
1060 res
= new_lst_loop (seq
);
1061 LST_LOOP_FATHER (loop
) = res
;
1066 /* Removes LST from the sequence of statements of its loop father. */
1069 lst_remove_from_sequence (lst_p lst
)
1071 lst_p father
= LST_LOOP_FATHER (lst
);
1072 int dewey
= lst_dewey_number (lst
);
1074 gcc_assert (lst
&& father
&& dewey
>= 0);
1076 VEC_ordered_remove (lst_p
, LST_SEQ (father
), dewey
);
1077 LST_LOOP_FATHER (lst
) = NULL
;
1080 /* Removes the loop LST and inline its body in the father loop. */
1083 lst_remove_loop_and_inline_stmts_in_loop_father (lst_p lst
)
1085 lst_p l
, father
= LST_LOOP_FATHER (lst
);
1086 int i
, dewey
= lst_dewey_number (lst
);
1088 gcc_assert (lst
&& father
&& dewey
>= 0);
1090 VEC_ordered_remove (lst_p
, LST_SEQ (father
), dewey
);
1091 LST_LOOP_FATHER (lst
) = NULL
;
1093 FOR_EACH_VEC_ELT (lst_p
, LST_SEQ (lst
), i
, l
)
1095 VEC_safe_insert (lst_p
, heap
, LST_SEQ (father
), dewey
+ i
, l
);
1096 LST_LOOP_FATHER (l
) = father
;
1100 /* Sets NITER to the upper bound approximation of the number of
1101 iterations of loop LST. */
1104 lst_niter_for_loop (lst_p lst
, mpz_t niter
)
1106 int depth
= lst_depth (lst
);
1107 poly_bb_p pbb
= LST_PBB (lst_find_first_pbb (lst
));
1109 gcc_assert (LST_LOOP_P (lst
));
1110 pbb_number_of_iterations_at_time (pbb
, psct_dynamic_dim (pbb
, depth
), niter
);
1113 /* Updates the scattering of PBB to be at the DEWEY number in the loop
1117 pbb_update_scattering (poly_bb_p pbb
, graphite_dim_t level
, int dewey
)
1119 ppl_Polyhedron_t ph
= PBB_TRANSFORMED_SCATTERING (pbb
);
1120 ppl_dimension_type sched
= psct_static_dim (pbb
, level
);
1121 ppl_dimension_type ds
[1];
1122 ppl_Constraint_t new_cstr
;
1123 ppl_Linear_Expression_t expr
;
1124 ppl_dimension_type dim
;
1126 ppl_Polyhedron_space_dimension (ph
, &dim
);
1128 ppl_Polyhedron_remove_space_dimensions (ph
, ds
, 1);
1129 ppl_insert_dimensions (ph
, sched
, 1);
1131 ppl_new_Linear_Expression_with_dimension (&expr
, dim
);
1132 ppl_set_coef (expr
, sched
, -1);
1133 ppl_set_inhomogeneous (expr
, dewey
);
1134 ppl_new_Constraint (&new_cstr
, expr
, PPL_CONSTRAINT_TYPE_EQUAL
);
1135 ppl_delete_Linear_Expression (expr
);
1136 ppl_Polyhedron_add_constraint (ph
, new_cstr
);
1137 ppl_delete_Constraint (new_cstr
);
1140 /* Updates the scattering of all the PBBs under LST to be at the DEWEY
1141 number in the loop at depth LEVEL. */
1144 lst_update_scattering_under (lst_p lst
, int level
, int dewey
)
1149 gcc_assert (lst
&& level
>= 0 && dewey
>= 0);
1151 if (LST_LOOP_P (lst
))
1152 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
1153 lst_update_scattering_under (l
, level
, dewey
);
1155 pbb_update_scattering (LST_PBB (lst
), level
, dewey
);
1158 /* Updates the all the scattering levels of all the PBBs under
1162 lst_update_scattering (lst_p lst
)
1170 if (LST_LOOP_FATHER (lst
))
1172 lst_p father
= LST_LOOP_FATHER (lst
);
1173 int dewey
= lst_dewey_number (lst
);
1174 int level
= lst_depth (lst
);
1176 gcc_assert (lst
&& father
&& dewey
>= 0 && level
>= 0);
1178 for (i
= dewey
; VEC_iterate (lst_p
, LST_SEQ (father
), i
, l
); i
++)
1179 lst_update_scattering_under (l
, level
, i
);
1182 if (LST_LOOP_P (lst
))
1183 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (lst
), i
, l
); i
++)
1184 lst_update_scattering (l
);
1187 /* Inserts LST1 before LST2 if BEFORE is true; inserts LST1 after LST2
1188 if BEFORE is false. */
1191 lst_insert_in_sequence (lst_p lst1
, lst_p lst2
, bool before
)
1196 /* Do not insert empty loops. */
1197 if (!lst1
|| lst_empty_p (lst1
))
1200 father
= LST_LOOP_FATHER (lst2
);
1201 dewey
= lst_dewey_number (lst2
);
1203 gcc_assert (lst2
&& father
&& dewey
>= 0);
1205 VEC_safe_insert (lst_p
, heap
, LST_SEQ (father
), before
? dewey
: dewey
+ 1,
1207 LST_LOOP_FATHER (lst1
) = father
;
1210 /* Replaces LST1 with LST2. */
1213 lst_replace (lst_p lst1
, lst_p lst2
)
1218 if (!lst2
|| lst_empty_p (lst2
))
1221 father
= LST_LOOP_FATHER (lst1
);
1222 dewey
= lst_dewey_number (lst1
);
1223 LST_LOOP_FATHER (lst2
) = father
;
1224 VEC_replace (lst_p
, LST_SEQ (father
), dewey
, lst2
);
1227 /* Returns a copy of ROOT where LST has been replaced by a copy of the
1228 LSTs A B C in this sequence. */
1231 lst_substitute_3 (lst_p root
, lst_p lst
, lst_p a
, lst_p b
, lst_p c
)
1235 VEC (lst_p
, heap
) *seq
;
1240 gcc_assert (lst
&& root
!= lst
);
1242 if (!LST_LOOP_P (root
))
1243 return new_lst_stmt (LST_PBB (root
));
1245 seq
= VEC_alloc (lst_p
, heap
, 5);
1247 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (root
), i
, l
); i
++)
1249 VEC_safe_push (lst_p
, heap
, seq
, lst_substitute_3 (l
, lst
, a
, b
, c
));
1252 if (!lst_empty_p (a
))
1253 VEC_safe_push (lst_p
, heap
, seq
, copy_lst (a
));
1254 if (!lst_empty_p (b
))
1255 VEC_safe_push (lst_p
, heap
, seq
, copy_lst (b
));
1256 if (!lst_empty_p (c
))
1257 VEC_safe_push (lst_p
, heap
, seq
, copy_lst (c
));
1260 return new_lst_loop (seq
);
1263 /* Moves LST before LOOP if BEFORE is true, and after the LOOP if
1267 lst_distribute_lst (lst_p loop
, lst_p lst
, bool before
)
1269 int loop_depth
= lst_depth (loop
);
1270 int depth
= lst_depth (lst
);
1271 int nb_loops
= depth
- loop_depth
;
1273 gcc_assert (lst
&& loop
&& LST_LOOP_P (loop
) && nb_loops
> 0);
1275 lst_remove_from_sequence (lst
);
1276 lst_insert_in_sequence (lst_create_nest (nb_loops
, lst
), loop
, before
);
1279 /* Removes from LOOP all the statements before/after and including PBB
1280 if BEFORE is true/false. Returns the negation of BEFORE when the
1281 statement PBB has been found. */
1284 lst_remove_all_before_including_pbb (lst_p loop
, poly_bb_p pbb
, bool before
)
1289 if (!loop
|| !LST_LOOP_P (loop
))
1292 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (loop
), i
, l
);)
1295 before
= lst_remove_all_before_including_pbb (l
, pbb
, before
);
1297 if (VEC_length (lst_p
, LST_SEQ (l
)) == 0)
1299 VEC_ordered_remove (lst_p
, LST_SEQ (loop
), i
);
1309 if (LST_PBB (l
) == pbb
)
1312 VEC_ordered_remove (lst_p
, LST_SEQ (loop
), i
);
1315 else if (LST_PBB (l
) == pbb
)
1318 VEC_ordered_remove (lst_p
, LST_SEQ (loop
), i
);
1328 /* Removes from LOOP all the statements before/after and excluding PBB
1329 if BEFORE is true/false; Returns the negation of BEFORE when the
1330 statement PBB has been found. */
1333 lst_remove_all_before_excluding_pbb (lst_p loop
, poly_bb_p pbb
, bool before
)
1338 if (!loop
|| !LST_LOOP_P (loop
))
1341 for (i
= 0; VEC_iterate (lst_p
, LST_SEQ (loop
), i
, l
);)
1344 before
= lst_remove_all_before_excluding_pbb (l
, pbb
, before
);
1346 if (VEC_length (lst_p
, LST_SEQ (l
)) == 0)
1348 VEC_ordered_remove (lst_p
, LST_SEQ (loop
), i
);
1357 if (before
&& LST_PBB (l
) != pbb
)
1359 VEC_ordered_remove (lst_p
, LST_SEQ (loop
), i
);
1366 if (LST_PBB (l
) == pbb
)
1367 before
= before
? false : true;
1373 /* A SCOP is a Static Control Part of the program, simple enough to be
1374 represented in polyhedral form. */
1377 /* A SCOP is defined as a SESE region. */
1380 /* Number of parameters in SCoP. */
1381 graphite_dim_t nb_params
;
1383 /* All the basic blocks in this scop that contain memory references
1384 and that will be represented as statements in the polyhedral
1386 VEC (poly_bb_p
, heap
) *bbs
;
1388 /* Original, transformed and saved schedules. */
1389 lst_p original_schedule
, transformed_schedule
, saved_schedule
;
1391 /* The context describes known restrictions concerning the parameters
1392 and relations in between the parameters.
1394 void f (int8_t a, uint_16_t b) {
1399 Here we can add these restrictions to the context:
1404 ppl_Pointset_Powerset_C_Polyhedron_t context
;
1406 /* A hashtable of the data dependence relations for the original
1408 htab_t original_pddrs
;
1410 /* True when the scop has been converted to its polyhedral
1415 #define SCOP_BBS(S) (S->bbs)
1416 #define SCOP_REGION(S) ((sese) S->region)
1417 #define SCOP_CONTEXT(S) (S->context)
1418 #define SCOP_ORIGINAL_PDDRS(S) (S->original_pddrs)
1419 #define SCOP_ORIGINAL_SCHEDULE(S) (S->original_schedule)
1420 #define SCOP_TRANSFORMED_SCHEDULE(S) (S->transformed_schedule)
1421 #define SCOP_SAVED_SCHEDULE(S) (S->saved_schedule)
1422 #define POLY_SCOP_P(S) (S->poly_scop_p)
1424 extern scop_p
new_scop (void *);
1425 extern void free_scop (scop_p
);
1426 extern void free_scops (VEC (scop_p
, heap
) *);
1427 extern void print_generated_program (FILE *, scop_p
);
1428 extern void debug_generated_program (scop_p
);
1429 extern void print_scattering_function (FILE *, poly_bb_p
, int);
1430 extern void print_scattering_functions (FILE *, scop_p
, int);
1431 extern void debug_scattering_function (poly_bb_p
, int);
1432 extern void debug_scattering_functions (scop_p
, int);
1433 extern int scop_max_loop_depth (scop_p
);
1434 extern int unify_scattering_dimensions (scop_p
);
1435 extern bool apply_poly_transforms (scop_p
);
1436 extern bool graphite_legal_transform (scop_p
);
1437 extern void cloog_checksum (scop_p
);
1439 /* Set the region of SCOP to REGION. */
1442 scop_set_region (scop_p scop
, void *region
)
1444 scop
->region
= region
;
1447 /* Returns the number of parameters for SCOP. */
1449 static inline graphite_dim_t
1450 scop_nb_params (scop_p scop
)
1452 return scop
->nb_params
;
1455 /* Set the number of params of SCOP to NB_PARAMS. */
1458 scop_set_nb_params (scop_p scop
, graphite_dim_t nb_params
)
1460 scop
->nb_params
= nb_params
;
1463 /* Allocates a new empty poly_scattering structure. */
1465 static inline poly_scattering_p
1466 poly_scattering_new (void)
1468 poly_scattering_p res
= XNEW (struct poly_scattering
);
1470 res
->scattering
= NULL
;
1471 res
->nb_local_variables
= 0;
1472 res
->nb_scattering
= 0;
1476 /* Free a poly_scattering structure. */
1479 poly_scattering_free (poly_scattering_p s
)
1481 ppl_delete_Polyhedron (s
->scattering
);
1485 /* Copies S and return a new scattering. */
1487 static inline poly_scattering_p
1488 poly_scattering_copy (poly_scattering_p s
)
1490 poly_scattering_p res
= poly_scattering_new ();
1492 ppl_new_C_Polyhedron_from_C_Polyhedron (&(res
->scattering
), s
->scattering
);
1493 res
->nb_local_variables
= s
->nb_local_variables
;
1494 res
->nb_scattering
= s
->nb_scattering
;
1498 /* Saves the transformed scattering of PBB. */
1501 store_scattering_pbb (poly_bb_p pbb
)
1503 gcc_assert (PBB_TRANSFORMED (pbb
));
1505 if (PBB_SAVED (pbb
))
1506 poly_scattering_free (PBB_SAVED (pbb
));
1508 PBB_SAVED (pbb
) = poly_scattering_copy (PBB_TRANSFORMED (pbb
));
1511 /* Stores the SCOP_TRANSFORMED_SCHEDULE to SCOP_SAVED_SCHEDULE. */
1514 store_lst_schedule (scop_p scop
)
1516 if (SCOP_SAVED_SCHEDULE (scop
))
1517 free_lst (SCOP_SAVED_SCHEDULE (scop
));
1519 SCOP_SAVED_SCHEDULE (scop
) = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop
));
1522 /* Restores the SCOP_TRANSFORMED_SCHEDULE from SCOP_SAVED_SCHEDULE. */
1525 restore_lst_schedule (scop_p scop
)
1527 if (SCOP_TRANSFORMED_SCHEDULE (scop
))
1528 free_lst (SCOP_TRANSFORMED_SCHEDULE (scop
));
1530 SCOP_TRANSFORMED_SCHEDULE (scop
) = copy_lst (SCOP_SAVED_SCHEDULE (scop
));
1533 /* Saves the scattering for all the pbbs in the SCOP. */
1536 store_scattering (scop_p scop
)
1541 for (i
= 0; VEC_iterate (poly_bb_p
, SCOP_BBS (scop
), i
, pbb
); i
++)
1542 store_scattering_pbb (pbb
);
1544 store_lst_schedule (scop
);
1547 /* Restores the scattering of PBB. */
1550 restore_scattering_pbb (poly_bb_p pbb
)
1552 gcc_assert (PBB_SAVED (pbb
));
1554 poly_scattering_free (PBB_TRANSFORMED (pbb
));
1555 PBB_TRANSFORMED (pbb
) = poly_scattering_copy (PBB_SAVED (pbb
));
1558 /* Restores the scattering for all the pbbs in the SCOP. */
1561 restore_scattering (scop_p scop
)
1566 for (i
= 0; VEC_iterate (poly_bb_p
, SCOP_BBS (scop
), i
, pbb
); i
++)
1567 restore_scattering_pbb (pbb
);
1569 restore_lst_schedule (scop
);
1572 /* For a given PBB, add to RES the scop context, the iteration domain,
1573 the original scattering when ORIGINAL_P is true, otherwise add the
1574 transformed scattering. */
1577 combine_context_id_scat (ppl_Pointset_Powerset_C_Polyhedron_t
*res
,
1578 poly_bb_p pbb
, bool original_p
)
1580 ppl_Pointset_Powerset_C_Polyhedron_t context
;
1581 ppl_Pointset_Powerset_C_Polyhedron_t id
;
1583 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1585 PBB_ORIGINAL_SCATTERING (pbb
) : PBB_TRANSFORMED_SCATTERING (pbb
));
1587 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1588 (&context
, SCOP_CONTEXT (PBB_SCOP (pbb
)));
1590 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1591 (&id
, PBB_DOMAIN (pbb
));
1593 /* Extend the context and the iteration domain to the dimension of
1594 the scattering: T|I|G. */
1596 ppl_dimension_type gdim
, tdim
, idim
;
1598 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (*res
, &tdim
);
1599 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (context
, &gdim
);
1600 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (id
, &idim
);
1603 ppl_insert_dimensions_pointset (context
, 0, tdim
- gdim
);
1606 ppl_insert_dimensions_pointset (id
, 0, tdim
- idim
);
1609 /* Add the context and the iteration domain to the result. */
1610 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (*res
, context
);
1611 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (*res
, id
);
1613 ppl_delete_Pointset_Powerset_C_Polyhedron (context
);
1614 ppl_delete_Pointset_Powerset_C_Polyhedron (id
);