2 /**-------------------------------------------------------------------**
4 **-------------------------------------------------------------------**
6 **-------------------------------------------------------------------**
7 ** First version: april 17th 2005 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
15 * Copyright (C) 2005 Cedric Bastoul *
17 * This is free software; you can redistribute it and/or modify it under the *
18 * terms of the GNU General Public License as published by the Free Software *
19 * Foundation; either version 2 of the License, or (at your option) any later *
22 * This software is distributed in the hope that it will be useful, but *
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
27 * You should have received a copy of the GNU General Public License along *
28 * with software; if not, write to the Free Software Foundation, Inc., *
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
34 ******************************************************************************/
35 /* CAUTION: the english used for comments is probably the worst you ever read,
36 * please feel free to correct and improve it !
43 # include "../include/cloog/cloog.h"
47 /******************************************************************************
48 * Memory leaks hunting *
49 ******************************************************************************/
53 * These functions and global variables are devoted to memory leaks hunting: we
54 * want to know at each moment how many CloogMatrix structures are allocated
55 * (cloog_matrix_allocated) and how many had been freed (cloog_matrix_freed).
56 * Each time a CloogMatrix structure is allocated, a call to the function
57 * cloog_matrix_leak_up() must be carried out, and respectively
58 * cloog_matrix_leak_down() when a CloogMatrix structure is freed. The special
59 * variable cloog_matrix_max gives the maximal number of CloogMatrix structures
60 * simultaneously alive (i.e. allocated and non-freed) in memory.
61 * - April 17th 2005: first version.
65 int cloog_matrix_allocated
= 0 ;
66 int cloog_matrix_freed
= 0 ;
67 int cloog_matrix_max
= 0 ;
70 static void cloog_matrix_leak_up()
71 { cloog_matrix_allocated
++ ;
72 if ((cloog_matrix_allocated
-cloog_matrix_freed
) > cloog_matrix_max
)
73 cloog_matrix_max
= cloog_matrix_allocated
- cloog_matrix_freed
;
77 static void cloog_matrix_leak_down()
78 { cloog_matrix_freed
++ ;
82 /******************************************************************************
84 ******************************************************************************/
88 * CLooG makes an intensive use of matrix operations and the PolyLib do
89 * the job. Here are the interfaces to all the PolyLib calls (CLooG uses 18
90 * PolyLib functions), with or without some adaptations. If another matrix
91 * library can be used, only these functions have to be changed.
96 * cloog_matrix_print function:
97 * This function prints the content of a CloogMatrix structure (matrix) into a
98 * file (foo, possibly stdout).
100 void cloog_matrix_print(FILE * foo
, CloogMatrix
* matrix
)
101 { Matrix_Print(foo
,P_VALUE_FMT
,matrix
) ;
106 * cloog_matrix_free function:
107 * This function frees the allocated memory for a CloogMatrix structure
110 void cloog_matrix_free(CloogMatrix
* matrix
)
111 { cloog_matrix_leak_down() ;
112 Matrix_Free(matrix
) ;
117 * cloog_matrix_alloc function:
118 * This function allocates the memory space for a CloogMatrix structure having
119 * nb_rows rows and nb_columns columns, it set its elements to 0.
121 CloogMatrix
* cloog_matrix_alloc(unsigned nb_rows
, unsigned nb_columns
)
122 { cloog_matrix_leak_up() ;
123 return Matrix_Alloc(nb_rows
,nb_columns
) ;
128 * cloog_matrix_matrix function:
129 * This function converts a PolyLib Matrix to a CloogMatrix structure.
131 CloogMatrix
* cloog_matrix_matrix(Matrix
*matrix
)
133 cloog_matrix_leak_up();
138 /******************************************************************************
139 * Structure display function *
140 ******************************************************************************/
144 * cloog_loop_print_structure function:
145 * Displays a CloogMatrix structure (matrix) into a file (file, possibly stdout)
146 * in a way that trends to be understandable without falling in a deep
147 * depression or, for the lucky ones, getting a headache... It includes an
148 * indentation level (level) in order to work with others print_structure
149 * functions. Written by Olivier Chorier, Luc Marchaud, Pierre Martin and
151 * - April 24th 2005: Initial version.
152 * - June 2nd 2005: (Ced) Extraction from cloog_loop_print_structure and
153 * integration in matrix.c.
154 * - June 22rd 2005: Adaptation for GMP.
156 void cloog_matrix_print_structure(FILE * file
, CloogMatrix
* matrix
, int level
)
159 /* Display the matrix. */
160 for (i
=0; i
<matrix
->NbRows
; i
++)
161 { for(j
=0; j
<=level
; j
++)
162 fprintf(file
,"|\t") ;
166 for (j
=0; j
<matrix
->NbColumns
; j
++)
167 { value_print(file
,P_VALUE_FMT
,matrix
->p
[i
][j
]) ;
171 fprintf(file
,"]\n") ;
176 /******************************************************************************
178 ******************************************************************************/
182 * cloog_matrix_read function:
183 * Adaptation from the PolyLib. This function reads a matrix into a file (foo,
184 * posibly stdin) and returns a pointer this matrix.
185 * October 18th 2001: first version.
186 * - April 17th 2005: this function moved from domain.c to here.
187 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
190 CloogMatrix
* cloog_matrix_read(FILE * foo
)
191 { unsigned NbRows
, NbColumns
;
193 char *c
, s
[MAX_STRING
], str
[MAX_STRING
] ;
194 CloogMatrix
* matrix
;
197 while (fgets(s
,MAX_STRING
,foo
) == 0) ;
198 while ((*s
=='#' || *s
=='\n') || (sscanf(s
," %u %u",&NbRows
,&NbColumns
)<2))
199 fgets(s
,MAX_STRING
,foo
) ;
201 matrix
= cloog_matrix_alloc(NbRows
,NbColumns
) ;
204 for (i
=0;i
<matrix
->NbRows
;i
++)
206 { c
= fgets(s
,MAX_STRING
,foo
) ;
207 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
210 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
213 { fprintf(stderr
, "[CLooG]ERROR: not enough rows.\n") ;
216 for (j
=0;j
<matrix
->NbColumns
;j
++)
217 { if (c
== NULL
|| *c
== '#' || *c
== '\n')
218 { fprintf(stderr
, "[CLooG]ERROR: not enough columns.\n") ;
221 /* NdCed : Dans le n ca met strlen(str). */
222 if (sscanf(c
,"%s%n",str
,&n
) == 0)
223 { fprintf(stderr
, "[CLooG]ERROR: not enough rows.\n") ;
226 value_read(*(p
++),str
) ;
235 /******************************************************************************
236 * Processing functions *
237 ******************************************************************************/
241 * Function cloog_matrix_normalize:
242 * This function will modify the constraint system in such a way that when
243 * there is an equality depending on the element at level 'level', there are
244 * no more (in)equalities depending on this element. For instance, try
245 * test/valilache.cloog with options -f 8 -l 9, with and without the call
246 * to this function. At a given moment, for the level L we will have
247 * 32*P=L && L>=1 (P is a lower level), this constraint system cannot be
248 * translated directly into a source code. Thus, we normalize the domain to
249 * remove L from the inequalities. In our example, this leads to
250 * 32*P=L && 32*P>=1, that can be transated to the code
251 * if (P>=1) { L=32*P ; ... }. This function solves the DaeGon Kim bug.
252 * WARNING: Remember that if there is another call to Polylib after a call to
253 * this function, we have to recall this function.
254 * -June 16th 2005: first version (adaptation from URGent June-7th-2005 by
256 * - June 21rd 2005: Adaptation for GMP.
257 * - November 4th 2005: Complete rewriting, simpler and faster. It is no more an
258 * adaptation from URGent.
260 void cloog_matrix_normalize(CloogMatrix
* matrix
, int level
)
262 Value factor_i
, factor_ref
, temp_i
, temp_ref
, gcd
;
267 /* Don't "normalize" the constant term. */
268 if (level
== matrix
->NbColumns
-1)
271 /* Let us find an equality for the current level that can be propagated. */
272 for (ref
=0;ref
<matrix
->NbRows
;ref
++)
273 if (value_zero_p(matrix
->p
[ref
][0]) && value_notzero_p(matrix
->p
[ref
][level
]))
274 { value_init_c(gcd
) ;
275 value_init_c(temp_i
) ;
276 value_init_c(temp_ref
) ;
277 value_init_c(factor_i
) ;
278 value_init_c(factor_ref
) ;
280 /* Row "ref" is the reference equality, now let us find a row to simplify.*/
281 for (i
=ref
+1;i
<matrix
->NbRows
;i
++)
282 if (value_notzero_p(matrix
->p
[i
][level
]))
283 { /* Now let us set to 0 the "level" coefficient of row "j" using "ref".
284 * First we compute the factors to apply to each row vector element.
286 Gcd(matrix
->p
[ref
][level
],matrix
->p
[i
][level
],&gcd
) ;
287 value_division(factor_i
,matrix
->p
[ref
][level
],gcd
) ;
288 value_division(factor_ref
,matrix
->p
[i
][level
],gcd
) ;
290 /* Maybe we are simplifying an inequality: factor_i must not be <0. */
291 if (value_neg_p(factor_i
))
292 { value_absolute(factor_i
,factor_i
) ;
293 value_oppose(factor_ref
,factor_ref
) ;
296 /* Now update the vector. */
297 for (j
=1;j
<matrix
->NbColumns
;j
++)
298 { value_multiply(temp_i
,factor_i
,matrix
->p
[i
][j
]) ;
299 value_multiply(temp_ref
,factor_ref
,matrix
->p
[ref
][j
]) ;
300 value_substract(matrix
->p
[i
][j
],temp_i
,temp_ref
) ;
303 /* Normalize (divide by GCD of all elements) the updated vector. */
304 Vector_Normalize(&(matrix
->p
[i
][1]),matrix
->NbColumns
-1) ;
308 value_clear_c(temp_i
) ;
309 value_clear_c(temp_ref
) ;
310 value_clear_c(factor_i
) ;
311 value_clear_c(factor_ref
) ;
318 * cloog_matrix_equality_update function:
319 * this function updates a matrix of equalities where each row corresponds to
320 * the equality "=0" of an affine expression such that the entry at column
321 * "row" (="level") is not zero. This matrix is upper-triangular, except the
322 * row number "level-1" which has to be updated for the matrix to be triangular.
323 * The first element of each row gives the equality type and is not related to
324 * the expression which is equal to zero. This function achieves the processing.
325 * - equal is the matrix to be updated,
326 * - level gives the row that has to be updated (it is actually row "level-1"),
327 * - nb_par is the number of parameters of the program.
329 * - September 20th 2005: first version.
331 void cloog_matrix_equality_update(CloogMatrix
* equal
, int level
, int nb_par
)
333 Value gcd
, factor_level
, factor_outer
, temp_level
, temp_outer
;
336 value_init_c(temp_level
) ;
337 value_init_c(temp_outer
) ;
338 value_init_c(factor_level
) ;
339 value_init_c(factor_outer
) ;
341 /* For each previous level, */
342 for (i
=level
-2;i
>=0;i
--)
343 { /* if the corresponding iterator is inside the current equality and is equal
346 if (value_notzero_p(equal
->p
[level
-1][i
+1]) &&
347 value_notzero_p(equal
->p
[i
][0]))
348 { /* Compute the Greatest Common Divisor. */
349 Gcd(equal
->p
[level
-1][i
+1],equal
->p
[i
][i
+1],&gcd
) ;
351 /* Compute the factors to apply to each row vector element. */
352 value_division(factor_level
,equal
->p
[i
][i
+1],gcd
) ;
353 value_division(factor_outer
,equal
->p
[level
-1][i
+1],gcd
) ;
355 /* Now update the row 'level'. */
356 /* - the iterators, up to level, */
357 for (j
=1;j
<=level
;j
++)
358 { value_multiply(temp_level
,factor_level
,equal
->p
[level
-1][j
]) ;
359 value_multiply(temp_outer
,factor_outer
,equal
->p
[i
][j
]) ;
360 value_substract(equal
->p
[level
-1][j
],temp_level
,temp_outer
) ;
362 /* - between last useful iterator (level) and the first parameter, the
363 * matrix is sparse (full of zeroes), we just do nothing there.
364 * - the parameters and the scalar.
366 for (j
=0;j
<nb_par
+1;j
++)
367 { value_multiply(temp_level
,factor_level
,
368 equal
->p
[level
-1][equal
->NbColumns
-j
-1]) ;
369 value_multiply(temp_outer
,factor_outer
,
370 equal
->p
[i
][equal
->NbColumns
-j
-1]) ;
371 value_substract(equal
->p
[level
-1][equal
->NbColumns
-j
-1],
372 temp_level
,temp_outer
) ;
377 /* Normalize (divide by GCD of all elements) the updated equality. */
378 Vector_Normalize(&(equal
->p
[level
-1][1]),equal
->NbColumns
-1) ;
381 value_clear_c(temp_level
) ;
382 value_clear_c(temp_outer
) ;
383 value_clear_c(factor_level
) ;
384 value_clear_c(factor_outer
) ;
389 * cloog_matrix_copy function:
390 * this functions builds and returns a "hard copy" (not a pointer copy) of a
391 * CloogMatrix data structure.
392 * - October 26th 2005: first version.
394 CloogMatrix
* cloog_matrix_copy(CloogMatrix
* matrix
)
398 copy
= cloog_matrix_alloc(matrix
->NbRows
,matrix
->NbColumns
) ;
400 for (i
=0;i
<matrix
->NbRows
;i
++)
401 for (j
=0;j
<matrix
->NbColumns
;j
++)
402 value_assign(copy
->p
[i
][j
],matrix
->p
[i
][j
]) ;
409 * cloog_matrix_vector_copy function:
410 * this function rutuns a hard copy of the vector "vector" of length "length"
412 * - November 3rd 2005: first version.
414 Value
* cloog_matrix_vector_copy(Value
* vector
, int length
)
418 /* We allocate the memory space for the new vector, and we fill it with
419 * the original coefficients.
421 copy
= (Value
*)malloc(length
* sizeof(Value
)) ;
422 for (i
=0;i
<length
;i
++)
423 { value_init_c(copy
[i
]) ;
424 value_assign(copy
[i
],vector
[i
]) ;
432 * cloog_matrix_vector_simplify function:
433 * this function simplify an affine expression with its coefficients in
434 * "vector" of length "length" thanks to an equality matrix "equal" that gives
435 * for some elements of the affine expression an equality with other elements,
436 * preferably constants. For instance, if the vector contains i+j+3 and the
437 * equality matrix gives i=n and j=2, the vector is simplified to n+3 and is
438 * returned in a new vector.
439 * - vector is the array of affine expression coefficients
440 * - equal is the matrix of equalities,
441 * - length is the vector length,
442 * - level is a level we don't want to simplify (-1 if none),
443 * - nb_par is the number of parameters of the program.
445 * - September 20th 2005: first version.
446 * - November 2nd 2005: (debug) we are simplifying inequalities, thus we are
447 * not allowed to multiply the vector by a negative
448 * constant.Problem found after a report of Michael
451 Value
* cloog_matrix_vector_simplify(vector
, equal
, length
, level
, nb_par
)
453 CloogMatrix
* equal
;
454 int length
, level
, nb_par
;
456 Value gcd
, factor_vector
, factor_equal
, temp_vector
, temp_equal
, * simplified
;
458 simplified
= cloog_matrix_vector_copy(vector
,length
) ;
461 value_init_c(temp_vector
) ;
462 value_init_c(temp_equal
) ;
463 value_init_c(factor_vector
) ;
464 value_init_c(factor_equal
) ;
466 /* For each non-null coefficient in the vector, */
467 for (i
=length
-nb_par
-2;i
>0;i
--)
469 { /* if the coefficient in not null, and there exists a useful equality */
470 if ((value_notzero_p(simplified
[i
])) &&
471 (value_notzero_p(equal
->p
[i
-1][0])))
472 { /* Compute the Greatest Common Divisor. */
473 Gcd(simplified
[i
],equal
->p
[i
-1][i
],&gcd
) ;
475 /* Compute the factors to apply to each row vector element. */
476 value_division(factor_vector
,equal
->p
[i
-1][i
],gcd
) ;
477 value_division(factor_equal
,simplified
[i
],gcd
) ;
479 /* We are simplifying an inequality: factor_vector must not be <0. */
480 if (value_neg_p(factor_vector
))
481 { value_absolute(factor_vector
,factor_vector
) ;
482 value_oppose(factor_equal
,factor_equal
) ;
485 /* Now update the vector. */
486 /* - the iterators, up to the current level, */
487 for (j
=1;j
<=length
-nb_par
-2;j
++)
488 { value_multiply(temp_vector
,factor_vector
,simplified
[j
]) ;
489 value_multiply(temp_equal
,factor_equal
,equal
->p
[i
-1][j
]) ;
490 value_substract(simplified
[j
],temp_vector
,temp_equal
) ;
492 /* - between last useful iterator (i) and the first parameter, the equal
493 * matrix is sparse (full of zeroes), we just do nothing there.
494 * - the parameters and the scalar.
496 for (j
=0;j
<nb_par
+1;j
++)
497 { value_multiply(temp_vector
,factor_vector
,simplified
[length
-1-j
]) ;
498 value_multiply(temp_equal
,factor_equal
,
499 equal
->p
[i
-1][equal
->NbColumns
-j
-1]) ;
500 value_substract(simplified
[length
-1-j
],temp_vector
,temp_equal
) ;
505 /* Normalize (divide by GCD of all elements) the updated vector. */
506 Vector_Normalize(&(simplified
[1]),length
-1) ;
509 value_clear_c(temp_vector
) ;
510 value_clear_c(temp_equal
) ;
511 value_clear_c(factor_vector
) ;
512 value_clear_c(factor_equal
) ;
519 * cloog_matrix_simplify function:
520 * this function simplify all constraints inside the matrix "matrix" thanks to
521 * an equality matrix "equal" that gives for some elements of the affine
522 * constraint an equality with other elements, preferably constants.
523 * For instance, if a row of the matrix contains i+j+3>=0 and the equality
524 * matrix gives i=n and j=2, the constraint is simplified to n+3>=0. The
525 * simplified constraints are returned back inside a new simplified matrix.
526 * - matrix is the set of constraints to simplify,
527 * - equal is the matrix of equalities,
528 * - level is a level we don't want to simplify (-1 if none),
529 * - nb_par is the number of parameters of the program.
531 * - November 4th 2005: first version.
533 CloogMatrix
* cloog_matrix_simplify(matrix
, equal
, level
, nb_par
)
534 CloogMatrix
* matrix
, * equal
;
538 CloogMatrix
* simplified
;
543 /* The simplified matrix is such that each row has been simplified thanks
544 * tho the "equal" matrix. We allocate the memory for the simplified matrix,
545 * then for each row of the original matrix, we compute the simplified
546 * vector and we copy its content into the according simplified row.
548 simplified
= cloog_matrix_alloc(matrix
->NbRows
,matrix
->NbColumns
) ;
549 for (i
=0;i
<matrix
->NbRows
;i
++)
550 { vector
= cloog_matrix_vector_simplify(matrix
->p
[i
],equal
,matrix
->NbColumns
,
552 for (j
=0;j
<matrix
->NbColumns
;j
++)
553 value_assign(simplified
->p
[i
][j
],vector
[j
]) ;
555 cloog_matrix_vector_free(vector
,matrix
->NbColumns
) ;
558 /* After simplification, it may happen that few constraints are the same,
559 * we remove them here by replacing them with 0=0 constraints.
561 for (i
=0;i
<simplified
->NbRows
;i
++)
562 for (j
=i
+1;j
<simplified
->NbRows
;j
++)
563 { for (k
=0;k
<simplified
->NbColumns
;k
++)
564 if (value_ne(simplified
->p
[i
][k
],simplified
->p
[j
][k
]))
567 if (k
== matrix
->NbColumns
)
568 { for (k
=0;k
<matrix
->NbColumns
;k
++)
569 value_set_si(simplified
->p
[j
][k
],0) ;
578 * cloog_matrix_vector_free function:
579 * this function clears the elements of a vector "vector" of length "length",
580 * then frees the vector itself this is useful for the GMP version of CLooG
581 * which has to clear all elements.
582 * - October 29th 2005: first version.
584 void cloog_matrix_vector_free(Value
* vector
, int length
)
587 for (i
=0;i
<length
;i
++)
588 value_clear_c(vector
[i
]) ;