2 /**-------------------------------------------------------------------**
4 **-------------------------------------------------------------------**
6 **-------------------------------------------------------------------**
7 ** First version: october 26th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
15 * Copyright (C) 2001-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 !
39 /* June 22nd 2005: General adaptation for GMP.
40 * October 26th 2005: General adaptation from CloogDomain to CloogMatrix data
41 * structure for all constraint systems.
42 * October 27th 2005: General adaptation from CloogEqual to CloogMatrix data
43 * structure for equality spreading.
49 # include "../include/cloog/cloog.h"
52 /******************************************************************************
53 * Memory leaks hunting *
54 ******************************************************************************/
57 * These global variables are devoted to memory leaks hunting: we
58 * want to know at each moment how many Value variables have been allocated
59 * since in GMP mode they have to be freed (see domain.c for the declaration).
60 * - July 3rd->11th 2003: first version (memory leaks hunt and correction).
63 extern int cloog_value_allocated
;
64 extern int cloog_value_freed
;
65 extern int cloog_value_max
;
68 /******************************************************************************
69 * Equalities spreading functions *
70 ******************************************************************************/
73 /* Equalities are stored inside a CloogMatrix data structure called "equal".
74 * This matrix has (nb_scattering + nb_iterators + 1) rows (i.e. total
75 * dimensions + 1, the "+ 1" is because a statement can be included inside an
76 * external loop without iteration domain), and (nb_scattering + nb_iterators +
77 * nb_parameters + 2) columns (all unknowns plus the scalar plus the equality
78 * type). The ith row corresponds to the equality "= 0" for the ith dimension
79 * iterator. The first column gives the equality type (0: no equality, then
80 * EQTYPE_* -see pprint.h-). At each recursion of pprint, if an equality for
81 * the current level is found, the corresponding row is updated. Then the
82 * equality if it exists is used to simplify expressions (e.g. if we have
83 * "i+1" while we know that "i=2", we simplify it in "3"). At the end of
84 * the pprint call, the corresponding row is reset to zero.
89 * pprint_equal_type function :
90 * This function returns the type of the equality in the constraint (line) of
91 * (equal) for the element (level). An equality is 'constant' iff all other
92 * factors are null except the constant one. It is a 'pure item' iff one and
93 * only one factor is non null and is 1 or -1. Otherwise it is an 'affine
96 * i = -13 is constant, i = j, j = -M are pure items,
97 * j = 2*M, i = j+1 are affine expressions.
98 * When the equality comes from a 'one time loop', (line) is ONE_TIME_LOOP.
99 * This case require a specific treatment since we have to study all the
101 * - equal is the matrix of equalities,
102 * - level is the column number in equal of the element which is 'equal to',
103 * - line is the line number in equal of the constraint we want to study;
104 * if it is -1, all lines must be studied.
106 * - July 3rd 2002: first version, called pprint_equal_isconstant.
107 * - July 6th 2002: adaptation for the 3 types.
108 * - June 15th 2005: (debug) expr = domain->Constraint[line] was evaluated
109 * before checking if line != ONE_TIME_LOOP. Since
110 * ONE_TIME_LOOP is -1, an invalid read was possible.
111 * - October 19th 2005: Removal of the once-time-loop specific processing.
113 int pprint_equal_type(equal
, level
, line
)
114 CloogMatrix
* equal
;
119 expr
= equal
->p
[line
] ;
121 /* There is only one non null factor, and it must be +1 or -1 for
122 * iterators or parameters.
124 for (i
=1;i
<=equal
->NbColumns
-2;i
++)
125 if (value_notzero_p(expr
[i
]) && (i
!= level
))
126 { if ((value_notone_p(expr
[i
]) && value_notmone_p(expr
[i
])) || (one
!= 0))
127 return EQTYPE_EXAFFINE
;
131 /* if the constant factor is non null, it must be alone. */
133 { if (value_notzero_p(expr
[equal
->NbColumns
-1]))
134 return EQTYPE_EXAFFINE
;
137 return EQTYPE_CONSTANT
;
139 return EQTYPE_PUREITEM
;
144 * pprint_equal_allow function:
145 * This function checks whether the options allow us to spread the equality or
146 * not. It returns 1 if so, 0 otherwise.
147 * - equal is the matrix of equalities,
148 * - level is the column number in equal of the element which is 'equal to',
149 * - line is the line number in equal of the constraint we want to study,
150 * - the infos structure gives the user all options on code printing and more.
152 * - October 27th 2005: first version (extracted from old pprint_equal_add).
154 int pprint_equal_allow(equal
, level
, line
, infos
)
155 CloogMatrix
* equal
;
158 { if ((!infos
->options
->csp
&& !infos
->options
->esp
) ||
159 (level
< infos
->options
->fsp
))
162 if (infos
->options
->csp
&&
163 (pprint_equal_type(equal
,level
,line
) == EQTYPE_EXAFFINE
) &&
164 !infos
->options
->esp
)
172 * pprint_equal function:
173 * This function returns the content an equality matrix (equal) into a string.
174 * - equal is the matrix of equalities,
175 * - the infos structure gives the user all options on code printing and more.
177 * - July 2nd 2002: first version.
178 * - March 16th 2003: return now a string instead of printing directly and do
179 * not write 'Sx()' if there is no spreading, but only 'Sx'.
181 char * pprint_equal(equal
, infos
)
182 CloogMatrix
* equal
;
184 { int i
, first
=1, iterator
;
185 char * body
, * temp
, * seq
, * sline
;
188 temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
189 body
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
191 seq
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
194 /* It is not necessary to print here the scattering iterators since they
195 * never appear in the statement bodies.
197 for (i
=infos
->names
->nb_scattering
;i
<equal
->NbRows
;i
++)
198 { if (value_notzero_p(equal
->p
[i
][0])&&pprint_equal_allow(equal
,i
+1,i
,infos
))
202 iterator
= i
- infos
->names
->nb_scattering
;
203 sprintf(temp
,"%s = ",infos
->names
->iterators
[iterator
]) ;
206 /* pprint_line needs to know that the current line is an equality, so
207 * we temporary remove the equality type and set it to zero (the equality
210 value_assign(type
,equal
->p
[i
][0]) ;
211 value_set_si(equal
->p
[i
][0],0) ;
212 sline
= pprint_line(equal
,equal
,i
,i
+1,infos
) ;
213 value_assign(equal
->p
[i
][0],type
) ;
221 value_clear_c(type
) ;
224 sprintf(seq
,"(%s)",body
) ;
226 sprintf(seq
,"%s",body
) ;
235 * pprint_equal_cpp function:
236 * This function prints the substitution data of a statement into a string.
237 * Using this function instead of pprint_equal is useful for generating
238 * a compilable pseudo-code by using preprocessor macro for each statement.
239 * By opposition to pprint_equal, the result is less human-readable. For
240 * instance this function will print (i,i+3,k,3) where pprint_equal would
241 * return (j=i+3,l=3).
242 * - equal is the matrix of equalities,
243 * - level is the number of loops enclosing the statement,
244 * - the infos structure gives the user all options on code printing and more.
246 * - March 12th 2004: first version.
247 * - November 21th 2005: (debug) now works well with GMP version.
249 char * pprint_equal_cpp(equal
, level
, infos
)
250 CloogMatrix
* equal
;
254 char * temp
, * seq
, * sline
;
257 temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
258 seq
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
263 for (i
=infos
->names
->nb_scattering
;i
<level
-1;i
++)
264 { if (value_notzero_p(equal
->p
[i
][0]))
265 { /* pprint_line needs to know that the current line is an equality, so
266 * we temporary remove the equality type and set it to zero (the equality
269 value_assign(type
,equal
->p
[i
][0]) ;
270 value_set_si(equal
->p
[i
][0],0) ;
271 sline
= pprint_line(equal
,equal
,i
,i
+1,infos
) ;
272 value_assign(equal
->p
[i
][0],type
) ;
278 { sprintf(temp
,"%s",infos
->names
->iterators
[i
-infos
->names
->nb_scattering
]);
286 value_clear_c(type
) ;
294 * pprint_equal_add function:
295 * This function updates the row (level-1) of the equality matrix (equal) with
296 * the row that corresponds to the row (line) of the matrix (matrix). It returns
297 * 1 if the row can be updated, 0 otherwise.
298 * - equal is the matrix of equalities,
299 * - matrix is the matrix of constraints,
300 * - level is the column number in matrix of the element which is 'equal to',
301 * - line is the line number in matrix of the constraint we want to study,
302 * - the infos structure gives the user all options on code printing and more.
304 * - July 2nd 2002: first version.
305 * - October 19th 2005: Addition of the once-time-loop specific processing.
307 int pprint_equal_add(equal
, matrix
, level
, line
, infos
)
308 CloogMatrix
* equal
, * matrix
;
312 Value numerator
, denominator
, division
, modulo
;
314 /* If we are in the case of a loop running once, this means that the equality
315 * comes from an inequality. Here we find this inequality.
317 if (line
== ONE_TIME_LOOP
)
318 { for (i
=0;i
<matrix
->NbRows
;i
++)
319 if ((value_notzero_p(matrix
->p
[i
][0]))&&
320 (value_notzero_p(matrix
->p
[i
][level
])))
323 /* Since in once-time-loops, equalities derive from inequalities, we
324 * may have to offset the values. For instance if we have 2i>=3, the
325 * equality is in fact i=2. This may happen when the level coefficient is
326 * not 1 or -1 and the scalar value is not zero. In any other case (e.g.,
327 * if the inequality is an expression including outer loop counters or
328 * parameters) the once time loop would not have been detected
329 * because of floord and ceild functions.
331 if (value_ne_si(matrix
->p
[i
][level
],1) &&
332 value_ne_si(matrix
->p
[i
][level
],-1) &&
333 value_notzero_p(matrix
->p
[i
][matrix
->NbColumns
-1]))
334 { value_init_c(numerator
) ;
335 value_init_c(denominator
) ;
336 value_init_c(division
) ;
337 value_init_c(modulo
) ;
339 value_assign(denominator
,matrix
->p
[i
][level
]) ;
340 value_absolute(denominator
,denominator
) ;
341 value_assign(numerator
,matrix
->p
[i
][matrix
->NbColumns
-1]) ;
342 value_modulus(modulo
,numerator
,denominator
) ;
343 value_division(division
,numerator
,denominator
) ;
345 /* There are 4 scenarios:
346 * di +n >= 0 --> i + (n div d) >= 0
347 * -di +n >= 0 --> -i + (n div d) >= 0
348 * di -n >= 0 --> if (n%d == 0) i + ((-n div d)+1) >= 0
349 * else i + (-n div d) >= 0
350 * -di -n >= 0 --> if (n%d == 0) -i + ((-n div d)-1) >= 0
351 * else -i + (-n div d) >= 0
352 * In the following we distinct the scalar value setting and the
355 if (value_pos_p(numerator
) || value_zero_p(modulo
))
356 value_assign(matrix
->p
[i
][matrix
->NbColumns
-1],division
) ;
358 { if (value_pos_p(matrix
->p
[i
][level
]))
359 value_increment(matrix
->p
[i
][matrix
->NbColumns
-1],division
) ;
361 value_decrement(matrix
->p
[i
][matrix
->NbColumns
-1],division
) ;
364 if (value_pos_p(matrix
->p
[i
][level
]))
365 value_set_si(matrix
->p
[i
][level
],1) ;
367 value_set_si(matrix
->p
[i
][level
],-1) ;
369 value_clear_c(numerator
) ;
370 value_clear_c(denominator
) ;
371 value_clear_c(division
) ;
372 value_clear_c(modulo
) ;
379 /* We update the line of equal corresponding to level:
380 * - the first element gives the equality type,
382 value_set_si(equal
->p
[level
-1][0],pprint_equal_type(matrix
,level
,line
)) ;
383 /* - the other elements corresponding to the equality itself
384 * (the iterators up to level, then the parameters and the scalar).
386 for (i
=1;i
<=level
;i
++)
387 value_assign(equal
->p
[level
-1][i
],matrix
->p
[line
][i
]) ;
388 for (i
=0;i
<infos
->names
->nb_parameters
+1;i
++)
389 value_assign(equal
->p
[level
-1][equal
->NbColumns
-i
-1],
390 matrix
->p
[line
][matrix
->NbColumns
-i
-1]) ;
392 cloog_matrix_equality_update(equal
,level
,infos
->names
->nb_parameters
) ;
394 return (pprint_equal_allow(equal
,level
,level
-1,infos
)) ;
399 * pprint_equal_del function :
400 * This function reset the equality corresponding to the iterator (level)
401 * in the equality matrix (equal).
402 * - July 2nd 2002: first version.
404 void pprint_equal_del(CloogMatrix
* equal
, int level
)
407 for (i
=0;i
<equal
->NbColumns
;i
++)
408 value_set_si(equal
->p
[level
-1][i
],0) ;
412 /******************************************************************************
413 * Pretty Printing (dirty) functions *
414 ******************************************************************************/
418 * pprint_val function:
419 * This function returns a string containing the printing of a value (possibly
420 * an iterator or a parameter with its coefficient or a constant).
421 * - val is the coefficient or constant value,
422 * - first is a pointer to a boolean set to 1 if the current value is the first
423 * of an expresion, 0 otherwise (this function can change it),
424 * - cst is a boolean set to 1 if the value is a constant, 0 otherwise,
425 * - name is a string containing the name of the iterator or of the parameter,
426 * - the infos structure gives the user some options about code printing,
427 * the number of parameters in domain (nb_par), and the arrays of iterator
428 * names and parameters (iters and params).
430 * - November 2nd 2001: first version.
431 * - November 8th 2001: complete rewriting.
432 * - July 6th 2002: integration of the equality spreading.
433 * - October 10th 2002: (debug) sline was sometimes freed twice (hard to find !)
434 * and equality spreading gives no more (for instance) --2
435 * but -(-2). (November 2005: now it's 2 !).
436 * - June 27th 2003: 64 bits version ready.
438 char * pprint_val(val
, level
, first
, cst
, name
, infos
)
440 int level
, * first
, cst
;
443 { char * sval
, * body
, * temp
;
445 temp
= (char *)malloc(MAX_STRING_VAL
*sizeof(char)) ;
446 body
= (char *)malloc(MAX_STRING_VAL
*sizeof(char)) ;
447 sval
= (char *)malloc(MAX_STRING_VAL
*sizeof(char)) ;
451 /* statements for the 'normal' processing. */
452 if (value_notzero_p(val
) && (!cst
))
453 { if ((*first
) || value_neg_p(val
))
454 { if (value_one_p(val
)) /* case 1 */
455 sprintf(sval
,"%s",name
) ;
457 { if (value_mone_p(val
)) /* case -1 */
458 sprintf(sval
,"-%s",name
) ;
459 else /* default case */
460 { value_sprint(sval
,VALUE_FMT
,val
) ;
461 sprintf(temp
,"*%s",name
) ;
468 { if (value_one_p(val
))
469 sprintf(sval
,"+%s",name
) ;
471 { sprintf(sval
,"+") ;
472 value_sprint(temp
,VALUE_FMT
,val
) ;
474 sprintf(temp
,"*%s",name
) ;
481 { if ((value_zero_p(val
) && (*first
)) || value_neg_p(val
))
482 value_sprint(sval
,VALUE_FMT
,val
) ;
483 if (value_pos_p(val
))
485 { value_sprint(sval
,"+"VALUE_FMT
,val
) ; /* Block macro ! */
488 value_sprint(sval
,VALUE_FMT
,val
) ;
500 * pprint_line function:
501 * This function returns a string containing the printing of the 'right part'
502 * of a constraint according to an element.
503 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
504 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
505 * function should return 'ceild(3*i+M,2)'.
506 * - matrix is the polyhedron containing all the constraints,
507 * - line_num is the line number in domain of the constraint we want to print,
508 * - level is the column number in domain of the element we want to use,
509 * - the infos structure gives the user some options about code printing,
510 * the number of parameters in domain (nb_par), and the arrays of iterator
511 * names and parameters (iters and params).
513 * - November 2nd 2001: first version.
514 * - June 27th 2003: 64 bits version ready.
516 char * pprint_line(matrix
, equal
, line_num
, level
, infos
)
517 CloogMatrix
* matrix
, * equal
;
518 int line_num
, level
;
520 { int i
, nb_iter
, sign
, first
=1, nb_elts
=0 ;
521 char * sval
, * body
, * sline
, * name
, * stemp
;
522 Value
* line
, numerator
, denominator
, temp
, division
;
524 line
= matrix
->p
[line_num
] ;
526 value_init_c(numerator
) ;
527 value_init_c(denominator
) ;
529 stemp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
530 body
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
532 sline
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
535 if (value_notzero_p(line
[level
]))
536 { /* Maybe we need to invert signs in such a way that the element sign is>0.*/
537 sign
= value_pos_p(line
[level
]) ? -1 : 1 ;
539 /* First, we have to print the iterators. */
540 nb_iter
= matrix
->NbColumns
- 2 - infos
->names
->nb_parameters
;
541 for (i
=1;i
<=nb_iter
;i
++)
542 if ((i
!= level
) && value_notzero_p(line
[i
]))
543 { if (i
<= infos
->names
->nb_scattering
)
544 name
= infos
->names
->scattering
[i
-1] ;
546 name
= infos
->names
->iterators
[i
-infos
->names
->nb_scattering
-1] ;
549 value_oppose(temp
,line
[i
]) ;
551 value_assign(temp
,line
[i
]) ;
553 sval
= pprint_val(temp
,i
,&first
,0,name
,infos
) ;
559 /* Next, the parameters. */
560 for (i
=nb_iter
+1;i
<=matrix
->NbColumns
-2;i
++)
561 if ((i
!= level
) && value_notzero_p(line
[i
]))
562 { name
= infos
->names
->parameters
[i
-nb_iter
-1] ;
565 value_oppose(temp
,line
[i
]) ;
567 value_assign(temp
,line
[i
]) ;
569 sval
=pprint_val(temp
,-1,&first
,0,name
,infos
) ;
576 { value_oppose(numerator
,line
[matrix
->NbColumns
- 1]) ;
577 value_assign(denominator
,line
[level
]) ;
580 { value_assign(numerator
,line
[matrix
->NbColumns
- 1]) ;
581 value_oppose(denominator
,line
[level
]) ;
584 /* Finally, the constant, and the final printing. */
586 { sval
= pprint_val(numerator
,-1,&first
,1,"",infos
) ;
592 if (value_notone_p(line
[level
]) && value_notmone_p(line
[level
]))
593 { if (value_one_p(line
[0]))
594 { if (value_pos_p(line
[level
]))
595 { if (infos
->language
== LANGUAGE_FORTRAN
)
596 { sprintf(sline
,"CEILING(REAL(%s)/REAL(",body
) ;
597 value_sprint(stemp
,VALUE_FMT
"))",denominator
) ;
600 { sprintf(sline
,"ceild(%s,",body
) ;
601 value_sprint(stemp
,VALUE_FMT
")",denominator
) ;
605 { if (infos
->language
== LANGUAGE_FORTRAN
)
606 { sprintf(sline
,"FLOOR(REAL(%s)/REAL(",body
) ;
607 value_sprint(stemp
,VALUE_FMT
"))",denominator
) ;
610 { sprintf(sline
,"floord(%s,",body
) ;
611 value_sprint(stemp
,VALUE_FMT
")",denominator
) ;
617 sprintf(sline
,"(%s)/",body
) ;
619 sprintf(sline
,"%s/",body
) ;
621 value_sprint(stemp
,VALUE_FMT
,denominator
) ;
623 strcat(sline
,stemp
) ;
626 sprintf(sline
,"%s",body
) ;
629 { if (value_zero_p(numerator
))
632 { if (value_notone_p(denominator
))
633 { if (value_one_p(line
[0])) /* useful? */
634 { value_modulus(temp
,numerator
,denominator
) ;
635 if (value_zero_p(temp
))
636 { value_division(temp
,numerator
,denominator
) ;
637 value_sprint(sline
,VALUE_FMT
,temp
) ;
640 { value_init_c(division
) ;
641 value_division(division
,numerator
,denominator
) ;
642 if (value_neg_p(numerator
))
643 { if (value_pos_p(line
[level
]))
645 { value_sprint(sline
,VALUE_FMT
,division
) ; /* Block macro ! */
648 { /* nb<0 need min */
649 value_decrement(temp
,division
) ;
650 value_sprint(sline
,VALUE_FMT
,temp
) ;
654 { if (value_pos_p(line
[level
]))
655 { /* nb>0 need max */
656 value_increment(temp
,division
) ;
657 value_sprint(sline
,VALUE_FMT
,temp
) ;
661 value_sprint(sline
,VALUE_FMT
,division
) ;
663 value_clear_c(division
) ;
667 { value_sprint(sline
,VALUE_FMT
"/",numerator
) ;
668 value_sprint(stemp
,VALUE_FMT
,denominator
) ;
669 strcat(sline
,stemp
) ;
673 value_sprint(sline
,VALUE_FMT
,numerator
) ;
680 value_clear_c(temp
) ;
681 value_clear_c(numerator
) ;
682 value_clear_c(denominator
) ;
689 * pprint_minmax function:
690 * This function returns a string containing the printing of a minimum or a
691 * maximum of the 'right parts' of all constraints according to an element.
692 * For instance consider the constraints:
696 * if we are looking for the minimum for the element j, the function should
697 * return 'max(ceild(3*i+M,2),-2*i)'.
698 * - matrix is the polyhedron containing all the constraints,
699 * - level is the column number in domain of the element we want to use,
700 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
701 * - guard is set to 0 if there is no guard, and set to the level of the element
702 * with a guard otherwise (then the function gives the max or the min only
703 * for the constraint where the guarded coefficient is 0),
704 * - the infos structure gives the user some options about code printing,
705 * the number of parameters in domain (nb_par), and the arrays of iterator
706 * names and parameters (iters and params).
708 * - November 2nd 2001: first version.
710 char * pprint_minmax(matrix
, equal
, level
, max
, guard
, infos
)
711 CloogMatrix
* matrix
, * equal
;
712 int level
, max
, guard
;
715 char * sline
, * body
, * sminmax
;
717 body
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
719 sminmax
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
722 for (i
=0;i
<matrix
->NbRows
;i
++)
723 if (((max
&& value_pos_p(matrix
->p
[i
][level
])) ||
724 (!max
&& value_neg_p(matrix
->p
[i
][level
]))) &&
725 (!guard
|| value_zero_p(matrix
->p
[i
][guard
])) &&
726 (value_notzero_p(matrix
->p
[i
][0])))
727 { sline
= pprint_line(matrix
,equal
,i
,level
,infos
) ;
728 strcat(sminmax
,sline
) ;
732 /* We begin after the first found element. */
733 for (i
++;i
<matrix
->NbRows
;i
++)
734 if (((max
&& value_pos_p(matrix
->p
[i
][level
])) ||
735 (!max
&& value_neg_p(matrix
->p
[i
][level
]))) &&
736 (!guard
|| value_zero_p(matrix
->p
[i
][guard
])) &&
737 (value_notzero_p(matrix
->p
[i
][0])))
738 { sline
= pprint_line(matrix
,equal
,i
,level
,infos
) ;
740 if (infos
->language
== LANGUAGE_FORTRAN
)
743 sprintf(body
,"MAX(%s,%s",sminmax
,sline
) ;
745 sprintf(body
,"MIN(%s,%s",sminmax
,sline
) ;
748 sprintf(sminmax
,"%s",body
) ;
751 { sprintf(body
,",%s",sline
) ;
752 strcat(sminmax
,body
) ;
757 sprintf(body
,"max(%s,%s)",sminmax
,sline
) ;
759 sprintf(body
,"min(%s,%s)",sminmax
,sline
) ;
761 sprintf(sminmax
,"%s",body
) ;
768 if ((infos
->language
== LANGUAGE_FORTRAN
) && (!first
))
769 strcat(sminmax
,")") ;
776 * pprint_guard function:
777 * This function returns a string containing the printing of a guard.
778 * A guard on an element (level) is :
779 * -> the conjunction of all the existing constraints where the coefficient of
780 * this element is 0 if the element is an iterator,
781 * -> the conjunction of all the existing constraints if the element isn't an
783 * For instance, considering these constraints and the element j:
786 * this function should return 'if (2*i+M>=0) {'.
787 * - matrix is the polyhedron containing all the constraints,
788 * - level is the column number of the element in matrix we want to use,
789 * - guard is a pointer to a boolean set to 0 if there is no guard, 1 otherwise,
790 * this function can set this boolean to 1 if there is a guard,
791 * - indent is a pointer to an integer giving the indent level, this function
792 * can increase indent if there is a guard,
793 * - the infos structure gives the user some options about code printing,
794 * the number of parameters in matrix (nb_par), and the arrays of iterator
795 * names and parameters (iters and params).
797 * - November 3rd 2001: first version.
798 * - November 14th 2001: a lot of 'purifications'.
799 * - July 31th 2002: (debug) some guard parts are no more redundants.
800 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
801 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
802 * (the need came from loop_simplify that may result in
803 * domain unions, now it should be fixed directly in
804 * cloog_loop_simplify).
806 char * pprint_guard(matrix
, equal
, level
, guard
, indent
, infos
)
807 CloogMatrix
* matrix
, * equal
;
808 int level
, * guard
, * indent
;
810 { int i
, j
, k
, l
, guarded
, minmax
=-1, nb_and
= 0, nb_iter
;
811 char * name
, * sline
, * body
, * temp
, * sguard
;
814 temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
815 body
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
816 sguard
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
820 { /* Well, it looks complicated because I wanted to have a particular, more
821 * readable, ordering, obviously this function may be far much simpler !
823 copy
= cloog_matrix_copy(matrix
) ;
825 nb_iter
= copy
->NbColumns
- 2 - infos
->names
->nb_parameters
;
829 /* We search for guard parts. */
830 for (i
=1;i
<=copy
->NbColumns
-2;i
++)
831 for (j
=0;j
<copy
->NbRows
;j
++)
832 if (value_notzero_p(copy
->p
[j
][i
]) &&
833 (value_zero_p(copy
->p
[j
][level
]) || (nb_iter
< level
)))
835 { if (i
<= infos
->names
->nb_scattering
)
836 name
= infos
->names
->scattering
[i
-1] ;
838 name
= infos
->names
->iterators
[i
-infos
->names
->nb_scattering
-1] ;
841 name
= infos
->names
->parameters
[i
-(nb_iter
+1)] ;
844 { if (infos
->language
== LANGUAGE_FORTRAN
)
845 strcat(body
," .AND. ") ;
847 strcat(body
," && ") ;
850 if (value_zero_p(copy
->p
[j
][0]))
851 { sprintf(temp
,"(%s == ",name
) ;
852 sline
= pprint_line(copy
,equal
,j
,i
,infos
) ;
855 { if (value_pos_p(copy
->p
[j
][i
]))
856 { sprintf(temp
,"(%s >= ",name
) ;
860 { sprintf(temp
,"(%s <= ",name
) ;
864 guarded
= (nb_iter
>= level
) ? level
: 0 ;
865 sline
= pprint_minmax(copy
,equal
,i
,minmax
,guarded
,infos
) ;
874 /* 'elimination' of the current constraint, this avoid to use one
875 * constraint more than once. The current line is always eliminated,
876 * and the next lines if they are in a min or a max.
878 for (k
=i
;k
<=copy
->NbColumns
-2;k
++)
879 value_set_si(copy
->p
[j
][k
],0) ;
882 for (l
=j
+1;l
<copy
->NbRows
;l
++)
883 if (((minmax
== 1) && value_pos_p(copy
->p
[l
][i
])) ||
884 ((minmax
== 0) && value_neg_p(copy
->p
[l
][i
])))
885 for (k
=i
;k
<=copy
->NbColumns
-2;k
++)
886 value_set_si(copy
->p
[l
][k
],0) ;
888 cloog_matrix_free(copy
) ;
893 { for (k
=0;k
<(*indent
);k
++)
896 if (infos
->language
== LANGUAGE_FORTRAN
)
897 strcat(sguard
,"IF ") ;
899 strcat(sguard
,"if ") ;
902 { strcat(sguard
,"(") ;
903 strcat(sguard
,body
) ;
907 strcat(sguard
,body
) ;
909 if (infos
->language
== LANGUAGE_FORTRAN
)
910 strcat(sguard
," THEN\n") ;
912 strcat(sguard
," {\n") ;
914 *indent
+= INDENT_STEP
;
923 * pprint_equality function:
924 * This function returns a string containing the printing of an equality
925 * constraint according to an element.
926 * An equality can be preceded by a 'modulo guard'.
927 * For instance, consider the constraint i -2*j = 0 and the
928 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
929 * - matrix is the polyhedron containing all the constraints,
930 * - num is the line number of the constraint in matrix we want to print,
931 * - level is the column number of the element in matrix we want to use,
932 * - modulo_guard is a pointer to a boolean set to 0 if there is no modulo
933 * guard, 1 otherwise, this function can set this boolean to 1,
934 * - indent is a pointer to an integer giving the indent level, this function
935 * can increase indent if there is a modulo guard,
936 * - the infos structure gives the user some options about code printing,
937 * - the infos structure gives the user some options about code printing,
938 * the number of parameters in matrix (nb_par), and the arrays of iterator
939 * names and parameters (iters and params).
941 * - November 13th 2001: first version.
942 * - June 26th 2003: simplification of the modulo guards (remove parts such as
943 * modulo is 0, compare vivien or vivien2 with a previous
944 * version for an idea).
945 * - June 29th 2003: non-unit strides support.
946 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
947 * it was previously included in a stride calculation.
949 char * pprint_equality(matrix
, equal
, num
, level
, modulo_guard
, indent
, infos
)
950 CloogMatrix
* matrix
, * equal
;
951 int num
, level
, * modulo_guard
, * indent
;
953 { int i
, sign
, first
=1, nb_elts
=0, nb_iter
=0, guarded
=0, in_stride
=0 ;
954 char * body
, * seq
, * sval
, * sline
, * name
;
959 body
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
961 seq
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
964 line
= matrix
->p
[num
] ;
965 sign
= value_pos_p(line
[level
]) ? -1 : 1 ;
966 nb_iter
= matrix
->NbColumns
- 2 - infos
->names
->nb_parameters
;
968 /* First, the modulo guard : the iterators... */
969 for (i
=1;i
<=nb_iter
;i
++)
970 { value_modulus(val
,line
[i
],line
[level
]) ;
971 if ((i
!= level
) && value_notzero_p(line
[i
]) && value_notzero_p(val
))
972 { value_modulus(val
,infos
->stride
[i
-1],line
[level
]) ;
973 if (value_notzero_p(val
))
975 value_oppose(val
,line
[i
]) ;
977 value_assign(val
,line
[i
]) ;
979 if (i
<= infos
->names
->nb_scattering
)
980 name
= infos
->names
->scattering
[i
-1] ;
982 name
= infos
->names
->iterators
[i
-infos
->names
->nb_scattering
-1] ;
984 sval
= pprint_val(val
,i
,&first
,0,name
,infos
) ;
990 /* We need to know if an element of the equality has not to be printed
991 * because of a stride that guarantees that this element can be divided by
992 * the current coefficient. Because when there is a constant element, it
993 * is included in the stride calculation (more exactly in the strided
994 * iterator new lower bound: the 'offset') and we have not to print it.
996 if (value_notone_p(infos
->stride
[i
-1]))
1001 /* ...the parameters... */
1002 for (i
=nb_iter
+1;i
<=matrix
->NbColumns
-2;i
++)
1003 { value_modulus(val
,line
[i
],line
[level
]) ;
1004 if (value_notzero_p(line
[i
]) && value_notzero_p(val
))
1006 value_oppose(val
,line
[i
]) ;
1008 value_assign(val
,line
[i
]) ;
1010 name
= infos
->names
->parameters
[i
-nb_iter
-1] ;
1011 sval
= pprint_val(val
,-1,&first
,0,name
,infos
) ;
1018 /* ...the constant. */
1019 value_modulus(val
,line
[matrix
->NbColumns
-1],line
[level
]) ;
1020 if ((nb_elts
|| (value_notzero_p(val
) && (!in_stride
))) &&
1021 value_notone_p(line
[level
]) && value_notmone_p(line
[level
]))
1023 value_oppose(val
,line
[matrix
->NbColumns
-1]) ;
1025 value_assign(val
,line
[matrix
->NbColumns
-1]) ;
1027 sval
= pprint_val(val
,-1,&first
,1,"",infos
) ;
1033 for (i
=0;i
<(*indent
);i
++)
1036 if (infos
->language
== LANGUAGE_FORTRAN
)
1037 strcat(seq
,"IF (") ;
1039 strcat(seq
,"if (") ;
1041 if ((-1 * sign
) == -1)
1042 value_oppose(val
,line
[level
]) ;
1044 value_assign(val
,line
[level
]) ;
1046 if (infos
->language
== LANGUAGE_FORTRAN
)
1047 { strcat(seq
,"MOD(") ;
1049 value_sprint(body
,","VALUE_FMT
") == 0) THEN\n",val
) ;
1061 value_sprint(body
,VALUE_FMT
" == 0) {\n",val
) ;
1066 *indent
+= INDENT_STEP
;
1070 if (!pprint_equal_add(equal
,matrix
,level
,num
,infos
))
1071 { /* Finally, the equality. */
1072 for (i
=0;i
<(*indent
);i
++)
1075 /* If we have to make a block by dimension, we start the block. Function
1076 * pprint knows if there is an equality, if this is the case, it checks
1077 * for the same following condition to close the brace.
1079 if (infos
->options
->block
&& (infos
->language
==LANGUAGE_C
))
1080 { strcat(seq
,"{ ") ;
1081 *indent
+= INDENT_STEP
;
1084 if (level
<= infos
->names
->nb_scattering
)
1085 sprintf(body
,"%s = ",infos
->names
->scattering
[level
-1]) ;
1087 sprintf(body
,"%s = ",
1088 infos
->names
->iterators
[level
-infos
->names
->nb_scattering
-1]) ;
1091 sline
= pprint_line(matrix
,equal
,num
,level
,infos
) ;
1092 if (infos
->language
== LANGUAGE_FORTRAN
)
1093 sprintf(body
,"%s\n",sline
) ;
1095 sprintf(body
,"%s ;\n",sline
) ;
1101 value_clear_c(val
) ;
1108 * pprint_for function:
1109 * This function returns a string containing the printing of a loop header
1110 * according to an element.
1111 * A loop header according to an element is the conjonction of a minimum and a
1112 * maximum on the element (they give the loop bounds).
1113 * For instance, considering these constraints and the element j:
1117 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1118 * - matrix is the polyhedron containing all the constraints,
1119 * - level is the column number of the element in matrix we want to use,
1120 * - accol is a pointer to a boolean set to 0 if there is no 'if', 1 otherwise,
1121 * this function can set this boolean to 1 if there is a 'if',
1122 * - indent is a pointer to an integer giving the indent level, this function
1123 * can increase indent if there is a 'if',
1124 * - the infos structure gives the user some options about code printing,
1125 * the number of parameters in matrix (nb_par), and the arrays of iterator
1126 * names and parameters (iters and params).
1128 * - July 2nd 2002: first version (pick from pprint function).
1129 * - March 6th 2003: infinite domain support.
1130 * - June 29th 2003: non-unit strides support.
1132 char * pprint_for(matrix
, equal
, level
, accol
, indent
, infos
)
1133 CloogMatrix
* matrix
, * equal
;
1134 int level
, * accol
, * indent
;
1135 CloogInfos
* infos
;
1137 char * sfor
, * sline1
, *sline2
, * temp
, * iterator
;
1139 if (level
<= infos
->names
->nb_scattering
)
1140 iterator
= infos
->names
->scattering
[level
-1] ;
1142 iterator
= infos
->names
->iterators
[level
-infos
->names
->nb_scattering
-1] ;
1144 temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1145 sfor
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1148 sline1
= pprint_minmax(matrix
,equal
,level
,1,0,infos
) ;
1149 sline2
= pprint_minmax(matrix
,equal
,level
,0,0,infos
) ;
1151 /* If min and max are not equal there is a 'for' else, there is a '='.
1152 * In the special case sline1 = sline2 = '\0', this is an infinite loop
1153 * so this is not a '='.
1155 if ((strcmp(sline1
,sline2
) != 0) || !infos
->options
->otl
||
1156 ((strlen(sline1
) == 0) && (strlen(sline2
) == 0)))
1157 { for (i
=0;i
<(*indent
);i
++)
1160 if (infos
->language
== LANGUAGE_FORTRAN
)
1161 sprintf(temp
,"DO ") ;
1163 sprintf(temp
,"for (") ;
1166 if (strlen(sline1
) != 0)
1167 { sprintf(temp
,"%s=%s",iterator
,sline1
) ;
1171 if (infos
->language
== LANGUAGE_FORTRAN
)
1172 { fprintf(stderr
,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
1176 if (infos
->language
== LANGUAGE_FORTRAN
)
1177 sprintf(temp
,", ") ;
1182 if (strlen(sline2
) != 0)
1183 { if (infos
->language
== LANGUAGE_FORTRAN
)
1184 sprintf(temp
,"%s",sline2
) ;
1186 sprintf(temp
,"%s<=%s",iterator
,sline2
) ;
1191 if (infos
->language
== LANGUAGE_FORTRAN
)
1192 { fprintf(stderr
,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
1196 if (infos
->language
== LANGUAGE_FORTRAN
)
1197 { if (value_gt_si(infos
->stride
[level
-1],1))
1198 { value_sprint(temp
,", "VALUE_FMT
"\n",infos
->stride
[level
-1]) ;
1201 sprintf(temp
,"\n") ;
1204 { if (value_gt_si(infos
->stride
[level
-1],1))
1205 { sprintf(temp
,";%s+=",iterator
) ; /* sline2 may be reused safely here. */
1206 value_sprint(sline2
,VALUE_FMT
") {\n",infos
->stride
[level
-1]) ;
1207 strcat(temp
,sline2
) ;
1210 sprintf(temp
,";%s++) {\n",iterator
) ;
1217 if (!pprint_equal_add(equal
,matrix
,level
,ONE_TIME_LOOP
,infos
))
1218 { for (i
=0;i
<(*indent
);i
++)
1220 if (infos
->language
== LANGUAGE_FORTRAN
)
1221 sprintf(temp
,"%s = %s\n",iterator
,sline1
);
1223 { /* If the option block is set, build the block. */
1224 if (infos
->options
->block
)
1225 { strcat(sfor
,"{ ") ;
1228 sprintf(temp
,"%s = %s ;\n",iterator
,sline1
);
1242 * pprint_scalar function:
1243 * This function returns a string containing the printing of the scalar values
1244 * that follows the level (level). It finds by scanning (loop) by inner level,
1245 * the first CloogBlock data structure (at this step, all blocks has the same
1246 * scalar vector information after (level)), and prints all the adjacent
1247 * scalar values following (level), if it is required by options in (info).
1248 * - loop is the loop structure to begin the search for a block,
1249 * - level is the current loop level,
1250 * - scalar points to the number of scalar values already visited,
1251 * - scalbraces points to the number of braces to close for scalar dimensions,
1252 * - indent points to the number of space required for indentation,
1253 * - the infos structure gives the user options about code printing and more.
1255 * - September 12th 2005: first version.
1257 char * pprint_scalar(loop
, level
, scalar
, scalbraces
, indent
, infos
)
1259 int level
, * scalar
, * scalbraces
, * indent
;
1260 CloogInfos
* infos
;
1262 char * sscalar
, * temp
;
1264 sscalar
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1267 if ((!infos
->options
->csp
) &&
1268 (level
+(*scalar
) <= infos
->nb_scattdims
) &&
1269 (infos
->scaldims
[level
+(*scalar
)-1]))
1270 { while (loop
->block
== NULL
)
1271 loop
= loop
->inner
;
1273 temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1274 while ((level
+(*scalar
) <= infos
->nb_scattdims
) &&
1275 (infos
->scaldims
[level
+(*scalar
)-1]))
1276 { for (i
=0;i
<(*indent
);i
++)
1277 strcat(sscalar
," ") ;
1279 if (infos
->options
->block
)
1280 { strcat(sscalar
,"{ ") ;
1284 sprintf(temp
,"%s = ",infos
->names
->scalars
[(*scalar
)]) ;
1285 strcat(sscalar
,temp
) ;
1286 value_sprint(temp
,VALUE_FMT
" ;\n",loop
->block
->scaldims
[(*scalar
)]) ;
1287 strcat(sscalar
,temp
) ;
1290 if (infos
->options
->block
)
1291 *indent
+= INDENT_STEP
;
1301 * pprint_block function:
1302 * This function returns a string containing the printing of a statement block
1304 * - block is the statement block,
1305 * - level is the number of loops enclosing the statement,
1306 * - accol is a pointer to a boolean set to 0 if there is no 'if' before the
1307 * statement, 1 otherwise,
1308 * - indent is a pointer to an integer giving the indentation level,
1309 * - the infos structure gives the user some options about code printing,
1310 * the number of parameters in domain (nb_par), and the arrays of iterator
1311 * names and parameters (iters and params).
1313 * - September 21th 2003: first version (pick from pprint function).
1315 char * pprint_block(block
, equal
, level
, accol
, indent
, infos
)
1316 CloogBlock
* block
;
1317 CloogMatrix
* equal
;
1318 int level
, accol
, indent
;
1319 CloogInfos
* infos
;
1320 { int i
, new_indent
;
1321 char * sstatement
, * sline
, * temp
;
1322 CloogStatement
* statement
;
1324 sstatement
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1325 sstatement
[0] = '\0' ;
1328 { temp
= (char *)malloc(MAX_STRING
*sizeof(char)) ;
1330 statement
= block
->statement
;
1332 while (statement
!= NULL
)
1333 { new_indent
= (accol
== 1) ? indent
+ INDENT_STEP
: indent
;
1335 /* Printing of one statement. */
1336 for (i
=0;i
<new_indent
;i
++)
1337 strcat(sstatement
," ") ;
1339 if (infos
->options
->cpp
== 0)
1340 sline
= pprint_equal(equal
,infos
) ;
1342 sline
= pprint_equal_cpp(equal
,level
,infos
) ;
1344 sprintf(temp
,"S%d%s",statement
->number
+1,sline
) ;
1345 strcat(sstatement
,temp
) ;
1348 if (infos
->language
!= LANGUAGE_FORTRAN
)
1349 strcat(sstatement
," ;") ;
1350 strcat(sstatement
,"\n") ;
1352 statement
= statement
->next
;
1357 return(sstatement
) ;
1363 * This function prints the content of a CloogLoop structure (loop) into a
1364 * file (foo, possibly stdout), in a C-like or FORTRAN-like language.
1365 * This function pretty-prints the data of a loop. The iterator (level) of
1366 * the current loop is given by 'level': this is the column number of the
1367 * domain corresponding to the current loop iterator. The data of a loop are
1368 * written in this order:
1369 * 1. The guard of the loop, i.e. each constraint in the domain that do not
1370 * depend on the iterator (when the entry in the column 'level' is 0).
1371 * 2. The iteration domain of the iterator, given by the constraints in the
1372 * domain depending on the iterator, i.e.:
1373 * * an equality if the iterator has only one value (possibly preceded by
1374 * a guard verifying if this value is integral), *OR*
1375 * * a loop from the minimum possible value of the iterator to the maximum
1377 * 3. The included statement block.
1378 * 4. The inner loops (recursive call).
1379 * 5. The following loops (recursive call).
1380 * - level is the recursion level or the iteration level that we are printing,
1381 * - indent is the indent level, the number of spaces to print before writing,
1382 * - the infos structure gives the user some options about code printing,
1383 * the number of parameters in domain (nb_par), and the arrays of iterator
1384 * names and parameters (iters and params).
1386 * - November 2nd 2001: first version.
1387 * - March 6th 2003: infinite domain support.
1388 * - April 19th 2003: (debug) NULL loop support.
1389 * - June 29th 2003: non-unit strides support.
1390 * - April 28th 2005: (debug) level is level+equality when print statement!
1391 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1392 * added to avoid iteration duplication (see DaeGon Kim
1393 * bug in cloog_program_generate). Try vasilache.cloog
1394 * with and without the call to cloog_matrix_normalize,
1395 * using -f 8 -l 9 options for an idea.
1396 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1397 * - October 16th 2005: (debug) scalar value is saved for next loops.
1399 void pprint(foo
, loop
, equal
, level
, scalar
, indent
, infos
)
1402 CloogMatrix
* equal
;
1403 int level
, scalar
, indent
;
1404 CloogInfos
* infos
;
1405 { int i
, new_indent
, stride
, equality
=0, accol
=0, scalbraces
=0, guard
=0,
1406 modulo_guard
=0, scalar_level
;
1408 CloogMatrix
* matrix
, * temp
;
1410 /* It can happen that loop be NULL when an input polyhedron is empty. */
1414 /* The matrix has not always a shape that allows us to generate code from it,
1415 * thus we normalize it, we also simplify it with the matrix of equalities.
1417 temp
= cloog_domain_domain2matrix(loop
->domain
) ;
1418 cloog_matrix_normalize(temp
,level
) ;
1419 matrix
= cloog_matrix_simplify(temp
,equal
,level
,infos
->names
->nb_parameters
) ;
1420 cloog_matrix_free(temp
) ;
1421 value_assign(infos
->stride
[level
-1],loop
->stride
) ;
1423 /* First of all we have to print the guard. */
1424 sline
= pprint_guard(matrix
,equal
,level
,&guard
,&indent
,infos
) ;
1425 fprintf(foo
,"%s",sline
) ;
1428 /* Then we print scalar dimensions. */
1429 scalar_level
= scalar
;
1430 sline
= pprint_scalar(loop
,level
,&scalar
,&scalbraces
,&indent
,infos
) ;
1431 fprintf(foo
,"%s",sline
) ;
1434 if ((matrix
->NbColumns
- 2 - infos
->names
->nb_parameters
>= level
))
1435 { /* We scan all the constraints to know in which case we are :
1436 * [[if] equality] or [for].
1438 for (i
=0;i
<matrix
->NbRows
;i
++)
1439 if (value_zero_p(matrix
->p
[i
][0]) &&
1440 value_notzero_p(matrix
->p
[i
][level
]))
1441 { /* If there is an equality, we can print it directly -no ambiguity-.
1442 * PolyLib can give more than one equality, we use just the first one
1443 * (this is a PolyLib problem, but all equalities are equivalent).
1445 sline
=pprint_equality(matrix
,equal
,i
,level
,&modulo_guard
,&indent
,infos
) ;
1452 sline
= pprint_for(matrix
,equal
,level
,&accol
,&indent
,infos
);
1455 { /* If no equality have been printed out (e.g. because of a spreading), we
1456 * have to specify that there is no open brace to close.
1458 if ((sline
== NULL
) || (!strcmp(sline
,"\0")))
1461 fprintf(foo
,"%s",sline
) ;
1465 /* Finally, if there is an included statement block, print it. */
1466 sline
= pprint_block(loop
->block
,equal
,level
+equality
,accol
,indent
,infos
) ;
1467 fprintf(foo
,"%s",sline
) ;
1470 /* Go to the next level. */
1471 if (loop
->inner
!= NULL
)
1472 { new_indent
= (accol
== 1) ? indent
+ INDENT_STEP
: indent
;
1473 pprint(foo
,loop
->inner
,equal
,level
+1,scalar
,new_indent
,infos
) ;
1476 /* Close the open braces. */
1477 /* Close the for (or do) loop brace if any. */
1479 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ;
1481 if (infos
->language
== LANGUAGE_FORTRAN
)
1482 fprintf(foo
,"END DO\n") ;
1484 fprintf(foo
,"}\n") ;
1487 { /* Close the equality brace if any. */
1488 if (equality
&& infos
->options
->block
&& (infos
->language
== LANGUAGE_C
))
1489 { indent
= indent
- INDENT_STEP
;
1490 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ;
1492 fprintf(foo
,"}\n") ;
1494 /* Close the modulo guard brace that may precede an equality if any. */
1496 { indent
= indent
- INDENT_STEP
;
1497 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ;
1499 if (infos
->language
== LANGUAGE_FORTRAN
)
1500 fprintf(foo
,"END IF\n") ;
1502 fprintf(foo
,"}\n") ;
1505 /* Close the scalar dimension braces if any. */
1506 if (infos
->language
== LANGUAGE_C
)
1507 { for (i
=0;i
<scalbraces
;i
++)
1508 { indent
= indent
- INDENT_STEP
;
1509 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ;
1511 fprintf(foo
,"}\n") ;
1514 /* Close the general guard brace if any. */
1516 { indent
= indent
- INDENT_STEP
;
1517 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ;
1519 if (infos
->language
== LANGUAGE_FORTRAN
)
1520 fprintf(foo
,"END IF\n") ;
1522 fprintf(foo
,"}\n") ;
1525 pprint_equal_del(equal
,level
) ;
1526 cloog_matrix_free(matrix
) ;
1527 /* Go to the next loop on the same level. */
1528 if (loop
->next
!= NULL
)
1529 pprint(foo
,loop
->next
,equal
,level
,scalar_level
,indent
,infos
) ;