Fix memory leaks.
[cloog-ppl.git] / include / cloog / ppl_backend.h
blob6f83f98917472d31f804181f6bc59bb463390bf2
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
42 #if PPL_VERSION_MAJOR == 0 && PPL_VERSION_MINOR < 10
43 # error "PPL version 0.10 or following is required"
44 #endif
46 #if defined(__cplusplus)
47 extern "C"
49 #endif
51 extern void cloog_initialize (void);
52 static inline void cloog_finalize (void)
54 ppl_finalize ();
57 typedef mpz_t Value;
58 #define VALUE_FMT "%s"
60 #define value_init(val) mpz_init (val)
61 #define value_assign(v1, v2) mpz_set (v1, v2)
62 #define value_set_si(val, i) mpz_set_si (val, i)
63 #define value_get_si(val) mpz_get_si (val)
64 #define value_set_double(val, d) mpz_set_d (val, d)
65 #define value_clear(val) mpz_clear (val)
66 #define value_read(val, str) mpz_set_str (val, str, 10)
67 #define value_print(Dst, fmt, val) {char *str; \
68 void (*gmp_free) (void *, size_t); \
69 str = mpz_get_str(0,10,(val)); \
70 fprintf((Dst),(fmt),str); \
71 mp_get_memory_functions(NULL, NULL, &gmp_free); \
72 (*gmp_free) (str, strlen(str)+1); \
74 #define value_swap(val1, val2) mpz_swap (val1, val2)
75 #define value_eq(v1, v2) (mpz_cmp((v1),(v2)) == 0)
76 #define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
77 #define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
78 #define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
79 #define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
80 #define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
81 #define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
82 #define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
83 #define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
84 #define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
85 #define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
86 #define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
87 #define value_sign(val) (mpz_sgn(val))
88 #define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
89 #define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
90 #define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
91 #define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
92 #define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
93 #define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
94 #define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
95 #define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
96 #define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
97 #define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
98 #define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
99 #define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
100 #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
101 #define value_oppose(ref,val) (mpz_neg((ref),(val)))
102 #define value_absolute(ref,val) (mpz_abs((ref),(val)))
103 #define value_pos_p(val) (mpz_sgn(val) > 0)
104 #define value_neg_p(val) (mpz_sgn(val) < 0)
105 #define value_zero_p(val) (mpz_sgn(val) == 0)
106 #define value_notzero_p(val) (mpz_sgn(val) != 0)
107 #define value_one_p(val) (mpz_cmp_si(val,1) == 0)
108 #define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
109 #define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
110 #define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
111 #define value_cmp_si(val, n) (mpz_cmp_si(val,n))
113 #define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
115 static inline void
116 cloog_vector_set (Value * ptr, int n, unsigned length)
118 unsigned i;
120 for (i = 0; i < length; i++, ptr++)
121 value_set_si (*ptr, n);
124 static inline void cloog_vector_copy (Value * p1, Value * p2, unsigned length)
126 unsigned i;
128 for (i = 0; i < length; i++)
129 value_assign (*p2++, *p1++);
132 static inline void Gcd (Value a, Value b, Value * gcd)
134 Value a1, b1;
136 value_init (a1), value_assign (a1, a);
137 value_init (b1), value_assign (b1, b);
139 while (value_notzero_p (a1))
141 value_modulus (*gcd, b1, a1);
142 value_assign (b1, a1);
143 value_assign (a1, *gcd);
146 value_absolute (*gcd, b1);
147 value_clear (a1);
148 value_clear (b1);
152 typedef struct
154 unsigned Size;
155 Value *p;
156 } Vector;
159 static inline void Vector_Free (Vector * vector)
161 unsigned i;
163 if (!vector)
164 return;
166 for (i = 0; i < vector->Size; i++)
167 value_clear (vector->p[i]);
169 free (vector->p);
170 free (vector);
173 typedef struct polyhedron
175 unsigned Dimension;
176 unsigned NbConstraints;
177 Value **Constraint;
178 } *polyhedron;
180 static inline unsigned cloog_pol_dim (polyhedron p)
182 return p->Dimension;
185 static inline unsigned cloog_pol_nbc (polyhedron p)
187 return p->NbConstraints;
190 typedef struct polyhedra_union
192 polyhedron _polyhedron;
193 struct polyhedra_union *_next;
194 } *polyhedra_union;
196 extern polyhedra_union cloog_new_upol (polyhedron);
198 static inline polyhedra_union cloog_upol_next (polyhedra_union p)
200 return p->_next;
203 static inline void
204 cloog_upol_set_next (polyhedra_union p, polyhedra_union n)
206 p->_next = n;
209 static inline polyhedron cloog_upol_polyhedron (polyhedra_union upol)
211 return upol->_polyhedron;
214 static inline void
215 cloog_upol_set_polyhedron (polyhedra_union ppl, polyhedron p)
217 ppl->_polyhedron = p;
220 static inline unsigned cloog_upol_dim (polyhedra_union p)
222 return cloog_pol_dim (cloog_upol_polyhedron (p));
225 static inline unsigned cloog_upol_nbc (polyhedra_union p)
227 return cloog_pol_nbc (cloog_upol_polyhedron (p));
230 static inline void cloog_upol_free (polyhedra_union upol)
232 free (upol);
235 typedef struct cloogdomain
237 struct polyhedra_union *_union;
238 int _references;
239 } 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 unsigned 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 extern Vector *Vector_Alloc (unsigned);
278 typedef struct cloog_matrix
280 int NbRows;
281 int NbColumns;
282 Value **p;
283 } CloogMatrix;
285 void cloog_matrix_print (FILE *, CloogMatrix *);
286 void cloog_matrix_free (CloogMatrix *);
287 CloogMatrix *cloog_matrix_alloc (unsigned, unsigned);
288 void cloog_matrix_print_structure (FILE *, CloogMatrix *, int);
289 CloogMatrix *cloog_matrix_read (FILE *);
290 void cloog_matrix_normalize (CloogMatrix *, int);
291 void cloog_matrix_equality_update (CloogMatrix *, int, int);
292 CloogMatrix *cloog_matrix_copy (CloogMatrix *);
293 Value *cloog_matrix_vector_copy (Value *, int);
294 Value *cloog_matrix_vector_simplify (Value *, CloogMatrix *, int, int, int);
295 CloogMatrix *cloog_matrix_simplify (CloogMatrix *, CloogMatrix *, int, int);
296 void cloog_matrix_vector_free (Value *, int);
298 static inline CloogMatrix *cloog_pol_matrix (polyhedron p)
300 int cols = cloog_pol_dim (p) + 2;
301 int rows = cloog_pol_nbc (p);
302 int i, j;
303 CloogMatrix *res = cloog_matrix_alloc (rows, cols);
305 for (i = 0; i < rows; i++)
306 for (j = 0; j < cols; j++)
307 value_assign (res->p[i][j], p->Constraint[i][j]);
309 return res;
312 static inline int cloog_matrix_ncolumns (CloogMatrix * m)
314 return m->NbColumns;
317 static inline int cloog_matrix_nrows (CloogMatrix * m)
319 return m->NbRows;
322 static inline int cloog_first_non_zero (Value * p, unsigned len)
324 Value *ptr = p;
325 unsigned i;
327 for (i = 0; i < len; i++, ptr++)
328 if (value_notzero_p (*ptr))
329 break;
331 return i == len ? -1 : (int) i;
334 polyhedron cloog_new_pol (int, int);
336 static inline polyhedron cloog_universe_polyhedron (unsigned dim)
338 polyhedron res = cloog_new_pol (dim, 1);
340 cloog_vector_set (res->Constraint[0], 0, dim + 2);
341 value_set_si (res->Constraint[0][0], 1);
342 value_set_si (res->Constraint[0][dim + 1], 1);
344 return res;
347 static inline polyhedron cloog_empty_polyhedron (int dim)
349 int i;
350 polyhedron res = cloog_new_pol (dim, dim + 1);
352 cloog_vector_set (res->Constraint[0], 0, (dim + 1) * (dim + 2));
354 for (i = 0; i <= dim; i++)
355 value_set_si (res->Constraint[i][i + 1], 1);
357 return res;
360 static inline void
361 cloog_matrix_exchange_rows (CloogMatrix * m, int row1, int row2)
363 int i;
365 for (i = 0; i < m->NbColumns; i++)
366 value_swap (m->p[row1][i], m->p[row2][i]);
369 static inline void cloog_vector_exchange (Value * p1, Value * p2, int len)
371 for (; len > 0; len--)
372 value_swap (p1[len - 1], p2[len - 1]);
375 polyhedron cloog_pol_from_matrix (CloogMatrix * m);
377 static inline void cloog_pol_free (polyhedron pol)
379 int n, i;
381 if (!pol)
382 return;
384 n = (cloog_pol_dim (pol) + 2) * cloog_pol_nbc (pol);
386 for (i = 0; i < n; i++)
387 value_clear (pol->Constraint[0][i]);
389 free (pol->Constraint[0]);
390 free (pol->Constraint);
391 free (pol);
394 polyhedron cloog_pol_copy (polyhedron pol);
395 void cloog_vector_gcd (Value *, int, Value *);
397 static inline int
398 cloog_pol_lexico_lt (polyhedron p, int i, int j)
400 int res = 0;
401 unsigned k;
402 Value a, b;
404 value_init (a), value_init (b);
406 for (k = 1; k < cloog_pol_dim (p) + 2; k++)
408 value_absolute (a, p->Constraint[i][k]);
409 value_absolute (b, p->Constraint[j][k]);
411 if (value_lt (a, b))
413 res = 1;
414 goto clear;
417 if (value_gt (a, b))
419 res = 0;
420 goto clear;
423 if (value_lt (p->Constraint[i][k], p->Constraint[j][k]))
425 res = 1;
426 goto clear;
429 if (value_gt (p->Constraint[i][k], p->Constraint[j][k]))
431 res = 0;
432 goto clear;
436 clear:
437 value_clear (a), value_clear (b);
438 return res;
441 static inline void
442 cloog_pol_exchange_rows (polyhedron p, int row1, int row2)
444 int i;
446 for (i = 0; i < (int) cloog_pol_dim (p) + 2; i++)
447 value_swap (p->Constraint[row1][i], p->Constraint[row2][i]);
450 static inline void
451 cloog_pol_sort_rows (polyhedron p)
453 unsigned i, j;
454 unsigned nbeq = cloog_pol_nbeq (p);
456 /* First sort the equalities. The equalities should be the first
457 rows in the matrix. */
458 for (i = 0; i < nbeq; i++)
459 for (j = i + 1; j < nbeq; j++)
460 if (cloog_pol_lexico_lt (p, i, j))
461 cloog_pol_exchange_rows (p, i, j);
463 /* Sort inequalities. */
464 for (i = nbeq; i < cloog_pol_nbc (p); i++)
465 for (j = i + 1; j < cloog_pol_nbc (p); j++)
466 if (cloog_pol_lexico_lt (p, i, j))
467 cloog_pol_exchange_rows (p, i, j);
470 static inline CloogMatrix *
471 cloog_upol_domain2matrix (polyhedra_union upol)
473 return cloog_pol_matrix (cloog_upol_polyhedron (upol));
476 static inline CloogMatrix *
477 cloog_domain_domain2matrix (CloogDomain *d)
479 return cloog_pol_matrix (cloog_domain_polyhedron (d));
482 static inline void
483 cloog_vector_normalize (Value * p, unsigned len)
485 unsigned i;
486 Value *ptr, gcd, one;
488 value_init (gcd);
489 cloog_vector_gcd (p, len, &gcd);
490 value_init (one);
491 value_set_si (one, 1);
493 if (value_gt (gcd, one))
494 for (ptr = p, i = 0; i < len; i++, ptr++)
495 value_division (*ptr, *ptr, gcd);
497 value_clear (one), value_clear (gcd);
500 static inline void cloog_vector_scale (Value * p1, Value * p2,
501 Value x,
502 unsigned length)
504 unsigned i;
506 for (i = 0; i < length; i++)
507 value_multiply (*p2++, *p1++, x);
510 static inline void
511 cloog_vector_combine (Value * p1, Value * p2, Value * p3, Value x,
512 Value y, unsigned length)
514 Value tmp;
515 unsigned i;
517 value_init (tmp);
519 for (i = 0; i < length; i++)
521 value_multiply (tmp, x, p1[i]);
522 value_addmul (tmp, y, p2[i]);
523 value_assign (p3[i], tmp);
526 value_clear (tmp);
529 extern void debug_poly (polyhedron);
530 extern void debug_ppl_poly (ppl_Polyhedron_t);
531 extern void debug_cloog_matrix (CloogMatrix *);
532 extern void debug_cloog_domain (CloogDomain *);
533 extern void debug_value (Value);
534 extern void debug_values (Value *, int);
536 #if defined(__cplusplus)
538 #endif
539 #endif /* define _H */