[ARM/AArch64][testsuite] Add vmull tests.
[gcc.git] / gcc / graphite-poly.h
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>.
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 #ifndef GCC_GRAPHITE_POLY_H
23 #define GCC_GRAPHITE_POLY_H
24
25 typedef struct poly_dr *poly_dr_p;
26
27 typedef struct poly_bb *poly_bb_p;
28
29 typedef struct scop *scop_p;
30
31 typedef unsigned graphite_dim_t;
32
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);
36
37 /* A data reference can write or read some memory or we
38 just know it may write some memory. */
39 enum poly_dr_type
40 {
41 PDR_READ,
42 /* PDR_MAY_READs are represented using PDR_READS. This does not
43 limit the expressiveness. */
44 PDR_WRITE,
45 PDR_MAY_WRITE
46 };
47
48 struct poly_dr
49 {
50 /* An identifier for this PDR. */
51 int id;
52
53 /* The number of data refs identical to this one in the PBB. */
54 int nb_refs;
55
56 /* A pointer to compiler's data reference description. */
57 void *compiler_dr;
58
59 /* A pointer to the PBB that contains this data reference. */
60 poly_bb_p pbb;
61
62 enum poly_dr_type type;
63
64 /* The access polyhedron contains the polyhedral space this data
65 reference will access.
66
67 The polyhedron contains these dimensions:
68
69 - The alias set (a):
70 Every memory access is classified in at least one alias set.
71
72 - The subscripts (s_0, ..., s_n):
73 The memory is accessed using zero or more subscript dimensions.
74
75 - The iteration domain (variables and parameters)
76
77 Do not hardcode the dimensions. Use the following accessor functions:
78 - pdr_alias_set_dim
79 - pdr_subscript_dim
80 - pdr_iterator_dim
81 - pdr_parameter_dim
82
83 Example:
84
85 | int A[1335][123];
86 | int *p = malloc ();
87 |
88 | k = ...
89 | for i
90 | {
91 | if (unknown_function ())
92 | p = A;
93 | ... = p[?][?];
94 | for j
95 | A[i][j+k] = m;
96 | }
97
98 The data access A[i][j+k] in alias set "5" is described like this:
99
100 | i j k a s0 s1 1
101 | 0 0 0 1 0 0 -5 = 0
102 |-1 0 0 0 1 0 0 = 0
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
108
109 The pointer "*p" in alias set "5" and "7" is described as a union of
110 polyhedron:
111
112
113 | i k a s0 1
114 | 0 0 1 0 -5 = 0
115 | 0 0 0 1 0 >= 0
116
117 "or"
118
119 | i k a s0 1
120 | 0 0 1 0 -7 = 0
121 | 0 0 0 1 0 >= 0
122
123 "*p" accesses all of the object allocated with 'malloc'.
124
125 The scalar data access "m" is represented as an array with zero subscript
126 dimensions.
127
128 | i j k a 1
129 | 0 0 0 -1 15 = 0
130
131 The difference between the graphite internal format for access data and
132 the OpenSop format is in the order of columns.
133 Instead of having:
134
135 | i j k a s0 s1 1
136 | 0 0 0 1 0 0 -5 = 0
137 |-1 0 0 0 1 0 0 = 0
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
143
144 In OpenScop we have:
145
146 | a s0 s1 i j k 1
147 | 1 0 0 0 0 0 -5 = 0
148 | 0 1 0 -1 0 0 0 = 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
154
155 The OpenScop access function is printed as follows:
156
157 | 1 # The number of disjunct components in a union of access functions.
158 | R C O I L P # Described bellow.
159 | a s0 s1 i j k 1
160 | 1 0 0 0 0 0 -5 = 0
161 | 0 1 0 -1 0 0 0 = 0
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
167
168 Where:
169 - R: Number of rows.
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.
175
176 In the example, the vector "R C O I L P" is "7 7 3 2 0 1". */
177 isl_map *accesses;
178 isl_set *extent;
179
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;
183
184 /* The number of subscripts. */
185 graphite_dim_t nb_subscripts;
186 };
187
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)
196
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);
203
204 /* The dimension of the iteration domain of the scop of PDR. */
205
206 static inline graphite_dim_t
207 pdr_dim_iter_domain (poly_dr_p pdr)
208 {
209 return pbb_dim_iter_domain (PDR_PBB (pdr));
210 }
211
212 /* The number of parameters of the scop of PDR. */
213
214 static inline graphite_dim_t
215 pdr_nb_params (poly_dr_p pdr)
216 {
217 return scop_nb_params (pdr_scop (pdr));
218 }
219
220 /* The dimension of the alias set in PDR. */
221
222 static inline graphite_dim_t
223 pdr_alias_set_dim (poly_dr_p pdr)
224 {
225 poly_bb_p pbb = PDR_PBB (pdr);
226
227 return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
228 }
229
230 /* The dimension in PDR containing subscript S. */
231
232 static inline graphite_dim_t
233 pdr_subscript_dim (poly_dr_p pdr, graphite_dim_t s)
234 {
235 poly_bb_p pbb = PDR_PBB (pdr);
236
237 return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb) + 1 + s;
238 }
239
240 /* The dimension in PDR containing the loop iterator ITER. */
241
242 static inline graphite_dim_t
243 pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED, graphite_dim_t iter)
244 {
245 return iter;
246 }
247
248 /* The dimension in PDR containing parameter PARAM. */
249
250 static inline graphite_dim_t
251 pdr_parameter_dim (poly_dr_p pdr, graphite_dim_t param)
252 {
253 poly_bb_p pbb = PDR_PBB (pdr);
254
255 return pbb_dim_iter_domain (pbb) + param;
256 }
257
258 /* Returns true when PDR is a "read". */
259
260 static inline bool
261 pdr_read_p (poly_dr_p pdr)
262 {
263 return PDR_TYPE (pdr) == PDR_READ;
264 }
265
266 /* Returns true when PDR is a "write". */
267
268 static inline bool
269 pdr_write_p (poly_dr_p pdr)
270 {
271 return PDR_TYPE (pdr) == PDR_WRITE;
272 }
273
274 /* Returns true when PDR is a "may write". */
275
276 static inline bool
277 pdr_may_write_p (poly_dr_p pdr)
278 {
279 return PDR_TYPE (pdr) == PDR_MAY_WRITE;
280 }
281
282 /* Return true when PDR1 and PDR2 are similar data accesses: they have
283 the same base array, and the same access functions. */
284
285 static inline bool
286 same_pdr_p (poly_dr_p pdr1, poly_dr_p pdr2)
287 {
288 return PDR_NB_SUBSCRIPTS (pdr1) == PDR_NB_SUBSCRIPTS (pdr2)
289 && PDR_BASE_OBJECT_SET (pdr1) == PDR_BASE_OBJECT_SET (pdr2);
290 }
291
292 typedef struct poly_scattering *poly_scattering_p;
293
294 struct poly_scattering
295 {
296 /* The number of local variables. */
297 int nb_local_variables;
298
299 /* The number of scattering dimensions. */
300 int nb_scattering;
301 };
302
303 /* POLY_BB represents a blackbox in the polyhedral model. */
304
305 struct poly_bb
306 {
307 /* Pointer to a basic block or a statement in the compiler. */
308 void *black_box;
309
310 /* Pointer to the SCOP containing this PBB. */
311 scop_p scop;
312
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.
315
316 Example:
317
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++)
321 S (i,j,k)
322
323 Loop iterators: i, j, k
324 Parameters: a, b
325
326 | i >= a - 7b + 8
327 | i <= 3a + 13b + 20
328 | j >= 2
329 | j <= 2i + 5
330 | k >= 0
331 | k <= 5
332
333 The number of variables in the DOMAIN may change and is not
334 related to the number of loops in the original code. */
335 isl_set *domain;
336
337 /* The data references we access. */
338 vec<poly_dr_p> drs;
339
340 /* The original scattering. */
341 poly_scattering_p _original;
342 isl_map *schedule;
343
344 /* The transformed scattering. */
345 poly_scattering_p _transformed;
346 isl_map *transformed;
347
348 /* A copy of the transformed scattering. */
349 poly_scattering_p _saved;
350 isl_map *saved;
351
352 /* For tiling, the map for computing the separating class. */
353 isl_map *map_sepclass;
354
355 /* True when this PBB contains only a reduction statement. */
356 bool is_reduction;
357 };
358
359 #define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box)
360 #define PBB_SCOP(PBB) (PBB->scop)
361 #define PBB_DOMAIN(PBB) (NULL)
362 #define PBB_DRS(PBB) (PBB->drs)
363 #define PBB_ORIGINAL(PBB) (PBB->_original)
364 #define PBB_ORIGINAL_SCATTERING(PBB) (NULL)
365 #define PBB_TRANSFORMED(PBB) (PBB->_transformed)
366 #define PBB_TRANSFORMED_SCATTERING(PBB) (NULL)
367 #define PBB_SAVED(PBB) (PBB->_saved)
368 /* XXX isl if we ever need local vars in the scatter, we can't use the
369 out dimension of transformed to count the scatterting transform dimension.
370 */
371 #define PBB_NB_LOCAL_VARIABLES(PBB) (0)
372 #define PBB_NB_SCATTERING_TRANSFORM(PBB) (isl_map_n_out (PBB->transformed))
373 #define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
374
375 extern poly_bb_p new_poly_bb (scop_p, void *);
376 extern void free_poly_bb (poly_bb_p);
377 extern void debug_loop_vec (poly_bb_p);
378 extern void schedule_to_scattering (poly_bb_p, int);
379 extern void print_pbb_domain (FILE *, poly_bb_p, int);
380 extern void print_pbb (FILE *, poly_bb_p, int);
381 extern void print_scop_context (FILE *, scop_p, int);
382 extern void print_scop (FILE *, scop_p, int);
383 extern void debug_pbb_domain (poly_bb_p, int);
384 extern void debug_pbb (poly_bb_p, int);
385 extern void print_pdrs (FILE *, poly_bb_p, int);
386 extern void debug_pdrs (poly_bb_p, int);
387 extern void debug_scop_context (scop_p, int);
388 extern void debug_scop (scop_p, int);
389 extern void print_scop_params (FILE *, scop_p, int);
390 extern void debug_scop_params (scop_p, int);
391 extern void print_iteration_domain (FILE *, poly_bb_p, int);
392 extern void print_iteration_domains (FILE *, scop_p, int);
393 extern void debug_iteration_domain (poly_bb_p, int);
394 extern void debug_iteration_domains (scop_p, int);
395 extern void print_isl_set (FILE *, isl_set *);
396 extern void print_isl_map (FILE *, isl_map *);
397 extern void print_isl_aff (FILE *, isl_aff *);
398 extern void print_isl_constraint (FILE *, isl_constraint *);
399 extern void debug_isl_set (isl_set *);
400 extern void debug_isl_map (isl_map *);
401 extern void debug_isl_aff (isl_aff *);
402 extern void debug_isl_constraint (isl_constraint *);
403 extern int scop_do_interchange (scop_p);
404 extern int scop_do_strip_mine (scop_p, int);
405 extern bool scop_do_block (scop_p);
406 extern bool flatten_all_loops (scop_p);
407 extern bool optimize_isl (scop_p);
408 extern void pbb_number_of_iterations_at_time (poly_bb_p, graphite_dim_t, mpz_t);
409 extern void debug_gmp_value (mpz_t);
410
411 /* Return the number of write data references in PBB. */
412
413 static inline int
414 number_of_write_pdrs (poly_bb_p pbb)
415 {
416 int res = 0;
417 int i;
418 poly_dr_p pdr;
419
420 for (i = 0; PBB_DRS (pbb).iterate (i, &pdr); i++)
421 if (PDR_TYPE (pdr) == PDR_WRITE)
422 res++;
423
424 return res;
425 }
426
427 /* Returns a gimple_bb from BB. */
428
429 static inline gimple_bb_p
430 gbb_from_bb (basic_block bb)
431 {
432 return (gimple_bb_p) bb->aux;
433 }
434
435 /* The poly_bb of the BB. */
436
437 static inline poly_bb_p
438 pbb_from_bb (basic_block bb)
439 {
440 return GBB_PBB (gbb_from_bb (bb));
441 }
442
443 /* The basic block of the PBB. */
444
445 static inline basic_block
446 pbb_bb (poly_bb_p pbb)
447 {
448 return GBB_BB (PBB_BLACK_BOX (pbb));
449 }
450
451 /* The index of the PBB. */
452
453 static inline int
454 pbb_index (poly_bb_p pbb)
455 {
456 return pbb_bb (pbb)->index;
457 }
458
459 /* The loop of the PBB. */
460
461 static inline loop_p
462 pbb_loop (poly_bb_p pbb)
463 {
464 return gbb_loop (PBB_BLACK_BOX (pbb));
465 }
466
467 /* The scop that contains the PDR. */
468
469 static inline scop_p
470 pdr_scop (poly_dr_p pdr)
471 {
472 return PBB_SCOP (PDR_PBB (pdr));
473 }
474
475 /* Set black box of PBB to BLACKBOX. */
476
477 static inline void
478 pbb_set_black_box (poly_bb_p pbb, void *black_box)
479 {
480 pbb->black_box = black_box;
481 }
482
483 /* The number of loops around PBB: the dimension of the iteration
484 domain. */
485
486 static inline graphite_dim_t
487 pbb_dim_iter_domain (const struct poly_bb *pbb)
488 {
489 return isl_set_dim (pbb->domain, isl_dim_set);
490 }
491
492 /* The number of params defined in PBB. */
493
494 static inline graphite_dim_t
495 pbb_nb_params (const struct poly_bb *pbb)
496 {
497 scop_p scop = PBB_SCOP (pbb);
498
499 return scop_nb_params (scop);
500 }
501
502 /* The number of scattering dimensions in the SCATTERING polyhedron
503 of a PBB for a given SCOP. */
504
505 static inline graphite_dim_t
506 pbb_nb_scattering_orig (const struct poly_bb *pbb)
507 {
508 return 2 * pbb_dim_iter_domain (pbb) + 1;
509 }
510
511 /* The number of scattering dimensions in PBB. */
512
513 static inline graphite_dim_t
514 pbb_nb_scattering_transform (const struct poly_bb *pbb)
515 {
516 return PBB_NB_SCATTERING_TRANSFORM (pbb);
517 }
518
519 /* The number of dynamic scattering dimensions in PBB. */
520
521 static inline graphite_dim_t
522 pbb_nb_dynamic_scattering_transform (const struct poly_bb *pbb)
523 {
524 /* This function requires the 2d + 1 scattering format to be
525 invariant during all transformations. */
526 gcc_assert (PBB_NB_SCATTERING_TRANSFORM (pbb) % 2);
527 return PBB_NB_SCATTERING_TRANSFORM (pbb) / 2;
528 }
529
530 /* Returns the number of local variables used in the transformed
531 scattering polyhedron of PBB. */
532
533 static inline graphite_dim_t
534 pbb_nb_local_vars (const struct poly_bb *pbb ATTRIBUTE_UNUSED)
535 {
536 /* For now we do not have any local variables, as we do not do strip
537 mining for example. */
538 return PBB_NB_LOCAL_VARIABLES (pbb);
539 }
540
541 /* The dimension in the domain of PBB containing the iterator ITER. */
542
543 static inline graphite_dim_t
544 pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t iter)
545 {
546 return iter;
547 }
548
549 /* The dimension in the domain of PBB containing the iterator ITER. */
550
551 static inline graphite_dim_t
552 pbb_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
553 {
554 return param
555 + pbb_dim_iter_domain (pbb);
556 }
557
558 /* The dimension in the original scattering polyhedron of PBB
559 containing the scattering iterator SCATTER. */
560
561 static inline graphite_dim_t
562 psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
563 {
564 gcc_assert (scatter < pbb_nb_scattering_orig (pbb));
565 return scatter;
566 }
567
568 /* The dimension in the transformed scattering polyhedron of PBB
569 containing the scattering iterator SCATTER. */
570
571 static inline graphite_dim_t
572 psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
573 {
574 gcc_assert (scatter <= pbb_nb_scattering_transform (pbb));
575 return scatter;
576 }
577
578 /* The dimension in the transformed scattering polyhedron of PBB of
579 the local variable LV. */
580
581 static inline graphite_dim_t
582 psct_local_var_dim (poly_bb_p pbb, graphite_dim_t lv)
583 {
584 gcc_assert (lv <= pbb_nb_local_vars (pbb));
585 return lv + pbb_nb_scattering_transform (pbb);
586 }
587
588 /* The dimension in the original scattering polyhedron of PBB
589 containing the loop iterator ITER. */
590
591 static inline graphite_dim_t
592 psco_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
593 {
594 gcc_assert (iter < pbb_dim_iter_domain (pbb));
595 return iter + pbb_nb_scattering_orig (pbb);
596 }
597
598 /* The dimension in the transformed scattering polyhedron of PBB
599 containing the loop iterator ITER. */
600
601 static inline graphite_dim_t
602 psct_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
603 {
604 gcc_assert (iter < pbb_dim_iter_domain (pbb));
605 return iter
606 + pbb_nb_scattering_transform (pbb)
607 + pbb_nb_local_vars (pbb);
608 }
609
610 /* The dimension in the original scattering polyhedron of PBB
611 containing parameter PARAM. */
612
613 static inline graphite_dim_t
614 psco_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
615 {
616 gcc_assert (param < pbb_nb_params (pbb));
617 return param
618 + pbb_nb_scattering_orig (pbb)
619 + pbb_dim_iter_domain (pbb);
620 }
621
622 /* The dimension in the transformed scattering polyhedron of PBB
623 containing parameter PARAM. */
624
625 static inline graphite_dim_t
626 psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
627 {
628 gcc_assert (param < pbb_nb_params (pbb));
629 return param
630 + pbb_nb_scattering_transform (pbb)
631 + pbb_nb_local_vars (pbb)
632 + pbb_dim_iter_domain (pbb);
633 }
634
635 /* The scattering dimension of PBB corresponding to the dynamic level
636 LEVEL. */
637
638 static inline graphite_dim_t
639 psct_dynamic_dim (poly_bb_p pbb, graphite_dim_t level)
640 {
641 graphite_dim_t result = 1 + 2 * level;
642
643 gcc_assert (result < pbb_nb_scattering_transform (pbb));
644 return result;
645 }
646
647 /* The scattering dimension of PBB corresponding to the static
648 sequence of the loop level LEVEL. */
649
650 static inline graphite_dim_t
651 psct_static_dim (poly_bb_p pbb, graphite_dim_t level)
652 {
653 graphite_dim_t result = 2 * level;
654
655 gcc_assert (result < pbb_nb_scattering_transform (pbb));
656 return result;
657 }
658
659 /* Adds to the transformed scattering polyhedron of PBB a new local
660 variable and returns its index. */
661
662 static inline graphite_dim_t
663 psct_add_local_variable (poly_bb_p pbb ATTRIBUTE_UNUSED)
664 {
665 gcc_unreachable ();
666 return 0;
667 }
668
669 typedef struct lst *lst_p;
670
671 /* Loops and Statements Tree. */
672 struct lst {
673
674 /* LOOP_P is true when an LST node is a loop. */
675 bool loop_p;
676
677 /* A pointer to the loop that contains this node. */
678 lst_p loop_father;
679
680 /* The sum of all the memory strides for an LST loop. */
681 mpz_t memory_strides;
682
683 /* Loop nodes contain a sequence SEQ of LST nodes, statements
684 contain a pointer to their polyhedral representation PBB. */
685 union {
686 poly_bb_p pbb;
687 vec<lst_p> seq;
688 } node;
689 };
690
691 #define LST_LOOP_P(LST) ((LST)->loop_p)
692 #define LST_LOOP_FATHER(LST) ((LST)->loop_father)
693 #define LST_PBB(LST) ((LST)->node.pbb)
694 #define LST_SEQ(LST) ((LST)->node.seq)
695 #define LST_LOOP_MEMORY_STRIDES(LST) ((LST)->memory_strides)
696
697 void scop_to_lst (scop_p);
698 void print_lst (FILE *, lst_p, int);
699 void debug_lst (lst_p);
700 void dot_lst (lst_p);
701
702 /* Creates a new LST loop with SEQ. */
703
704 static inline lst_p
705 new_lst_loop (vec<lst_p> seq)
706 {
707 lst_p lst = XNEW (struct lst);
708 int i;
709 lst_p l;
710
711 LST_LOOP_P (lst) = true;
712 LST_SEQ (lst) = seq;
713 LST_LOOP_FATHER (lst) = NULL;
714 mpz_init (LST_LOOP_MEMORY_STRIDES (lst));
715 mpz_set_si (LST_LOOP_MEMORY_STRIDES (lst), -1);
716
717 for (i = 0; seq.iterate (i, &l); i++)
718 LST_LOOP_FATHER (l) = lst;
719
720 return lst;
721 }
722
723 /* Creates a new LST statement with PBB. */
724
725 static inline lst_p
726 new_lst_stmt (poly_bb_p pbb)
727 {
728 lst_p lst = XNEW (struct lst);
729
730 LST_LOOP_P (lst) = false;
731 LST_PBB (lst) = pbb;
732 LST_LOOP_FATHER (lst) = NULL;
733 return lst;
734 }
735
736 /* Frees the memory used by LST. */
737
738 static inline void
739 free_lst (lst_p lst)
740 {
741 if (!lst)
742 return;
743
744 if (LST_LOOP_P (lst))
745 {
746 int i;
747 lst_p l;
748
749 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
750 free_lst (l);
751
752 mpz_clear (LST_LOOP_MEMORY_STRIDES (lst));
753 LST_SEQ (lst).release ();
754 }
755
756 free (lst);
757 }
758
759 /* Returns a copy of LST. */
760
761 static inline lst_p
762 copy_lst (lst_p lst)
763 {
764 if (!lst)
765 return NULL;
766
767 if (LST_LOOP_P (lst))
768 {
769 int i;
770 lst_p l;
771 vec<lst_p> seq;
772 seq.create (5);
773
774 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
775 seq.safe_push (copy_lst (l));
776
777 return new_lst_loop (seq);
778 }
779
780 return new_lst_stmt (LST_PBB (lst));
781 }
782
783 /* Adds a new loop under the loop LST. */
784
785 static inline void
786 lst_add_loop_under_loop (lst_p lst)
787 {
788 vec<lst_p> seq;
789 seq.create (1);
790 lst_p l = new_lst_loop (LST_SEQ (lst));
791
792 gcc_assert (LST_LOOP_P (lst));
793
794 LST_LOOP_FATHER (l) = lst;
795 seq.quick_push (l);
796 LST_SEQ (lst) = seq;
797 }
798
799 /* Returns the loop depth of LST. */
800
801 static inline int
802 lst_depth (lst_p lst)
803 {
804 if (!lst)
805 return -2;
806
807 /* The depth of the outermost "fake" loop is -1. This outermost
808 loop does not have a loop father and it is just a container, as
809 in the loop representation of GCC. */
810 if (!LST_LOOP_FATHER (lst))
811 return -1;
812
813 return lst_depth (LST_LOOP_FATHER (lst)) + 1;
814 }
815
816 /* Returns the Dewey number for LST. */
817
818 static inline int
819 lst_dewey_number (lst_p lst)
820 {
821 int i;
822 lst_p l;
823
824 if (!lst)
825 return -1;
826
827 if (!LST_LOOP_FATHER (lst))
828 return 0;
829
830 FOR_EACH_VEC_ELT (LST_SEQ (LST_LOOP_FATHER (lst)), i, l)
831 if (l == lst)
832 return i;
833
834 return -1;
835 }
836
837 /* Returns the Dewey number of LST at depth DEPTH. */
838
839 static inline int
840 lst_dewey_number_at_depth (lst_p lst, int depth)
841 {
842 gcc_assert (lst && depth >= 0 && lst_depth (lst) <= depth);
843
844 if (lst_depth (lst) == depth)
845 return lst_dewey_number (lst);
846
847 return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst), depth);
848 }
849
850 /* Returns the predecessor of LST in the sequence of its loop father.
851 Returns NULL if LST is the first statement in the sequence. */
852
853 static inline lst_p
854 lst_pred (lst_p lst)
855 {
856 int dewey;
857 lst_p father;
858
859 if (!lst || !LST_LOOP_FATHER (lst))
860 return NULL;
861
862 dewey = lst_dewey_number (lst);
863 if (dewey == 0)
864 return NULL;
865
866 father = LST_LOOP_FATHER (lst);
867 return LST_SEQ (father)[dewey - 1];
868 }
869
870 /* Returns the successor of LST in the sequence of its loop father.
871 Returns NULL if there is none. */
872
873 static inline lst_p
874 lst_succ (lst_p lst)
875 {
876 int dewey;
877 lst_p father;
878
879 if (!lst || !LST_LOOP_FATHER (lst))
880 return NULL;
881
882 dewey = lst_dewey_number (lst);
883 father = LST_LOOP_FATHER (lst);
884
885 if (LST_SEQ (father).length () == (unsigned) dewey + 1)
886 return NULL;
887
888 return LST_SEQ (father)[dewey + 1];
889 }
890
891
892 /* Return the LST node corresponding to PBB. */
893
894 static inline lst_p
895 lst_find_pbb (lst_p lst, poly_bb_p pbb)
896 {
897 int i;
898 lst_p l;
899
900 if (!lst)
901 return NULL;
902
903 if (!LST_LOOP_P (lst))
904 return (pbb == LST_PBB (lst)) ? lst : NULL;
905
906 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
907 {
908 lst_p res = lst_find_pbb (l, pbb);
909 if (res)
910 return res;
911 }
912
913 return NULL;
914 }
915
916 /* Return the LST node corresponding to the loop around STMT at depth
917 LOOP_DEPTH. */
918
919 static inline lst_p
920 find_lst_loop (lst_p stmt, int loop_depth)
921 {
922 lst_p loop = LST_LOOP_FATHER (stmt);
923
924 gcc_assert (loop_depth >= 0);
925
926 while (loop_depth < lst_depth (loop))
927 loop = LST_LOOP_FATHER (loop);
928
929 return loop;
930 }
931
932 /* Return the first LST representing a PBB statement in LST. */
933
934 static inline lst_p
935 lst_find_first_pbb (lst_p lst)
936 {
937 int i;
938 lst_p l;
939
940 if (!lst)
941 return NULL;
942
943 if (!LST_LOOP_P (lst))
944 return lst;
945
946 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
947 {
948 lst_p res = lst_find_first_pbb (l);
949 if (res)
950 return res;
951 }
952
953 return NULL;
954 }
955
956 /* Returns true when LST is a loop that does not contain
957 statements. */
958
959 static inline bool
960 lst_empty_p (lst_p lst)
961 {
962 return !lst_find_first_pbb (lst);
963 }
964
965 /* Return the last LST representing a PBB statement in LST. */
966
967 static inline lst_p
968 lst_find_last_pbb (lst_p lst)
969 {
970 int i;
971 lst_p l, res = NULL;
972
973 if (!lst)
974 return NULL;
975
976 if (!LST_LOOP_P (lst))
977 return lst;
978
979 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
980 {
981 lst_p last = lst_find_last_pbb (l);
982
983 if (last)
984 res = last;
985 }
986
987 gcc_assert (res);
988 return res;
989 }
990
991 /* Returns true if LOOP contains LST, in other words, if LST is nested
992 in LOOP. */
993
994 static inline bool
995 lst_contains_p (lst_p loop, lst_p lst)
996 {
997 if (!loop || !lst || !LST_LOOP_P (loop))
998 return false;
999
1000 if (loop == lst)
1001 return true;
1002
1003 return lst_contains_p (loop, LST_LOOP_FATHER (lst));
1004 }
1005
1006 /* Returns true if LOOP contains PBB, in other words, if PBB is nested
1007 in LOOP. */
1008
1009 static inline bool
1010 lst_contains_pbb (lst_p loop, poly_bb_p pbb)
1011 {
1012 return lst_find_pbb (loop, pbb) ? true : false;
1013 }
1014
1015 /* Creates a loop nest of depth NB_LOOPS containing LST. */
1016
1017 static inline lst_p
1018 lst_create_nest (int nb_loops, lst_p lst)
1019 {
1020 lst_p res, loop;
1021 vec<lst_p> seq;
1022
1023 if (nb_loops == 0)
1024 return lst;
1025
1026 seq.create (1);
1027 loop = lst_create_nest (nb_loops - 1, lst);
1028 seq.quick_push (loop);
1029 res = new_lst_loop (seq);
1030 LST_LOOP_FATHER (loop) = res;
1031
1032 return res;
1033 }
1034
1035 /* Removes LST from the sequence of statements of its loop father. */
1036
1037 static inline void
1038 lst_remove_from_sequence (lst_p lst)
1039 {
1040 lst_p father = LST_LOOP_FATHER (lst);
1041 int dewey = lst_dewey_number (lst);
1042
1043 gcc_assert (lst && father && dewey >= 0);
1044
1045 LST_SEQ (father).ordered_remove (dewey);
1046 LST_LOOP_FATHER (lst) = NULL;
1047 }
1048
1049 /* Removes the loop LST and inline its body in the father loop. */
1050
1051 static inline void
1052 lst_remove_loop_and_inline_stmts_in_loop_father (lst_p lst)
1053 {
1054 lst_p l, father = LST_LOOP_FATHER (lst);
1055 int i, dewey = lst_dewey_number (lst);
1056
1057 gcc_assert (lst && father && dewey >= 0);
1058
1059 LST_SEQ (father).ordered_remove (dewey);
1060 LST_LOOP_FATHER (lst) = NULL;
1061
1062 FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
1063 {
1064 LST_SEQ (father).safe_insert (dewey + i, l);
1065 LST_LOOP_FATHER (l) = father;
1066 }
1067 }
1068
1069 /* Sets NITER to the upper bound approximation of the number of
1070 iterations of loop LST. */
1071
1072 static inline void
1073 lst_niter_for_loop (lst_p lst, mpz_t niter)
1074 {
1075 int depth = lst_depth (lst);
1076 poly_bb_p pbb = LST_PBB (lst_find_first_pbb (lst));
1077
1078 gcc_assert (LST_LOOP_P (lst));
1079 pbb_number_of_iterations_at_time (pbb, psct_dynamic_dim (pbb, depth), niter);
1080 }
1081
1082 /* Updates the scattering of PBB to be at the DEWEY number in the loop
1083 at depth LEVEL. */
1084
1085 static inline void
1086 pbb_update_scattering (poly_bb_p pbb, graphite_dim_t level, int dewey)
1087 {
1088 graphite_dim_t sched = psct_static_dim (pbb, level);
1089 isl_space *d = isl_map_get_space (pbb->transformed);
1090 isl_space *d1 = isl_space_range (d);
1091 unsigned i, n = isl_space_dim (d1, isl_dim_out);
1092 isl_space *d2 = isl_space_add_dims (d1, isl_dim_in, n);
1093 isl_map *x = isl_map_universe (d2);
1094
1095 x = isl_map_fix_si (x, isl_dim_out, sched, dewey);
1096
1097 for (i = 0; i < n; i++)
1098 if (i != sched)
1099 x = isl_map_equate (x, isl_dim_in, i, isl_dim_out, i);
1100
1101 pbb->transformed = isl_map_apply_range (pbb->transformed, x);
1102 }
1103
1104 /* Updates the scattering of all the PBBs under LST to be at the DEWEY
1105 number in the loop at depth LEVEL. */
1106
1107 static inline void
1108 lst_update_scattering_under (lst_p lst, int level, int dewey)
1109 {
1110 int i;
1111 lst_p l;
1112
1113 gcc_assert (lst && level >= 0 && dewey >= 0);
1114
1115 if (LST_LOOP_P (lst))
1116 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
1117 lst_update_scattering_under (l, level, dewey);
1118 else
1119 pbb_update_scattering (LST_PBB (lst), level, dewey);
1120 }
1121
1122 /* Updates the all the scattering levels of all the PBBs under
1123 LST. */
1124
1125 static inline void
1126 lst_update_scattering (lst_p lst)
1127 {
1128 int i;
1129 lst_p l;
1130
1131 if (!lst)
1132 return;
1133
1134 if (LST_LOOP_FATHER (lst))
1135 {
1136 lst_p father = LST_LOOP_FATHER (lst);
1137 int dewey = lst_dewey_number (lst);
1138 int level = lst_depth (lst);
1139
1140 gcc_assert (lst && father && dewey >= 0 && level >= 0);
1141
1142 for (i = dewey; LST_SEQ (father).iterate (i, &l); i++)
1143 lst_update_scattering_under (l, level, i);
1144 }
1145
1146 if (LST_LOOP_P (lst))
1147 for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
1148 lst_update_scattering (l);
1149 }
1150
1151 /* Inserts LST1 before LST2 if BEFORE is true; inserts LST1 after LST2
1152 if BEFORE is false. */
1153
1154 static inline void
1155 lst_insert_in_sequence (lst_p lst1, lst_p lst2, bool before)
1156 {
1157 lst_p father;
1158 int dewey;
1159
1160 /* Do not insert empty loops. */
1161 if (!lst1 || lst_empty_p (lst1))
1162 return;
1163
1164 father = LST_LOOP_FATHER (lst2);
1165 dewey = lst_dewey_number (lst2);
1166
1167 gcc_assert (lst2 && father && dewey >= 0);
1168
1169 LST_SEQ (father).safe_insert (before ? dewey : dewey + 1, lst1);
1170 LST_LOOP_FATHER (lst1) = father;
1171 }
1172
1173 /* Replaces LST1 with LST2. */
1174
1175 static inline void
1176 lst_replace (lst_p lst1, lst_p lst2)
1177 {
1178 lst_p father;
1179 int dewey;
1180
1181 if (!lst2 || lst_empty_p (lst2))
1182 return;
1183
1184 father = LST_LOOP_FATHER (lst1);
1185 dewey = lst_dewey_number (lst1);
1186 LST_LOOP_FATHER (lst2) = father;
1187 LST_SEQ (father)[dewey] = lst2;
1188 }
1189
1190 /* Returns a copy of ROOT where LST has been replaced by a copy of the
1191 LSTs A B C in this sequence. */
1192
1193 static inline lst_p
1194 lst_substitute_3 (lst_p root, lst_p lst, lst_p a, lst_p b, lst_p c)
1195 {
1196 int i;
1197 lst_p l;
1198 vec<lst_p> seq;
1199
1200 if (!root)
1201 return NULL;
1202
1203 gcc_assert (lst && root != lst);
1204
1205 if (!LST_LOOP_P (root))
1206 return new_lst_stmt (LST_PBB (root));
1207
1208 seq.create (5);
1209
1210 for (i = 0; LST_SEQ (root).iterate (i, &l); i++)
1211 if (l != lst)
1212 seq.safe_push (lst_substitute_3 (l, lst, a, b, c));
1213 else
1214 {
1215 if (!lst_empty_p (a))
1216 seq.safe_push (copy_lst (a));
1217 if (!lst_empty_p (b))
1218 seq.safe_push (copy_lst (b));
1219 if (!lst_empty_p (c))
1220 seq.safe_push (copy_lst (c));
1221 }
1222
1223 return new_lst_loop (seq);
1224 }
1225
1226 /* Moves LST before LOOP if BEFORE is true, and after the LOOP if
1227 BEFORE is false. */
1228
1229 static inline void
1230 lst_distribute_lst (lst_p loop, lst_p lst, bool before)
1231 {
1232 int loop_depth = lst_depth (loop);
1233 int depth = lst_depth (lst);
1234 int nb_loops = depth - loop_depth;
1235
1236 gcc_assert (lst && loop && LST_LOOP_P (loop) && nb_loops > 0);
1237
1238 lst_remove_from_sequence (lst);
1239 lst_insert_in_sequence (lst_create_nest (nb_loops, lst), loop, before);
1240 }
1241
1242 /* Removes from LOOP all the statements before/after and including PBB
1243 if BEFORE is true/false. Returns the negation of BEFORE when the
1244 statement PBB has been found. */
1245
1246 static inline bool
1247 lst_remove_all_before_including_pbb (lst_p loop, poly_bb_p pbb, bool before)
1248 {
1249 int i;
1250 lst_p l;
1251
1252 if (!loop || !LST_LOOP_P (loop))
1253 return before;
1254
1255 for (i = 0; LST_SEQ (loop).iterate (i, &l);)
1256 if (LST_LOOP_P (l))
1257 {
1258 before = lst_remove_all_before_including_pbb (l, pbb, before);
1259
1260 if (LST_SEQ (l).length () == 0)
1261 {
1262 LST_SEQ (loop).ordered_remove (i);
1263 free_lst (l);
1264 }
1265 else
1266 i++;
1267 }
1268 else
1269 {
1270 if (before)
1271 {
1272 if (LST_PBB (l) == pbb)
1273 before = false;
1274
1275 LST_SEQ (loop).ordered_remove (i);
1276 free_lst (l);
1277 }
1278 else if (LST_PBB (l) == pbb)
1279 {
1280 before = true;
1281 LST_SEQ (loop).ordered_remove (i);
1282 free_lst (l);
1283 }
1284 else
1285 i++;
1286 }
1287
1288 return before;
1289 }
1290
1291 /* Removes from LOOP all the statements before/after and excluding PBB
1292 if BEFORE is true/false; Returns the negation of BEFORE when the
1293 statement PBB has been found. */
1294
1295 static inline bool
1296 lst_remove_all_before_excluding_pbb (lst_p loop, poly_bb_p pbb, bool before)
1297 {
1298 int i;
1299 lst_p l;
1300
1301 if (!loop || !LST_LOOP_P (loop))
1302 return before;
1303
1304 for (i = 0; LST_SEQ (loop).iterate (i, &l);)
1305 if (LST_LOOP_P (l))
1306 {
1307 before = lst_remove_all_before_excluding_pbb (l, pbb, before);
1308
1309 if (LST_SEQ (l).length () == 0)
1310 {
1311 LST_SEQ (loop).ordered_remove (i);
1312 free_lst (l);
1313 continue;
1314 }
1315
1316 i++;
1317 }
1318 else
1319 {
1320 if (before && LST_PBB (l) != pbb)
1321 {
1322 LST_SEQ (loop).ordered_remove (i);
1323 free_lst (l);
1324 continue;
1325 }
1326
1327 i++;
1328
1329 if (LST_PBB (l) == pbb)
1330 before = before ? false : true;
1331 }
1332
1333 return before;
1334 }
1335
1336 /* A SCOP is a Static Control Part of the program, simple enough to be
1337 represented in polyhedral form. */
1338 struct scop
1339 {
1340 /* A SCOP is defined as a SESE region. */
1341 void *region;
1342
1343 /* Number of parameters in SCoP. */
1344 graphite_dim_t nb_params;
1345
1346 /* All the basic blocks in this scop that contain memory references
1347 and that will be represented as statements in the polyhedral
1348 representation. */
1349 vec<poly_bb_p> bbs;
1350
1351 /* Original, transformed and saved schedules. */
1352 lst_p original_schedule, transformed_schedule, saved_schedule;
1353
1354 /* The context describes known restrictions concerning the parameters
1355 and relations in between the parameters.
1356
1357 void f (int8_t a, uint_16_t b) {
1358 c = 2 a + b;
1359 ...
1360 }
1361
1362 Here we can add these restrictions to the context:
1363
1364 -128 >= a >= 127
1365 0 >= b >= 65,535
1366 c = 2a + b */
1367 isl_set *context;
1368
1369 /* The context used internally by ISL. */
1370 isl_ctx *ctx;
1371
1372 /* The original dependence relations:
1373 RAW are read after write dependences,
1374 WAR are write after read dependences,
1375 WAW are write after write dependences. */
1376 isl_union_map *must_raw, *may_raw, *must_raw_no_source, *may_raw_no_source,
1377 *must_war, *may_war, *must_war_no_source, *may_war_no_source,
1378 *must_waw, *may_waw, *must_waw_no_source, *may_waw_no_source;
1379
1380 /* True when the scop has been converted to its polyhedral
1381 representation. */
1382 bool poly_scop_p;
1383 };
1384
1385 #define SCOP_BBS(S) (S->bbs)
1386 #define SCOP_REGION(S) ((sese) S->region)
1387 #define SCOP_CONTEXT(S) (NULL)
1388 #define SCOP_ORIGINAL_SCHEDULE(S) (S->original_schedule)
1389 #define SCOP_TRANSFORMED_SCHEDULE(S) (S->transformed_schedule)
1390 #define SCOP_SAVED_SCHEDULE(S) (S->saved_schedule)
1391 #define POLY_SCOP_P(S) (S->poly_scop_p)
1392
1393 extern scop_p new_scop (void *);
1394 extern void free_scop (scop_p);
1395 extern void free_scops (vec<scop_p> );
1396 extern void print_generated_program (FILE *, scop_p);
1397 extern void debug_generated_program (scop_p);
1398 extern void print_scattering_function (FILE *, poly_bb_p, int);
1399 extern void print_scattering_functions (FILE *, scop_p, int);
1400 extern void debug_scattering_function (poly_bb_p, int);
1401 extern void debug_scattering_functions (scop_p, int);
1402 extern int scop_max_loop_depth (scop_p);
1403 extern int unify_scattering_dimensions (scop_p);
1404 extern bool apply_poly_transforms (scop_p);
1405 extern bool graphite_legal_transform (scop_p);
1406
1407 /* Set the region of SCOP to REGION. */
1408
1409 static inline void
1410 scop_set_region (scop_p scop, void *region)
1411 {
1412 scop->region = region;
1413 }
1414
1415 /* Returns the number of parameters for SCOP. */
1416
1417 static inline graphite_dim_t
1418 scop_nb_params (scop_p scop)
1419 {
1420 return scop->nb_params;
1421 }
1422
1423 /* Set the number of params of SCOP to NB_PARAMS. */
1424
1425 static inline void
1426 scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
1427 {
1428 scop->nb_params = nb_params;
1429 }
1430
1431 /* Allocates a new empty poly_scattering structure. */
1432
1433 static inline poly_scattering_p
1434 poly_scattering_new (void)
1435 {
1436 poly_scattering_p res = XNEW (struct poly_scattering);
1437
1438 res->nb_local_variables = 0;
1439 res->nb_scattering = 0;
1440 return res;
1441 }
1442
1443 /* Free a poly_scattering structure. */
1444
1445 static inline void
1446 poly_scattering_free (poly_scattering_p s)
1447 {
1448 free (s);
1449 }
1450
1451 /* Copies S and return a new scattering. */
1452
1453 static inline poly_scattering_p
1454 poly_scattering_copy (poly_scattering_p s)
1455 {
1456 poly_scattering_p res = poly_scattering_new ();
1457
1458 res->nb_local_variables = s->nb_local_variables;
1459 res->nb_scattering = s->nb_scattering;
1460 return res;
1461 }
1462
1463 /* Saves the transformed scattering of PBB. */
1464
1465 static inline void
1466 store_scattering_pbb (poly_bb_p pbb)
1467 {
1468 isl_map_free (pbb->saved);
1469 pbb->saved = isl_map_copy (pbb->transformed);
1470 }
1471
1472 /* Stores the SCOP_TRANSFORMED_SCHEDULE to SCOP_SAVED_SCHEDULE. */
1473
1474 static inline void
1475 store_lst_schedule (scop_p scop)
1476 {
1477 if (SCOP_SAVED_SCHEDULE (scop))
1478 free_lst (SCOP_SAVED_SCHEDULE (scop));
1479
1480 SCOP_SAVED_SCHEDULE (scop) = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
1481 }
1482
1483 /* Restores the SCOP_TRANSFORMED_SCHEDULE from SCOP_SAVED_SCHEDULE. */
1484
1485 static inline void
1486 restore_lst_schedule (scop_p scop)
1487 {
1488 if (SCOP_TRANSFORMED_SCHEDULE (scop))
1489 free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
1490
1491 SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (SCOP_SAVED_SCHEDULE (scop));
1492 }
1493
1494 /* Saves the scattering for all the pbbs in the SCOP. */
1495
1496 static inline void
1497 store_scattering (scop_p scop)
1498 {
1499 int i;
1500 poly_bb_p pbb;
1501
1502 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1503 store_scattering_pbb (pbb);
1504
1505 store_lst_schedule (scop);
1506 }
1507
1508 /* Restores the scattering of PBB. */
1509
1510 static inline void
1511 restore_scattering_pbb (poly_bb_p pbb)
1512 {
1513 gcc_assert (pbb->saved);
1514
1515 isl_map_free (pbb->transformed);
1516 pbb->transformed = isl_map_copy (pbb->saved);
1517 }
1518
1519 /* Restores the scattering for all the pbbs in the SCOP. */
1520
1521 static inline void
1522 restore_scattering (scop_p scop)
1523 {
1524 int i;
1525 poly_bb_p pbb;
1526
1527 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1528 restore_scattering_pbb (pbb);
1529
1530 restore_lst_schedule (scop);
1531 }
1532
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 *);
1537
1538
1539 void
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);
1553
1554 isl_union_map *
1555 scop_get_dependences (scop_p scop);
1556
1557 bool
1558 carries_deps (__isl_keep isl_union_map *schedule,
1559 __isl_keep isl_union_map *deps,
1560 int depth);
1561
1562 #endif