1*e4b17023SJohn Marino /* Gimple Represented as Polyhedra.
2*e4b17023SJohn Marino    Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3*e4b17023SJohn Marino    Contributed by Sebastian Pop <sebastian.pop@amd.com>
4*e4b17023SJohn Marino    and Tobias Grosser <grosser@fim.uni-passau.de>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino #ifdef HAVE_cloog
27*e4b17023SJohn Marino 
28*e4b17023SJohn Marino #include "ppl_c.h"
29*e4b17023SJohn Marino #include "graphite-cloog-util.h"
30*e4b17023SJohn Marino #include "graphite-ppl.h"
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino /* Set the inhomogeneous term of E to X.  */
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino void
ppl_set_inhomogeneous_gmp(ppl_Linear_Expression_t e,mpz_t x)35*e4b17023SJohn Marino ppl_set_inhomogeneous_gmp (ppl_Linear_Expression_t e, mpz_t x)
36*e4b17023SJohn Marino {
37*e4b17023SJohn Marino   mpz_t v0, v1;
38*e4b17023SJohn Marino   ppl_Coefficient_t c;
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino   mpz_init (v0);
41*e4b17023SJohn Marino   mpz_init (v1);
42*e4b17023SJohn Marino   ppl_new_Coefficient (&c);
43*e4b17023SJohn Marino 
44*e4b17023SJohn Marino   ppl_Linear_Expression_inhomogeneous_term (e, c);
45*e4b17023SJohn Marino   ppl_Coefficient_to_mpz_t (c, v1);
46*e4b17023SJohn Marino   mpz_neg (v1, v1);
47*e4b17023SJohn Marino   mpz_set (v0, x);
48*e4b17023SJohn Marino   mpz_add (v0, v0, v1);
49*e4b17023SJohn Marino   ppl_assign_Coefficient_from_mpz_t (c, v0);
50*e4b17023SJohn Marino   ppl_Linear_Expression_add_to_inhomogeneous (e, c);
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino   mpz_clear (v0);
53*e4b17023SJohn Marino   mpz_clear (v1);
54*e4b17023SJohn Marino   ppl_delete_Coefficient (c);
55*e4b17023SJohn Marino }
56*e4b17023SJohn Marino 
57*e4b17023SJohn Marino /* Set E[I] to X.  */
58*e4b17023SJohn Marino 
59*e4b17023SJohn Marino void
ppl_set_coef_gmp(ppl_Linear_Expression_t e,ppl_dimension_type i,mpz_t x)60*e4b17023SJohn Marino ppl_set_coef_gmp (ppl_Linear_Expression_t e, ppl_dimension_type i, mpz_t x)
61*e4b17023SJohn Marino {
62*e4b17023SJohn Marino   mpz_t v0, v1;
63*e4b17023SJohn Marino   ppl_Coefficient_t c;
64*e4b17023SJohn Marino 
65*e4b17023SJohn Marino   mpz_init (v0);
66*e4b17023SJohn Marino   mpz_init (v1);
67*e4b17023SJohn Marino   ppl_new_Coefficient (&c);
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino   ppl_Linear_Expression_coefficient (e, i, c);
70*e4b17023SJohn Marino   ppl_Coefficient_to_mpz_t (c, v1);
71*e4b17023SJohn Marino   mpz_neg (v1, v1);
72*e4b17023SJohn Marino   mpz_set (v0, x);
73*e4b17023SJohn Marino   mpz_add (v0, v0, v1);
74*e4b17023SJohn Marino   ppl_assign_Coefficient_from_mpz_t (c, v0);
75*e4b17023SJohn Marino   ppl_Linear_Expression_add_to_coefficient (e, i, c);
76*e4b17023SJohn Marino 
77*e4b17023SJohn Marino   mpz_clear (v0);
78*e4b17023SJohn Marino   mpz_clear (v1);
79*e4b17023SJohn Marino   ppl_delete_Coefficient (c);
80*e4b17023SJohn Marino }
81*e4b17023SJohn Marino 
82*e4b17023SJohn Marino /* Insert after X NB_NEW_DIMS empty dimensions into PH.
83*e4b17023SJohn Marino 
84*e4b17023SJohn Marino    With x = 3 and nb_new_dims = 4
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino    |  d0 d1 d2 d3 d4
87*e4b17023SJohn Marino 
88*e4b17023SJohn Marino    is transformed to
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino    |  d0 d1 d2 x0 x1 x2 x3 d3 d4
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino    | map = {0, 1, 2, 7, 8, 3, 4, 5, 6}
93*e4b17023SJohn Marino */
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino void
ppl_insert_dimensions_pointset(ppl_Pointset_Powerset_C_Polyhedron_t ph,int x,int nb_new_dims)96*e4b17023SJohn Marino ppl_insert_dimensions_pointset (ppl_Pointset_Powerset_C_Polyhedron_t ph, int x,
97*e4b17023SJohn Marino 				int nb_new_dims)
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino   ppl_dimension_type i, dim;
100*e4b17023SJohn Marino   ppl_dimension_type *map;
101*e4b17023SJohn Marino   ppl_dimension_type x_ppl, nb_new_dims_ppl;
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino   x_ppl = (ppl_dimension_type) x;
104*e4b17023SJohn Marino   nb_new_dims_ppl = (ppl_dimension_type) nb_new_dims;
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (ph, &dim);
107*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_add_space_dimensions_and_embed (ph, nb_new_dims);
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino   map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim + nb_new_dims);
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino   for (i = 0; i < x_ppl; i++)
112*e4b17023SJohn Marino     map[i] = i;
113*e4b17023SJohn Marino 
114*e4b17023SJohn Marino   for (i = x_ppl; i < x_ppl + nb_new_dims_ppl; i++)
115*e4b17023SJohn Marino     map[dim + i - x_ppl] = i;
116*e4b17023SJohn Marino 
117*e4b17023SJohn Marino   for (i = x_ppl + nb_new_dims_ppl; i < dim + nb_new_dims_ppl; i++)
118*e4b17023SJohn Marino     map[i - nb_new_dims_ppl] = i;
119*e4b17023SJohn Marino 
120*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_map_space_dimensions (ph, map, dim + nb_new_dims);
121*e4b17023SJohn Marino   free (map);
122*e4b17023SJohn Marino }
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino /* Insert after X NB_NEW_DIMS empty dimensions into PH.
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino    With x = 3 and nb_new_dims = 4
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino    |  d0 d1 d2 d3 d4
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino    is transformed to
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino    |  d0 d1 d2 x0 x1 x2 x3 d3 d4
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino    | map = {0, 1, 2, 7, 8, 3, 4, 5, 6}
135*e4b17023SJohn Marino */
136*e4b17023SJohn Marino 
137*e4b17023SJohn Marino void
ppl_insert_dimensions(ppl_Polyhedron_t ph,int x,int nb_new_dims)138*e4b17023SJohn Marino ppl_insert_dimensions (ppl_Polyhedron_t ph, int x,
139*e4b17023SJohn Marino 		       int nb_new_dims)
140*e4b17023SJohn Marino {
141*e4b17023SJohn Marino   ppl_dimension_type i, dim;
142*e4b17023SJohn Marino   ppl_dimension_type *map;
143*e4b17023SJohn Marino   ppl_dimension_type x_ppl, nb_new_dims_ppl;
144*e4b17023SJohn Marino 
145*e4b17023SJohn Marino   x_ppl = (ppl_dimension_type) x;
146*e4b17023SJohn Marino   nb_new_dims_ppl = (ppl_dimension_type) nb_new_dims;
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino   ppl_Polyhedron_space_dimension (ph, &dim);
149*e4b17023SJohn Marino   ppl_Polyhedron_add_space_dimensions_and_embed (ph, nb_new_dims);
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino   map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim + nb_new_dims);
152*e4b17023SJohn Marino 
153*e4b17023SJohn Marino   for (i = 0; i < x_ppl; i++)
154*e4b17023SJohn Marino     map[i] = i;
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino   for (i = x_ppl; i < x_ppl + nb_new_dims_ppl; i++)
157*e4b17023SJohn Marino     map[dim + i - x_ppl] = i;
158*e4b17023SJohn Marino 
159*e4b17023SJohn Marino   for (i = x_ppl + nb_new_dims_ppl; i < dim + nb_new_dims_ppl; i++)
160*e4b17023SJohn Marino     map[i - nb_new_dims_ppl] = i;
161*e4b17023SJohn Marino 
162*e4b17023SJohn Marino   ppl_Polyhedron_map_space_dimensions (ph, map, dim + nb_new_dims);
163*e4b17023SJohn Marino   free (map);
164*e4b17023SJohn Marino }
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino /* Based on the original polyhedron PH, returns a new polyhedron with
167*e4b17023SJohn Marino    an extra dimension placed at position LOOP + 1 that slices the
168*e4b17023SJohn Marino    dimension LOOP into strips of size STRIDE.  */
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino ppl_Polyhedron_t
ppl_strip_loop(ppl_Polyhedron_t ph,ppl_dimension_type loop,int stride)171*e4b17023SJohn Marino ppl_strip_loop (ppl_Polyhedron_t ph, ppl_dimension_type loop, int stride)
172*e4b17023SJohn Marino {
173*e4b17023SJohn Marino   ppl_const_Constraint_System_t pcs;
174*e4b17023SJohn Marino   ppl_Constraint_System_const_iterator_t cit, end;
175*e4b17023SJohn Marino   ppl_const_Constraint_t cstr;
176*e4b17023SJohn Marino   ppl_Linear_Expression_t expr;
177*e4b17023SJohn Marino   int v;
178*e4b17023SJohn Marino   ppl_dimension_type dim;
179*e4b17023SJohn Marino   ppl_Polyhedron_t res;
180*e4b17023SJohn Marino   ppl_Coefficient_t c;
181*e4b17023SJohn Marino   mpz_t val;
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   mpz_init (val);
184*e4b17023SJohn Marino   ppl_new_Coefficient (&c);
185*e4b17023SJohn Marino 
186*e4b17023SJohn Marino   ppl_Polyhedron_space_dimension (ph, &dim);
187*e4b17023SJohn Marino   ppl_Polyhedron_get_constraints (ph, &pcs);
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino   /* Start from a copy of the constraints.  */
190*e4b17023SJohn Marino   ppl_new_C_Polyhedron_from_space_dimension (&res, dim + 1, 0);
191*e4b17023SJohn Marino   ppl_Polyhedron_add_constraints (res, pcs);
192*e4b17023SJohn Marino 
193*e4b17023SJohn Marino   /* Add an empty dimension for the strip loop.  */
194*e4b17023SJohn Marino   ppl_insert_dimensions (res, loop, 1);
195*e4b17023SJohn Marino 
196*e4b17023SJohn Marino   /* Identify the constraints that define the lower and upper bounds
197*e4b17023SJohn Marino      of the strip-mined loop, and add them to the strip loop.  */
198*e4b17023SJohn Marino   {
199*e4b17023SJohn Marino     ppl_Polyhedron_t tmp;
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino     ppl_new_C_Polyhedron_from_space_dimension (&tmp, dim + 1, 0);
202*e4b17023SJohn Marino     ppl_new_Constraint_System_const_iterator (&cit);
203*e4b17023SJohn Marino     ppl_new_Constraint_System_const_iterator (&end);
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino     for (ppl_Constraint_System_begin (pcs, cit),
206*e4b17023SJohn Marino 	   ppl_Constraint_System_end (pcs, end);
207*e4b17023SJohn Marino 	 !ppl_Constraint_System_const_iterator_equal_test (cit, end);
208*e4b17023SJohn Marino 	 ppl_Constraint_System_const_iterator_increment (cit))
209*e4b17023SJohn Marino       {
210*e4b17023SJohn Marino 	ppl_Constraint_System_const_iterator_dereference (cit, &cstr);
211*e4b17023SJohn Marino 	ppl_new_Linear_Expression_from_Constraint (&expr, cstr);
212*e4b17023SJohn Marino 	ppl_Linear_Expression_coefficient (expr, loop, c);
213*e4b17023SJohn Marino 	ppl_delete_Linear_Expression (expr);
214*e4b17023SJohn Marino 	ppl_Coefficient_to_mpz_t (c, val);
215*e4b17023SJohn Marino 	v = mpz_get_si (val);
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino 	if (0 < v || v < 0)
218*e4b17023SJohn Marino 	  ppl_Polyhedron_add_constraint (tmp, cstr);
219*e4b17023SJohn Marino       }
220*e4b17023SJohn Marino     ppl_delete_Constraint_System_const_iterator (cit);
221*e4b17023SJohn Marino     ppl_delete_Constraint_System_const_iterator (end);
222*e4b17023SJohn Marino 
223*e4b17023SJohn Marino     ppl_insert_dimensions (tmp, loop + 1, 1);
224*e4b17023SJohn Marino     ppl_Polyhedron_get_constraints (tmp, &pcs);
225*e4b17023SJohn Marino     ppl_Polyhedron_add_constraints (res, pcs);
226*e4b17023SJohn Marino     ppl_delete_Polyhedron (tmp);
227*e4b17023SJohn Marino   }
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino   /* Lower bound of a tile starts at "stride * outer_iv".  */
230*e4b17023SJohn Marino   {
231*e4b17023SJohn Marino     ppl_Constraint_t new_cstr;
232*e4b17023SJohn Marino     ppl_new_Linear_Expression_with_dimension (&expr, dim + 1);
233*e4b17023SJohn Marino 
234*e4b17023SJohn Marino     ppl_set_coef (expr, loop + 1, 1);
235*e4b17023SJohn Marino     ppl_set_coef (expr, loop, -1 * stride);
236*e4b17023SJohn Marino 
237*e4b17023SJohn Marino     ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
238*e4b17023SJohn Marino     ppl_delete_Linear_Expression (expr);
239*e4b17023SJohn Marino     ppl_Polyhedron_add_constraint (res, new_cstr);
240*e4b17023SJohn Marino     ppl_delete_Constraint (new_cstr);
241*e4b17023SJohn Marino   }
242*e4b17023SJohn Marino 
243*e4b17023SJohn Marino   /* Upper bound of a tile stops at "stride * outer_iv + stride - 1",
244*e4b17023SJohn Marino      or at the old upper bound that is not modified.  */
245*e4b17023SJohn Marino   {
246*e4b17023SJohn Marino     ppl_Constraint_t new_cstr;
247*e4b17023SJohn Marino     ppl_new_Linear_Expression_with_dimension (&expr, dim + 1);
248*e4b17023SJohn Marino 
249*e4b17023SJohn Marino     ppl_set_coef (expr, loop + 1, -1);
250*e4b17023SJohn Marino     ppl_set_coef (expr, loop, stride);
251*e4b17023SJohn Marino     ppl_set_inhomogeneous (expr, stride - 1);
252*e4b17023SJohn Marino 
253*e4b17023SJohn Marino     ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
254*e4b17023SJohn Marino     ppl_delete_Linear_Expression (expr);
255*e4b17023SJohn Marino     ppl_Polyhedron_add_constraint (res, new_cstr);
256*e4b17023SJohn Marino     ppl_delete_Constraint (new_cstr);
257*e4b17023SJohn Marino   }
258*e4b17023SJohn Marino 
259*e4b17023SJohn Marino   mpz_clear (val);
260*e4b17023SJohn Marino   ppl_delete_Coefficient (c);
261*e4b17023SJohn Marino   return res;
262*e4b17023SJohn Marino }
263*e4b17023SJohn Marino 
264*e4b17023SJohn Marino /* Lexicographically compares two linear expressions A and B and
265*e4b17023SJohn Marino    returns negative when A < B, 0 when A == B and positive when A > B.  */
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino int
ppl_lexico_compare_linear_expressions(ppl_Linear_Expression_t a,ppl_Linear_Expression_t b)268*e4b17023SJohn Marino ppl_lexico_compare_linear_expressions (ppl_Linear_Expression_t a,
269*e4b17023SJohn Marino 				       ppl_Linear_Expression_t b)
270*e4b17023SJohn Marino {
271*e4b17023SJohn Marino   ppl_dimension_type min_length, length1, length2;
272*e4b17023SJohn Marino   ppl_dimension_type i;
273*e4b17023SJohn Marino   ppl_Coefficient_t c;
274*e4b17023SJohn Marino   int res;
275*e4b17023SJohn Marino   mpz_t va, vb;
276*e4b17023SJohn Marino 
277*e4b17023SJohn Marino   ppl_Linear_Expression_space_dimension (a, &length1);
278*e4b17023SJohn Marino   ppl_Linear_Expression_space_dimension (b, &length2);
279*e4b17023SJohn Marino   ppl_new_Coefficient (&c);
280*e4b17023SJohn Marino   mpz_init (va);
281*e4b17023SJohn Marino   mpz_init (vb);
282*e4b17023SJohn Marino 
283*e4b17023SJohn Marino   if (length1 < length2)
284*e4b17023SJohn Marino     min_length = length1;
285*e4b17023SJohn Marino   else
286*e4b17023SJohn Marino     min_length = length2;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   for (i = 0; i < min_length; i++)
289*e4b17023SJohn Marino     {
290*e4b17023SJohn Marino       ppl_Linear_Expression_coefficient (a, i, c);
291*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (c, va);
292*e4b17023SJohn Marino       ppl_Linear_Expression_coefficient (b, i, c);
293*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (c, vb);
294*e4b17023SJohn Marino       res = mpz_cmp (va, vb);
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino       if (res == 0)
297*e4b17023SJohn Marino 	continue;
298*e4b17023SJohn Marino 
299*e4b17023SJohn Marino       mpz_clear (va);
300*e4b17023SJohn Marino       mpz_clear (vb);
301*e4b17023SJohn Marino       ppl_delete_Coefficient (c);
302*e4b17023SJohn Marino       return res;
303*e4b17023SJohn Marino     }
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino   mpz_clear (va);
306*e4b17023SJohn Marino   mpz_clear (vb);
307*e4b17023SJohn Marino   ppl_delete_Coefficient (c);
308*e4b17023SJohn Marino   return length1 - length2;
309*e4b17023SJohn Marino }
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino /* Print to FILE the polyhedron PH under its PolyLib matrix form.  */
312*e4b17023SJohn Marino 
313*e4b17023SJohn Marino void
ppl_print_polyhedron_matrix(FILE * file,ppl_const_Polyhedron_t ph)314*e4b17023SJohn Marino ppl_print_polyhedron_matrix (FILE *file, ppl_const_Polyhedron_t ph)
315*e4b17023SJohn Marino {
316*e4b17023SJohn Marino   CloogMatrix *mat = new_Cloog_Matrix_from_ppl_Polyhedron (ph);
317*e4b17023SJohn Marino   cloog_matrix_print (file, mat);
318*e4b17023SJohn Marino   cloog_matrix_free (mat);
319*e4b17023SJohn Marino }
320*e4b17023SJohn Marino 
321*e4b17023SJohn Marino /* Print to FILE the linear expression LE.  */
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino void
ppl_print_linear_expr(FILE * file,ppl_Linear_Expression_t le)324*e4b17023SJohn Marino ppl_print_linear_expr (FILE *file, ppl_Linear_Expression_t le)
325*e4b17023SJohn Marino {
326*e4b17023SJohn Marino   ppl_Constraint_t c;
327*e4b17023SJohn Marino   ppl_Polyhedron_t pol;
328*e4b17023SJohn Marino   ppl_dimension_type dim;
329*e4b17023SJohn Marino 
330*e4b17023SJohn Marino   ppl_Linear_Expression_space_dimension (le, &dim);
331*e4b17023SJohn Marino   ppl_new_C_Polyhedron_from_space_dimension (&pol, dim, 0);
332*e4b17023SJohn Marino   ppl_new_Constraint (&c, le, PPL_CONSTRAINT_TYPE_EQUAL);
333*e4b17023SJohn Marino   ppl_Polyhedron_add_constraint (pol, c);
334*e4b17023SJohn Marino   ppl_print_polyhedron_matrix (file, pol);
335*e4b17023SJohn Marino }
336*e4b17023SJohn Marino 
337*e4b17023SJohn Marino /* Print to STDERR the linear expression LE.  */
338*e4b17023SJohn Marino 
339*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_ppl_linear_expr(ppl_Linear_Expression_t le)340*e4b17023SJohn Marino debug_ppl_linear_expr (ppl_Linear_Expression_t le)
341*e4b17023SJohn Marino {
342*e4b17023SJohn Marino   ppl_print_linear_expr (stderr, le);
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino 
345*e4b17023SJohn Marino /* Print to FILE the powerset PS in its PolyLib matrix form.  */
346*e4b17023SJohn Marino 
347*e4b17023SJohn Marino void
ppl_print_powerset_matrix(FILE * file,ppl_Pointset_Powerset_C_Polyhedron_t ps)348*e4b17023SJohn Marino ppl_print_powerset_matrix (FILE *file,
349*e4b17023SJohn Marino 			   ppl_Pointset_Powerset_C_Polyhedron_t ps)
350*e4b17023SJohn Marino {
351*e4b17023SJohn Marino   size_t nb_disjuncts;
352*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end;
353*e4b17023SJohn Marino 
354*e4b17023SJohn Marino   ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it);
355*e4b17023SJohn Marino   ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end);
356*e4b17023SJohn Marino 
357*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_size (ps, &nb_disjuncts);
358*e4b17023SJohn Marino   fprintf (file, "%d\n", (int) nb_disjuncts);
359*e4b17023SJohn Marino 
360*e4b17023SJohn Marino   for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it),
361*e4b17023SJohn Marino        ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end);
362*e4b17023SJohn Marino        !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end);
363*e4b17023SJohn Marino        ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it))
364*e4b17023SJohn Marino     {
365*e4b17023SJohn Marino       ppl_const_Polyhedron_t ph;
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino       ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph);
368*e4b17023SJohn Marino       ppl_print_polyhedron_matrix (file, ph);
369*e4b17023SJohn Marino     }
370*e4b17023SJohn Marino 
371*e4b17023SJohn Marino   ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it);
372*e4b17023SJohn Marino   ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end);
373*e4b17023SJohn Marino }
374*e4b17023SJohn Marino 
375*e4b17023SJohn Marino /* Print to STDERR the polyhedron PH under its PolyLib matrix form.  */
376*e4b17023SJohn Marino 
377*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_ppl_polyhedron_matrix(ppl_Polyhedron_t ph)378*e4b17023SJohn Marino debug_ppl_polyhedron_matrix (ppl_Polyhedron_t ph)
379*e4b17023SJohn Marino {
380*e4b17023SJohn Marino   ppl_print_polyhedron_matrix (stderr, ph);
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino /* Print to STDERR the powerset PS in its PolyLib matrix form.  */
384*e4b17023SJohn Marino 
385*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_ppl_powerset_matrix(ppl_Pointset_Powerset_C_Polyhedron_t ps)386*e4b17023SJohn Marino debug_ppl_powerset_matrix (ppl_Pointset_Powerset_C_Polyhedron_t ps)
387*e4b17023SJohn Marino {
388*e4b17023SJohn Marino   ppl_print_powerset_matrix (stderr, ps);
389*e4b17023SJohn Marino }
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino /* Read from FILE a polyhedron under PolyLib matrix form and return a
392*e4b17023SJohn Marino    PPL polyhedron object.  */
393*e4b17023SJohn Marino 
394*e4b17023SJohn Marino void
ppl_read_polyhedron_matrix(ppl_Polyhedron_t * ph,FILE * file)395*e4b17023SJohn Marino ppl_read_polyhedron_matrix (ppl_Polyhedron_t *ph, FILE *file)
396*e4b17023SJohn Marino {
397*e4b17023SJohn Marino   CloogMatrix *mat = cloog_matrix_read (file);
398*e4b17023SJohn Marino   new_C_Polyhedron_from_Cloog_Matrix (ph, mat);
399*e4b17023SJohn Marino   cloog_matrix_free (mat);
400*e4b17023SJohn Marino }
401*e4b17023SJohn Marino 
402*e4b17023SJohn Marino /* Return in RES the maximum of the linear expression LE on the
403*e4b17023SJohn Marino    pointset powerset of polyhedra PS.  */
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino void
ppl_max_for_le_pointset(ppl_Pointset_Powerset_C_Polyhedron_t ps,ppl_Linear_Expression_t le,mpz_t res)406*e4b17023SJohn Marino ppl_max_for_le_pointset (ppl_Pointset_Powerset_C_Polyhedron_t ps,
407*e4b17023SJohn Marino                          ppl_Linear_Expression_t le, mpz_t res)
408*e4b17023SJohn Marino {
409*e4b17023SJohn Marino   ppl_Coefficient_t num, denom;
410*e4b17023SJohn Marino   mpz_t dv, nv;
411*e4b17023SJohn Marino   int maximum, err;
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino   mpz_init (nv);
414*e4b17023SJohn Marino   mpz_init (dv);
415*e4b17023SJohn Marino   ppl_new_Coefficient (&num);
416*e4b17023SJohn Marino   ppl_new_Coefficient (&denom);
417*e4b17023SJohn Marino   err = ppl_Pointset_Powerset_C_Polyhedron_maximize (ps, le, num, denom, &maximum);
418*e4b17023SJohn Marino 
419*e4b17023SJohn Marino   if (err > 0)
420*e4b17023SJohn Marino     {
421*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (num, nv);
422*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (denom, dv);
423*e4b17023SJohn Marino       gcc_assert (mpz_sgn (dv) != 0);
424*e4b17023SJohn Marino       mpz_tdiv_q (res, nv, dv);
425*e4b17023SJohn Marino     }
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino   mpz_clear (nv);
428*e4b17023SJohn Marino   mpz_clear (dv);
429*e4b17023SJohn Marino   ppl_delete_Coefficient (num);
430*e4b17023SJohn Marino   ppl_delete_Coefficient (denom);
431*e4b17023SJohn Marino }
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino /* Return in RES the maximum of the linear expression LE on the
434*e4b17023SJohn Marino    polyhedron POL.  */
435*e4b17023SJohn Marino 
436*e4b17023SJohn Marino void
ppl_min_for_le_pointset(ppl_Pointset_Powerset_C_Polyhedron_t ps,ppl_Linear_Expression_t le,mpz_t res)437*e4b17023SJohn Marino ppl_min_for_le_pointset (ppl_Pointset_Powerset_C_Polyhedron_t ps,
438*e4b17023SJohn Marino 			 ppl_Linear_Expression_t le, mpz_t res)
439*e4b17023SJohn Marino {
440*e4b17023SJohn Marino   ppl_Coefficient_t num, denom;
441*e4b17023SJohn Marino   mpz_t dv, nv;
442*e4b17023SJohn Marino   int minimum, err;
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   mpz_init (nv);
445*e4b17023SJohn Marino   mpz_init (dv);
446*e4b17023SJohn Marino   ppl_new_Coefficient (&num);
447*e4b17023SJohn Marino   ppl_new_Coefficient (&denom);
448*e4b17023SJohn Marino   err = ppl_Pointset_Powerset_C_Polyhedron_minimize (ps, le, num, denom, &minimum);
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino   if (err > 0)
451*e4b17023SJohn Marino     {
452*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (num, nv);
453*e4b17023SJohn Marino       ppl_Coefficient_to_mpz_t (denom, dv);
454*e4b17023SJohn Marino       gcc_assert (mpz_sgn (dv) != 0);
455*e4b17023SJohn Marino       mpz_tdiv_q (res, nv, dv);
456*e4b17023SJohn Marino     }
457*e4b17023SJohn Marino 
458*e4b17023SJohn Marino   mpz_clear (nv);
459*e4b17023SJohn Marino   mpz_clear (dv);
460*e4b17023SJohn Marino   ppl_delete_Coefficient (num);
461*e4b17023SJohn Marino   ppl_delete_Coefficient (denom);
462*e4b17023SJohn Marino }
463*e4b17023SJohn Marino 
464*e4b17023SJohn Marino /* Builds a constraint in dimension DIM relating dimensions POS1 to
465*e4b17023SJohn Marino    POS2 as "POS1 - POS2 + C CSTR_TYPE 0" */
466*e4b17023SJohn Marino 
467*e4b17023SJohn Marino ppl_Constraint_t
ppl_build_relation(int dim,int pos1,int pos2,int c,enum ppl_enum_Constraint_Type cstr_type)468*e4b17023SJohn Marino ppl_build_relation (int dim, int pos1, int pos2, int c,
469*e4b17023SJohn Marino 		    enum ppl_enum_Constraint_Type cstr_type)
470*e4b17023SJohn Marino {
471*e4b17023SJohn Marino   ppl_Linear_Expression_t expr;
472*e4b17023SJohn Marino   ppl_Constraint_t cstr;
473*e4b17023SJohn Marino   ppl_Coefficient_t coef;
474*e4b17023SJohn Marino   mpz_t v, v_op, v_c;
475*e4b17023SJohn Marino 
476*e4b17023SJohn Marino   mpz_init (v);
477*e4b17023SJohn Marino   mpz_init (v_op);
478*e4b17023SJohn Marino   mpz_init (v_c);
479*e4b17023SJohn Marino 
480*e4b17023SJohn Marino   mpz_set_si (v, 1);
481*e4b17023SJohn Marino   mpz_set_si (v_op, -1);
482*e4b17023SJohn Marino   mpz_set_si (v_c, c);
483*e4b17023SJohn Marino 
484*e4b17023SJohn Marino   ppl_new_Coefficient (&coef);
485*e4b17023SJohn Marino   ppl_new_Linear_Expression_with_dimension (&expr, dim);
486*e4b17023SJohn Marino 
487*e4b17023SJohn Marino   ppl_assign_Coefficient_from_mpz_t (coef, v);
488*e4b17023SJohn Marino   ppl_Linear_Expression_add_to_coefficient (expr, pos1, coef);
489*e4b17023SJohn Marino   ppl_assign_Coefficient_from_mpz_t (coef, v_op);
490*e4b17023SJohn Marino   ppl_Linear_Expression_add_to_coefficient (expr, pos2, coef);
491*e4b17023SJohn Marino   ppl_assign_Coefficient_from_mpz_t (coef, v_c);
492*e4b17023SJohn Marino   ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
493*e4b17023SJohn Marino 
494*e4b17023SJohn Marino   ppl_new_Constraint (&cstr, expr, cstr_type);
495*e4b17023SJohn Marino 
496*e4b17023SJohn Marino   ppl_delete_Linear_Expression (expr);
497*e4b17023SJohn Marino   ppl_delete_Coefficient (coef);
498*e4b17023SJohn Marino   mpz_clear (v);
499*e4b17023SJohn Marino   mpz_clear (v_op);
500*e4b17023SJohn Marino   mpz_clear (v_c);
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino   return cstr;
503*e4b17023SJohn Marino }
504*e4b17023SJohn Marino 
505*e4b17023SJohn Marino /* Print to STDERR the GMP value VAL.  */
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_gmp_value(mpz_t val)508*e4b17023SJohn Marino debug_gmp_value (mpz_t val)
509*e4b17023SJohn Marino {
510*e4b17023SJohn Marino   char *str = mpz_get_str (0, 10, val);
511*e4b17023SJohn Marino   void (*gmp_free) (void *, size_t);
512*e4b17023SJohn Marino 
513*e4b17023SJohn Marino   fprintf (stderr, "%s", str);
514*e4b17023SJohn Marino   mp_get_memory_functions (NULL, NULL, &gmp_free);
515*e4b17023SJohn Marino   (*gmp_free) (str, strlen (str) + 1);
516*e4b17023SJohn Marino }
517*e4b17023SJohn Marino 
518*e4b17023SJohn Marino /* Checks for integer feasibility: returns true when the powerset
519*e4b17023SJohn Marino    polyhedron PS has no integer solutions.  */
520*e4b17023SJohn Marino 
521*e4b17023SJohn Marino bool
ppl_powerset_is_empty(ppl_Pointset_Powerset_C_Polyhedron_t ps)522*e4b17023SJohn Marino ppl_powerset_is_empty (ppl_Pointset_Powerset_C_Polyhedron_t ps)
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino   ppl_PIP_Problem_t pip;
525*e4b17023SJohn Marino   ppl_dimension_type d;
526*e4b17023SJohn Marino   ppl_const_Constraint_System_t pcs;
527*e4b17023SJohn Marino   ppl_Constraint_System_const_iterator_t first, last;
528*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_iterator_t it, end;
529*e4b17023SJohn Marino   bool has_integer_solutions = false;
530*e4b17023SJohn Marino 
531*e4b17023SJohn Marino   if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (ps))
532*e4b17023SJohn Marino     return true;
533*e4b17023SJohn Marino 
534*e4b17023SJohn Marino   ppl_Pointset_Powerset_C_Polyhedron_space_dimension (ps, &d);
535*e4b17023SJohn Marino   ppl_new_Constraint_System_const_iterator (&first);
536*e4b17023SJohn Marino   ppl_new_Constraint_System_const_iterator (&last);
537*e4b17023SJohn Marino   ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&it);
538*e4b17023SJohn Marino   ppl_new_Pointset_Powerset_C_Polyhedron_iterator (&end);
539*e4b17023SJohn Marino 
540*e4b17023SJohn Marino   for (ppl_Pointset_Powerset_C_Polyhedron_iterator_begin (ps, it),
541*e4b17023SJohn Marino        ppl_Pointset_Powerset_C_Polyhedron_iterator_end (ps, end);
542*e4b17023SJohn Marino        !ppl_Pointset_Powerset_C_Polyhedron_iterator_equal_test (it, end);
543*e4b17023SJohn Marino        ppl_Pointset_Powerset_C_Polyhedron_iterator_increment (it))
544*e4b17023SJohn Marino     {
545*e4b17023SJohn Marino       ppl_const_Polyhedron_t ph;
546*e4b17023SJohn Marino       ppl_Pointset_Powerset_C_Polyhedron_iterator_dereference (it, &ph);
547*e4b17023SJohn Marino 
548*e4b17023SJohn Marino       ppl_Polyhedron_get_constraints (ph, &pcs);
549*e4b17023SJohn Marino       ppl_Constraint_System_begin (pcs, first);
550*e4b17023SJohn Marino       ppl_Constraint_System_end (pcs, last);
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino       ppl_new_PIP_Problem_from_constraints (&pip, d, first, last, 0, NULL);
553*e4b17023SJohn Marino       has_integer_solutions |= ppl_PIP_Problem_is_satisfiable (pip);
554*e4b17023SJohn Marino 
555*e4b17023SJohn Marino       ppl_delete_PIP_Problem (pip);
556*e4b17023SJohn Marino     }
557*e4b17023SJohn Marino 
558*e4b17023SJohn Marino   ppl_delete_Constraint_System_const_iterator (first);
559*e4b17023SJohn Marino   ppl_delete_Constraint_System_const_iterator (last);
560*e4b17023SJohn Marino   ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (it);
561*e4b17023SJohn Marino   ppl_delete_Pointset_Powerset_C_Polyhedron_iterator (end);
562*e4b17023SJohn Marino 
563*e4b17023SJohn Marino   return !has_integer_solutions;
564*e4b17023SJohn Marino }
565*e4b17023SJohn Marino 
566*e4b17023SJohn Marino #endif
567