OSDN Git Service

2009-10-05 Sebastian Pop <sebastian.pop@amd.com>
[pf3gnuchains/gcc-fork.git] / gcc / graphite-poly.h
1 /* Graphite polyhedral representation.
2    Copyright (C) 2009 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 DEF_VEC_P(poly_dr_p);
27 DEF_VEC_ALLOC_P (poly_dr_p, heap);
28
29 typedef struct poly_bb *poly_bb_p;
30 DEF_VEC_P(poly_bb_p);
31 DEF_VEC_ALLOC_P (poly_bb_p, heap);
32
33 typedef struct scop *scop_p;
34 DEF_VEC_P(scop_p);
35 DEF_VEC_ALLOC_P (scop_p, heap);
36
37 typedef ppl_dimension_type graphite_dim_t;
38
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);
42
43 /* A data reference can write or read some memory or we
44    just know it may write some memory.  */
45 enum poly_dr_type
46 {
47   PDR_READ,
48   /* PDR_MAY_READs are represented using PDR_READS.  This does not
49      limit the expressiveness.  */
50   PDR_WRITE,
51   PDR_MAY_WRITE
52 };
53
54 struct poly_dr
55 {
56   /* An identifier for this PDR.  */
57   int id;
58
59   /* The number of data refs identical to this one in the PBB.  */
60   int nb_refs;
61
62   /* A pointer to compiler's data reference description.  */
63   void *compiler_dr;
64
65   /* A pointer to the PBB that contains this data reference.  */
66   poly_bb_p pbb;
67
68   enum poly_dr_type type;
69
70   /* The access polyhedron contains the polyhedral space this data
71      reference will access.
72
73      The polyhedron contains these dimensions:
74
75      - The alias set (a):
76      Every memory access is classified in at least one alias set.
77
78      - The subscripts (s_0, ..., s_n):
79      The memory is accessed using zero or more subscript dimensions.
80
81      - The iteration domain (variables and parameters)
82
83      Do not hardcode the dimensions.  Use the following accessor functions:
84      - pdr_alias_set_dim
85      - pdr_subscript_dim
86      - pdr_iterator_dim
87      - pdr_parameter_dim
88
89      Example:
90
91      | int A[1335][123];
92      | int *p = malloc ();
93      |
94      | k = ...
95      | for i
96      |   {
97      |     if (unknown_function ())
98      |       p = A;
99      |       ... = p[?][?];
100      |     for j
101      |       A[i][j+k] = m;
102      |   }
103
104      The data access A[i][j+k] in alias set "5" is described like this:
105
106      | i   j   k   a  s0  s1   1
107      | 0   0   0   1   0   0  -5     =  0
108      |-1   0   0   0   1   0   0     =  0
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
114
115      The pointer "*p" in alias set "5" and "7" is described as a union of
116      polyhedron:
117
118
119      | i   k   a  s0   1
120      | 0   0   1   0  -5   =  0
121      | 0   0   0   1   0   >= 0
122
123      "or"
124
125      | i   k   a  s0   1
126      | 0   0   1   0  -7   =  0
127      | 0   0   0   1   0   >= 0
128
129      "*p" accesses all of the object allocated with 'malloc'.
130
131      The scalar data access "m" is represented as an array with zero subscript
132      dimensions.
133
134      | i   j   k   a   1
135      | 0   0   0  -1   15  = 0 */
136   ppl_Pointset_Powerset_C_Polyhedron_t accesses;
137
138   /* Data reference's base object set number, we must assure 2 pdrs are in the
139      same base object set before dependency checking.  */
140   int dr_base_object_set;
141
142   /* The number of subscripts.  */
143   graphite_dim_t nb_subscripts;
144 };
145
146 #define PDR_ID(PDR) (PDR->id)
147 #define PDR_NB_REFS(PDR) (PDR->nb_refs)
148 #define PDR_CDR(PDR) (PDR->compiler_dr)
149 #define PDR_PBB(PDR) (PDR->pbb)
150 #define PDR_TYPE(PDR) (PDR->type)
151 #define PDR_ACCESSES(PDR) (PDR->accesses)
152 #define PDR_BASE_OBJECT_SET(PDR) (PDR->dr_base_object_set)
153 #define PDR_NB_SUBSCRIPTS(PDR) (PDR->nb_subscripts)
154
155 void new_poly_dr (poly_bb_p, int, ppl_Pointset_Powerset_C_Polyhedron_t,
156                   enum poly_dr_type, void *, graphite_dim_t);
157 void free_poly_dr (poly_dr_p);
158 void debug_pdr (poly_dr_p);
159 void print_pdr (FILE *, poly_dr_p);
160 static inline scop_p pdr_scop (poly_dr_p pdr);
161
162 /* The dimension of the PDR_ACCESSES polyhedron of PDR.  */
163
164 static inline ppl_dimension_type
165 pdr_dim (poly_dr_p pdr)
166 {
167   ppl_dimension_type dim;
168   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PDR_ACCESSES (pdr),
169                                                       &dim);
170   return dim;
171 }
172
173 /* The dimension of the iteration domain of the scop of PDR.  */
174
175 static inline ppl_dimension_type
176 pdr_dim_iter_domain (poly_dr_p pdr)
177 {
178   return pbb_dim_iter_domain (PDR_PBB (pdr));
179 }
180
181 /* The number of parameters of the scop of PDR.  */
182
183 static inline ppl_dimension_type
184 pdr_nb_params (poly_dr_p pdr)
185 {
186   return scop_nb_params (pdr_scop (pdr));
187 }
188
189 /* The dimension of the alias set in PDR.  */
190
191 static inline ppl_dimension_type
192 pdr_alias_set_dim (poly_dr_p pdr)
193 {
194   poly_bb_p pbb = PDR_PBB (pdr);
195
196   return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
197 }
198
199 /* The dimension in PDR containing subscript S.  */
200
201 static inline ppl_dimension_type
202 pdr_subscript_dim (poly_dr_p pdr, graphite_dim_t s)
203 {
204   poly_bb_p pbb = PDR_PBB (pdr);
205
206   return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb) + 1 + s;
207 }
208
209 /* The dimension in PDR containing the loop iterator ITER.  */
210
211 static inline ppl_dimension_type
212 pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED, graphite_dim_t iter)
213 {
214   return iter;
215 }
216
217 /* The dimension in PDR containing parameter PARAM.  */
218
219 static inline ppl_dimension_type
220 pdr_parameter_dim (poly_dr_p pdr, graphite_dim_t param)
221 {
222   poly_bb_p pbb = PDR_PBB (pdr);
223
224   return pbb_dim_iter_domain (pbb) + param;
225 }
226
227 /* Returns true when PDR is a "read".  */
228
229 static inline bool
230 pdr_read_p (poly_dr_p pdr)
231 {
232   return PDR_TYPE (pdr) == PDR_READ;
233 }
234
235 /* Returns true when PDR is a "write".  */
236
237 static inline bool
238 pdr_write_p (poly_dr_p pdr)
239 {
240   return PDR_TYPE (pdr) == PDR_WRITE;
241 }
242
243 /* Returns true when PDR is a "may write".  */
244
245 static inline bool
246 pdr_may_write_p (poly_dr_p pdr)
247 {
248   return PDR_TYPE (pdr) == PDR_MAY_WRITE;
249 }
250
251 typedef struct poly_scattering *poly_scattering_p;
252
253 struct poly_scattering
254 {
255   /* The scattering function containing the transformations.  */
256   ppl_Polyhedron_t scattering;
257
258   /* The number of local variables.  */
259   int nb_local_variables;
260
261   /* The number of scattering dimensions.  */
262   int nb_scattering;
263 };
264
265 /* POLY_BB represents a blackbox in the polyhedral model.  */
266
267 struct poly_bb
268 {
269   void *black_box;
270
271   scop_p scop;
272
273   /* The iteration domain of this bb.
274      Example:
275
276      for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
277        for (j = 2; j <= 2*i + 5; j++)
278          for (k = 0; k <= 5; k++)
279            S (i,j,k)
280
281      Loop iterators: i, j, k
282      Parameters: a, b
283
284      | i >=  a -  7b +  8
285      | i <= 3a + 13b + 20
286      | j >= 2
287      | j <= 2i + 5
288      | k >= 0
289      | k <= 5
290
291      The number of variables in the DOMAIN may change and is not
292      related to the number of loops in the original code.  */
293   ppl_Pointset_Powerset_C_Polyhedron_t domain;
294
295   /* The data references we access.  */
296   VEC (poly_dr_p, heap) *drs;
297
298   /* The original scattering.  */
299   poly_scattering_p original;
300
301   /* The transformed scattering.  */
302   poly_scattering_p transformed;
303
304   /* A copy of the transformed scattering.  */
305   poly_scattering_p saved;
306
307   /* True when the PDR duplicates have already been removed.  */
308   bool pdr_duplicates_removed;
309
310   /* True when this PBB contains only a reduction statement.  */
311   bool is_reduction;
312 };
313
314 #define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box)
315 #define PBB_SCOP(PBB) (PBB->scop)
316 #define PBB_DOMAIN(PBB) (PBB->domain)
317 #define PBB_DRS(PBB) (PBB->drs)
318 #define PBB_ORIGINAL(PBB) (PBB->original)
319 #define PBB_ORIGINAL_SCATTERING(PBB) (PBB->original->scattering)
320 #define PBB_TRANSFORMED(PBB) (PBB->transformed)
321 #define PBB_TRANSFORMED_SCATTERING(PBB) (PBB->transformed->scattering)
322 #define PBB_SAVED(PBB) (PBB->saved)
323 #define PBB_NB_LOCAL_VARIABLES(PBB) (PBB->transformed->nb_local_variables)
324 #define PBB_NB_SCATTERING_TRANSFORM(PBB) (PBB->transformed->nb_scattering)
325 #define PBB_PDR_DUPLICATES_REMOVED(PBB) (PBB->pdr_duplicates_removed)
326 #define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
327
328 extern void new_poly_bb (scop_p, void *, bool);
329 extern void free_poly_bb (poly_bb_p);
330 extern void debug_loop_vec (poly_bb_p);
331 extern void schedule_to_scattering (poly_bb_p, int);
332 extern void print_pbb_domain (FILE *, poly_bb_p);
333 extern void print_pbb (FILE *, poly_bb_p);
334 extern void print_scop_context (FILE *, scop_p);
335 extern void print_scop (FILE *, scop_p);
336 extern void debug_pbb_domain (poly_bb_p);
337 extern void debug_pbb (poly_bb_p);
338 extern void print_pdrs (FILE *, poly_bb_p);
339 extern void debug_pdrs (poly_bb_p);
340 extern void debug_scop_context (scop_p);
341 extern void debug_scop (scop_p);
342 extern void print_scop_params (FILE *, scop_p);
343 extern void debug_scop_params (scop_p);
344 extern void print_iteration_domain (FILE *, poly_bb_p);
345 extern void print_iteration_domains (FILE *, scop_p);
346 extern void debug_iteration_domain (poly_bb_p);
347 extern void debug_iteration_domains (scop_p);
348 extern bool scop_do_interchange (scop_p);
349 extern bool scop_do_strip_mine (scop_p);
350 extern void pbb_number_of_iterations (poly_bb_p, graphite_dim_t, Value);
351 extern void pbb_number_of_iterations_at_time (poly_bb_p, graphite_dim_t, Value);
352 extern void pbb_remove_duplicate_pdrs (poly_bb_p);
353
354 /* The index of the PBB.  */
355
356 static inline int
357 pbb_index (poly_bb_p pbb)
358 {
359   return GBB_BB (PBB_BLACK_BOX (pbb))->index;
360 }
361
362 /* The loop of the PBB.  */
363
364 static inline loop_p
365 pbb_loop (poly_bb_p pbb)
366 {
367   return gbb_loop (PBB_BLACK_BOX (pbb));
368 }
369
370 /* The scop that contains the PDR.  */
371
372 static inline scop_p
373 pdr_scop (poly_dr_p pdr)
374 {
375   return PBB_SCOP (PDR_PBB (pdr));
376 }
377
378 /* Set black box of PBB to BLACKBOX.  */
379
380 static inline void
381 pbb_set_black_box (poly_bb_p pbb, void *black_box)
382 {
383   pbb->black_box = black_box;
384 }
385
386 /* The number of loops around PBB: the dimension of the iteration
387    domain.  */
388
389 static inline graphite_dim_t
390 pbb_dim_iter_domain (const struct poly_bb *pbb)
391 {
392   scop_p scop = PBB_SCOP (pbb);
393   ppl_dimension_type dim;
394
395   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb), &dim);
396   return dim - scop_nb_params (scop);
397 }
398
399 /* The number of params defined in PBB.  */
400
401 static inline graphite_dim_t
402 pbb_nb_params (const struct poly_bb *pbb)
403 {
404   scop_p scop = PBB_SCOP (pbb);
405
406   return scop_nb_params (scop);
407 }
408
409 /* The number of scattering dimensions in the SCATTERING polyhedron
410    of a PBB for a given SCOP.  */
411
412 static inline graphite_dim_t
413 pbb_nb_scattering_orig (const struct poly_bb *pbb)
414 {
415   return 2 * pbb_dim_iter_domain (pbb) + 1;
416 }
417
418 /* The number of scattering dimensions in PBB.  */
419
420 static inline graphite_dim_t
421 pbb_nb_scattering_transform (const struct poly_bb *pbb)
422 {
423   return PBB_NB_SCATTERING_TRANSFORM (pbb);
424 }
425
426 /* The number of dynamic scattering dimensions in PBB.  */
427
428 static inline graphite_dim_t
429 pbb_nb_dynamic_scattering_transform (const struct poly_bb *pbb)
430 {
431   /* This function requires the 2d + 1 scattering format to be
432      invariant during all transformations.  */
433   gcc_assert (PBB_NB_SCATTERING_TRANSFORM (pbb) % 2);
434   return PBB_NB_SCATTERING_TRANSFORM (pbb) / 2;
435 }
436
437 /* Returns the number of local variables used in the transformed
438    scattering polyhedron of PBB.  */
439
440 static inline graphite_dim_t
441 pbb_nb_local_vars (const struct poly_bb *pbb)
442 {
443   /* For now we do not have any local variables, as we do not do strip
444      mining for example.  */
445   return PBB_NB_LOCAL_VARIABLES (pbb);
446 }
447
448 /* The dimension in the domain of PBB containing the iterator ITER.  */
449
450 static inline ppl_dimension_type
451 pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t iter)
452 {
453   return iter;
454 }
455
456 /* The dimension in the domain of PBB containing the iterator ITER.  */
457
458 static inline ppl_dimension_type
459 pbb_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
460 {
461   return param
462     + pbb_dim_iter_domain (pbb);
463 }
464
465 /* The dimension in the original scattering polyhedron of PBB
466    containing the scattering iterator SCATTER.  */
467
468 static inline ppl_dimension_type
469 psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
470 {
471   gcc_assert (scatter < pbb_nb_scattering_orig (pbb));
472   return scatter;
473 }
474
475 /* The dimension in the transformed scattering polyhedron of PBB
476    containing the scattering iterator SCATTER.  */
477
478 static inline ppl_dimension_type
479 psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
480 {
481   gcc_assert (scatter <= pbb_nb_scattering_transform (pbb));
482   return scatter;
483 }
484
485 ppl_dimension_type psct_scattering_dim_for_loop_depth (poly_bb_p,
486                                                        graphite_dim_t);
487
488 /* The dimension in the transformed scattering polyhedron of PBB of
489    the local variable LV.  */
490
491 static inline ppl_dimension_type
492 psct_local_var_dim (poly_bb_p pbb, graphite_dim_t lv)
493 {
494   gcc_assert (lv <= pbb_nb_local_vars (pbb));
495   return lv + pbb_nb_scattering_transform (pbb);
496 }
497
498 /* The dimension in the original scattering polyhedron of PBB
499    containing the loop iterator ITER.  */
500
501 static inline ppl_dimension_type
502 psco_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
503 {
504   gcc_assert (iter < pbb_dim_iter_domain (pbb));
505   return iter + pbb_nb_scattering_orig (pbb);
506 }
507
508 /* The dimension in the transformed scattering polyhedron of PBB
509    containing the loop iterator ITER.  */
510
511 static inline ppl_dimension_type
512 psct_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
513 {
514   gcc_assert (iter < pbb_dim_iter_domain (pbb));
515   return iter
516     + pbb_nb_scattering_transform (pbb)
517     + pbb_nb_local_vars (pbb);
518 }
519
520 /* The dimension in the original scattering polyhedron of PBB
521    containing parameter PARAM.  */
522
523 static inline ppl_dimension_type
524 psco_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
525 {
526   gcc_assert (param < pbb_nb_params (pbb));
527   return param
528     + pbb_nb_scattering_orig (pbb)
529     + pbb_dim_iter_domain (pbb);
530 }
531
532 /* The dimension in the transformed scattering polyhedron of PBB
533    containing parameter PARAM.  */
534
535 static inline ppl_dimension_type
536 psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
537 {
538   gcc_assert (param < pbb_nb_params (pbb));
539   return param
540     + pbb_nb_scattering_transform (pbb)
541     + pbb_nb_local_vars (pbb)
542     + pbb_dim_iter_domain (pbb);
543 }
544
545 /* The scattering dimension of PBB corresponding to the dynamic level
546    LEVEL.  */
547
548 static inline ppl_dimension_type
549 psct_dynamic_dim (poly_bb_p pbb, graphite_dim_t level)
550 {
551   graphite_dim_t result;
552   result = 1 + 2 * level;
553
554   gcc_assert (result < pbb_nb_scattering_transform (pbb));
555   return result;
556 }
557
558 /* Adds to the transformed scattering polyhedron of PBB a new local
559    variable and returns its index.  */
560
561 static inline graphite_dim_t
562 psct_add_local_variable (poly_bb_p pbb)
563 {
564   graphite_dim_t nlv = pbb_nb_local_vars (pbb);
565   ppl_dimension_type lv_column = psct_local_var_dim (pbb, nlv);
566   ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), lv_column, 1);
567   PBB_NB_LOCAL_VARIABLES (pbb) += 1;
568   return nlv;
569 }
570
571 /* Adds a dimension to the transformed scattering polyhedron of PBB at
572    INDEX.  */
573
574 static inline void
575 psct_add_scattering_dimension (poly_bb_p pbb, ppl_dimension_type index)
576 {
577   gcc_assert (index < pbb_nb_scattering_transform (pbb));
578
579   ppl_insert_dimensions (PBB_TRANSFORMED_SCATTERING (pbb), index, 1);
580   PBB_NB_SCATTERING_TRANSFORM (pbb) += 1;
581 }
582
583 /* A SCOP is a Static Control Part of the program, simple enough to be
584    represented in polyhedral form.  */
585 struct scop
586 {
587   /* A SCOP is defined as a SESE region.  */
588   void *region;
589
590   /* Number of parameters in SCoP.  */
591   graphite_dim_t nb_params;
592
593   /* All the basic blocks in this scop that contain memory references
594      and that will be represented as statements in the polyhedral
595      representation.  */
596   VEC (poly_bb_p, heap) *bbs;
597
598   /* Data dependence graph for this SCoP.  */
599   struct graph *dep_graph;
600
601   /* The context describes known restrictions concerning the parameters
602      and relations in between the parameters.
603
604   void f (int8_t a, uint_16_t b) {
605     c = 2 a + b;
606     ...
607   }
608
609   Here we can add these restrictions to the context:
610
611   -128 >= a >= 127
612      0 >= b >= 65,535
613      c = 2a + b  */
614   ppl_Pointset_Powerset_C_Polyhedron_t context;
615
616   /* A hashtable of the data dependence relations for the original
617      scattering.  */
618   htab_t original_pddrs;
619 };
620
621 #define SCOP_BBS(S) (S->bbs)
622 #define SCOP_REGION(S) ((sese) S->region)
623 #define SCOP_DEP_GRAPH(S) (S->dep_graph)
624 #define SCOP_CONTEXT(S) (S->context)
625 #define SCOP_ORIGINAL_PDDRS(S) (S->original_pddrs)
626
627 extern scop_p new_scop (void *);
628 extern void free_scop (scop_p);
629 extern void free_scops (VEC (scop_p, heap) *);
630 extern void print_generated_program (FILE *, scop_p);
631 extern void debug_generated_program (scop_p);
632 extern void print_scattering_function (FILE *, poly_bb_p);
633 extern void print_scattering_functions (FILE *, scop_p);
634 extern void debug_scattering_function (poly_bb_p);
635 extern void debug_scattering_functions (scop_p);
636 extern int scop_max_loop_depth (scop_p);
637 extern int unify_scattering_dimensions (scop_p);
638 extern bool apply_poly_transforms (scop_p);
639 extern bool graphite_legal_transform (scop_p);
640
641 /* Set the region of SCOP to REGION.  */
642
643 static inline void
644 scop_set_region (scop_p scop, void *region)
645 {
646   scop->region = region;
647 }
648
649 /* Returns the number of parameters for SCOP.  */
650
651 static inline graphite_dim_t
652 scop_nb_params (scop_p scop)
653 {
654   return scop->nb_params;
655 }
656
657 /* Set the number of params of SCOP to NB_PARAMS.  */
658
659 static inline void
660 scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
661 {
662   scop->nb_params = nb_params;
663 }
664
665 /* Allocates a new empty poly_scattering structure.  */
666
667 static inline poly_scattering_p
668 poly_scattering_new (void)
669 {
670   poly_scattering_p res = XNEW (struct poly_scattering);
671
672   res->scattering = NULL;
673   res->nb_local_variables = 0;
674   res->nb_scattering = 0;
675   return res;
676 }
677
678 /* Free a poly_scattering structure.  */
679
680 static inline void
681 poly_scattering_free (poly_scattering_p s)
682 {
683   ppl_delete_Polyhedron (s->scattering);
684   free (s);
685 }
686
687 /* Copies S and return a new scattering.  */
688
689 static inline poly_scattering_p
690 poly_scattering_copy (poly_scattering_p s)
691 {
692   poly_scattering_p res = poly_scattering_new ();
693
694   ppl_new_C_Polyhedron_from_C_Polyhedron (&(res->scattering), s->scattering);
695   res->nb_local_variables = s->nb_local_variables;
696   res->nb_scattering = s->nb_scattering;
697   return res;
698 }
699
700 /* Saves the transformed scattering of PBB.  */
701
702 static inline void
703 store_scattering_pbb (poly_bb_p pbb)
704 {
705   gcc_assert (PBB_TRANSFORMED (pbb));
706
707   if (PBB_SAVED (pbb))
708     poly_scattering_free (PBB_SAVED (pbb));
709
710   PBB_SAVED (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
711 }
712
713 /* Saves the scattering for all the pbbs in the SCOP.  */
714
715 static inline void
716 store_scattering (scop_p scop)
717 {
718   int i;
719   poly_bb_p pbb;
720
721   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
722     store_scattering_pbb (pbb);
723 }
724
725 /* Restores the scattering of PBB.  */
726
727 static inline void
728 restore_scattering_pbb (poly_bb_p pbb)
729 {
730   gcc_assert (PBB_SAVED (pbb));
731
732   poly_scattering_free (PBB_TRANSFORMED (pbb));
733   PBB_TRANSFORMED (pbb) = poly_scattering_copy (PBB_SAVED (pbb));
734 }
735
736 /* Restores the scattering for all the pbbs in the SCOP.  */
737
738 static inline void
739 restore_scattering (scop_p scop)
740 {
741   int i;
742   poly_bb_p pbb;
743
744   for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
745     restore_scattering_pbb (pbb);
746 }
747
748 #endif