2 /**-------------------------------------------------------------------**
4 **-------------------------------------------------------------------**
6 **-------------------------------------------------------------------**
7 ** First version: october 28th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
15 * Copyright (C) 2001-2005 Cedric Bastoul *
17 * This is free software; you can redistribute it and/or modify it under the *
18 * terms of the GNU General Public License as published by the Free Software *
19 * Foundation; either version 2 of the License, or (at your option) any later *
22 * This software is distributed in the hope that it will be useful, but *
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
27 * You should have received a copy of the GNU General Public License along *
28 * with software; if not, write to the Free Software Foundation, Inc., *
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
34 ******************************************************************************/
35 /* CAUTION: the english used for comments is probably the worst you ever read,
36 * please feel free to correct and improve it !
43 #include <cloog/polylib/cloog.h>
45 static CloogDomain
* cloog_domain_matrix2domain(CloogState
*state
,
46 Matrix
*, int nb_par
);
47 static Matrix
* cloog_domain_domain2matrix(CloogDomain
*);
50 /******************************************************************************
51 * Memory leaks hunting *
52 ******************************************************************************/
56 * These functions and global variables are devoted to memory leaks hunting: we
57 * want to know at each moment how many Polyhedron structures had been allocated
58 * (cloog_domain_from_polylib_polyhedronated) and how many had been freed (cloog_domain_freed).
59 * Each time a Polyhedron structure is allocated, a call to the function
60 * cloog_domain_leak_up() must be carried out, and respectively
61 * cloog_domain_leak_down() when a Polyhedron structure is freed. The special
62 * variable cloog_domain_max gives the maximal number of Polyhedron structures
63 * simultaneously alive (i.e. allocated and non-freed) in memory.
64 * - July 3rd->11th 2003: first version (memory leaks hunt and correction).
68 static void cloog_domain_leak_up(CloogState
*state
)
70 state
->domain_allocated
++;
71 if ((state
->domain_allocated
- state
->domain_freed
) > state
->domain_max
)
72 state
->domain_max
= state
->domain_allocated
- state
->domain_freed
;
76 static void cloog_domain_leak_down(CloogState
*state
)
78 state
->domain_freed
++;
82 /******************************************************************************
84 ******************************************************************************/
87 /* CLooG makes an intensive use of polyhedral operations and the PolyLib do
88 * the job. Here are the interfaces to all the PolyLib calls (CLooG uses 19
89 * PolyLib functions), with or without some adaptations. If another polyhedral
90 * library can be used, only these functions have to be changed.
91 * - April 16th 2005: Since PolyLib 5.20, compacting is no more useful and have
92 * been removed. The direct use of the PolyLib's Polyhedron
93 * data structure is also replaced with the CloogDomain data
94 * structure that includes the Polyhedron and an additional
95 * counter on how many pointers point on this structure.
96 * This allows to save memory (cloog_domain_copy now only
97 * increment the counter) while memory leaks are avoided (the
98 * function cloog_domain_free decrements the counter and
99 * actually frees the data structure only when its value
104 * Returns true if each scattering dimension is defined in terms
105 * of the original iterators.
107 int cloog_scattering_fully_specified(CloogScattering
*scattering
,
110 int scattering_dim
= cloog_domain_dimension(&scattering
->dom
) -
111 cloog_domain_dimension(domain
);
112 return scattering
->dom
.polyhedron
->NbEq
>= scattering_dim
;
116 * cloog_domain_matrix2domain function:
117 * Given a matrix of constraints (matrix), this function constructs and returns
118 * the corresponding domain (i.e. the CloogDomain structure including the
119 * polyhedron with its double representation: constraint matrix and the set of
122 CloogDomain
*cloog_domain_matrix2domain(CloogState
*state
,
123 Matrix
*matrix
, int nb_par
)
125 Polyhedron
*P
= Constraints2Polyhedron(matrix
, state
->backend
->MAX_RAYS
);
126 return cloog_domain_from_polylib_polyhedron(state
, P
, nb_par
);
131 * cloog_domain_domain2matrix function:
132 * Given a polyhedron (in domain), this function returns its corresponding
133 * matrix of constraints.
135 Matrix
* cloog_domain_domain2matrix(CloogDomain
* domain
)
137 return cloog_matrix_matrix(Polyhedron2Constraints(domain
->polyhedron
));
140 CloogConstraintSet
*cloog_domain_constraints(CloogDomain
*domain
)
142 return cloog_domain_domain2matrix(domain
);
147 * Create duplicate of domain.
149 CloogDomain
*cloog_domain_duplicate(CloogDomain
*domain
)
151 Polyhedron
*P
= Polyhedron_Copy(domain
->polyhedron
);
152 return cloog_domain_from_polylib_polyhedron(domain
->state
, P
, domain
->nb_par
);
157 * cloog_domain_print function:
158 * This function prints the content of a CloogDomain structure (domain) into
159 * a file (foo, possibly stdout).
161 void cloog_domain_print(FILE * foo
, CloogDomain
* domain
)
162 { Polyhedron_Print(foo
,P_VALUE_FMT
,domain
->polyhedron
) ;
163 fprintf(foo
,"Number of active references: %d\n",domain
->references
) ;
166 void cloog_domain_print_constraints(FILE *foo
, CloogDomain
*domain
,
169 Polyhedron
*polyhedron
;
174 /* Number of polyhedron inside the union of disjoint polyhedra. */
175 for (polyhedron
= cloog_domain_polyhedron(domain
); polyhedron
;
176 polyhedron
= polyhedron
->next
)
178 fprintf(foo
, "%d\n", j
);
181 /* The polyhedra themselves. */
182 for (polyhedron
= cloog_domain_polyhedron(domain
); polyhedron
;
183 polyhedron
= polyhedron
->next
) {
184 matrix
= cloog_matrix_matrix(Polyhedron2Constraints(polyhedron
));
185 cloog_matrix_print(foo
,matrix
);
186 cloog_matrix_free(matrix
);
191 * cloog_polyhedron_print function:
192 * This function prints the content of a Polyhedron structure (polyhedron) into
193 * a file (foo, possibly stdout). Just there as a development facility.
195 void cloog_polyhedron_print(FILE * foo
, Polyhedron
* polyhedron
)
196 { Polyhedron_Print(foo
,P_VALUE_FMT
,polyhedron
) ;
201 * cloog_domain_free function:
202 * This function frees the allocated memory for a CloogDomain structure
203 * (domain). It decrements the number of active references to this structure,
204 * if there are no more references on the structure, it frees it (with the
205 * included list of polyhedra).
207 void cloog_domain_free(CloogDomain
* domain
)
208 { if (domain
!= NULL
)
209 { domain
->references
-- ;
211 if (domain
->references
== 0) {
212 if (domain
->polyhedron
!= NULL
) {
213 cloog_domain_leak_down(domain
->state
);
214 Domain_Free(domain
->polyhedron
) ;
221 void cloog_scattering_free(CloogScattering
*scatt
)
223 cloog_domain_free(&scatt
->dom
);
228 * cloog_domain_copy function:
229 * This function returns a copy of a CloogDomain structure (domain). To save
230 * memory this is not a memory copy but we increment a counter of active
231 * references inside the structure, then return a pointer to that structure.
233 CloogDomain
* cloog_domain_copy(CloogDomain
* domain
)
234 { domain
->references
++ ;
240 * cloog_domain_image function:
241 * This function returns a CloogDomain structure such that the included
242 * polyhedral domain is computed from the former one into another
243 * domain according to a given affine mapping function (mapping).
245 CloogDomain
* cloog_domain_image(CloogDomain
* domain
, Matrix
* mapping
)
248 I
= DomainImage(domain
->polyhedron
, mapping
, domain
->state
->backend
->MAX_RAYS
);
249 return cloog_domain_from_polylib_polyhedron(domain
->state
, I
, domain
->nb_par
);
254 * cloog_domain_preimage function:
255 * Given a polyhedral domain (polyhedron) inside a CloogDomain structure and a
256 * mapping function (mapping), this function returns a new CloogDomain structure
257 * with a polyhedral domain which when transformed by mapping function (mapping)
258 * gives (polyhedron).
260 CloogDomain
* cloog_domain_preimage(CloogDomain
* domain
, Matrix
* mapping
)
263 I
= DomainPreimage(domain
->polyhedron
, mapping
, domain
->state
->backend
->MAX_RAYS
);
264 return cloog_domain_from_polylib_polyhedron(domain
->state
, I
, domain
->nb_par
);
269 * cloog_domain_convex function:
270 * Given a polyhedral domain (polyhedron), this function concatenates the lists
271 * of rays and lines of the two (or more) polyhedra in the domain into one
272 * combined list, and find the set of constraints which tightly bound all of
273 * those objects. It returns the corresponding polyhedron.
275 CloogDomain
* cloog_domain_convex(CloogDomain
* domain
)
278 C
= DomainConvex(domain
->polyhedron
, domain
->state
->backend
->MAX_RAYS
);
279 return cloog_domain_from_polylib_polyhedron(domain
->state
, C
, domain
->nb_par
);
284 * cloog_domain_simplified_hull:
285 * Given a list (union) of polyhedra, this function returns a single
286 * polyhedron that contains this union and uses only contraints that
287 * appear in one or more of the polyhedra in the list.
289 * We simply iterate over all constraints of all polyhedra and test
290 * whether all rays of the other polyhedra satisfy/saturate the constraint.
292 static CloogDomain
*cloog_domain_simplified_hull(CloogDomain
* domain
)
294 int dim
= cloog_domain_dimension(domain
) + domain
->nb_par
;
296 int nb_pol
= 0, nb_constraints
= 0;
298 Matrix
**rays
, *matrix
;
303 for (P
= domain
->polyhedron
; P
; P
= P
->next
) {
305 nb_constraints
+= P
->NbConstraints
;
307 matrix
= cloog_matrix_alloc(nb_constraints
, 1 + dim
+ 1);
309 rays
= (Matrix
**)malloc(nb_pol
* sizeof(Matrix
*));
310 for (P
= domain
->polyhedron
, i
= 0; P
; P
= P
->next
, ++i
)
311 rays
[i
] = Polyhedron2Rays(P
);
313 for (P
= domain
->polyhedron
, i
= 0; P
; P
= P
->next
, ++i
) {
314 Matrix
*constraints
= Polyhedron2Constraints(P
);
315 for (j
= 0; j
< constraints
->NbRows
; ++j
) {
316 for (k
= 0; k
< nb_pol
; ++k
) {
319 for (l
= 0; l
< rays
[k
]->NbRows
; ++l
) {
320 Inner_Product(constraints
->p
[j
]+1, rays
[k
]->p
[l
]+1, dim
+1, &tmp
);
321 if (value_neg_p(tmp
))
323 if ((value_zero_p(constraints
->p
[j
][0]) ||
324 value_zero_p(rays
[k
]->p
[l
][0])) && value_pos_p(tmp
))
327 if (l
< rays
[k
]->NbRows
)
331 Vector_Copy(constraints
->p
[j
], matrix
->p
[nb_constraints
++], 1+dim
+1);
333 Matrix_Free(constraints
);
336 for (P
= domain
->polyhedron
, i
= 0; P
; P
= P
->next
, ++i
)
337 Matrix_Free(rays
[i
]);
341 matrix
->NbRows
= nb_constraints
;
342 bounds
= cloog_domain_matrix2domain(domain
->state
, matrix
, domain
->nb_par
);
343 cloog_matrix_free(matrix
);
350 * cloog_domain_simple_convex:
351 * Given a list (union) of polyhedra, this function returns a "simple"
352 * convex hull of this union. In particular, the constraints of the
353 * the returned polyhedron consist of (parametric) lower and upper
354 * bounds on individual variables and constraints that appear in the
355 * original polyhedra.
357 CloogDomain
*cloog_domain_simple_convex(CloogDomain
*domain
)
360 int dim
= cloog_domain_dimension(domain
);
361 CloogDomain
*convex
= NULL
;
363 if (cloog_domain_isconvex(domain
))
364 return cloog_domain_copy(domain
);
366 for (i
= 0; i
< dim
; ++i
) {
367 CloogDomain
*bounds
= cloog_domain_bounds(domain
, i
);
372 CloogDomain
*temp
= cloog_domain_intersection(convex
, bounds
);
373 cloog_domain_free(bounds
);
374 cloog_domain_free(convex
);
379 CloogDomain
*temp
, *bounds
;
381 bounds
= cloog_domain_simplified_hull(domain
);
382 temp
= cloog_domain_intersection(convex
, bounds
);
383 cloog_domain_free(bounds
);
384 cloog_domain_free(convex
);
393 * cloog_domain_simplify function:
394 * Given two polyhedral domains (pol1) and (pol2) inside two CloogDomain
395 * structures, this function finds the largest domain set (or the smallest list
396 * of non-redundant constraints), that when intersected with polyhedral
397 * domain (pol2) equals (Pol1)intersect(Pol2). The output is a new CloogDomain
398 * structure with a polyhedral domain with the "redundant" constraints removed.
399 * NB: this function do not work as expected with unions of polyhedra...
401 CloogDomain
* cloog_domain_simplify(CloogDomain
* dom1
, CloogDomain
* dom2
)
405 Polyhedron
*P
= dom1
->polyhedron
;
406 int MAX_RAYS
= dom1
->state
->backend
->MAX_RAYS
;
408 /* DomainSimplify doesn't remove all redundant equalities,
409 * so we remove them here first in case both dom1 and dom2
410 * are single polyhedra (i.e., not unions of polyhedra).
412 if (!dom1
->polyhedron
->next
&& !dom2
->polyhedron
->next
&&
413 P
->NbEq
&& dom2
->polyhedron
->NbEq
) {
415 int rows
= P
->NbEq
+ dom2
->polyhedron
->NbEq
;
416 int cols
= P
->Dimension
+2;
418 M
= cloog_matrix_alloc(rows
, cols
);
419 M2
= cloog_matrix_alloc(P
->NbConstraints
, cols
);
420 Vector_Copy(dom2
->polyhedron
->Constraint
[0], M
->p
[0],
421 dom2
->polyhedron
->NbEq
* cols
);
422 rank
= dom2
->polyhedron
->NbEq
;
424 for (i
= 0; i
< P
->NbEq
; ++i
) {
425 Vector_Copy(P
->Constraint
[i
], M
->p
[rank
], cols
);
426 if (Gauss(M
, rank
+1, cols
-1) > rank
) {
427 Vector_Copy(P
->Constraint
[i
], M2
->p
[row
++], cols
);
432 if (P
->NbConstraints
> P
->NbEq
)
433 Vector_Copy(P
->Constraint
[P
->NbEq
], M2
->p
[row
],
434 (P
->NbConstraints
- P
->NbEq
) * cols
);
435 P
= Constraints2Polyhedron(M2
, MAX_RAYS
);
437 cloog_matrix_free(M2
);
438 cloog_matrix_free(M
);
440 dom
= cloog_domain_from_polylib_polyhedron(dom1
->state
,
441 DomainSimplify(P
, dom2
->polyhedron
, MAX_RAYS
),
443 if (P
!= dom1
->polyhedron
)
450 * cloog_domain_union function:
451 * This function returns a new CloogDomain structure including a polyhedral
452 * domain which is the union of two polyhedral domains (pol1) U (pol2) inside
453 * two CloogDomain structures.
455 CloogDomain
* cloog_domain_union(CloogDomain
* dom1
, CloogDomain
* dom2
)
457 int MAX_RAYS
= dom1
->state
->backend
->MAX_RAYS
;
458 return cloog_domain_from_polylib_polyhedron(dom1
->state
, DomainUnion(dom1
->polyhedron
,
459 dom2
->polyhedron
, MAX_RAYS
),
465 * cloog_domain_intersection function:
466 * This function returns a new CloogDomain structure including a polyhedral
467 * domain which is the intersection of two polyhedral domains (pol1)inter(pol2)
468 * inside two CloogDomain structures.
470 CloogDomain
* cloog_domain_intersection(CloogDomain
* dom1
, CloogDomain
* dom2
)
472 int MAX_RAYS
= dom1
->state
->backend
->MAX_RAYS
;
473 return cloog_domain_from_polylib_polyhedron(dom1
->state
, DomainIntersection(dom1
->polyhedron
,
474 dom2
->polyhedron
, MAX_RAYS
),
480 * cloog_domain_difference function:
481 * This function returns a new CloogDomain structure including a polyhedral
482 * domain which is the difference of two polyhedral domains domain \ minus
483 * inside two CloogDomain structures.
484 * - November 8th 2001: first version.
486 CloogDomain
* cloog_domain_difference(CloogDomain
* domain
, CloogDomain
* minus
)
488 int MAX_RAYS
= domain
->state
->backend
->MAX_RAYS
;
489 if (cloog_domain_isempty(minus
))
490 return(cloog_domain_copy(domain
)) ;
492 return cloog_domain_from_polylib_polyhedron(domain
->state
, DomainDifference(domain
->polyhedron
,
493 minus
->polyhedron
,MAX_RAYS
),
499 * cloog_domain_addconstraints function :
500 * This function adds source's polyhedron constraints to target polyhedron: for
501 * each element of the polyhedron inside 'target' (i.e. element of the union
502 * of polyhedra) it adds the constraints of the corresponding element in
504 * - August 10th 2002: first version.
505 * Nota bene for future : it is possible that source and target don't have the
506 * same number of elements (try iftest2 without non-shared constraint
507 * elimination in cloog_loop_separate !). This function is yet another part
508 * of the DomainSimplify patching problem...
510 CloogDomain
* cloog_domain_addconstraints(domain_source
, domain_target
)
511 CloogDomain
* domain_source
, * domain_target
;
512 { unsigned nb_constraint
;
513 Value
* constraints
;
514 Polyhedron
* source
, * target
, * new, * next
, * last
;
515 int MAX_RAYS
= domain_source
->state
->backend
->MAX_RAYS
;
517 source
= domain_source
->polyhedron
;
518 target
= domain_target
->polyhedron
;
520 constraints
= source
->p_Init
;
521 nb_constraint
= source
->NbConstraints
;
522 source
= source
->next
;
523 new = AddConstraints(constraints
,nb_constraint
,target
,MAX_RAYS
) ;
525 next
= target
->next
;
528 { /* BUG !!! This is actually a bug. I don't know yet how to cleanly avoid
529 * the situation where source and target do not have the same number of
530 * elements. So this 'if' is an awful trick, waiting for better.
533 { constraints
= source
->p_Init
;
534 nb_constraint
= source
->NbConstraints
;
535 source
= source
->next
;
537 last
->next
= AddConstraints(constraints
,nb_constraint
,next
,MAX_RAYS
) ;
542 return cloog_domain_from_polylib_polyhedron(domain_source
->state
, new, domain_source
->nb_par
);
547 * cloog_domain_sort function:
548 * This function topologically sorts (nb_pols) polyhedra. Here (pols) is a an
549 * array of pointers to polyhedra, (nb_pols) is the number of polyhedra,
550 * (level) is the level to consider for partial ordering (nb_par) is the
551 * parameter space dimension, (permut) if not NULL, is an array of (nb_pols)
552 * integers that contains a permutation specification after call in order to
553 * apply the topological sorting.
555 void cloog_domain_sort(CloogDomain
**doms
, unsigned nb_doms
, unsigned level
,
565 nb_par
= doms
[0]->nb_par
;
566 MAX_RAYS
= doms
[0]->state
->backend
->MAX_RAYS
;
568 pols
= (Polyhedron
**) malloc(nb_doms
* sizeof(Polyhedron
*));
570 for (i
= 0; i
< nb_doms
; i
++)
571 pols
[i
] = cloog_domain_polyhedron(doms
[i
]);
573 /* time is an array of (nb_doms) integers to store logical time values. We
574 * do not use it, but it is compulsory for PolyhedronTSort.
576 time
= (int *)malloc(nb_doms
* sizeof(int));
578 /* PolyhedronTSort will fill up permut (and time). */
579 PolyhedronTSort(pols
, nb_doms
, level
, nb_par
, time
, permut
, MAX_RAYS
);
587 * cloog_domain_empty function:
588 * This function allocates the memory space for a CloogDomain structure and
589 * sets its polyhedron to an empty polyhedron with the same dimensions
591 * Then it returns a pointer to the allocated space.
592 * - June 10th 2005: first version.
594 CloogDomain
* cloog_domain_empty(CloogDomain
*template)
596 unsigned dim
= cloog_domain_dimension(template) + template->nb_par
;
597 return cloog_domain_from_polylib_polyhedron(template->state
,
598 Empty_Polyhedron(dim
), template->nb_par
);
602 /******************************************************************************
603 * Structure display function *
604 ******************************************************************************/
607 static void print_structure_prefix(FILE *file
, int level
)
611 for(i
= 0; i
< level
; i
++)
612 fprintf(file
, "|\t");
617 * cloog_domain_print_structure :
618 * this function is a more human-friendly way to display the CloogDomain data
619 * structure, it only shows the constraint system and includes an indentation
620 * level (level) in order to work with others print_structure functions.
621 * Written by Olivier Chorier, Luc Marchaud, Pierre Martin and Romain Tartiere.
622 * - April 24th 2005: Initial version.
623 * - May 26th 2005: Memory leak hunt.
624 * - June 16th 2005: (Ced) Integration in domain.c.
626 void cloog_domain_print_structure(FILE *file
, CloogDomain
*domain
, int level
,
632 print_structure_prefix(file
, level
);
635 { fprintf(file
,"+-- %s\n", name
);
637 /* Print the matrix. */
638 for (P
= domain
->polyhedron
; P
; P
= P
->next
) {
639 matrix
= Polyhedron2Constraints(P
);
640 cloog_matrix_print_structure(file
, matrix
, level
);
641 cloog_matrix_free(matrix
);
644 print_structure_prefix(file
, level
+1);
649 fprintf(file
,"+-- Null CloogDomain\n") ;
655 * cloog_scattering_list_print function:
656 * This function prints the content of a CloogScatteringList structure into a
657 * file (foo, possibly stdout).
658 * - November 6th 2001: first version.
660 void cloog_scattering_list_print(FILE * foo
, CloogScatteringList
* list
)
661 { while (list
!= NULL
)
662 { cloog_domain_print(foo
, &list
->scatt
->dom
);
668 /******************************************************************************
669 * Memory deallocation function *
670 ******************************************************************************/
674 * cloog_scattering_list_free function:
675 * This function frees the allocated memory for a CloogScatteringList structure.
676 * - November 6th 2001: first version.
678 void cloog_scattering_list_free(CloogScatteringList
* list
)
679 { CloogScatteringList
* temp
;
682 { temp
= list
->next
;
683 cloog_scattering_free(list
->scatt
);
690 /******************************************************************************
692 ******************************************************************************/
696 * cloog_domain_read function:
697 * Adaptation from the PolyLib. This function reads a matrix into a file (foo,
698 * posibly stdin) and returns a pointer to a polyhedron containing the read
700 * - October 18th 2001: first version.
702 CloogDomain
*cloog_domain_read(CloogState
*state
, FILE *foo
, int nb_parameters
)
704 CloogDomain
* domain
;
706 matrix
= cloog_matrix_read(foo
) ;
707 domain
= cloog_domain_matrix2domain(state
, matrix
, nb_parameters
);
708 cloog_matrix_free(matrix
) ;
715 * cloog_domain_read_context:
716 * Read parameter domain. For the PolyLib backend, a parameter domain
717 * is indistinguishable from a parametric domain.
719 CloogDomain
*cloog_domain_read_context(CloogState
*state
, FILE * foo
)
721 CloogDomain
*context
= cloog_domain_read(state
, foo
, 0);
722 context
->nb_par
= context
->polyhedron
->Dimension
;
728 * cloog_domain_from_context
729 * Reinterpret context by turning parameters into variables.
731 CloogDomain
*cloog_domain_from_context(CloogDomain
*context
)
734 domain
= cloog_domain_duplicate(context
);
735 cloog_domain_free(context
);
742 * cloog_domain_union_read function:
743 * This function reads a union of polyhedra into a file (foo, posibly stdin) and
744 * returns a pointer to a Polyhedron containing the read information.
745 * - September 9th 2002: first version.
746 * - October 29th 2005: (debug) removal of a leak counting "correction" that
747 * was just false since ages.
749 CloogDomain
*cloog_domain_union_read(CloogState
*state
,
750 FILE *foo
, int nb_parameters
)
751 { int i
, nb_components
;
753 CloogDomain
* domain
, * temp
, * old
;
755 /* domain reading: nb_components (constraint matrices). */
756 while (fgets(s
,MAX_STRING
,foo
) == 0) ;
757 while ((*s
=='#' || *s
=='\n') || (sscanf(s
," %d",&nb_components
)<1))
758 fgets(s
,MAX_STRING
,foo
) ;
760 if (nb_components
> 0)
761 { /* 1. first part of the polyhedra union, */
762 domain
= cloog_domain_read(state
, foo
, nb_parameters
);
763 /* 2. and the nexts. */
764 for (i
=1;i
<nb_components
;i
++)
765 { /* Leak counting is OK since next allocated domain is freed here. */
766 temp
= cloog_domain_read(state
, foo
, nb_parameters
);
768 domain
= cloog_domain_union(temp
,old
) ;
769 cloog_domain_free(temp
) ;
770 cloog_domain_free(old
) ;
780 * cloog_domain_read_scattering function:
781 * This function reads in a scattering function fro the file foo.
783 CloogScattering
*cloog_domain_read_scattering(CloogDomain
*domain
, FILE *foo
)
785 return (CloogScattering
*)
786 cloog_domain_read(domain
->state
, foo
, domain
->nb_par
);
790 /******************************************************************************
791 * Processing functions *
792 ******************************************************************************/
796 * cloog_domain_malloc function:
797 * This function allocates the memory space for a CloogDomain structure and
798 * sets its fields with default values. Then it returns a pointer to the
800 * - November 21th 2005: first version.
802 CloogDomain
*cloog_domain_malloc(CloogState
*state
)
803 { CloogDomain
* domain
;
805 domain
= (CloogDomain
*)malloc(sizeof(CloogDomain
)) ;
807 cloog_die("memory overflow.\n");
808 cloog_domain_leak_up(state
);
810 /* We set the various fields with default values. */
811 domain
->state
= state
;
812 domain
->polyhedron
= NULL
;
813 domain
->references
= 1 ;
820 * cloog_domain_from_polylib_polyhedron function:
821 * This function allocates the memory space for a CloogDomain structure and
822 * sets its fields with those given as input. Then it returns a pointer to the
824 * - April 19th 2005: first version.
825 * - November 21th 2005: cloog_domain_malloc use.
827 CloogDomain
*cloog_domain_from_polylib_polyhedron(CloogState
*state
,
828 Polyhedron
*polyhedron
, int nb_par
)
829 { CloogDomain
* domain
;
831 if (polyhedron
== NULL
)
834 domain
= cloog_domain_malloc(state
);
835 domain
->polyhedron
= polyhedron
;
836 domain
->nb_par
= nb_par
;
844 * cloog_scattering_from_polylib_polyhedron function:
845 * This function allocates the memory space for a CloogDomain structure and
846 * sets its fields with those given as input. Then it returns a pointer to the
848 * - April 19th 2005: first version.
849 * - November 21th 2005: cloog_domain_malloc use.
851 CloogScattering
*cloog_scattering_from_polylib_polyhedron(CloogState
*state
,
852 Polyhedron
*polyhedron
, int nb_par
)
854 return (CloogScattering
*)
855 cloog_domain_from_polylib_polyhedron(state
, polyhedron
, nb_par
);
860 * cloog_domain_isempty function:
861 * This function returns 1 if the polyhedron given as input is empty, 0
863 * - October 28th 2001: first version.
865 int cloog_domain_isempty(CloogDomain
* domain
)
866 { if (!domain
|| domain
->polyhedron
== NULL
)
869 if (domain
->polyhedron
->next
)
871 return((domain
->polyhedron
->Dimension
< domain
->polyhedron
->NbEq
) ? 1 : 0) ;
876 * cloog_domain_universe function:
877 * This function returns the complete dim-dimensional space.
879 CloogDomain
*cloog_domain_universe(CloogState
*state
, unsigned dim
)
881 return cloog_domain_from_polylib_polyhedron(state
, Universe_Polyhedron(dim
), 0);
886 * cloog_domain_project function:
887 * From Quillere's LoopGen 0.4. This function returns the projection of
888 * (domain) on the (level) first dimensions (i.e. outer loops). It returns a
889 * pointer to the projected Polyhedron.
891 * - October 27th 2001: first version.
892 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
895 CloogDomain
*cloog_domain_project(CloogDomain
*domain
, int level
)
896 { int row
, column
, nb_rows
, nb_columns
, difference
;
897 CloogDomain
* projected_domain
;
900 nb_rows
= level
+ domain
->nb_par
+ 1 ;
901 nb_columns
= domain
->polyhedron
->Dimension
+ 1 ;
902 difference
= nb_columns
- nb_rows
;
905 return(cloog_domain_copy(domain
)) ;
907 matrix
= cloog_matrix_alloc(nb_rows
,nb_columns
) ;
909 for (row
=0;row
<level
;row
++)
910 for (column
=0;column
<nb_columns
; column
++)
911 value_set_si(matrix
->p
[row
][column
],(row
== column
? 1 : 0)) ;
913 for (;row
<nb_rows
;row
++)
914 for (column
=0;column
<nb_columns
;column
++)
915 value_set_si(matrix
->p
[row
][column
],(row
+difference
== column
? 1 : 0)) ;
917 projected_domain
= cloog_domain_image(domain
,matrix
) ;
918 cloog_matrix_free(matrix
) ;
920 return(projected_domain
) ;
925 * cloog_domain_bounds:
926 * Given a list (union) of polyhedra "domain", this function returns a single
927 * polyhedron with constraints that reflect the (parametric) lower and
928 * upper bound on dimension "dim".
930 CloogDomain
*cloog_domain_bounds(CloogDomain
*domain
, int dim
)
932 int row
, nb_rows
, nb_columns
, difference
;
933 CloogDomain
* projected_domain
, *extended_domain
, *bounds
;
936 nb_rows
= 1 + domain
->nb_par
+ 1;
937 nb_columns
= domain
->polyhedron
->Dimension
+ 1 ;
938 difference
= nb_columns
- nb_rows
;
941 return(cloog_domain_convex(domain
));
943 matrix
= cloog_matrix_alloc(nb_rows
, nb_columns
);
945 value_set_si(matrix
->p
[0][dim
], 1);
946 for (row
= 1; row
< nb_rows
; row
++)
947 value_set_si(matrix
->p
[row
][row
+difference
], 1);
949 projected_domain
= cloog_domain_image(domain
,matrix
) ;
950 extended_domain
= cloog_domain_preimage(projected_domain
, matrix
);
951 cloog_domain_free(projected_domain
);
952 cloog_matrix_free(matrix
) ;
953 bounds
= cloog_domain_convex(extended_domain
);
954 cloog_domain_free(extended_domain
);
961 * cloog_domain_extend function:
962 * From Quillere's LoopGen 0.4. This function returns the (domain) given as
963 * input with (dim)+(nb_par) dimensions. The new dimensions are added before
964 * the (nb_par) parameters. This function does not free (domain), and returns
967 * - October 27th 2001: first version.
968 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
971 CloogDomain
*cloog_domain_extend(CloogDomain
*domain
, int dim
)
972 { int row
, column
, nb_rows
, nb_columns
, difference
;
973 CloogDomain
* extended_domain
;
976 nb_rows
= 1 + domain
->polyhedron
->Dimension
;
977 nb_columns
= dim
+ domain
->nb_par
+ 1 ;
978 difference
= nb_columns
- nb_rows
;
981 return(cloog_domain_copy(domain
)) ;
983 matrix
= cloog_matrix_alloc(nb_rows
,nb_columns
) ;
985 for (row
= 0; row
< domain
->polyhedron
->Dimension
- domain
->nb_par
; row
++)
986 for (column
=0;column
<nb_columns
;column
++)
987 value_set_si(matrix
->p
[row
][column
],(row
== column
? 1 : 0)) ;
989 for (;row
<=domain
->polyhedron
->Dimension
;row
++)
990 for (column
=0;column
<nb_columns
;column
++)
991 value_set_si(matrix
->p
[row
][column
],(row
+difference
== column
? 1 : 0)) ;
993 extended_domain
= cloog_domain_preimage(domain
,matrix
) ;
994 cloog_matrix_free(matrix
) ;
996 return(extended_domain
) ;
1001 * cloog_domain_never_integral function:
1002 * For us, an equality like 3*i -4 = 0 is always false since 4%3 != 0. This
1003 * function returns a boolean set to 1 if there is this kind of 'never true'
1004 * constraint inside a polyhedron, 0 otherwise.
1005 * - domain is the polyhedron to check,
1007 * - November 28th 2001: first version.
1008 * - June 26th 2003: for iterators, more 'never true' constraints are found
1009 * (compare cholesky2 and vivien with a previous version),
1010 * checking for the parameters created (compare using vivien).
1011 * - June 28th 2003: Previously in loop.c and called
1012 * cloog_loop_simplify_nevertrue, now here !
1013 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1015 * - October 14th 2005: Complete rewriting, not faster but code quite shorter.
1017 int cloog_domain_never_integral(CloogDomain
* domain
)
1018 { int i
, dimension
;
1020 Polyhedron
* polyhedron
;
1022 if ((domain
== NULL
) || (domain
->polyhedron
== NULL
))
1027 polyhedron
= domain
->polyhedron
;
1028 dimension
= polyhedron
->Dimension
+ 2 ;
1030 /* For each constraint... */
1031 for (i
=0; i
<polyhedron
->NbConstraints
; i
++)
1032 { /* If we have an equality and the scalar part is not zero... */
1033 if (value_zero_p(polyhedron
->Constraint
[i
][0]) &&
1034 value_notzero_p(polyhedron
->Constraint
[i
][dimension
-1]))
1035 { /* Then we check whether the scalar can be divided by the gcd of the
1036 * unknown vector (including iterators and parameters) or not. If not,
1037 * there is no integer point in the polyhedron and we return 1.
1039 Vector_Gcd(&(polyhedron
->Constraint
[i
][1]),dimension
-2,&gcd
) ;
1040 value_modulus(modulo
,polyhedron
->Constraint
[i
][dimension
-1],gcd
) ;
1042 if (value_notzero_p(modulo
)) {
1044 value_clear(modulo
);
1051 value_clear(modulo
);
1057 * cloog_domain_stride function:
1058 * This function finds the stride imposed to unknown with the column number
1059 * 'strided_level' in order to be integral. For instance, if we have a
1060 * constraint like -i - 2j + 2k = 0, and we consider k, then k can be integral
1061 * only if (i + 2j)%2 = 0. Then only if i%2 = 0. Then k imposes a stride 2 to
1062 * the unknown i. The function returns the imposed stride in a parameter field.
1063 * - domain is the set of constraint we have to consider,
1064 * - strided_level is the column number of the unknown for which a stride have
1066 * - looking_level is the column number of the unknown that impose a stride to
1067 * the first unknown.
1068 * - stride is the stride that is returned back as a function parameter.
1069 * - offset is the value of the constant c if the condition is of the shape
1070 * (i + c)%s = 0, s being the stride.
1072 * - June 28th 2003: first version.
1073 * - July 14th 2003: can now look for multiple striding constraints and returns
1074 * the GCD of the strides and the common offset.
1075 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1078 void cloog_domain_stride(CloogDomain
*domain
, int strided_level
,
1079 Value
*stride
, Value
*offset
)
1081 Polyhedron
* polyhedron
;
1082 int n_col
, n_row
, rank
;
1087 polyhedron
= domain
->polyhedron
;
1088 dimension
= polyhedron
->Dimension
;
1090 /* Look at all equalities involving strided_level and the inner
1091 * iterators. We can ignore the outer iterators and the parameters
1092 * here because the lower bound on strided_level is assumed to
1095 n_col
= (1+dimension
-domain
->nb_par
) - strided_level
;
1096 for (i
=0, n_row
=0; i
< polyhedron
->NbEq
; i
++)
1097 if (First_Non_Zero(polyhedron
->Constraint
[i
]+strided_level
, n_col
) != -1)
1100 M
= cloog_matrix_alloc(n_row
+1, n_col
+1);
1101 for (i
=0, n_row
= 0; i
< polyhedron
->NbEq
; i
++) {
1102 if (First_Non_Zero(polyhedron
->Constraint
[i
]+strided_level
, n_col
) == -1)
1104 Vector_Copy(polyhedron
->Constraint
[i
]+strided_level
, M
->p
[n_row
], n_col
);
1105 value_assign(M
->p
[n_row
][n_col
], polyhedron
->Constraint
[i
][1+dimension
]);
1108 value_set_si(M
->p
[n_row
][n_col
], 1);
1110 /* Then look at the general solution to the above equalities. */
1111 rank
= SolveDiophantine(M
, &U
, &V
);
1112 cloog_matrix_free(M
);
1115 /* There is no solution, so the body of this loop will
1116 * never execute. We just leave the constraints alone here so
1117 * that they will ensure the body will not be executed.
1118 * We should probably propagate this information up so that
1119 * the loop can be removed entirely.
1121 value_set_si(*offset
, 0);
1122 value_set_si(*stride
, 1);
1124 value_oppose(*offset
, V
->p
[0]);
1125 /* If rank == M->NbRows, i.e., if there is a unique fixed solution,
1126 * then SolveDiophantine will return a 0x0 U matrix.
1127 * In this case, v = 0 * x + v, so we set stride to 0.
1130 value_set_si(*stride
, 0);
1132 /* Compute the gcd of the coefficients defining strided_level. */
1133 Vector_Gcd(U
->p
[0], U
->NbColumns
, stride
);
1134 value_pmodulus(*offset
, *offset
, *stride
);
1145 * cloog_domain_integral_lowerbound function:
1146 * This function returns 1 if the lower bound of an iterator (such as its
1147 * column rank in the constraint set 'domain' is 'level') is integral,
1148 * 0 otherwise. If the lower bound is actually integral, the function fills
1149 * the 'lower' field with the lower bound value.
1150 * - June 29th 2003: first version.
1151 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1154 int cloog_domain_integral_lowerbound(domain
, level
, lower
)
1155 CloogDomain
* domain
;
1158 { int i
, first_lower
=1, dimension
, lower_constraint
=-1 ;
1159 Value iterator
, constant
, tmp
;
1160 Polyhedron
* polyhedron
;
1162 polyhedron
= domain
->polyhedron
;
1163 dimension
= polyhedron
->Dimension
;
1165 /* We want one and only one lower bound (e.g. no equality, no maximum
1168 for (i
=0; i
<polyhedron
->NbConstraints
; i
++)
1169 if (value_zero_p(polyhedron
->Constraint
[i
][0]) &&
1170 value_notzero_p(polyhedron
->Constraint
[i
][level
]))
1173 for (i
=0; i
<polyhedron
->NbConstraints
; i
++)
1174 if (value_pos_p(polyhedron
->Constraint
[i
][level
]))
1177 lower_constraint
= i
;
1185 /* We want an integral lower bound: no other non-zero entry except the
1186 * iterator coefficient and the constant.
1188 for (i
=1; i
<level
; i
++)
1189 if (value_notzero_p(polyhedron
->Constraint
[lower_constraint
][i
]))
1191 for (i
=level
+1; i
<=polyhedron
->Dimension
; i
++)
1192 if (value_notzero_p(polyhedron
->Constraint
[lower_constraint
][i
]))
1195 value_init(iterator
);
1196 value_init(constant
);
1199 /* If all is passed, then find the lower bound and return 1. */
1200 value_assign(iterator
, polyhedron
->Constraint
[lower_constraint
][level
]) ;
1201 value_oppose(constant
, polyhedron
->Constraint
[lower_constraint
][dimension
+1]);
1203 value_modulus(tmp
, constant
, iterator
) ;
1204 value_division(*lower
, constant
, iterator
) ;
1206 if (!(value_zero_p(tmp
) || value_neg_p(constant
)))
1207 value_increment(*lower
, *lower
) ;
1209 value_clear(iterator
);
1210 value_clear(constant
);
1218 * cloog_domain_lowerbound_update function:
1219 * This function updates the integral lower bound of an iterator (such as its
1220 * column rank in the constraint set 'domain' is 'level') into 'lower'
1221 * and returns the updated domain.
1222 * - Jun 29th 2003: first version.
1223 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1226 CloogDomain
*cloog_domain_lowerbound_update(CloogDomain
*domain
, int level
,
1229 Polyhedron
* polyhedron
;
1231 polyhedron
= domain
->polyhedron
;
1233 /* There is only one lower bound, the first one is the good one. */
1234 for (i
=0; i
<polyhedron
->NbConstraints
; i
++)
1235 if (value_pos_p(polyhedron
->Constraint
[i
][level
]))
1236 { value_set_si(polyhedron
->Constraint
[i
][level
], 1) ;
1237 value_oppose(polyhedron
->Constraint
[i
][polyhedron
->Dimension
+1], lower
) ;
1245 * cloog_domain_lazy_equal function:
1246 * This function returns 1 if the domains given as input are the same, 0 if it
1247 * is unable to decide. This function makes an entry-to-entry comparison between
1248 * the constraint systems, if all the entries are the same, the domains are
1249 * obviously the same and it returns 1, at the first difference, it returns 0.
1250 * This is a very fast way to verify this property. It has been shown (with the
1251 * CLooG benchmarks) that operations on equal domains are 17% of all the
1252 * polyhedral computations. For 75% of the actually identical domains, this
1253 * function answer that they are the same and allow to give immediately the
1254 * trivial solution instead of calling the heavy general functions of PolyLib.
1255 * - August 22th 2003: first version.
1256 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1259 int cloog_domain_lazy_equal(CloogDomain
* d1
, CloogDomain
* d2
)
1260 { int i
, nb_elements
;
1261 Polyhedron
* p1
, * p2
;
1263 p1
= d1
->polyhedron
;
1264 p2
= d2
->polyhedron
;
1266 while ((p1
!= NULL
) && (p2
!= NULL
))
1267 { if ((p1
->NbConstraints
!= p2
->NbConstraints
) ||
1268 (p1
->Dimension
!= p2
->Dimension
))
1271 nb_elements
= p1
->NbConstraints
* (p1
->Dimension
+ 2) ;
1273 for (i
=0;i
<nb_elements
;i
++)
1274 if (value_ne(p1
->p_Init
[i
], p2
->p_Init
[i
]))
1281 if ((p1
!= NULL
) || (p2
!= NULL
))
1289 * cloog_scattering_lazy_block function:
1290 * This function returns 1 if the two domains d1 and d2 given as input are the
1291 * same (possibly except for a dimension equal to a constant where we accept
1292 * a difference of 1) AND if we are sure that there are no other domain in
1293 * the code generation problem that may put integral points between those of
1294 * d1 and d2 (0 otherwise). In fact this function answers the question "can I
1295 * safely consider the two domains as only one with two statements (a block) ?".
1296 * The original implementation had a problem and has therefore been
1297 * (temporarily) replaced by the safest possible implementation: always
1298 * assume that we cannot block the two statements.
1299 * - d1 and d2 are the two domains to check for blocking,
1300 * - scattering is the linked list of all domains,
1301 * - scattdims is the total number of scattering dimentions.
1303 int cloog_scattering_lazy_block(CloogScattering
*d1
, CloogScattering
*d2
,
1304 CloogScatteringList
*scattering
, int scattdims
)
1311 * cloog_domain_lazy_disjoint function:
1312 * This function returns 1 if the domains given as input are disjoint, 0 if it
1313 * is unable to decide. This function finds the unknown with fixed values in
1314 * both domains (on a given constraint, their column entry is not zero and
1315 * only the constant coefficient can be different from zero) and verify that
1316 * their values are the same. If not, the domains are obviously disjoint and
1317 * it returns 1, if there is not such case it returns 0. This is a very fast
1318 * way to verify this property. It has been shown (with the CLooG benchmarks)
1319 * that operations on disjoint domains are 36% of all the polyhedral
1320 * computations. For 94% of the actually identical domains, this
1321 * function answer that they are disjoint and allow to give immediately the
1322 * trivial solution instead of calling the heavy general functions of PolyLib.
1323 * - August 22th 2003: first version.
1324 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1327 int cloog_domain_lazy_disjoint(CloogDomain
* d1
, CloogDomain
* d2
)
1328 { int i1
, j1
, i2
, j2
, scat_dim
;
1330 Polyhedron
* p1
, * p2
;
1332 p1
= d1
->polyhedron
;
1333 p2
= d2
->polyhedron
;
1335 if ((p1
->next
!= NULL
) || (p2
->next
!= NULL
))
1338 value_init(scat_val
);
1340 for (i1
=0; i1
<p1
->NbConstraints
; i1
++)
1341 { if (value_notzero_p(p1
->Constraint
[i1
][0]))
1345 while (value_zero_p(p1
->Constraint
[i1
][scat_dim
]) &&
1346 (scat_dim
< p1
->Dimension
))
1349 if (value_notone_p(p1
->Constraint
[i1
][scat_dim
]))
1352 { for (j1
=scat_dim
+1; j1
<=p1
->Dimension
; j1
++)
1353 if (value_notzero_p(p1
->Constraint
[i1
][j1
]))
1356 if (j1
!= p1
->Dimension
+1)
1359 value_assign(scat_val
,p1
->Constraint
[i1
][p1
->Dimension
+1]) ;
1361 for (i2
=0; i2
<p2
->NbConstraints
; i2
++)
1362 { for (j2
=0;j2
<scat_dim
;j2
++)
1363 if (value_notzero_p(p2
->Constraint
[i2
][j2
]))
1366 if ((j2
!= scat_dim
) || value_notone_p(p2
->Constraint
[i2
][scat_dim
]))
1369 for (j2
=scat_dim
+1; j2
<=p2
->Dimension
; j2
++)
1370 if (value_notzero_p(p2
->Constraint
[i2
][j2
]))
1373 if (j2
!= p2
->Dimension
+1)
1376 if (value_ne(p2
->Constraint
[i2
][p2
->Dimension
+1],scat_val
)) {
1377 value_clear(scat_val
);
1384 value_clear(scat_val
);
1390 * cloog_scattering_list_lazy_same function:
1391 * This function returns 1 if two domains in the list are the same, 0 if it
1392 * is unable to decide.
1393 * - February 9th 2004: first version.
1395 int cloog_scattering_list_lazy_same(CloogScatteringList
* list
)
1396 { /*int i=1, j=1 ;*/
1397 CloogScatteringList
* current
, * next
;
1400 while (current
!= NULL
)
1401 { next
= current
->next
;
1403 while (next
!= NULL
) {
1404 if (cloog_domain_lazy_equal(¤t
->scatt
->dom
, &next
->scatt
->dom
))
1405 { /*printf("Same domains: %d and %d\n",i,j) ;*/
1412 current
= current
->next
;
1420 * Those functions are provided for "object encapsulation", to separate as much
1421 * as possible the inside of the CloogDomain structure from the rest of the
1422 * program, in order to ease the change of polyhedral library. For efficiency
1423 * reasons, they are defined and used as macros in domain.h.
1424 * - April 20th 2005: setting.
1426 Polyhedron * cloog_domain_polyhedron(CloogDomain * domain)
1427 { return domain->polyhedron ;
1430 int cloog_domain_nbconstraints(CloogDomain * domain)
1431 { return domain->polyhedron->NbConstraints ;
1435 int cloog_domain_dimension(CloogDomain
* domain
)
1437 return domain
->polyhedron
->Dimension
- domain
->nb_par
;
1440 int cloog_domain_parameter_dimension(CloogDomain
*domain
)
1442 return domain
->nb_par
;
1445 int cloog_scattering_dimension(CloogScattering
*scatt
, CloogDomain
*domain
)
1447 return cloog_domain_dimension(&scatt
->dom
) - cloog_domain_dimension(domain
);
1450 int cloog_domain_isconvex(CloogDomain
* domain
)
1451 { return (domain
->polyhedron
->next
== NULL
)? 1 : 0 ;
1456 * cloog_domain_cut_first function:
1457 * This function splits off and returns the first convex set in the
1458 * union "domain". The remainder of the union is returned in rest.
1459 * The original "domain" itself is destroyed and may not be used
1460 * after a call to this function.
1462 CloogDomain
*cloog_domain_cut_first(CloogDomain
*domain
, CloogDomain
**rest
)
1464 if (!domain
|| !domain
->polyhedron
|| cloog_domain_isconvex(domain
)) {
1469 if (domain
->references
== 1) {
1470 *rest
= cloog_domain_from_polylib_polyhedron(domain
->state
,
1471 domain
->polyhedron
->next
, domain
->nb_par
);
1472 domain
->polyhedron
->next
= NULL
;
1476 cloog_domain_free(domain
);
1477 *rest
= cloog_domain_from_polylib_polyhedron(domain
->state
, Domain_Copy(domain
->polyhedron
->next
),
1479 return cloog_domain_from_polylib_polyhedron(domain
->state
,
1480 Polyhedron_Copy(domain
->polyhedron
), domain
->nb_par
);
1485 * Given a union domain, try to find a simpler representation
1486 * using fewer sets in the union.
1487 * Since PolyLib does not have a proper implementation for this
1488 * functionality, we compute
1489 * convex(domain) \ (convex(domain) \ domain)
1490 * which usually approximates what we want.
1491 * The original "domain" itself is destroyed and may not be used
1492 * after a call to this function.
1494 CloogDomain
*cloog_domain_simplify_union(CloogDomain
*domain
)
1496 CloogDomain
*convex
, *temp
;
1498 convex
= cloog_domain_convex(domain
);
1499 temp
= cloog_domain_difference(convex
, domain
);
1500 cloog_domain_free(domain
);
1501 domain
= cloog_domain_difference(convex
, temp
);
1502 cloog_domain_free(convex
);
1503 cloog_domain_free(temp
);
1509 static int polyhedron_lazy_isconstant(Polyhedron
*polyhedron
, int dimension
,
1514 /* For each constraint... */
1515 for (i
=0;i
<polyhedron
->NbConstraints
;i
++)
1516 { /* ...if it is concerned by the potentially scalar dimension... */
1517 if (value_notzero_p(polyhedron
->Constraint
[i
][dimension
+1]))
1518 { /* ...check that the constraint has the shape "dimension + scalar = 0". */
1519 for (j
=0;j
<=dimension
;j
++)
1520 if (value_notzero_p(polyhedron
->Constraint
[i
][j
]))
1523 if (value_notone_p(polyhedron
->Constraint
[i
][dimension
+1]))
1526 for (j
=dimension
+2;j
<(polyhedron
->Dimension
+ 1);j
++)
1527 if (value_notzero_p(polyhedron
->Constraint
[i
][j
]))
1531 value_assign(*value
,polyhedron
->Constraint
[i
][polyhedron
->Dimension
+1]);
1532 value_oppose(*value
,*value
);
1543 * cloog_scattering_lazy_isscalar function:
1544 * this function returns 1 if the dimension 'dimension' in the domain 'domain'
1545 * is scalar, this means that the only constraint on this dimension must have
1546 * the shape "x.dimension + scalar = 0" with x an integral variable. This
1547 * function is lazy since we only accept x=1 (further calculations are easier
1549 * If value is not NULL, then it is set to the constant value of dimension.
1550 * - June 14th 2005: first version.
1551 * - June 21rd 2005: Adaptation for GMP.
1553 int cloog_scattering_lazy_isscalar(CloogScattering
*domain
, int dimension
,
1556 return polyhedron_lazy_isconstant(domain
->dom
.polyhedron
, dimension
, value
);
1561 * cloog_domain_lazy_isconstant function:
1562 * this function returns 1 if the dimension 'dimension' in the
1563 * domain 'domain' is constant.
1564 * If value is not NULL, then it is set to the constant value of dimension.
1566 int cloog_domain_lazy_isconstant(CloogDomain
*domain
, int dimension
)
1568 return polyhedron_lazy_isconstant(domain
->polyhedron
, dimension
, NULL
);
1573 * cloog_scattering_erase_dimension function:
1574 * this function returns a CloogDomain structure builds from 'domain' where
1575 * we removed the dimension 'dimension' and every constraint considering this
1576 * dimension. This is not a projection ! Every data concerning the
1577 * considered dimension is simply erased.
1578 * - June 14th 2005: first version.
1579 * - June 21rd 2005: Adaptation for GMP.
1581 CloogScattering
*cloog_scattering_erase_dimension(CloogScattering
*scatt
,
1583 { int i
, j
, mi
, nb_dim
;
1585 CloogDomain
* erased
;
1586 Polyhedron
* polyhedron
;
1587 CloogDomain
*domain
;
1589 domain
= &scatt
->dom
;
1590 polyhedron
= domain
->polyhedron
;
1591 nb_dim
= polyhedron
->Dimension
;
1593 /* The matrix is one column less and at least one constraint less. */
1594 matrix
= cloog_matrix_alloc(polyhedron
->NbConstraints
-1,nb_dim
+1) ;
1596 /* mi is the constraint counter for the matrix. */
1598 for (i
=0;i
<polyhedron
->NbConstraints
;i
++)
1599 if (value_zero_p(polyhedron
->Constraint
[i
][dimension
+1]))
1600 { for (j
=0;j
<=dimension
;j
++)
1601 value_assign(matrix
->p
[mi
][j
],polyhedron
->Constraint
[i
][j
]) ;
1603 for (j
=dimension
+2;j
<nb_dim
+2;j
++)
1604 value_assign(matrix
->p
[mi
][j
-1],polyhedron
->Constraint
[i
][j
]) ;
1609 erased
= cloog_domain_matrix2domain(domain
->state
, matrix
, domain
->nb_par
);
1610 cloog_matrix_free(matrix
) ;
1612 return (CloogScattering
*)erased
;
1617 * cloog_domain_cube:
1618 * Construct and return a dim-dimensional cube, with values ranging
1619 * between min and max in each dimension.
1621 CloogDomain
*cloog_domain_cube(CloogState
*state
,
1622 int dim
, cloog_int_t min
, cloog_int_t max
)
1628 M
= Matrix_Alloc(2*dim
, 2+dim
);
1629 for (i
= 0; i
< dim
; ++i
) {
1630 value_set_si(M
->p
[2*i
][0], 1);
1631 value_set_si(M
->p
[2*i
][1+i
], 1);
1632 value_oppose(M
->p
[2*i
][1+dim
], min
);
1633 value_set_si(M
->p
[2*i
+1][0], 1);
1634 value_set_si(M
->p
[2*i
+1][1+i
], -1);
1635 value_assign(M
->p
[2*i
+1][1+dim
], max
);
1637 P
= Constraints2Polyhedron(M
, state
->backend
->MAX_RAYS
);
1639 return cloog_domain_from_polylib_polyhedron(state
, P
, 0);
1643 * cloog_domain_scatter function:
1644 * This function add the scattering (scheduling) informations in a domain.
1646 CloogDomain
*cloog_domain_scatter(CloogDomain
*domain
, CloogScattering
*scatt
)
1648 CloogDomain
*ext
, *newdom
, *newpart
, *temp
;
1651 scatt_dim
= cloog_scattering_dimension(scatt
, domain
);
1653 /* For each polyhedron of domain (it can be an union of polyhedra). */
1654 while (domain
!= NULL
)
1655 { /* Extend the domain by adding the scattering dimensions as the new
1656 * first domain dimensions.
1658 domain
->nb_par
= domain
->polyhedron
->Dimension
;
1659 ext
= cloog_domain_extend(domain
, scatt_dim
);
1660 ext
->nb_par
= domain
->nb_par
= scatt
->dom
.nb_par
;
1661 /* Then add the scattering constraints. */
1662 newpart
= cloog_domain_addconstraints(&scatt
->dom
, ext
);
1663 cloog_domain_free(ext
) ;
1667 newdom
= cloog_domain_union(newdom
,newpart
) ;
1668 cloog_domain_free(temp
) ;
1669 cloog_domain_free(newpart
) ;
1674 /* We don't want to free the rest of the list. */
1675 temp
= cloog_domain_cut_first(domain
, &domain
);
1676 cloog_domain_free(temp
) ;