Ported cloog_domain_project, but not enabled.
[cloog-ppl.git] / source / ppl / domain.c
blob519c191cac6ac744f81a6ad7887c6b1bc49baed1
2 /**-------------------------------------------------------------------**
3 ** CLooG **
4 **-------------------------------------------------------------------**
5 ** domain.c **
6 **-------------------------------------------------------------------**
7 ** First version: october 28th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
14 * *
15 * Copyright (C) 2001-2005 Cedric Bastoul *
16 * *
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 *
20 * version. *
21 * *
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 *
25 * for more details. *
26 * *
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 *
30 * *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
33 * *
34 ******************************************************************************/
35 /* CAUTION: the english used for comments is probably the worst you ever read,
36 * please feel free to correct and improve it !
39 # include <stdlib.h>
40 # include <stdio.h>
41 # include <ctype.h>
42 # include "../../include/cloog/cloog.h"
43 #include "matrix.h"
45 static int cloog_check_polyhedral_ops = 1;
46 static int cloog_return_ppl_result = 0;
47 static int cloog_print_debug = 0;
49 static CloogDomain *
50 print_result (char *s, CloogDomain *d)
52 if (cloog_print_debug)
54 fprintf (stderr, "%s \n", s);
55 debug_cloog_domain (d);
57 return d;
60 /* Variables names for pretty printing. */
61 static char wild_name[200][40];
63 static inline const char*
64 variable_output_function (ppl_dimension_type var)
66 if (var < 40)
67 return wild_name[var + 1];
68 else
69 return 0;
72 static inline void
73 error_handler (enum ppl_enum_error_code code, const char* description)
75 fprintf (stderr, "PPL error code %d\n%s", code, description);
76 exit (1);
79 void
80 cloog_initialize (void)
82 sprintf (wild_name[0], "1");
83 sprintf (wild_name[1], "a");
84 sprintf (wild_name[2], "b");
85 sprintf (wild_name[3], "c");
86 sprintf (wild_name[4], "d");
87 sprintf (wild_name[5], "e");
88 sprintf (wild_name[6], "f");
89 sprintf (wild_name[7], "g");
90 sprintf (wild_name[8], "h");
91 sprintf (wild_name[9], "i");
92 sprintf (wild_name[10], "j");
93 sprintf (wild_name[11], "k");
94 sprintf (wild_name[12], "l");
95 sprintf (wild_name[13], "m");
96 sprintf (wild_name[14], "n");
97 sprintf (wild_name[15], "o");
98 sprintf (wild_name[16], "p");
99 sprintf (wild_name[17], "q");
100 sprintf (wild_name[18], "r");
101 sprintf (wild_name[19], "s");
102 sprintf (wild_name[20], "t");
103 sprintf (wild_name[21], "alpha");
104 sprintf (wild_name[22], "beta");
105 sprintf (wild_name[23], "gamma");
106 sprintf (wild_name[24], "delta");
107 sprintf (wild_name[25], "tau");
108 sprintf (wild_name[26], "sigma");
109 sprintf (wild_name[27], "chi");
110 sprintf (wild_name[28], "omega");
111 sprintf (wild_name[29], "pi");
112 sprintf (wild_name[30], "ni");
113 sprintf (wild_name[31], "Alpha");
114 sprintf (wild_name[32], "Beta");
115 sprintf (wild_name[33], "Gamma");
116 sprintf (wild_name[34], "Delta");
117 sprintf (wild_name[35], "Tau");
118 sprintf (wild_name[36], "Sigma");
119 sprintf (wild_name[37], "Chi");
120 sprintf (wild_name[38], "Omega");
121 sprintf (wild_name[39], "xxx");
123 if (ppl_initialize() < 0)
125 fprintf (stderr, "Cannot initialize the Parma Polyhedra Library.\n");
126 exit (1);
129 if (ppl_set_error_handler (error_handler) < 0)
131 fprintf (stderr, "Cannot install the custom error handler.\n");
132 exit (1);
135 if (ppl_io_set_variable_output_function (variable_output_function) < 0)
137 fprintf (stderr, "Cannot install the PPL custom variable output function. \n");
138 exit (1);
142 static inline Polyhedron *
143 u2p (ppl_polyhedra_union * upol)
145 Polyhedron *res = Polyhedron_Copy (cloog_upol_polyhedron (upol));
146 Polyhedron *p = res;
148 while (upol)
150 ppl_polyhedra_union *next = cloog_upol_next (upol);
151 Polyhedron *n;
153 if (next)
154 n = Polyhedron_Copy (cloog_upol_polyhedron (next));
155 else
156 n = NULL;
158 p->next = n;
159 p = n;
160 upol = next;
163 return res;
166 static inline Polyhedron *
167 d2p (CloogDomain * d)
169 return u2p (cloog_domain_upol (d));
173 static inline ppl_polyhedra_union *
174 p2u (Polyhedron * p)
176 ppl_polyhedra_union *u = cloog_new_upol (p);
177 ppl_polyhedra_union *res = u;
179 while (p)
181 Polyhedron *next = p->next;
182 ppl_polyhedra_union *n;
184 if (next)
185 n = cloog_new_upol (next);
186 else
187 n = NULL;
189 cloog_upol_set_next (u, n);
190 u = n;
191 p->next = NULL;
192 p = next;
195 return res;
199 * The maximal number of rays allowed to be allocated by PolyLib. In fact since
200 * version 5.20, PolyLib automatically tune the number of rays by multiplying
201 * by 2 this number each time the maximum is reached. For unknown reasons
202 * PolyLib makes a segmentation fault if this number is too small. If this
203 * number is too small, performances will be reduced, if it is too high, memory
204 * will be saturated. Note that the option "-rays X" set this number to X.
206 int MAX_RAYS = 50;
208 /* Unused in this backend. */
210 int cloog_domain_allocated = 0;
211 int cloog_domain_freed = 0;
212 int cloog_domain_max = 0;
214 /* The same for Value variables since in GMP mode they have to be freed. */
215 int cloog_value_allocated = 0;
216 int cloog_value_freed = 0;
217 int cloog_value_max = 0;
220 void
221 cloog_value_leak_up ()
223 cloog_value_allocated++;
224 if ((cloog_value_allocated - cloog_value_freed) > cloog_value_max)
225 cloog_value_max = cloog_value_allocated - cloog_value_freed;
229 void
230 cloog_value_leak_down ()
232 cloog_value_freed++;
235 static inline void
236 cloog_domain_polyhedron_set (CloogDomain * d, ppl_polyhedra_union * p)
238 d->_polyhedron = p;
241 static inline void
242 cloog_domain_set_references (CloogDomain * d, int i)
244 d->_references = i;
247 static CloogDomain *
248 cloog_new_domain (ppl_polyhedra_union *p)
250 CloogDomain *domain = (CloogDomain *) malloc (sizeof (CloogDomain));
251 domain->_polyhedron = p;
252 cloog_domain_set_references (domain, 1);
253 return domain;
256 static CloogDomain *
257 cloog_domain_alloc (Polyhedron *p)
259 return print_result ("cloog_domain_alloc", cloog_new_domain (p2u (p)));
262 static inline CloogDomain *
263 cloog_check_domain_id (CloogDomain *dom)
265 return dom;
268 static inline CloogDomain *
269 cloog_check_domain (CloogDomain *dom)
271 if (!dom)
272 return dom;
274 /* FIXME: Remove this check. */
275 if (cloog_domain_polyhedron (dom)->next)
277 fprintf (stderr, "polyhedra of domains should be convex.\n");
278 exit (1);
281 return dom;
285 * cloog_domain_matrix2domain function:
286 * Given a matrix of constraints (matrix), this function constructs and returns
287 * the corresponding domain (i.e. the CloogDomain structure including the
288 * polyhedron with its double representation: constraint matrix and the set of
289 * rays).
291 static CloogDomain *
292 cloog_domain_matrix2domain (CloogMatrix * matrix)
294 return print_result ("cloog_domain_matrix2domain", cloog_check_domain (cloog_domain_alloc (Constraints2Polyhedron (matrix, MAX_RAYS))));
297 static inline CloogMatrix *
298 cloog_upol_domain2matrix (ppl_polyhedra_union * upol)
300 return Polyhedron2Constraints (cloog_upol_polyhedron (upol));
303 /* In the matrix representation an equality has a 0 in the first
304 column. When the value of the first column is 1, the row
305 represents an inequality. */
307 static inline int
308 cloog_matrix_row_is_eq_p (CloogMatrix *matrix, int row)
310 return value_zero_p (matrix->p[row][0]);
313 static ppl_Polyhedron_t
314 cloog_translate_constraint_matrix (CloogMatrix *matrix)
316 int i, j;
317 ppl_Polyhedron_t res;
318 ppl_Constraint_t cstr;
319 ppl_Linear_Expression_t expr;
320 ppl_Coefficient_t coef;
321 ppl_dimension_type dim = matrix->NbColumns - 2;
323 ppl_new_Coefficient (&coef);
324 ppl_new_NNC_Polyhedron_from_dimension (&res, dim);
326 for (i = 0; i < matrix->NbRows; i++)
328 ppl_new_Linear_Expression_with_dimension (&expr, dim);
330 for (j = 1; j < matrix->NbColumns - 1; j++)
332 ppl_assign_Coefficient_from_mpz_t (coef, matrix->p[i][j]);
333 ppl_Linear_Expression_add_to_coefficient (expr, j - 1, coef);
336 ppl_assign_Coefficient_from_mpz_t
337 (coef, matrix->p[i][matrix->NbColumns - 1]);
338 ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
340 if (cloog_matrix_row_is_eq_p (matrix, i))
341 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
342 else
343 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_THAN_OR_EQUAL);
345 ppl_Polyhedron_add_constraint (res, cstr);
348 if (cloog_check_polyhedral_ops)
349 ppl_Polyhedron_OK (res);
351 return res;
354 static CloogDomain *
355 cloog_translate_ppl_polyhedron (ppl_Polyhedron_t pol)
357 CloogDomain *res;
358 CloogMatrix *matrix ;
359 ppl_dimension_type dim;
360 ppl_const_Constraint_System_t pcs;
361 ppl_Constraint_System_const_iterator_t cit, end;
362 int row;
364 ppl_Polyhedron_constraints (pol, &pcs);
365 ppl_new_Constraint_System_const_iterator (&cit);
366 ppl_new_Constraint_System_const_iterator (&end);
368 for (row = 0, ppl_Constraint_System_begin (pcs, cit), ppl_Constraint_System_end (pcs, end);
369 !ppl_Constraint_System_const_iterator_equal_test (cit, end);
370 ppl_Constraint_System_const_iterator_increment (cit), row++);
372 ppl_Polyhedron_space_dimension (pol, &dim);
373 matrix = cloog_matrix_alloc (row, dim + 2);
375 for (row = 0, ppl_Constraint_System_begin (pcs, cit), ppl_Constraint_System_end (pcs, end);
376 !ppl_Constraint_System_const_iterator_equal_test (cit, end);
377 ppl_Constraint_System_const_iterator_increment (cit), row++)
379 ppl_const_Constraint_t pc;
380 ppl_Coefficient_t coef;
381 ppl_dimension_type col;
382 Value val;
383 int neg;
385 value_init (val);
386 ppl_new_Coefficient (&coef);
387 ppl_Constraint_System_const_iterator_dereference (cit, &pc);
389 neg = (ppl_Constraint_type (pc) == PPL_CONSTRAINT_TYPE_LESS_THAN
390 || ppl_Constraint_type (pc) == PPL_CONSTRAINT_TYPE_LESS_THAN_OR_EQUAL) ? 1 : 0;
392 for (col = 0; col < dim; col++)
394 ppl_Constraint_coefficient (pc, col, coef);
395 ppl_Coefficient_to_mpz_t (coef, val);
397 if (neg)
398 value_oppose (val, val);
400 value_assign (matrix->p[row][col+1], val);
403 ppl_Constraint_inhomogeneous_term (pc, coef);
404 ppl_Coefficient_to_mpz_t (coef, val);
405 value_assign (matrix->p[row][dim + 1], val);
407 switch (ppl_Constraint_type (pc))
409 case PPL_CONSTRAINT_TYPE_EQUAL:
410 value_set_si (matrix->p[row][0], 0);
411 break;
413 case PPL_CONSTRAINT_TYPE_LESS_THAN:
414 case PPL_CONSTRAINT_TYPE_GREATER_THAN:
415 value_decrement (matrix->p[row][dim + 1], matrix->p[row][dim + 1]);
416 value_set_si (matrix->p[row][0], 1);
417 break;
419 case PPL_CONSTRAINT_TYPE_LESS_THAN_OR_EQUAL:
420 case PPL_CONSTRAINT_TYPE_GREATER_THAN_OR_EQUAL:
421 value_set_si (matrix->p[row][0], 1);
422 break;
424 default:
425 fprintf (stderr, "PPL_CONSTRAINT_TYPE_%d not implemented yet\n",
426 ppl_Constraint_type (pc));
427 exit (1);
431 res = cloog_domain_matrix2domain (matrix);
432 return print_result ("cloog_translate_ppl_polyhedron", cloog_check_domain (res));
435 static inline int
436 cloog_domain_references (CloogDomain * d)
438 return d->_references;
442 * cloog_domain_print function:
443 * This function prints the content of a CloogDomain structure (domain) into
444 * a file (foo, possibly stdout).
446 void
447 cloog_domain_print (FILE * foo, CloogDomain * domain)
449 ppl_polyhedra_union *upol = cloog_domain_upol (domain);
451 while (upol)
453 Polyhedron_Print (foo, P_VALUE_FMT, cloog_upol_polyhedron (upol));
454 upol = cloog_upol_next (upol);
457 fprintf (foo, "Number of active references: %d\n",
458 cloog_domain_references (domain));
462 * cloog_domain_free function:
463 * This function frees the allocated memory for a CloogDomain structure
464 * (domain). It decrements the number of active references to this structure,
465 * if there are no more references on the structure, it frees it (with the
466 * included list of polyhedra).
468 void
469 cloog_domain_free (CloogDomain * domain)
471 if (domain)
473 cloog_domain_set_references (domain,
474 cloog_domain_references (domain) - 1);
476 if (cloog_domain_references (domain) == 0)
479 ppl_polyhedra_union *upol = cloog_domain_upol (domain);
481 while (upol)
483 Polyhedron_Free (cloog_upol_polyhedron (upol));
484 upol = cloog_upol_next (upol);
487 free (domain);
494 * cloog_domain_copy function:
495 * This function returns a copy of a CloogDomain structure (domain). To save
496 * memory this is not a memory copy but we increment a counter of active
497 * references inside the structure, then return a pointer to that structure.
499 CloogDomain *
500 cloog_domain_copy (CloogDomain * domain)
502 cloog_domain_set_references (domain, cloog_domain_references (domain) + 1);
503 return print_result ("cloog_domain_copy", domain);
508 * cloog_domain_image function:
509 * This function returns a CloogDomain structure such that the included
510 * polyhedral domain is computed from the former one into another
511 * domain according to a given affine mapping function (mapping).
513 static CloogDomain *
514 cloog_domain_image (CloogDomain * domain, CloogMatrix * mapping)
516 Polyhedron *p = d2p (domain);
517 CloogDomain *res =
518 cloog_check_domain (cloog_domain_alloc
519 (DomainImage (p, mapping, MAX_RAYS)));
520 Polyhedron_Free (p);
521 return print_result ("cloog_domain_image", res);
526 * cloog_domain_preimage function:
527 * Given a polyhedral domain (polyhedron) inside a CloogDomain structure and a
528 * mapping function (mapping), this function returns a new CloogDomain structure
529 * with a polyhedral domain which when transformed by mapping function (mapping)
530 * gives (polyhedron).
532 static CloogDomain *
533 cloog_domain_preimage (CloogDomain * domain, CloogMatrix * mapping)
535 Polyhedron *p = d2p (domain);
536 CloogDomain *res =
537 cloog_check_domain (cloog_domain_alloc
538 (DomainPreimage (p, mapping, MAX_RAYS)));
539 Polyhedron_Free (p);
540 return print_result ("cloog_domain_preimage", res);
545 * cloog_domain_convex function:
546 * Given a polyhedral domain (polyhedron), this function concatenates the lists
547 * of rays and lines of the two (or more) polyhedra in the domain into one
548 * combined list, and find the set of constraints which tightly bound all of
549 * those objects. It returns the corresponding polyhedron.
551 CloogDomain *
552 cloog_domain_convex (CloogDomain * domain)
554 Polyhedron *p = d2p (domain);
555 CloogDomain *res =
556 cloog_check_domain (cloog_domain_alloc
557 (DomainConvex (p, MAX_RAYS)));
558 Polyhedron_Free (p);
559 return print_result ("cloog_domain_convex", res);
562 static inline unsigned
563 cloog_upol_nbc (ppl_polyhedra_union * p)
565 return cloog_upol_polyhedron (p)->NbConstraints;
568 static inline int
569 cloog_domain_nbconstraints (CloogDomain * domain)
571 return cloog_domain_polyhedron (domain)->NbConstraints;
574 static inline unsigned
575 cloog_upol_nbeq (ppl_polyhedra_union * d)
577 return cloog_upol_polyhedron (d)->NbEq;
580 static inline unsigned
581 cloog_domain_nbeq (CloogDomain * d)
583 return cloog_domain_polyhedron (d)->NbEq;
586 static inline unsigned
587 cloog_upol_dim (ppl_polyhedra_union * p)
589 return cloog_upol_polyhedron (p)->Dimension;
593 cloog_domain_isconvex (CloogDomain * domain)
595 if (cloog_domain_polyhedron (domain))
596 return !cloog_upol_next (cloog_domain_upol (domain));
598 return 1;
601 unsigned
602 cloog_domain_dim (CloogDomain * d)
604 return cloog_domain_polyhedron (d)->Dimension;
607 static CloogDomain *
608 cloog_check_domains (CloogDomain *ppl, CloogDomain *polylib)
610 /* Cannot use cloog_domain_lazy_equal (polylib, ppl) here as this
611 function is too dumb: it does not detect permutations of
612 constraints. */
613 if (!cloog_domain_isempty (cloog_domain_difference (ppl, polylib))
614 || !cloog_domain_isempty (cloog_domain_difference (polylib, ppl)))
616 fprintf (stderr, "different domains ( \n ppl (\n");
617 cloog_domain_print (stderr, ppl);
618 fprintf (stderr, ") \n polylib (\n");
619 cloog_domain_print (stderr, polylib);
620 fprintf (stderr, "))\n");
621 exit (1);
624 if (cloog_return_ppl_result)
625 return ppl;
626 else
627 return polylib;
631 * cloog_domain_simple_convex:
632 * Given a list (union) of polyhedra, this function returns a "simple"
633 * convex hull of this union. In particular, the constraints of the
634 * the returned polyhedron consist of (parametric) lower and upper
635 * bounds on individual variables and constraints that appear in the
636 * original polyhedra.
638 * nb_par is the number of parameters of the domain.
640 CloogDomain *
641 cloog_domain_simple_convex (CloogDomain * domain, int nb_par)
643 fprintf (stderr, "cloog_domain_simple_convex is not implemented yet.\n");
644 exit (1);
649 * cloog_domain_simplify function:
650 * Given two polyhedral domains (pol1) and (pol2) inside two CloogDomain
651 * structures, this function finds the largest domain set (or the smallest list
652 * of non-redundant constraints), that when intersected with polyhedral
653 * domain (pol2) equals (Pol1)intersect(Pol2). The output is a new CloogDomain
654 * structure with a polyhedral domain with the "redundant" constraints removed.
655 * NB: this function do not work as expected with unions of polyhedra...
657 CloogDomain *
658 cloog_domain_simplify (CloogDomain * dom1, CloogDomain * dom2)
660 CloogMatrix *M, *M2;
661 CloogDomain *dom;
662 Polyhedron *d2, *P = d2p (dom1);
663 int nbc = cloog_domain_nbconstraints (dom1);
665 /* DomainSimplify doesn't remove all redundant equalities,
666 * so we remove them here first in case both dom1 and dom2
667 * are single polyhedra (i.e., not unions of polyhedra).
669 if (cloog_domain_isconvex (dom1) && cloog_domain_isconvex (dom2)
670 && cloog_domain_nbeq (dom1) && cloog_domain_nbeq (dom2))
672 int i, row;
673 int rows = cloog_domain_nbeq (dom1) + cloog_domain_nbeq (dom2);
674 int cols = cloog_domain_dim (dom1) + 2;
675 int rank;
676 M = cloog_matrix_alloc (rows, cols);
677 M2 = cloog_matrix_alloc (nbc, cols);
678 Vector_Copy (cloog_domain_polyhedron (dom2)->Constraint[0],
679 M->p[0], cloog_domain_nbeq (dom2) * cols);
680 rank = cloog_domain_nbeq (dom2);
681 row = 0;
682 for (i = 0; i < cloog_domain_nbeq (dom1); ++i)
684 Vector_Copy (P->Constraint[i], M->p[rank], cols);
685 if (Gauss (M, rank + 1, cols - 1) > rank)
687 Vector_Copy (P->Constraint[i], M2->p[row++], cols);
688 rank++;
691 if (row < cloog_domain_nbeq (dom1))
693 Vector_Copy (P->Constraint[cloog_domain_nbeq (dom1)],
694 M2->p[row], (nbc - cloog_domain_nbeq (dom1)) * cols);
695 P = Constraints2Polyhedron (M2, MAX_RAYS);
697 cloog_matrix_free (M2);
698 cloog_matrix_free (M);
700 d2 = d2p (dom2);
701 dom = cloog_domain_alloc (DomainSimplify (P, d2, MAX_RAYS));
702 Polyhedron_Free (d2);
703 Polyhedron_Free (P);
704 return print_result ("cloog_domain_simplify", cloog_check_domain (dom));
707 static ppl_polyhedra_union *
708 cloog_upol_copy (ppl_polyhedra_union *p)
710 ppl_polyhedra_union *res = cloog_new_upol (Polyhedron_Copy (cloog_upol_polyhedron (p)));
711 ppl_polyhedra_union *upol = res;
713 while (cloog_upol_next (p))
715 cloog_upol_set_next (upol, cloog_new_upol (Polyhedron_Copy (cloog_upol_polyhedron (p))));
716 upol = cloog_upol_next (upol);
717 p = cloog_upol_next (p);
720 return res;
723 /* Adds to D1 the union of polyhedra from D2, with no checks of
724 redundancies between polyhedra. */
726 CloogDomain *
727 cloog_domain_add_domain (CloogDomain *d1, CloogDomain *d2)
729 ppl_polyhedra_union *upol;
731 if (!d1)
732 return d2;
734 if (!d2)
735 return d1;
737 upol = cloog_domain_upol (d1);
738 while (cloog_upol_next (upol))
739 upol = cloog_upol_next (upol);
741 cloog_upol_set_next (upol, cloog_domain_upol (d2));
742 return d1;
746 * cloog_domain_union function:
747 * This function returns a new CloogDomain structure including a polyhedral
748 * domain which is the union of two polyhedral domains (pol1) U (pol2) inside
749 * two CloogDomain structures.
751 CloogDomain *
752 cloog_domain_union (CloogDomain * dom1, CloogDomain * dom2)
754 CloogDomain *res;
755 ppl_polyhedra_union *head1, *head2, *tail1, *tail2;
756 ppl_polyhedra_union *d1, *d2;
758 if (!dom1)
759 return dom2;
761 if (!dom2)
762 return dom1;
764 if (cloog_domain_dim (dom1) != cloog_domain_dim (dom2))
766 fprintf (stderr, "cloog_domain_union should not be called on domains of different dimensions.\n");
767 exit (1);
770 head1 = NULL;
771 tail1 = NULL;
772 for (d1 = cloog_domain_upol (dom1); d1; d1 = cloog_upol_next (d1))
774 int found = 0;
775 ppl_Polyhedron_t ppl1 = cloog_translate_constraint_matrix (cloog_upol_domain2matrix (d1));
777 for (d2 = cloog_domain_upol (dom2); d2; d2 = cloog_upol_next (d2))
779 ppl_Polyhedron_t ppl2 = cloog_translate_constraint_matrix (cloog_upol_domain2matrix (d2));
781 if (ppl_Polyhedron_contains_Polyhedron (ppl2, ppl1))
783 found = 1;
784 break;
788 if (!found)
790 if (!tail1)
792 head1 = cloog_upol_copy (d1);
793 tail1 = head1;
795 else
797 cloog_upol_set_next (tail1, cloog_upol_copy (d1));
798 tail1 = cloog_upol_next (tail1);
803 head2 = NULL;
804 tail2 = NULL;
805 for (d2 = cloog_domain_upol (dom2); d2; d2 = cloog_upol_next (d2))
807 int found = 0;
808 ppl_Polyhedron_t ppl2 = cloog_translate_constraint_matrix (cloog_upol_domain2matrix (d2));
810 for (d1 = head1; d1; d1 = cloog_upol_next (d1))
812 ppl_Polyhedron_t ppl1 = cloog_translate_constraint_matrix (cloog_upol_domain2matrix (d1));
814 if (ppl_Polyhedron_contains_Polyhedron (ppl1, ppl2))
816 found = 1;
817 break;
821 if (!found)
823 if (!tail2)
825 head2 = cloog_upol_copy (d2);
826 tail2 = head2;
828 else
830 cloog_upol_set_next (tail2, cloog_upol_copy (d2));
831 tail2 = cloog_upol_next (tail2);
836 if (!head1)
837 res = cloog_new_domain (head2);
838 else
840 cloog_upol_set_next (tail1, head2);
841 res = cloog_new_domain (head1);
844 if (cloog_check_polyhedral_ops)
846 Polyhedron *p1 = d2p (dom1);
847 Polyhedron *p2 = d2p (dom2);
849 cloog_check_domains (res, cloog_domain_alloc (DomainUnion (p1, p2, MAX_RAYS)));
851 Polyhedron_Free (p1);
852 Polyhedron_Free (p2);
855 return print_result ("cloog_domain_union", cloog_check_domain (res));
859 * cloog_domain_intersection function:
860 * This function returns a new CloogDomain structure including a polyhedral
861 * domain which is the intersection of two polyhedral domains (pol1)inter(pol2)
862 * inside two CloogDomain structures.
864 CloogDomain *
865 cloog_domain_intersection (CloogDomain * dom1, CloogDomain * dom2)
867 CloogDomain *res;
868 ppl_polyhedra_union *p1, *p2;
869 ppl_Polyhedron_t ppl1, ppl2;
871 res = cloog_domain_empty (cloog_domain_dim (dom1));
873 for (p1 = cloog_domain_upol (dom1); p1; p1 = cloog_upol_next (p1))
875 ppl1 = cloog_translate_constraint_matrix (Polyhedron2Constraints (cloog_upol_polyhedron (p1)));
877 for (p2 = cloog_domain_upol (dom2); p2; p2 = cloog_upol_next (p2))
879 ppl2 = cloog_translate_constraint_matrix (Polyhedron2Constraints (cloog_upol_polyhedron (p2)));
880 ppl_Polyhedron_intersection_assign (ppl2, ppl1);
882 res = cloog_domain_union (res, cloog_translate_ppl_polyhedron (ppl2));
886 if (cloog_check_polyhedral_ops)
888 Polyhedron *a1 = d2p (dom1);
889 Polyhedron *a2 = d2p (dom2);
891 res = cloog_check_domains (res, cloog_domain_alloc (DomainIntersection (a1, a2, MAX_RAYS)));
893 Polyhedron_Free (a1);
894 Polyhedron_Free (a2);
897 return print_result ("cloog_domain_intersection", res);
902 * cloog_domain_difference function:
903 * This function returns a new CloogDomain structure including a polyhedral
904 * domain which is the difference of two polyhedral domains domain \ minus
905 * inside two CloogDomain structures.
906 * - November 8th 2001: first version.
908 CloogDomain *
909 cloog_domain_difference (CloogDomain * domain, CloogDomain * minus)
911 if (cloog_domain_isempty (minus))
912 return print_result ("cloog_domain_difference", cloog_domain_copy (domain));
913 else
915 Polyhedron *p1 = d2p (domain);
916 Polyhedron *p2 = d2p (minus);
917 CloogDomain *res = cloog_domain_alloc (DomainDifference (p1, p2, MAX_RAYS));
918 Polyhedron_Free (p1);
919 Polyhedron_Free (p2);
920 return print_result ("cloog_domain_difference", res);
926 * cloog_domain_addconstraints function :
927 * This function adds source's polyhedron constraints to target polyhedron: for
928 * each element of the polyhedron inside 'target' (i.e. element of the union
929 * of polyhedra) it adds the constraints of the corresponding element in
930 * 'source'.
931 * - August 10th 2002: first version.
932 * Nota bene for future : it is possible that source and target don't have the
933 * same number of elements (try iftest2 without non-shared constraint
934 * elimination in cloog_loop_separate !). This function is yet another part
935 * of the DomainSimplify patching problem...
937 CloogDomain *
938 cloog_domain_addconstraints (domain_source, domain_target)
939 CloogDomain *domain_source, *domain_target;
941 unsigned nb_constraint;
942 Value *constraints;
943 ppl_polyhedra_union *source, *target, *new, *next, *last;
945 source = cloog_domain_upol (domain_source);
946 target = cloog_domain_upol (domain_target);
948 constraints = cloog_upol_polyhedron (source)->p_Init;
949 nb_constraint = cloog_upol_nbc (source);
950 last = new = cloog_new_upol (AddConstraints (constraints, nb_constraint,
951 u2p (target), MAX_RAYS));
952 source = cloog_upol_next (source);
953 next = cloog_upol_next (target);
955 while (next)
956 { /* BUG !!! This is actually a bug. I don't know yet how to cleanly avoid
957 * the situation where source and target do not have the same number of
958 * elements. So this 'if' is an awful trick, waiting for better.
960 if (source)
962 constraints = cloog_upol_polyhedron (source)->p_Init;
963 nb_constraint = cloog_upol_nbc (source);
964 source = cloog_upol_next (source);
966 cloog_upol_set_next
967 (last, cloog_new_upol (AddConstraints (constraints, nb_constraint,
968 u2p (next), MAX_RAYS)));
969 last = cloog_upol_next (last);
970 next = cloog_upol_next (next);
973 return print_result ("cloog_domain_addconstraints", cloog_check_domain (cloog_new_domain (new)));
978 * cloog_domain_sort function:
979 * This function topologically sorts (nb_pols) polyhedra. Here (pols) is a an
980 * array of pointers to polyhedra, (nb_pols) is the number of polyhedra,
981 * (level) is the level to consider for partial ordering (nb_par) is the
982 * parameter space dimension, (permut) if not NULL, is an array of (nb_pols)
983 * integers that contains a permutation specification after call in order to
984 * apply the topological sorting.
986 void
987 cloog_domain_sort (doms, nb_pols, level, nb_par, permut)
988 CloogDomain **doms;
989 unsigned nb_pols, level, nb_par;
990 int *permut;
992 int *time, i;
993 Polyhedron **pols = (Polyhedron **) malloc (nb_pols * sizeof (Polyhedron *));
995 for (i = 0; i < nb_pols; i++)
996 pols[i] = cloog_domain_polyhedron (doms[i]);
998 /* time is an array of (nb_pols) integers to store logical time values. We
999 * do not use it, but it is compulsory for PolyhedronTSort.
1001 time = (int *) malloc (nb_pols * sizeof (int));
1003 /* PolyhedronTSort will fill up permut (and time). */
1004 PolyhedronTSort (pols, nb_pols, level, nb_par, time, permut, MAX_RAYS);
1006 free (pols);
1007 free (time);
1012 * cloog_domain_empty function:
1013 * This function allocates the memory space for a CloogDomain structure and
1014 * sets its polyhedron to an empty polyhedron with 'dimension' dimensions.
1015 * Then it returns a pointer to the allocated space.
1016 * - June 10th 2005: first version.
1018 CloogDomain *
1019 cloog_domain_empty (int dimension)
1021 return (cloog_domain_alloc (Empty_Polyhedron (dimension)));
1025 /******************************************************************************
1026 * Structure display function *
1027 ******************************************************************************/
1031 * cloog_domain_print_structure :
1032 * this function is a more human-friendly way to display the CloogDomain data
1033 * structure, it only shows the constraint system and includes an indentation
1034 * level (level) in order to work with others print_structure functions.
1035 * Written by Olivier Chorier, Luc Marchaud, Pierre Martin and Romain Tartiere.
1036 * - April 24th 2005: Initial version.
1037 * - May 26th 2005: Memory leak hunt.
1038 * - June 16th 2005: (Ced) Integration in domain.c.
1040 void
1041 cloog_domain_print_structure (FILE * file, CloogDomain * domain, int level)
1043 int i;
1044 CloogMatrix *matrix;
1046 /* Go to the right level. */
1047 for (i = 0; i < level; i++)
1048 fprintf (file, "|\t");
1050 if (domain != NULL)
1052 fprintf (file, "+-- CloogDomain\n");
1054 /* Print the matrix. */
1055 matrix = cloog_upol_domain2matrix (cloog_domain_upol (domain));
1056 cloog_matrix_print_structure (file, matrix, level);
1057 cloog_matrix_free (matrix);
1059 /* A blank line. */
1060 for (i = 0; i < level + 1; i++)
1061 fprintf (file, "|\t");
1062 fprintf (file, "\n");
1064 else
1065 fprintf (file, "+-- Null CloogDomain\n");
1071 * cloog_domain_list_print function:
1072 * This function prints the content of a CloogDomainList structure into a
1073 * file (foo, possibly stdout).
1074 * - November 6th 2001: first version.
1076 void
1077 cloog_domain_list_print (FILE * foo, CloogDomainList * list)
1079 while (list != NULL)
1081 cloog_domain_print (foo, cloog_domain (list));
1082 list = cloog_next_domain (list);
1087 /******************************************************************************
1088 * Memory deallocation function *
1089 ******************************************************************************/
1093 * cloog_domain_list_free function:
1094 * This function frees the allocated memory for a CloogDomainList structure.
1095 * - November 6th 2001: first version.
1097 void
1098 cloog_domain_list_free (CloogDomainList * list)
1100 CloogDomainList *temp;
1102 while (list != NULL)
1104 temp = cloog_next_domain (list);
1105 cloog_domain_free (cloog_domain (list));
1106 free (list);
1107 list = temp;
1112 /******************************************************************************
1113 * Reading function *
1114 ******************************************************************************/
1118 * cloog_domain_read function:
1119 * Adaptation from the PolyLib. This function reads a matrix into a file (foo,
1120 * posibly stdin) and returns a pointer to a polyhedron containing the read
1121 * information.
1122 * - October 18th 2001: first version.
1124 CloogDomain *
1125 cloog_domain_read (FILE * foo)
1127 CloogMatrix *matrix;
1128 CloogDomain *domain;
1130 matrix = cloog_matrix_read (foo);
1131 domain = cloog_domain_matrix2domain (matrix);
1132 cloog_matrix_free (matrix);
1134 return print_result ("cloog_domain_read", domain);
1139 * cloog_domain_union_read function:
1140 * This function reads a union of polyhedra into a file (foo, posibly stdin) and
1141 * returns a pointer to a Polyhedron containing the read information.
1142 * - September 9th 2002: first version.
1143 * - October 29th 2005: (debug) removal of a leak counting "correction" that
1144 * was just false since ages.
1146 CloogDomain *
1147 cloog_domain_union_read (FILE * foo)
1149 int i, nb_components;
1150 char s[MAX_STRING];
1151 CloogDomain *domain, *temp, *old;
1153 /* domain reading: nb_components (constraint matrices). */
1154 while (fgets (s, MAX_STRING, foo) == 0);
1155 while ((*s == '#' || *s == '\n') || (sscanf (s, " %d", &nb_components) < 1))
1156 fgets (s, MAX_STRING, foo);
1158 if (nb_components > 0)
1159 { /* 1. first part of the polyhedra union, */
1160 domain = cloog_domain_read (foo);
1161 /* 2. and the nexts. */
1162 for (i = 1; i < nb_components; i++)
1163 { /* Leak counting is OK since next allocated domain is freed here. */
1164 temp = cloog_domain_read (foo);
1165 old = domain;
1166 domain = cloog_domain_union (temp, old);
1167 cloog_domain_free (temp);
1168 cloog_domain_free (old);
1170 return print_result ("cloog_domain_union_read", cloog_check_domain (domain));
1172 else
1173 return NULL;
1178 * cloog_domain_list_read function:
1179 * This function reads a list of polyhedra into a file (foo, posibly stdin) and
1180 * returns a pointer to a CloogDomainList containing the read information.
1181 * - November 6th 2001: first version.
1183 CloogDomainList *
1184 cloog_domain_list_read (FILE * foo)
1186 int i, nb_pols;
1187 char s[MAX_STRING];
1188 CloogDomainList *list, *now, *next;
1191 /* We read first the number of polyhedra in the list. */
1192 while (fgets (s, MAX_STRING, foo) == 0);
1193 while ((*s == '#' || *s == '\n') || (sscanf (s, " %d", &nb_pols) < 1))
1194 fgets (s, MAX_STRING, foo);
1196 /* Then we read the polyhedra. */
1197 list = NULL;
1198 if (nb_pols > 0)
1200 list = (CloogDomainList *) malloc (sizeof (CloogDomainList));
1201 cloog_set_domain (list, cloog_domain_read (foo));
1202 cloog_set_next_domain (list, NULL);
1203 now = list;
1204 for (i = 1; i < nb_pols; i++)
1206 next = (CloogDomainList *) malloc (sizeof (CloogDomainList));
1207 cloog_set_domain (next, cloog_domain_read (foo));
1208 cloog_set_next_domain (next, NULL);
1209 cloog_set_next_domain (now, next);
1210 now = cloog_next_domain (now);
1213 return list;
1217 /******************************************************************************
1218 * Processing functions *
1219 ******************************************************************************/
1222 * cloog_domain_isempty function:
1223 * This function returns 1 if the polyhedron given as input is empty, 0
1224 * otherwise.
1225 * - October 28th 2001: first version.
1228 cloog_domain_isempty (CloogDomain * domain)
1230 if (cloog_domain_polyhedron (domain) == NULL)
1231 return 1;
1233 if (cloog_upol_next (cloog_domain_upol (domain)))
1234 return 0;
1236 return ((cloog_domain_dim (domain) < cloog_domain_nbeq (domain)) ? 1 : 0);
1240 * cloog_domain_project function:
1241 * From Quillere's LoopGen 0.4. This function returns the projection of
1242 * (domain) on the (level) first dimensions (i.e. outer loops). It returns a
1243 * pointer to the projected Polyhedron.
1244 * - nb_par is the number of parameters.
1246 * - October 27th 2001: first version.
1247 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1248 * CLooG 0.12.1).
1250 CloogDomain *
1251 cloog_domain_project_1 (CloogDomain * domain, int level, int nb_par)
1253 int row, column, nb_rows, nb_columns, difference;
1254 CloogDomain *projected_domain;
1255 CloogMatrix *matrix;
1257 nb_rows = level + nb_par + 1;
1258 nb_columns = cloog_domain_dim (domain) + 1;
1259 difference = nb_columns - nb_rows;
1261 if (difference == 0)
1262 return print_result ("cloog_domain_project", cloog_domain_copy (domain));
1264 matrix = cloog_matrix_alloc (nb_rows, nb_columns);
1266 for (row = 0; row < level; row++)
1267 for (column = 0; column < nb_columns; column++)
1268 value_set_si (matrix->p[row][column], (row == column ? 1 : 0));
1270 for (; row < nb_rows; row++)
1271 for (column = 0; column < nb_columns; column++)
1272 value_set_si (matrix->p[row][column],
1273 (row + difference == column ? 1 : 0));
1275 projected_domain = cloog_domain_image (domain, matrix);
1276 cloog_matrix_free (matrix);
1278 return print_result ("cloog_domain_project_1", cloog_check_domain (projected_domain));
1281 CloogDomain *
1282 cloog_domain_project (CloogDomain * domain, int level, int nb_par)
1284 return print_result ("cloog_domain_project",
1285 cloog_domain_project_1 (domain, level, nb_par));
1288 CloogDomain *
1289 cloog_domain_project_ported (CloogDomain * domain, int level, int nb_par)
1291 CloogDomain *res = NULL;
1292 ppl_polyhedra_union *upol = cloog_domain_upol (domain);
1293 int i, diff = cloog_domain_dim (domain) - level - nb_par;
1294 size_t n;
1295 ppl_dimension_type *to_remove;
1297 if (diff == 0)
1298 return print_result ("cloog_domain_project", domain);
1300 n = diff;
1301 to_remove = (ppl_dimension_type *) malloc (n * sizeof (ppl_dimension_type));
1303 for (i = 0; i < n; i++)
1304 to_remove[i] = i + level;
1306 while (upol)
1308 ppl_Polyhedron_t ppl = cloog_translate_constraint_matrix (cloog_upol_domain2matrix (upol));
1310 ppl_Polyhedron_remove_space_dimensions (ppl, to_remove, n);
1311 res = cloog_domain_add_domain (res, cloog_translate_ppl_polyhedron (ppl));
1312 upol = cloog_upol_next (upol);
1315 if (cloog_check_polyhedral_ops)
1316 return print_result ("cloog_domain_project",
1317 cloog_check_domains
1318 (res, cloog_domain_project_1 (domain, level, nb_par)));
1320 return print_result ("cloog_domain_project", res);
1324 * cloog_domain_extend function:
1325 * From Quillere's LoopGen 0.4. This function returns the (domain) given as
1326 * input with (dim)+(nb_par) dimensions. The new dimensions are added before
1327 * the (nb_par) parameters. This function does not free (domain), and returns
1328 * a new polyhedron.
1329 * - nb_par is the number of parameters.
1331 * - October 27th 2001: first version.
1332 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1333 * CLooG 0.12.1).
1335 CloogDomain *
1336 cloog_domain_extend (CloogDomain * domain, int dim, int nb_par)
1338 int row, column, nb_rows, nb_columns, difference;
1339 CloogDomain *extended_domain;
1340 CloogMatrix *matrix;
1342 nb_rows = 1 + cloog_domain_dim (domain);
1343 nb_columns = dim + nb_par + 1;
1344 difference = nb_columns - nb_rows;
1346 if (difference == 0)
1347 return print_result ("cloog_domain_extend", cloog_domain_copy (domain));
1349 matrix = cloog_matrix_alloc (nb_rows, nb_columns);
1351 for (row = 0; row < cloog_domain_dim (domain) - nb_par; row++)
1352 for (column = 0; column < nb_columns; column++)
1353 value_set_si (matrix->p[row][column], (row == column ? 1 : 0));
1355 for (; row <= cloog_domain_dim (domain); row++)
1356 for (column = 0; column < nb_columns; column++)
1357 value_set_si (matrix->p[row][column],
1358 (row + difference == column ? 1 : 0));
1360 extended_domain = cloog_domain_preimage (domain, matrix);
1361 cloog_matrix_free (matrix);
1363 return print_result ("cloog_domain_extend", cloog_check_domain (extended_domain));
1368 * cloog_domain_never_integral function:
1369 * For us, an equality like 3*i -4 = 0 is always false since 4%3 != 0. This
1370 * function returns a boolean set to 1 if there is this kind of 'never true'
1371 * constraint inside a polyhedron, 0 otherwise.
1372 * - domain is the polyhedron to check,
1374 * - November 28th 2001: first version.
1375 * - June 26th 2003: for iterators, more 'never true' constraints are found
1376 * (compare cholesky2 and vivien with a previous version),
1377 * checking for the parameters created (compare using vivien).
1378 * - June 28th 2003: Previously in loop.c and called
1379 * cloog_loop_simplify_nevertrue, now here !
1380 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1381 * CLooG 0.12.1).
1382 * - October 14th 2005: Complete rewriting, not faster but code quite shorter.
1385 cloog_domain_never_integral (CloogDomain * domain)
1387 int i, dimension, nbc;
1388 Value gcd, modulo;
1389 Polyhedron *polyhedron;
1391 if ((domain == NULL) || (cloog_domain_polyhedron (domain) == NULL))
1392 return 1;
1394 value_init_c (gcd);
1395 value_init_c (modulo);
1396 polyhedron = d2p (domain);
1397 dimension = cloog_domain_dim (domain) + 2;
1398 nbc = cloog_domain_nbconstraints (domain);
1400 /* For each constraint... */
1401 for (i = 0; i < nbc; i++)
1402 { /* If we have an equality and the scalar part is not zero... */
1403 if (value_zero_p (polyhedron->Constraint[i][0]) &&
1404 value_notzero_p (polyhedron->Constraint[i][dimension - 1]))
1405 { /* Then we check whether the scalar can be divided by the gcd of the
1406 * unknown vector (including iterators and parameters) or not. If not,
1407 * there is no integer point in the polyhedron and we return 1.
1409 Vector_Gcd (&(polyhedron->Constraint[i][1]), dimension - 2, &gcd);
1410 value_modulus (modulo,
1411 polyhedron->Constraint[i][dimension - 1],
1412 gcd);
1414 if (value_notzero_p (modulo))
1416 value_clear_c (gcd);
1417 value_clear_c (modulo);
1418 Polyhedron_Free (polyhedron);
1419 return 1;
1424 value_clear_c (gcd);
1425 value_clear_c (modulo);
1426 Polyhedron_Free (polyhedron);
1427 return (0);
1432 * cloog_domain_stride function:
1433 * This function finds the stride imposed to unknown with the column number
1434 * 'strided_level' in order to be integral. For instance, if we have a
1435 * constraint like -i - 2j + 2k = 0, and we consider k, then k can be integral
1436 * only if (i + 2j)%2 = 0. Then only if i%2 = 0. Then k imposes a stride 2 to
1437 * the unknown i. The function returns the imposed stride in a parameter field.
1438 * - domain is the set of constraint we have to consider,
1439 * - strided_level is the column number of the unknown for which a stride have
1440 * to be found,
1441 * - looking_level is the column number of the unknown that impose a stride to
1442 * the first unknown.
1443 * - stride is the stride that is returned back as a function parameter.
1444 * - offset is the value of the constant c if the condition is of the shape
1445 * (i + c)%s = 0, s being the stride.
1447 * - June 28th 2003: first version.
1448 * - July 14th 2003: can now look for multiple striding constraints and returns
1449 * the GCD of the strides and the common offset.
1450 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1451 * CLooG 0.12.1).
1453 void
1454 cloog_domain_stride (domain, strided_level, nb_par, stride, offset)
1455 CloogDomain *domain;
1456 int strided_level, nb_par;
1457 Value *stride, *offset;
1459 int i;
1460 int n_col, n_row, rank;
1461 CloogMatrix *M;
1462 Matrix *U;
1463 Vector *V;
1464 Polyhedron *polyhedron = d2p (domain);
1465 int dimension = cloog_domain_dim (domain);
1466 int nbeq = cloog_domain_nbeq (domain);
1468 /* Look at all equalities involving strided_level and the inner
1469 * iterators. We can ignore the outer iterators and the parameters
1470 * here because the lower bound on strided_level is assumed to
1471 * be a constant.
1473 n_col = (1 + dimension - nb_par) - strided_level;
1474 for (i = 0, n_row = 0; i < nbeq; i++)
1475 if (First_Non_Zero
1476 (polyhedron->Constraint[i] + strided_level, n_col) != -1)
1477 ++n_row;
1479 M = cloog_matrix_alloc (n_row + 1, n_col + 1);
1480 for (i = 0, n_row = 0; i < nbeq; i++)
1482 if (First_Non_Zero
1483 (polyhedron->Constraint[i] + strided_level, n_col) == -1)
1484 continue;
1485 Vector_Copy (polyhedron->Constraint[i] + strided_level,
1486 M->p[n_row], n_col);
1487 value_assign (M->p[n_row][n_col],
1488 polyhedron->Constraint[i][1 + dimension]);
1489 ++n_row;
1491 value_set_si (M->p[n_row][n_col], 1);
1493 /* Then look at the general solution to the above equalities. */
1494 rank = SolveDiophantine (M, &U, &V);
1495 cloog_matrix_free (M);
1497 if (rank == -1)
1499 /* There is no solution, so the body of this loop will
1500 * never execute. We just leave the constraints alone here so
1501 * that they will ensure the body will not be executed.
1502 * We should probably propagate this information up so that
1503 * the loop can be removed entirely.
1505 value_set_si (*offset, 0);
1506 value_set_si (*stride, 1);
1508 else
1510 /* Compute the gcd of the coefficients defining strided_level. */
1511 Vector_Gcd (U->p[0], U->NbColumns, stride);
1512 value_oppose (*offset, V->p[0]);
1513 value_pmodulus (*offset, *offset, *stride);
1515 Matrix_Free (U);
1516 Vector_Free (V);
1517 Polyhedron_Free (polyhedron);
1518 return;
1523 * cloog_domain_integral_lowerbound function:
1524 * This function returns 1 if the lower bound of an iterator (such as its
1525 * column rank in the constraint set 'domain' is 'level') is integral,
1526 * 0 otherwise. If the lower bound is actually integral, the function fills
1527 * the 'lower' field with the lower bound value.
1528 * - June 29th 2003: first version.
1529 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1530 * CLooG 0.12.1).
1533 cloog_domain_integral_lowerbound (domain, level, lower)
1534 CloogDomain *domain;
1535 int level;
1536 Value *lower;
1538 int i, first_lower = 1, dimension, lower_constraint = -1, nbc;
1539 Value iterator, constant, tmp;
1540 Polyhedron *polyhedron;
1542 polyhedron = d2p (domain);
1543 dimension = cloog_domain_dim (domain);
1544 nbc = cloog_domain_nbconstraints (domain);
1546 /* We want one and only one lower bound (e.g. no equality, no maximum
1547 * calculation...).
1549 for (i = 0; i < nbc; i++)
1550 if (value_zero_p (polyhedron->Constraint[i][0])
1551 && value_notzero_p (polyhedron->Constraint[i][level]))
1553 Polyhedron_Free (polyhedron);
1554 return 0;
1557 for (i = 0; i < nbc; i++)
1558 if (value_pos_p (polyhedron->Constraint[i][level]))
1560 if (first_lower)
1562 first_lower = 0;
1563 lower_constraint = i;
1565 else
1567 Polyhedron_Free (polyhedron);
1568 return 0;
1572 if (first_lower)
1574 Polyhedron_Free (polyhedron);
1575 return 0;
1578 /* We want an integral lower bound: no other non-zero entry except the
1579 * iterator coefficient and the constant.
1581 for (i = 1; i < level; i++)
1582 if (value_notzero_p
1583 (polyhedron->Constraint[lower_constraint][i]))
1585 Polyhedron_Free (polyhedron);
1586 return 0;
1589 for (i = level + 1; i <= dimension; i++)
1590 if (value_notzero_p
1591 (polyhedron->Constraint[lower_constraint][i]))
1593 Polyhedron_Free (polyhedron);
1594 return 0;
1597 value_init_c (iterator);
1598 value_init_c (constant);
1599 value_init_c (tmp);
1601 /* If all is passed, then find the lower bound and return 1. */
1602 value_assign (iterator,
1603 polyhedron->Constraint[lower_constraint][level]);
1604 value_oppose (constant,
1605 polyhedron->Constraint[lower_constraint][dimension + 1]);
1607 value_modulus (tmp, constant, iterator);
1608 value_division (*lower, constant, iterator);
1610 if (!(value_zero_p (tmp) || value_neg_p (constant)))
1611 value_increment (*lower, *lower);
1613 value_clear_c (iterator);
1614 value_clear_c (constant);
1615 value_clear_c (tmp);
1616 Polyhedron_Free (polyhedron);
1617 return 1;
1622 * cloog_domain_lowerbound_update function:
1623 * This function updates the integral lower bound of an iterator (such as its
1624 * column rank in the constraint set 'domain' is 'level') into 'lower'.
1625 * - Jun 29th 2003: first version.
1626 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1627 * CLooG 0.12.1).
1629 void
1630 cloog_domain_lowerbound_update (domain, level, lower)
1631 CloogDomain *domain;
1632 int level;
1633 Value lower;
1635 int i;
1636 int nbc = cloog_domain_nbconstraints (domain);
1637 int dim = cloog_domain_dim (domain);
1638 Polyhedron *polyhedron = cloog_domain_polyhedron (domain);
1640 /* There is only one lower bound, the first one is the good one. */
1641 for (i = 0; i < nbc; i++)
1642 if (value_pos_p (polyhedron->Constraint[i][level]))
1644 value_set_si (polyhedron->Constraint[i][level], 1);
1645 value_oppose (polyhedron->Constraint[i][dim + 1], lower);
1646 break;
1652 * cloog_domain_lazy_equal function:
1653 * This function returns 1 if the domains given as input are the same, 0 if it
1654 * is unable to decide. This function makes an entry-to-entry comparison between
1655 * the constraint systems, if all the entries are the same, the domains are
1656 * obviously the same and it returns 1, at the first difference, it returns 0.
1657 * This is a very fast way to verify this property. It has been shown (with the
1658 * CLooG benchmarks) that operations on equal domains are 17% of all the
1659 * polyhedral computations. For 75% of the actually identical domains, this
1660 * function answer that they are the same and allow to give immediately the
1661 * trivial solution instead of calling the heavy general functions of PolyLib.
1662 * - August 22th 2003: first version.
1663 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
1664 * CLooG 0.12.1).
1667 cloog_domain_lazy_equal (CloogDomain * d1, CloogDomain * d2)
1669 int i, nb_elements;
1670 ppl_polyhedra_union *u1 = cloog_domain_upol (d1);
1671 ppl_polyhedra_union *u2 = cloog_domain_upol (d2);
1673 while (u1 && u2)
1675 if ((cloog_upol_nbc (u1) != cloog_upol_nbc (u2)) ||
1676 (cloog_upol_dim (u1) != cloog_upol_dim (u2)))
1677 return 0;
1679 nb_elements =
1680 cloog_upol_nbc (u1) * (cloog_upol_dim (u1) + 2);
1682 for (i = 0; i < nb_elements; i++)
1683 if (value_ne (cloog_upol_polyhedron (u1)->p_Init[i],
1684 cloog_upol_polyhedron (u2)->p_Init[i]))
1685 return 0;
1687 u1 = cloog_upol_next (u1);
1688 u2 = cloog_upol_next (u2);
1691 if (u1 || u2)
1692 return 0;
1694 return 1;
1699 * cloog_domain_lazy_block function:
1700 * This function returns 1 if the two domains d1 and d2 given as input are the
1701 * same (possibly except for a dimension equal to a constant where we accept
1702 * a difference of 1) AND if we are sure that there are no other domain in
1703 * the code generation problem that may put integral points between those of
1704 * d1 and d2 (0 otherwise). In fact this function answers the question "can I
1705 * safely consider the two domains as only one with two statements (a block) ?".
1706 * This function is lazy: it asks for very standard scattering representation
1707 * (only one constraint per dimension which is an equality, and the constraints
1708 * are ordered per dimension depth: the left hand side of the constraint matrix
1709 * is the identity) and will answer NO at the very first problem.
1710 * - d1 and d2 are the two domains to check for blocking,
1711 * - scattering is the linked list of all domains,
1712 * - scattdims is the total number of scattering dimentions.
1714 * - April 30th 2005: beginning
1715 * - June 9th 2005: first working version.
1716 * - June 10th 2005: debugging.
1717 * - June 21rd 2005: Adaptation for GMP.
1718 * - October 16th 2005: (debug) some false blocks have been removed.
1721 cloog_domain_lazy_block (d1, d2, scattering, scattdims)
1722 CloogDomain *d1, *d2;
1723 CloogDomainList *scattering;
1724 int scattdims;
1726 int i, j, difference = 0, different_constraint = 0, nbc;
1727 int dim1, dim2;
1728 Value date1, date2, date3, temp;
1729 Polyhedron *p1, *p2;
1731 /* Some basic checks: we only accept convex domains, with same constraint
1732 * and dimension numbers.
1734 if (!cloog_domain_isconvex (d1) || !cloog_domain_isconvex (d2) ||
1735 (cloog_domain_nbconstraints (d1) != cloog_domain_nbconstraints (d2)) ||
1736 (cloog_domain_dim (d1) != cloog_domain_dim (d2)))
1737 return 0;
1739 p1 = d2p (d1);
1740 p2 = d2p (d2);
1741 nbc = cloog_domain_nbconstraints (d1);
1742 dim1 = cloog_domain_dim (d1);
1743 dim2 = cloog_domain_dim (d2);
1745 /* There should be only one difference between the two domains, it
1746 * has to be at the constant level and the difference must be of +1,
1747 * moreover, after the difference all domain coefficient has to be 0.
1748 * The matrix shape is:
1750 * |===========|=====|<- 0 line
1751 * |===========|=====|
1752 * |===========|====?|<- different_constraint line (found here)
1753 * |===========|0000=|
1754 * |===========|0000=|<- pX->NbConstraints line
1755 * ^ ^ ^
1756 * | | |
1757 * | | (pX->Dimension + 2) column
1758 * | scattdims column
1759 * 0 column
1762 value_init_c (temp);
1763 for (i = 0; i < nbc; i++)
1765 if (difference == 0)
1766 { /* All elements except scalar must be equal. */
1767 for (j = 0; j < dim1 + 1; j++)
1768 if (value_ne (p1->Constraint[i][j],
1769 p2->Constraint[i][j]))
1771 value_clear_c (temp);
1772 Polyhedron_Free (p1);
1773 Polyhedron_Free (p2);
1774 return 0;
1776 /* The scalar may differ from +1 (now j=(p1->Dimension + 1)). */
1777 if (value_ne (p1->Constraint[i][j],
1778 p2->Constraint[i][j]))
1780 value_increment (temp, p2->Constraint[i][j]);
1781 if (value_ne (p1->Constraint[i][j], temp))
1783 value_clear_c (temp);
1784 Polyhedron_Free (p1);
1785 Polyhedron_Free (p2);
1786 return 0;
1788 else
1790 difference = 1;
1791 different_constraint = i;
1795 else
1796 { /* Scattering coefficients must be equal. */
1797 for (j = 0; j < (scattdims + 1); j++)
1798 if (value_ne (p1->Constraint[i][j],
1799 p2->Constraint[i][j]))
1801 value_clear_c (temp);
1802 Polyhedron_Free (p1);
1803 Polyhedron_Free (p2);
1804 return 0;
1807 /* Domain coefficients must be 0. */
1808 for (; j < dim1 + 1; j++)
1809 if (value_notzero_p (p1->Constraint[i][j])
1810 || value_notzero_p (p2->Constraint[i][j]))
1812 value_clear_c (temp);
1813 Polyhedron_Free (p1);
1814 Polyhedron_Free (p2);
1815 return 0;
1818 /* Scalar must be equal. */
1819 if (value_ne (p1->Constraint[i][j],
1820 p2->Constraint[i][j]))
1822 value_clear_c (temp);
1823 Polyhedron_Free (p1);
1824 Polyhedron_Free (p2);
1825 return 0;
1829 value_clear_c (temp);
1831 /* If the domains are exactly the same, this is a block. */
1832 if (difference == 0)
1834 Polyhedron_Free (p1);
1835 Polyhedron_Free (p2);
1836 return 1;
1839 /* Now a basic check that the constraint with the difference is an
1840 * equality of a dimension with a constant.
1842 for (i = 0; i <= different_constraint; i++)
1843 if (value_notzero_p (p1->Constraint[different_constraint][i]))
1845 Polyhedron_Free (p1);
1846 Polyhedron_Free (p2);
1847 return 0;
1850 if (value_notone_p (p1->Constraint[different_constraint][different_constraint + 1]))
1852 Polyhedron_Free (p1);
1853 Polyhedron_Free (p2);
1854 return 0;
1857 for (i = different_constraint + 2; i < dim1 + 1; i++)
1858 if (value_notzero_p (p1->Constraint[different_constraint][i]))
1860 Polyhedron_Free (p1);
1861 Polyhedron_Free (p2);
1862 return 0;
1865 /* For the moment, d1 and d2 are a block candidate. There remains to check
1866 * that there is no other domain that may put an integral point between
1867 * them. In our lazy test we ensure this property by verifying that the
1868 * constraint matrices have a very strict shape: let us consider that the
1869 * dimension with the difference is d. Then the first d dimensions are
1870 * defined in their depth order using equalities (thus the first column begins
1871 * with d zeroes, there is a d*d identity matrix and a zero-matrix for
1872 * the remaining simensions). If a domain can put integral points between the
1873 * domains of the block candidate, this means that the other entries on the
1874 * first d constraints are equal to those of d1 or d2. Thus we are looking for
1875 * such a constraint system, if it exists d1 and d2 is considered to not be
1876 * a block, it is a bock otherwise.
1878 * 1. Only equalities (for the first different_constraint+1 lines).
1879 * | 2. Must be the identity.
1880 * | | 3. Must be zero.
1881 * | | | 4. Elements are equal, the last one is either date1 or 2.
1882 * | | | |
1883 * | /-\ /---\ /---\
1884 * |0|100|00000|=====|<- 0 line
1885 * |0|010|00000|=====|
1886 * |0|001|00000|====?|<- different_constraint line
1887 * |*|***|*****|*****|
1888 * |*|***|*****|*****|<- pX->NbConstraints line
1889 * ^ ^ ^ ^
1890 * | | | |
1891 * | | | (pX->Dimension + 2) column
1892 * | | scattdims column
1893 * | different_constraint+1 column
1894 * 0 column
1897 /* Step 1 and 2. This is only necessary to check one domain because
1898 * we checked that they are equal on this part before.
1900 for (i = 0; i <= different_constraint; i++)
1902 for (j = 0; j < i + 1; j++)
1903 if (value_notzero_p (p1->Constraint[i][j]))
1905 Polyhedron_Free (p1);
1906 Polyhedron_Free (p2);
1907 return 0;
1910 if (value_notone_p (p1->Constraint[i][i + 1]))
1912 Polyhedron_Free (p1);
1913 Polyhedron_Free (p2);
1914 return 0;
1917 for (j = i + 2; j <= different_constraint + 1; j++)
1918 if (value_notzero_p (p1->Constraint[i][j]))
1920 Polyhedron_Free (p1);
1921 Polyhedron_Free (p2);
1922 return 0;
1926 /* Step 3. */
1927 for (i = 0; i <= different_constraint; i++)
1928 for (j = different_constraint + 2; j <= scattdims; j++)
1929 if (value_notzero_p (p1->Constraint[i][j]))
1931 Polyhedron_Free (p1);
1932 Polyhedron_Free (p2);
1933 return 0;
1936 value_init_c (date1);
1937 value_init_c (date2);
1938 value_init_c (date3);
1940 /* Now we have to check that the two different dates are unique. */
1941 value_assign (date1, p1->Constraint[different_constraint][dim1 + 1]);
1942 value_assign (date2, p2->Constraint[different_constraint][dim2 + 1]);
1944 /* Step 4. We check all domains except d1 and d2 and we look for at least
1945 * a difference with d1 or d2 on the first different_constraint+1 dimensions.
1947 while (scattering != NULL)
1949 if ((cloog_domain (scattering) != d1)
1950 && (cloog_domain (scattering) != d2))
1952 CloogDomain *d3 = cloog_domain (scattering);
1953 Polyhedron *p3 = d2p (d3);
1954 int dim3 = cloog_domain_dim (d3);
1956 value_assign (date3,
1957 p3->Constraint[different_constraint][dim3 + 1]);
1958 difference = 0;
1960 if (value_ne (date3, date2) && value_ne (date3, date1))
1961 difference = 1;
1963 for (i = 0; (i < different_constraint) && (!difference); i++)
1964 for (j = 0; (j < dim3 + 2) && !difference; j++)
1965 if (value_ne
1966 (p1->Constraint[i][j],
1967 p3->Constraint[i][j]))
1968 difference = 1;
1970 for (j = 0; (j < dim3 + 1) && !difference; j++)
1971 if (value_ne
1972 (p1->Constraint[different_constraint][j],
1973 p3->Constraint[different_constraint][j]))
1974 difference = 1;
1976 Polyhedron_Free (p3);
1977 if (!difference)
1979 value_clear_c (date1);
1980 value_clear_c (date2);
1981 value_clear_c (date3);
1982 Polyhedron_Free (p1);
1983 Polyhedron_Free (p2);
1984 return 0;
1988 scattering = cloog_next_domain (scattering);
1991 Polyhedron_Free (p1);
1992 Polyhedron_Free (p2);
1993 value_clear_c (date1);
1994 value_clear_c (date2);
1995 value_clear_c (date3);
1996 return 1;
2001 * cloog_domain_lazy_disjoint function:
2002 * This function returns 1 if the domains given as input are disjoint, 0 if it
2003 * is unable to decide. This function finds the unknown with fixed values in
2004 * both domains (on a given constraint, their column entry is not zero and
2005 * only the constant coefficient can be different from zero) and verify that
2006 * their values are the same. If not, the domains are obviously disjoint and
2007 * it returns 1, if there is not such case it returns 0. This is a very fast
2008 * way to verify this property. It has been shown (with the CLooG benchmarks)
2009 * that operations on disjoint domains are 36% of all the polyhedral
2010 * computations. For 94% of the actually identical domains, this
2011 * function answer that they are disjoint and allow to give immediately the
2012 * trivial solution instead of calling the heavy general functions of PolyLib.
2013 * - August 22th 2003: first version.
2014 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
2015 * CLooG 0.12.1).
2018 cloog_domain_lazy_disjoint (CloogDomain * d1, CloogDomain * d2)
2020 int i1, j1, i2, j2, scat_dim, nbc1, nbc2;
2021 int dim1, dim2;
2022 Value scat_val;
2023 Polyhedron *p1, *p2;
2025 if (!cloog_domain_isconvex (d1) || !cloog_domain_isconvex (d2))
2026 return 0;
2028 p1 = d2p (d1);
2029 p2 = d2p (d2);
2030 nbc1 = cloog_domain_nbconstraints (d1);
2031 nbc2 = cloog_domain_nbconstraints (d2);
2032 dim1 = cloog_domain_dim (d1);
2033 dim2 = cloog_domain_dim (d2);
2034 value_init_c (scat_val);
2036 for (i1 = 0; i1 < nbc1; i1++)
2038 if (value_notzero_p (p1->Constraint[i1][0]))
2039 continue;
2041 scat_dim = 1;
2042 while (value_zero_p (p1->Constraint[i1][scat_dim]) &&
2043 (scat_dim < dim1))
2044 scat_dim++;
2046 if (value_notone_p (p1->Constraint[i1][scat_dim]))
2047 continue;
2048 else
2050 for (j1 = scat_dim + 1; j1 <= dim1; j1++)
2051 if (value_notzero_p (p1->Constraint[i1][j1]))
2052 break;
2054 if (j1 != dim1 + 1)
2055 continue;
2057 value_assign (scat_val,
2058 p1->Constraint[i1][dim1 + 1]);
2060 for (i2 = 0; i2 < nbc2; i2++)
2062 for (j2 = 0; j2 < scat_dim; j2++)
2063 if (value_notzero_p (p2->Constraint[i2][j2]))
2064 break;
2066 if ((j2 != scat_dim)
2068 value_notone_p (p2->Constraint[i2][scat_dim]))
2069 continue;
2071 for (j2 = scat_dim + 1; j2 < dim2; j2++)
2072 if (value_notzero_p (p2->Constraint[i2][j2]))
2073 break;
2075 if (j2 != dim2)
2076 continue;
2078 if (value_ne
2079 (p2->Constraint[i2][dim2 + 1], scat_val))
2081 value_clear_c (scat_val);
2082 return 1;
2088 value_clear_c (scat_val);
2089 Polyhedron_Free (p1);
2090 Polyhedron_Free (p2);
2091 return 0;
2096 * cloog_domain_list_lazy_same function:
2097 * This function returns 1 if two domains in the list are the same, 0 if it
2098 * is unable to decide.
2099 * - February 9th 2004: first version.
2102 cloog_domain_list_lazy_same (CloogDomainList * list)
2103 { /*int i=1, j=1 ; */
2104 CloogDomainList *current, *next;
2106 current = list;
2107 while (current != NULL)
2109 next = cloog_next_domain (current);
2110 /*j=i+1; */
2111 while (next != NULL)
2113 if (cloog_domain_lazy_equal (cloog_domain (current),
2114 cloog_domain (next)))
2115 { /*printf("Same domains: %d and %d\n",i,j) ; */
2116 return 1;
2118 /*j++ ; */
2119 next = cloog_next_domain (next);
2121 /*i++ ; */
2122 current = cloog_next_domain (current);
2125 return 0;
2129 * cloog_domain_cut_first function:
2130 * this function returns a CloogDomain structure with everything except the
2131 * first part of the polyhedra union of the input domain as domain. After a call
2132 * to this function, there remains in the CloogDomain structure provided as
2133 * input only the first part of the original polyhedra union.
2134 * - April 20th 2005: first version, extracted from different part of loop.c.
2136 CloogDomain *
2137 cloog_domain_cut_first (CloogDomain * domain)
2139 CloogDomain *rest;
2141 if (domain && cloog_domain_polyhedron (domain))
2143 if (!cloog_upol_next (cloog_domain_upol (domain)))
2144 return NULL;
2146 rest = cloog_new_domain (cloog_upol_next (cloog_domain_upol (domain)));
2147 cloog_upol_set_next (cloog_domain_upol (domain), NULL);
2149 else
2150 rest = NULL;
2152 return print_result ("cloog_domain_cut_first", cloog_check_domain (rest));
2157 * cloog_domain_lazy_isscalar function:
2158 * this function returns 1 if the dimension 'dimension' in the domain 'domain'
2159 * is scalar, this means that the only constraint on this dimension must have
2160 * the shape "x.dimension + scalar = 0" with x an integral variable. This
2161 * function is lazy since we only accept x=1 (further calculations are easier
2162 * in this way).
2163 * - June 14th 2005: first version.
2164 * - June 21rd 2005: Adaptation for GMP.
2167 cloog_domain_lazy_isscalar (CloogDomain * domain, int dimension)
2169 int i, j;
2170 Polyhedron *polyhedron = d2p (domain);
2171 int nbc = cloog_domain_nbconstraints (domain);
2172 int dim = cloog_domain_dim (domain);
2174 /* For each constraint... */
2175 for (i = 0; i < nbc; i++)
2176 { /* ...if it is concerned by the potentially scalar dimension... */
2177 if (value_notzero_p
2178 (polyhedron->Constraint[i][dimension + 1]))
2179 { /* ...check that the constraint has the shape "dimension + scalar = 0". */
2180 for (j = 0; j <= dimension; j++)
2181 if (value_notzero_p (polyhedron->Constraint[i][j]))
2183 Polyhedron_Free (polyhedron);
2184 return 0;
2187 if (value_notone_p
2188 (polyhedron->Constraint[i][dimension + 1]))
2190 Polyhedron_Free (polyhedron);
2191 return 0;
2194 for (j = dimension + 2; j < dim + 1; j++)
2195 if (value_notzero_p (polyhedron->Constraint[i][j]))
2197 Polyhedron_Free (polyhedron);
2198 return 0;
2203 Polyhedron_Free (polyhedron);
2204 return 1;
2209 * cloog_domain_scalar function:
2210 * when we call this function, we know that "dimension" is a scalar dimension,
2211 * this function finds the scalar value in "domain" and returns it in "value".
2212 * - June 30th 2005: first version.
2214 void
2215 cloog_domain_scalar (CloogDomain * domain, int dimension, Value * value)
2217 int i;
2218 Polyhedron *polyhedron = d2p (domain);
2219 int nbc = cloog_domain_nbconstraints (domain);
2220 int dim = cloog_domain_dim (domain);
2222 /* For each constraint... */
2223 for (i = 0; i < nbc; i++)
2224 { /* ...if it is the equality defining the scalar dimension... */
2225 if (value_notzero_p
2226 (polyhedron->Constraint[i][dimension + 1])
2227 && value_zero_p (polyhedron->Constraint[i][0]))
2228 { /* ...Then send the scalar value. */
2229 value_assign (*value, polyhedron->Constraint[i][dim + 1]);
2230 value_oppose (*value, *value);
2231 Polyhedron_Free (polyhedron);
2232 return;
2236 /* We should have found a scalar value: if not, there is an error. */
2237 fprintf (stderr, "[CLooG]ERROR: dimension %d is not scalar as expected.\n",
2238 dimension);
2239 Polyhedron_Free (polyhedron);
2240 exit (0);
2245 * cloog_domain_erase_dimension function:
2246 * this function returns a CloogDomain structure builds from 'domain' where
2247 * we removed the dimension 'dimension' and every constraint considering this
2248 * dimension. This is not a projection ! Every data concerning the
2249 * considered dimension is simply erased.
2250 * - June 14th 2005: first version.
2251 * - June 21rd 2005: Adaptation for GMP.
2253 CloogDomain *
2254 cloog_domain_erase_dimension (CloogDomain * domain, int dimension)
2256 int i, j, mi, nb_dim, nbc;
2257 CloogMatrix *matrix;
2258 CloogDomain *erased;
2259 Polyhedron *polyhedron;
2261 polyhedron = d2p (domain);
2262 nb_dim = cloog_domain_dim (domain);
2263 nbc = cloog_domain_nbconstraints (domain);
2265 /* The matrix is one column less and at least one constraint less. */
2266 matrix = cloog_matrix_alloc (nbc - 1, nb_dim + 1);
2268 /* mi is the constraint counter for the matrix. */
2269 mi = 0;
2270 for (i = 0; i < nbc; i++)
2271 if (value_zero_p (polyhedron->Constraint[i][dimension + 1]))
2273 for (j = 0; j <= dimension; j++)
2274 value_assign (matrix->p[mi][j],
2275 polyhedron->Constraint[i][j]);
2277 for (j = dimension + 2; j < nb_dim + 2; j++)
2278 value_assign (matrix->p[mi][j - 1],
2279 polyhedron->Constraint[i][j]);
2281 mi++;
2284 erased = cloog_domain_matrix2domain (matrix);
2285 cloog_matrix_free (matrix);
2287 Polyhedron_Free (polyhedron);
2288 return print_result ("cloog_domain_erase_dimension", cloog_check_domain (erased));
2291 /* Number of polyhedra inside the union of disjoint polyhedra. */
2293 unsigned
2294 cloog_domain_nb_polyhedra (CloogDomain * domain)
2296 unsigned res = 0;
2297 ppl_polyhedra_union *upol = cloog_domain_upol (domain);
2299 while (upol)
2301 res++;
2302 upol = cloog_upol_next (upol);
2305 return res;
2308 void
2309 cloog_domain_print_polyhedra (FILE * foo, CloogDomain * domain)
2311 ppl_polyhedra_union *upol = cloog_domain_upol (domain);
2313 while (upol != NULL)
2315 CloogMatrix *matrix = cloog_upol_domain2matrix (upol);
2316 cloog_matrix_print (foo, matrix);
2317 cloog_matrix_free (matrix);
2318 upol = cloog_upol_next (upol);
2322 void
2323 debug_cloog_domain (CloogDomain *domain)
2325 cloog_domain_print_polyhedra (stderr, domain);
2328 void
2329 debug_cloog_matrix (CloogMatrix *m)
2331 cloog_matrix_print (stderr, m);