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
42 #if PPL_VERSION_MAJOR == 0 && PPL_VERSION_MINOR < 10
43 # error "PPL version 0.10 or following is required"
46 #if defined(__cplusplus)
51 extern void cloog_initialize (void);
52 static inline void cloog_finalize (void)
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)))
116 cloog_vector_set (Value
* ptr
, int n
, unsigned length
)
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
)
128 for (i
= 0; i
< length
; i
++)
129 value_assign (*p2
++, *p1
++);
132 static inline void Gcd (Value a
, Value b
, Value
* gcd
)
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
);
159 static inline void Vector_Free (Vector
* vector
)
166 for (i
= 0; i
< vector
->Size
; i
++)
167 value_clear (vector
->p
[i
]);
173 typedef struct polyhedron
176 unsigned NbConstraints
;
180 static inline unsigned cloog_pol_dim (polyhedron p
)
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
;
196 extern polyhedra_union
cloog_new_upol (polyhedron
);
198 static inline polyhedra_union
cloog_upol_next (polyhedra_union p
)
204 cloog_upol_set_next (polyhedra_union p
, polyhedra_union n
)
209 static inline polyhedron
cloog_upol_polyhedron (polyhedra_union upol
)
211 return upol
->_polyhedron
;
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
)
235 typedef struct cloogdomain
237 struct polyhedra_union
*_union
;
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 extern Vector
*Vector_Alloc (unsigned);
278 typedef struct cloog_matrix
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
);
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
]);
312 static inline int cloog_matrix_ncolumns (CloogMatrix
* m
)
317 static inline int cloog_matrix_nrows (CloogMatrix
* m
)
322 static inline int cloog_first_non_zero (Value
* p
, unsigned len
)
327 for (i
= 0; i
< len
; i
++, ptr
++)
328 if (value_notzero_p (*ptr
))
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);
347 static inline polyhedron
cloog_empty_polyhedron (int dim
)
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);
361 cloog_matrix_exchange_rows (CloogMatrix
* m
, int row1
, int row2
)
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
)
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
);
394 polyhedron
cloog_pol_copy (polyhedron pol
);
395 void cloog_vector_gcd (Value
*, int, Value
*);
398 cloog_pol_lexico_lt (polyhedron p
, int i
, int j
)
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
]);
423 if (value_lt (p
->Constraint
[i
][k
], p
->Constraint
[j
][k
]))
429 if (value_gt (p
->Constraint
[i
][k
], p
->Constraint
[j
][k
]))
437 value_clear (a
), value_clear (b
);
442 cloog_pol_exchange_rows (polyhedron p
, int row1
, int row2
)
446 for (i
= 0; i
< (int) cloog_pol_dim (p
) + 2; i
++)
447 value_swap (p
->Constraint
[row1
][i
], p
->Constraint
[row2
][i
]);
451 cloog_pol_sort_rows (polyhedron p
)
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
));
483 cloog_vector_normalize (Value
* p
, unsigned len
)
486 Value
*ptr
, gcd
, one
;
489 cloog_vector_gcd (p
, len
, &gcd
);
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
,
506 for (i
= 0; i
< length
; i
++)
507 value_multiply (*p2
++, *p1
++, x
);
511 cloog_vector_combine (Value
* p1
, Value
* p2
, Value
* p3
, Value x
,
512 Value y
, unsigned length
)
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
);
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)
539 #endif /* define _H */