1 /**-------------------------------------------------------------------**
3 **-------------------------------------------------------------------**
5 **-------------------------------------------------------------------**
6 ** First version: July 22th 2008 **
7 **-------------------------------------------------------------------**/
10 /******************************************************************************
11 * CLooG : the Chunky Loop Generator (experimental) *
12 ******************************************************************************
14 * Copyright (C) 2001-2008 Cedric Bastoul *
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 *
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 *
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 *
30 * CLooG, the Chunky Loop Generator *
32 ******************************************************************************/
39 #ifndef CLOOG_PPL_BACKEND_H
40 #define CLOOG_PPL_BACKEND_H
41 #if defined(__cplusplus)
46 extern void cloog_initialize (void);
47 static inline void cloog_finalize (void)
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)))
111 cloog_vector_set (Value
* ptr
, int n
, unsigned length
)
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
)
123 for (i
= 0; i
< length
; i
++)
124 value_assign (*p2
++, *p1
++);
127 static inline void Gcd (Value a
, Value b
, Value
* gcd
)
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
);
154 static inline void Vector_Free (Vector
* vector
)
161 for (i
= 0; i
< vector
->Size
; i
++)
162 value_clear (vector
->p
[i
]);
168 typedef struct polyhedron
171 unsigned NbConstraints
;
175 static inline unsigned cloog_pol_dim (polyhedron p
)
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
;
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
;
200 static inline polyhedra_union
cloog_upol_next (polyhedra_union p
)
206 cloog_upol_set_next (polyhedra_union p
, polyhedra_union n
)
211 static inline polyhedron
cloog_upol_polyhedron (polyhedra_union upol
)
213 return upol
->_polyhedron
;
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
;
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
)
265 for (i
= 0; i
< p
->NbConstraints
; i
++)
266 res
+= value_zero_p (p
->Constraint
[i
][0]) ? 1 : 0;
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
)
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
]);
290 typedef struct cloog_matrix
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
);
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
]);
325 static inline int cloog_matrix_ncolumns (CloogMatrix
* m
)
330 static inline int cloog_matrix_nrows (CloogMatrix
* m
)
335 static inline int cloog_first_non_zero (Value
* p
, unsigned len
)
340 for (i
= 0; i
< len
; i
++, ptr
++)
341 if (value_notzero_p (*ptr
))
344 return i
== len
? -1 : i
;
347 static inline polyhedron
cloog_new_pol (int dim
, int nrows
)
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
)
362 for (i
= 0; i
< nrows
; i
++, p
+= ncolumns
)
363 res
->Constraint
[i
] = p
;
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);
379 static inline polyhedron
cloog_empty_polyhedron (int dim
)
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);
393 cloog_matrix_exchange_rows (CloogMatrix
* m
, int row1
, int row2
)
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
)
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
);
426 polyhedron
cloog_pol_copy (polyhedron pol
);
427 void cloog_vector_gcd (Value
*, unsigned, Value
*);
430 cloog_pol_lexico_lt (polyhedron p
, int i
, int j
)
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
]);
448 if (value_lt (p
->Constraint
[i
][k
], p
->Constraint
[j
][k
]))
451 if (value_gt (p
->Constraint
[i
][k
], p
->Constraint
[j
][k
]))
455 value_clear (a
), value_clear (b
);
461 cloog_pol_exchange_rows (polyhedron p
, int row1
, int row2
)
465 for (i
= 0; i
< (int) cloog_pol_dim (p
) + 2; i
++)
466 value_swap (p
->Constraint
[row1
][i
], p
->Constraint
[row2
][i
]);
470 cloog_pol_sort_rows (polyhedron p
)
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
));
496 cloog_vector_normalize (Value
* p
, unsigned len
)
499 Value
*ptr
, gcd
, one
;
502 cloog_vector_gcd (p
, len
, &gcd
);
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
,
519 for (i
= 0; i
< length
; i
++)
520 value_multiply (*p2
++, *p1
++, x
);
524 cloog_vector_combine (Value
* p1
, Value
* p2
, Value
* p3
, Value x
,
525 Value y
, unsigned length
)
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
);
542 #if defined(__cplusplus)
545 #endif /* define _H */