Ported SolveDiophantine and removed last dependences on PolyLib.
[cloog-ppl.git] / include / cloog / ppl_backend.h
bloba93ac80e71fd4b4c472205fc9eae3d30e2b19886
1 /**-------------------------------------------------------------------**
2 ** CLooG **
3 **-------------------------------------------------------------------**
4 ** polyhedron.h **
5 **-------------------------------------------------------------------**
6 ** First version: July 22th 2008 **
7 **-------------------------------------------------------------------**/
10 /******************************************************************************
11 * CLooG : the Chunky Loop Generator (experimental) *
12 ******************************************************************************
13 * *
14 * Copyright (C) 2001-2008 Cedric Bastoul *
15 * *
16 * This is free software; you can redistribute it and/or modify it under the *
17 * terms of the GNU General Public License as published by the Free Software *
18 * Foundation; either version 2 of the License, or (at your option) any later *
19 * version. *
20 * *
21 * This software is distributed in the hope that it will be useful, but *
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
24 * for more details. *
25 * *
26 * You should have received a copy of the GNU General Public License along *
27 * with software; if not, write to the Free Software Foundation, Inc., *
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
29 * *
30 * CLooG, the Chunky Loop Generator *
31 * *
32 ******************************************************************************/
34 #include <ppl_c.h>
35 #include <gmp.h>
36 #include <stdlib.h>
37 #include <string.h>
39 #ifndef CLOOG_PPL_BACKEND_H
40 #define CLOOG_PPL_BACKEND_H
41 #if defined(__cplusplus)
42 extern "C"
44 #endif
46 extern void cloog_initialize (void);
47 static inline void cloog_finalize (void)
49 ppl_finalize ();
52 typedef mpz_t Value;
53 #define VALUE_FMT "%s"
55 #define value_init(val) mpz_init (val)
56 #define value_assign(v1, v2) mpz_set (v1, v2)
57 #define value_set_si(val, i) mpz_set_si (val, i)
58 #define value_get_si(val) mpz_get_si (val)
59 #define value_set_double(val, d) mpz_set_d (val, d)
60 #define value_clear(val) mpz_clear (val)
61 #define value_read(val, str) mpz_set_str (val, str, 10)
62 #define value_print(Dst, fmt, val) {char *str; \
63 void (*gmp_free) (void *, size_t); \
64 str = mpz_get_str(0,10,(val)); \
65 fprintf((Dst),(fmt),str); \
66 mp_get_memory_functions(NULL, NULL, &gmp_free); \
67 (*gmp_free) (str, strlen(str)+1); \
69 #define value_swap(val1, val2) mpz_swap (val1, val2)
70 #define value_eq(v1, v2) (mpz_cmp((v1),(v2)) == 0)
71 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
72 #define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
73 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
74 #define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
75 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
76 #define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
77 #define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
78 #define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
79 #define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
80 #define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
81 #define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
82 #define value_sign(val) (mpz_sgn(val))
83 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
84 #define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
85 #define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
86 #define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
87 #define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
88 #define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
89 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
90 #define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
91 #define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
92 #define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
93 #define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
94 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
95 #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
96 #define value_oppose(ref,val) (mpz_neg((ref),(val)))
97 #define value_absolute(ref,val) (mpz_abs((ref),(val)))
98 #define value_pos_p(val) (mpz_sgn(val) > 0)
99 #define value_neg_p(val) (mpz_sgn(val) < 0)
100 #define value_zero_p(val) (mpz_sgn(val) == 0)
101 #define value_notzero_p(val) (mpz_sgn(val) != 0)
102 #define value_one_p(val) (mpz_cmp_si(val,1) == 0)
103 #define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
104 #define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
105 #define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
106 #define value_cmp_si(val, n) (mpz_cmp_si(val,n))
108 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
110 static inline void
111 cloog_vector_set (Value * ptr, int n, unsigned length)
113 int i;
115 for (i = 0; i < length; i++, ptr++)
116 value_set_si (*ptr, n);
119 static inline void cloog_vector_copy (Value * p1, Value * p2, unsigned length)
121 int i;
123 for (i = 0; i < length; i++)
124 value_assign (*p2++, *p1++);
127 static inline void Gcd (Value a, Value b, Value * gcd)
129 Value a1, b1;
131 value_init (a1), value_assign (a1, a);
132 value_init (b1), value_assign (b1, b);
134 while (value_notzero_p (a1))
136 value_modulus (*gcd, b1, a1);
137 value_assign (b1, a1);
138 value_assign (a1, *gcd);
141 value_absolute (*gcd, b1);
142 value_clear (a1);
143 value_clear (b1);
147 typedef struct
149 unsigned Size;
150 Value *p;
151 } Vector;
154 static inline void Vector_Free (Vector * vector)
156 int i;
158 if (!vector)
159 return;
161 for (i = 0; i < vector->Size; i++)
162 value_clear (vector->p[i]);
164 free (vector->p);
165 free (vector);
168 typedef struct polyhedron
170 unsigned Dimension;
171 unsigned NbConstraints;
172 Value **Constraint;
173 } *polyhedron;
175 static inline unsigned cloog_pol_dim (polyhedron p)
177 return p->Dimension;
180 static inline unsigned cloog_pol_nbc (polyhedron p)
182 return p->NbConstraints;
185 typedef struct polyhedra_union
187 polyhedron _polyhedron;
188 struct polyhedra_union *_next;
189 } *polyhedra_union;
191 static inline polyhedra_union cloog_new_upol (polyhedron p)
193 polyhedra_union ppl =
194 (polyhedra_union) malloc (sizeof (struct polyhedra_union));
195 ppl->_polyhedron = p;
196 ppl->_next = NULL;
197 return ppl;
200 static inline polyhedra_union cloog_upol_next (polyhedra_union p)
202 return p->_next;
205 static inline void
206 cloog_upol_set_next (polyhedra_union p, polyhedra_union n)
208 p->_next = n;
211 static inline polyhedron cloog_upol_polyhedron (polyhedra_union upol)
213 return upol->_polyhedron;
216 static inline void
217 cloog_upol_set_polyhedron (polyhedra_union ppl, polyhedron p)
219 ppl->_polyhedron = p;
222 static inline unsigned cloog_upol_dim (polyhedra_union p)
224 return cloog_pol_dim (cloog_upol_polyhedron (p));
227 static inline unsigned cloog_upol_nbc (polyhedra_union p)
229 return cloog_pol_nbc (cloog_upol_polyhedron (p));
233 typedef struct cloogdomain
235 struct polyhedra_union *_union;
236 int _references;
237 } CloogDomain;
239 extern void debug_cloog_domain (CloogDomain *);
241 static inline polyhedra_union cloog_domain_upol (CloogDomain * domain)
243 return domain->_union;
246 static inline polyhedron cloog_domain_polyhedron (CloogDomain * domain)
248 return cloog_upol_polyhedron (cloog_domain_upol (domain));
251 static inline unsigned cloog_domain_dim (CloogDomain * d)
253 return cloog_pol_dim (cloog_domain_polyhedron (d));
256 static inline int cloog_domain_nbconstraints (CloogDomain * domain)
258 return cloog_pol_nbc (cloog_domain_polyhedron (domain));
261 static inline unsigned cloog_pol_nbeq (polyhedron p)
263 int i, res = 0;
265 for (i = 0; i < p->NbConstraints; i++)
266 res += value_zero_p (p->Constraint[i][0]) ? 1 : 0;
268 return res;
271 static inline unsigned cloog_domain_nbeq (CloogDomain * d)
273 return cloog_pol_nbeq (cloog_upol_polyhedron (cloog_domain_upol (d)));
276 static inline Vector *Vector_Alloc (unsigned length)
278 int i;
279 Vector *vector = (Vector *) malloc (sizeof (Vector));
281 vector->Size = length;
282 vector->p = (Value *) malloc (length * sizeof (Value));
284 for (i = 0; i < length; i++)
285 value_init (vector->p[i]);
287 return vector;
290 typedef struct cloog_matrix
292 int NbRows;
293 int NbColumns;
294 Value **p;
295 } CloogMatrix;
297 void cloog_matrix_print (FILE *, CloogMatrix *);
298 void cloog_matrix_free (CloogMatrix *);
299 CloogMatrix *cloog_matrix_alloc (unsigned, unsigned);
300 void debug_cloog_matrix (CloogMatrix *);
301 void cloog_matrix_print_structure (FILE *, CloogMatrix *, int);
302 CloogMatrix *cloog_matrix_read (FILE *);
303 void cloog_matrix_normalize (CloogMatrix *, int);
304 void cloog_matrix_equality_update (CloogMatrix *, int, int);
305 CloogMatrix *cloog_matrix_copy (CloogMatrix *);
306 Value *cloog_matrix_vector_copy (Value *, int);
307 Value *cloog_matrix_vector_simplify (Value *, CloogMatrix *, int, int, int);
308 CloogMatrix *cloog_matrix_simplify (CloogMatrix *, CloogMatrix *, int, int);
309 void cloog_matrix_vector_free (Value *, int);
311 static inline CloogMatrix *cloog_pol_matrix (polyhedron p)
313 int cols = cloog_pol_dim (p) + 2;
314 int rows = cloog_pol_nbc (p);
315 int i, j;
316 CloogMatrix *res = cloog_matrix_alloc (rows, cols);
318 for (i = 0; i < rows; i++)
319 for (j = 0; j < cols; j++)
320 value_assign (res->p[i][j], p->Constraint[i][j]);
322 return res;
325 static inline int cloog_matrix_ncolumns (CloogMatrix * m)
327 return m->NbColumns;
330 static inline int cloog_matrix_nrows (CloogMatrix * m)
332 return m->NbRows;
335 static inline int cloog_first_non_zero (Value * p, unsigned len)
337 Value *ptr = p;
338 int i;
340 for (i = 0; i < len; i++, ptr++)
341 if (value_notzero_p (*ptr))
342 break;
344 return i == len ? -1 : i;
347 static inline polyhedron cloog_new_pol (int dim, int nrows)
349 int i;
350 polyhedron res = (polyhedron) malloc (sizeof (struct polyhedron));
351 int ncolumns = dim + 2;
352 int n = nrows * ncolumns;
353 Value *p = (Value *) malloc (n * sizeof (Value));
355 res->Dimension = dim;
356 res->NbConstraints = nrows;
357 res->Constraint = (Value **) malloc (nrows * sizeof (Value *));
359 for (i = 0; i < n; ++i)
360 value_init (p[i]);
362 for (i = 0; i < nrows; i++, p += ncolumns)
363 res->Constraint[i] = p;
365 return res;
368 static inline polyhedron cloog_universe_polyhedron (unsigned dim)
370 polyhedron res = cloog_new_pol (dim, 1);
372 cloog_vector_set (res->Constraint[0], 0, dim + 2);
373 value_set_si (res->Constraint[0][0], 1);
374 value_set_si (res->Constraint[0][dim + 1], 1);
376 return res;
379 static inline polyhedron cloog_empty_polyhedron (int dim)
381 int i;
382 polyhedron res = cloog_new_pol (dim, dim + 1);
384 cloog_vector_set (res->Constraint[0], 0, (dim + 1) * (dim + 2));
386 for (i = 0; i <= dim; i++)
387 value_set_si (res->Constraint[i][i + 1], 1);
389 return res;
392 static inline void
393 cloog_matrix_exchange_rows (CloogMatrix * m, int row1, int row2)
395 int i;
397 for (i = 0; i < m->NbColumns; i++)
398 value_swap (m->p[row1][i], m->p[row2][i]);
401 static inline void cloog_vector_exchange (Value * p1, Value * p2, int len)
403 for (; len > 0; len--)
404 value_swap (p1[len - 1], p2[len - 1]);
407 polyhedron cloog_pol_from_matrix (CloogMatrix * m);
409 static inline void cloog_pol_free (polyhedron pol)
411 int n, i;
413 if (!pol)
414 return;
416 n = (cloog_pol_dim (pol) + 2) * cloog_pol_nbc (pol);
418 for (i = 0; i < n; i++)
419 value_clear (pol->Constraint[0][i]);
421 free (pol->Constraint[0]);
422 free (pol->Constraint);
423 free (pol);
426 polyhedron cloog_pol_copy (polyhedron pol);
427 void cloog_vector_gcd (Value *, unsigned, Value *);
429 static inline int
430 cloog_pol_lexico_lt (polyhedron p, int i, int j)
432 int k;
433 Value a, b;
435 value_init (a), value_init (b);
437 for (k = 1; k < cloog_pol_dim (p) + 2; k++)
439 value_absolute (a, p->Constraint[i][k]);
440 value_absolute (b, p->Constraint[j][k]);
442 if (value_lt (a, b))
443 return 1;
445 if (value_gt (a, b))
446 return 0;
448 if (value_lt (p->Constraint[i][k], p->Constraint[j][k]))
449 return 1;
451 if (value_gt (p->Constraint[i][k], p->Constraint[j][k]))
452 return 0;
455 value_clear (a), value_clear (b);
457 return 0;
460 static inline void
461 cloog_pol_exchange_rows (polyhedron p, int row1, int row2)
463 int i;
465 for (i = 0; i < (int) cloog_pol_dim (p) + 2; i++)
466 value_swap (p->Constraint[row1][i], p->Constraint[row2][i]);
469 static inline void
470 cloog_pol_sort_rows (polyhedron p)
472 int i, j;
473 int nbeq = cloog_pol_nbeq (p);
475 /* First sort the equalities. The equalities should be the first
476 rows in the matrix. */
477 for (i = 0; i < nbeq; i++)
478 for (j = i + 1; j < nbeq; j++)
479 if (cloog_pol_lexico_lt (p, i, j))
480 cloog_pol_exchange_rows (p, i, j);
482 /* Sort inequalities. */
483 for (i = nbeq; i < cloog_pol_nbc (p); i++)
484 for (j = i + 1; j < cloog_pol_nbc (p); j++)
485 if (cloog_pol_lexico_lt (p, i, j))
486 cloog_pol_exchange_rows (p, i, j);
489 static inline CloogMatrix *
490 cloog_upol_domain2matrix (polyhedra_union upol)
492 return cloog_pol_matrix (cloog_upol_polyhedron (upol));
495 static inline void
496 cloog_vector_normalize (Value * p, unsigned len)
498 int i;
499 Value *ptr, gcd, one;
501 value_init (gcd);
502 cloog_vector_gcd (p, len, &gcd);
503 value_init (one);
504 value_set_si (one, 1);
506 if (value_gt (gcd, one))
507 for (ptr = p, i = 0; i < len; i++, ptr++)
508 value_division (*ptr, *ptr, gcd);
510 value_clear (one), value_clear (gcd);
513 static inline void cloog_vector_scale (Value * p1, Value * p2,
514 Value x,
515 unsigned length)
517 int i;
519 for (i = 0; i < length; i++)
520 value_multiply (*p2++, *p1++, x);
523 static inline void
524 cloog_vector_combine (Value * p1, Value * p2, Value * p3, Value x,
525 Value y, unsigned length)
527 Value tmp;
528 int i;
530 value_init (tmp);
532 for (i = 0; i < length; i++)
534 value_multiply (tmp, x, p1[i]);
535 value_addmul (tmp, y, p2[i]);
536 value_assign (p3[i], tmp);
539 value_clear (tmp);
542 #if defined(__cplusplus)
544 #endif
545 #endif /* define _H */