First commit : 0.14.0 version (with roadmap in doc instead of
[cloog/uuh.git] / source / pprint.c
blob6759c695edb97a0cdb1ef962a1e4e2db4d64ae6a
2 /**-------------------------------------------------------------------**
3 ** CLooG **
4 **-------------------------------------------------------------------**
5 ** pprint.c **
6 **-------------------------------------------------------------------**
7 ** First version: october 26th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
14 * *
15 * Copyright (C) 2001-2005 Cedric Bastoul *
16 * *
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 *
20 * version. *
21 * *
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 *
25 * for more details. *
26 * *
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 *
30 * *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
33 * *
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.
46 # include <stdlib.h>
47 # include <stdio.h>
48 # include <string.h>
49 # include "../include/cloog/cloog.h"
52 /******************************************************************************
53 * Memory leaks hunting *
54 ******************************************************************************/
56 /**
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.
88 /**
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
94 * expression'.
95 * For instance:
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
100 * constraints.
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 ;
115 int level, line ;
116 { int i, one=0 ;
117 Value * expr ;
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 ;
128 else
129 one = 1 ;
131 /* if the constant factor is non null, it must be alone. */
132 if (one != 0)
133 { if (value_notzero_p(expr[equal->NbColumns-1]))
134 return EQTYPE_EXAFFINE ;
136 else
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 ;
156 int level, line ;
157 CloogInfos * infos ;
158 { if ((!infos->options->csp && !infos->options->esp) ||
159 (level < infos->options->fsp))
160 return 0 ;
162 if (infos->options->csp &&
163 (pprint_equal_type(equal,level,line) == EQTYPE_EXAFFINE) &&
164 !infos->options->esp)
165 return 0 ;
167 return 1 ;
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 ;
183 CloogInfos * infos ;
184 { int i, first=1, iterator ;
185 char * body, * temp, * seq, * sline ;
186 Value type ;
188 temp = (char *)malloc(MAX_STRING*sizeof(char)) ;
189 body = (char *)malloc(MAX_STRING*sizeof(char)) ;
190 body[0] = '\0' ;
191 seq = (char *)malloc(MAX_STRING*sizeof(char)) ;
192 value_init_c(type) ;
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))
199 { if (!first)
200 strcat(body,",") ;
202 iterator = i - infos->names->nb_scattering ;
203 sprintf(temp,"%s = ",infos->names->iterators[iterator]) ;
204 strcat(body,temp) ;
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
208 * tag in PolyLib.
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) ;
215 strcat(body,sline) ;
216 free(sline) ;
217 first = 0 ;
220 free(temp) ;
221 value_clear_c(type) ;
223 if (!first)
224 sprintf(seq,"(%s)",body) ;
225 else
226 sprintf(seq,"%s",body) ;
228 free(body) ;
230 return(seq) ;
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 ;
251 int level ;
252 CloogInfos * infos ;
253 { int i ;
254 char * temp, * seq, * sline ;
255 Value type ;
257 temp = (char *)malloc(MAX_STRING*sizeof(char)) ;
258 seq = (char *)malloc(MAX_STRING*sizeof(char)) ;
259 seq[0] = '\0' ;
260 value_init_c(type) ;
262 strcat(seq,"(") ;
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
267 * tag in PolyLib.
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) ;
274 strcat(seq,sline) ;
275 free(sline) ;
277 else
278 { sprintf(temp,"%s",infos->names->iterators[i-infos->names->nb_scattering]);
279 strcat(seq,temp) ;
282 if (i != level-2)
283 strcat(seq,",") ;
285 free(temp) ;
286 value_clear_c(type) ;
287 strcat(seq,")") ;
289 return(seq) ;
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 ;
309 int level, line ;
310 CloogInfos * infos ;
311 { int i ;
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])))
321 { line = i ;
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
353 * level coefficient.
355 if (value_pos_p(numerator) || value_zero_p(modulo))
356 value_assign(matrix->p[i][matrix->NbColumns-1],division) ;
357 else
358 { if (value_pos_p(matrix->p[i][level]))
359 value_increment(matrix->p[i][matrix->NbColumns-1],division) ;
360 else
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) ;
366 else
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) ;
375 break ;
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)
405 { int i ;
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)
439 Value val ;
440 int level, * first, cst ;
441 char * name ;
442 CloogInfos * infos ;
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)) ;
448 body[0] = '\0' ;
449 sval[0] = '\0' ;
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) ;
456 else
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) ;
462 strcat(sval,temp) ;
465 *first = 0 ;
467 else
468 { if (value_one_p(val))
469 sprintf(sval,"+%s",name) ;
470 else
471 { sprintf(sval,"+") ;
472 value_sprint(temp,VALUE_FMT,val) ;
473 strcat(sval,temp) ;
474 sprintf(temp,"*%s",name) ;
475 strcat(sval,temp) ;
479 else
480 { if (cst)
481 { if ((value_zero_p(val) && (*first)) || value_neg_p(val))
482 value_sprint(sval,VALUE_FMT,val) ;
483 if (value_pos_p(val))
484 { if (!(*first))
485 { value_sprint(sval,"+"VALUE_FMT,val) ; /* Block macro ! */
487 else
488 value_sprint(sval,VALUE_FMT,val) ;
492 free(temp) ;
493 free(body) ;
495 return(sval) ;
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 ;
519 CloogInfos * infos ;
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] ;
525 value_init_c(temp) ;
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)) ;
531 body[0] = '\0' ;
532 sline = (char *)malloc(MAX_STRING*sizeof(char)) ;
533 sline[0] = '\0' ;
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] ;
545 else
546 name = infos->names->iterators[i-infos->names->nb_scattering-1] ;
548 if (sign == -1)
549 value_oppose(temp,line[i]) ;
550 else
551 value_assign(temp,line[i]) ;
553 sval = pprint_val(temp,i,&first,0,name,infos) ;
554 strcat(body,sval) ;
555 free(sval) ;
556 nb_elts ++ ;
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] ;
564 if (sign == -1)
565 value_oppose(temp,line[i]) ;
566 else
567 value_assign(temp,line[i]) ;
569 sval=pprint_val(temp,-1,&first,0,name,infos) ;
570 strcat(body,sval) ;
571 free(sval) ;
572 nb_elts ++ ;
575 if (sign == -1)
576 { value_oppose(numerator,line[matrix->NbColumns - 1]) ;
577 value_assign(denominator,line[level]) ;
579 else
580 { value_assign(numerator,line[matrix->NbColumns - 1]) ;
581 value_oppose(denominator,line[level]) ;
584 /* Finally, the constant, and the final printing. */
585 if (!first)
586 { sval = pprint_val(numerator,-1,&first,1,"",infos) ;
587 strcat(body,sval) ;
588 if (strlen(sval)>0)
589 nb_elts ++ ;
590 free(sval) ;
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) ;
599 else
600 { sprintf(sline,"ceild(%s,",body) ;
601 value_sprint(stemp,VALUE_FMT")",denominator) ;
604 else
605 { if (infos->language == LANGUAGE_FORTRAN)
606 { sprintf(sline,"FLOOR(REAL(%s)/REAL(",body) ;
607 value_sprint(stemp,VALUE_FMT"))",denominator) ;
609 else
610 { sprintf(sline,"floord(%s,",body) ;
611 value_sprint(stemp,VALUE_FMT")",denominator) ;
615 else
616 { if (nb_elts > 1)
617 sprintf(sline,"(%s)/",body) ;
618 else
619 sprintf(sline,"%s/",body) ;
621 value_sprint(stemp,VALUE_FMT,denominator) ;
623 strcat(sline,stemp) ;
625 else
626 sprintf(sline,"%s",body) ;
628 else
629 { if (value_zero_p(numerator))
630 sprintf(sline,"0") ;
631 else
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) ;
639 else
640 { value_init_c(division) ;
641 value_division(division,numerator,denominator) ;
642 if (value_neg_p(numerator))
643 { if (value_pos_p(line[level]))
644 /* nb<0 need max */
645 { value_sprint(sline,VALUE_FMT,division) ; /* Block macro ! */
647 else
648 { /* nb<0 need min */
649 value_decrement(temp,division) ;
650 value_sprint(sline,VALUE_FMT,temp) ;
653 else
654 { if (value_pos_p(line[level]))
655 { /* nb>0 need max */
656 value_increment(temp,division) ;
657 value_sprint(sline,VALUE_FMT,temp) ;
659 else
660 /* nb>0 need min */
661 value_sprint(sline,VALUE_FMT,division) ;
663 value_clear_c(division) ;
666 else
667 { value_sprint(sline,VALUE_FMT"/",numerator) ;
668 value_sprint(stemp,VALUE_FMT,denominator) ;
669 strcat(sline,stemp) ;
672 else
673 value_sprint(sline,VALUE_FMT,numerator) ;
678 free(stemp) ;
679 free(body) ;
680 value_clear_c(temp) ;
681 value_clear_c(numerator) ;
682 value_clear_c(denominator) ;
684 return(sline) ;
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:
693 * -3*i +2*j -M >= 0
694 * 2*i +j >= 0
695 * -i -j +2*M >= 0
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 ;
713 CloogInfos * infos ;
714 { int i, first=1 ;
715 char * sline, * body, * sminmax ;
717 body = (char *)malloc(MAX_STRING*sizeof(char)) ;
718 body[0] = '\0' ;
719 sminmax = (char *)malloc(MAX_STRING*sizeof(char)) ;
720 sminmax[0] = '\0' ;
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) ;
729 free(sline) ;
730 break ;
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)
741 { if (first)
742 { if (max)
743 sprintf(body,"MAX(%s,%s",sminmax,sline) ;
744 else
745 sprintf(body,"MIN(%s,%s",sminmax,sline) ;
747 first = 0 ;
748 sprintf(sminmax,"%s",body) ;
750 else
751 { sprintf(body,",%s",sline) ;
752 strcat(sminmax,body) ;
755 else
756 { if (max)
757 sprintf(body,"max(%s,%s)",sminmax,sline) ;
758 else
759 sprintf(body,"min(%s,%s)",sminmax,sline) ;
761 sprintf(sminmax,"%s",body) ;
764 free(sline) ;
766 free(body) ;
768 if ((infos->language == LANGUAGE_FORTRAN) && (!first))
769 strcat(sminmax,")") ;
771 return(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
782 * iterator.
783 * For instance, considering these constraints and the element j:
784 * -3*i +2*j -M >= 0
785 * 2*i +M >= 0
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 ;
809 CloogInfos * infos ;
810 { int i, j, k, l, guarded, minmax=-1, nb_and = 0, nb_iter ;
811 char * name, * sline, * body, * temp, * sguard ;
812 CloogMatrix * copy ;
814 temp = (char *)malloc(MAX_STRING*sizeof(char)) ;
815 body = (char *)malloc(MAX_STRING*sizeof(char)) ;
816 sguard = (char *)malloc(MAX_STRING*sizeof(char)) ;
817 sguard[0] = '\0' ;
819 if (matrix != NULL)
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 ;
827 nb_and = 0 ;
828 body[0] = '\0' ;
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)))
834 { if (i <= nb_iter)
835 { if (i <= infos->names->nb_scattering)
836 name = infos->names->scattering[i-1] ;
837 else
838 name = infos->names->iterators[i-infos->names->nb_scattering-1] ;
840 else
841 name = infos->names->parameters[i-(nb_iter+1)] ;
843 if (nb_and)
844 { if (infos->language == LANGUAGE_FORTRAN)
845 strcat(body," .AND. ") ;
846 else
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) ;
854 else
855 { if (value_pos_p(copy->p[j][i]))
856 { sprintf(temp,"(%s >= ",name) ;
857 minmax = 1 ;
859 else
860 { sprintf(temp,"(%s <= ",name) ;
861 minmax = 0 ;
864 guarded = (nb_iter >= level) ? level : 0 ;
865 sline = pprint_minmax(copy,equal,i,minmax,guarded,infos) ;
868 strcat(body,temp) ;
869 strcat(body,sline) ;
870 strcat(body,")") ;
871 nb_and ++ ;
872 free(sline) ;
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) ;
881 if (minmax != -1)
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) ;
890 free(temp) ;
892 if (nb_and)
893 { for (k=0;k<(*indent);k++)
894 strcat(sguard," ") ;
896 if (infos->language == LANGUAGE_FORTRAN)
897 strcat(sguard,"IF ") ;
898 else
899 strcat(sguard,"if ") ;
901 if (nb_and > 1)
902 { strcat(sguard,"(") ;
903 strcat(sguard,body) ;
904 strcat(sguard,")") ;
906 else
907 strcat(sguard,body) ;
909 if (infos->language == LANGUAGE_FORTRAN)
910 strcat(sguard," THEN\n") ;
911 else
912 strcat(sguard," {\n") ;
913 *guard = 1 ;
914 *indent += INDENT_STEP ;
916 free(body) ;
918 return(sguard) ;
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 ;
952 CloogInfos * infos ;
953 { int i, sign, first=1, nb_elts=0, nb_iter=0, guarded=0, in_stride=0 ;
954 char * body, * seq, * sval, * sline, * name ;
955 Value * line, val ;
957 value_init_c(val) ;
959 body = (char *)malloc(MAX_STRING*sizeof(char)) ;
960 body[0] = '\0' ;
961 seq = (char *)malloc(MAX_STRING*sizeof(char)) ;
962 seq[0] = '\0' ;
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))
974 { if (sign == -1)
975 value_oppose(val,line[i]) ;
976 else
977 value_assign(val,line[i]) ;
979 if (i <= infos->names->nb_scattering)
980 name = infos->names->scattering[i-1] ;
981 else
982 name = infos->names->iterators[i-infos->names->nb_scattering-1] ;
984 sval = pprint_val(val,i,&first,0,name,infos) ;
985 strcat(body,sval) ;
986 free(sval) ;
987 nb_elts ++ ;
989 else
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]))
997 in_stride = 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))
1005 { if (sign == -1)
1006 value_oppose(val,line[i]) ;
1007 else
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) ;
1012 strcat(body,sval) ;
1013 free(sval) ;
1014 nb_elts ++ ;
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]))
1022 { if (sign == -1)
1023 value_oppose(val,line[matrix->NbColumns-1]) ;
1024 else
1025 value_assign(val,line[matrix->NbColumns-1]) ;
1027 sval = pprint_val(val,-1,&first,1,"",infos) ;
1028 strcat(body,sval) ;
1029 if (strlen(sval)>0)
1030 nb_elts ++ ;
1031 free(sval) ;
1033 for (i=0;i<(*indent);i++)
1034 strcat(seq," ") ;
1036 if (infos->language == LANGUAGE_FORTRAN)
1037 strcat(seq,"IF (") ;
1038 else
1039 strcat(seq,"if (") ;
1041 if ((-1 * sign) == -1)
1042 value_oppose(val,line[level]) ;
1043 else
1044 value_assign(val,line[level]) ;
1046 if (infos->language == LANGUAGE_FORTRAN)
1047 { strcat(seq,"MOD(") ;
1048 strcat(seq,body) ;
1049 value_sprint(body,","VALUE_FMT") == 0) THEN\n",val) ;
1051 else
1052 { if (nb_elts > 1)
1053 { strcat(seq,"(") ;
1054 strcat(seq,body) ;
1055 strcat(seq,")") ;
1057 else
1058 strcat(seq,body) ;
1060 strcat(seq,"\%") ;
1061 value_sprint(body,VALUE_FMT" == 0) {\n",val) ;
1064 strcat(seq,body) ;
1065 *modulo_guard = 1 ;
1066 *indent += INDENT_STEP ;
1067 guarded = 1 ;
1070 if (!pprint_equal_add(equal,matrix,level,num,infos))
1071 { /* Finally, the equality. */
1072 for (i=0;i<(*indent);i++)
1073 strcat(seq," ") ;
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]) ;
1086 else
1087 sprintf(body,"%s = ",
1088 infos->names->iterators[level-infos->names->nb_scattering-1]) ;
1090 strcat(seq,body) ;
1091 sline = pprint_line(matrix,equal,num,level,infos) ;
1092 if (infos->language == LANGUAGE_FORTRAN)
1093 sprintf(body,"%s\n",sline) ;
1094 else
1095 sprintf(body,"%s ;\n",sline) ;
1096 strcat(seq,body) ;
1097 free(sline) ;
1100 free(body) ;
1101 value_clear_c(val) ;
1103 return(seq) ;
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:
1114 * i + j -9*M >= 0
1115 * -j +5*M >= 0
1116 * j -4*M >= 0
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 ;
1136 { int i ;
1137 char * sfor, * sline1, *sline2, * temp, * iterator ;
1139 if (level <= infos->names->nb_scattering)
1140 iterator = infos->names->scattering[level-1] ;
1141 else
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)) ;
1146 sfor[0] = '\0' ;
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++)
1158 strcat(sfor," ") ;
1160 if (infos->language == LANGUAGE_FORTRAN)
1161 sprintf(temp,"DO ") ;
1162 else
1163 sprintf(temp,"for (") ;
1165 strcat(sfor,temp) ;
1166 if (strlen(sline1) != 0)
1167 { sprintf(temp,"%s=%s",iterator,sline1) ;
1168 strcat(sfor,temp) ;
1170 else
1171 if (infos->language == LANGUAGE_FORTRAN)
1172 { fprintf(stderr,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
1173 exit(1) ;
1176 if (infos->language == LANGUAGE_FORTRAN)
1177 sprintf(temp,", ") ;
1178 else
1179 sprintf(temp,";") ;
1181 strcat(sfor,temp) ;
1182 if (strlen(sline2) != 0)
1183 { if (infos->language == LANGUAGE_FORTRAN)
1184 sprintf(temp,"%s",sline2) ;
1185 else
1186 sprintf(temp,"%s<=%s",iterator,sline2) ;
1188 strcat(sfor,temp) ;
1190 else
1191 if (infos->language == LANGUAGE_FORTRAN)
1192 { fprintf(stderr,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
1193 exit(1) ;
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]) ;
1200 else
1201 sprintf(temp,"\n") ;
1203 else
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) ;
1209 else
1210 sprintf(temp,";%s++) {\n",iterator) ;
1213 *accol = 1 ;
1214 strcat(sfor,temp) ;
1216 else
1217 if (!pprint_equal_add(equal,matrix,level,ONE_TIME_LOOP,infos))
1218 { for (i=0;i<(*indent);i++)
1219 strcat(sfor," ") ;
1220 if (infos->language == LANGUAGE_FORTRAN)
1221 sprintf(temp,"%s = %s\n",iterator,sline1);
1222 else
1223 { /* If the option block is set, build the block. */
1224 if (infos->options->block)
1225 { strcat(sfor,"{ ") ;
1226 *accol = 1 ;
1228 sprintf(temp,"%s = %s ;\n",iterator,sline1);
1230 strcat(sfor,temp) ;
1233 free(temp) ;
1234 free(sline1) ;
1235 free(sline2) ;
1237 return(sfor) ;
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)
1258 CloogLoop * loop ;
1259 int level, * scalar, * scalbraces, * indent ;
1260 CloogInfos * infos ;
1261 { int i ;
1262 char * sscalar, * temp ;
1264 sscalar = (char *)malloc(MAX_STRING*sizeof(char)) ;
1265 sscalar[0] = '\0' ;
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,"{ ") ;
1281 (*scalbraces) ++ ;
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) ;
1288 (*scalar) ++ ;
1290 if (infos->options->block)
1291 *indent += INDENT_STEP ;
1293 free(temp) ;
1296 return(sscalar) ;
1301 * pprint_block function:
1302 * This function returns a string containing the printing of a statement block
1303 * structure.
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' ;
1327 if (block != NULL)
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) ;
1341 else
1342 sline = pprint_equal_cpp(equal,level,infos) ;
1344 sprintf(temp,"S%d%s",statement->number+1,sline) ;
1345 strcat(sstatement,temp) ;
1346 free(sline) ;
1348 if (infos->language != LANGUAGE_FORTRAN)
1349 strcat(sstatement," ;") ;
1350 strcat(sstatement,"\n") ;
1352 statement = statement->next ;
1354 free(temp) ;
1357 return(sstatement) ;
1362 * pprint function:
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
1376 * possible value.
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)
1400 FILE * foo ;
1401 CloogLoop * loop ;
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 ;
1407 char * sline ;
1408 CloogMatrix * matrix, * temp ;
1410 /* It can happen that loop be NULL when an input polyhedron is empty. */
1411 if (loop == NULL)
1412 return ;
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) ;
1426 free(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) ;
1432 free(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) ;
1446 equality = 1 ;
1447 break ;
1450 if (!equality)
1451 { stride = 0 ;
1452 sline = pprint_for(matrix,equal,level,&accol,&indent,infos);
1454 else
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")))
1459 equality = 0 ;
1461 fprintf(foo,"%s",sline) ;
1462 free(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) ;
1468 free(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. */
1478 if (accol)
1479 { for (i=0;i<indent;i++) fprintf(foo," ") ;
1481 if (infos->language == LANGUAGE_FORTRAN)
1482 fprintf(foo,"END DO\n") ;
1483 else
1484 fprintf(foo,"}\n") ;
1486 else
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. */
1495 if (modulo_guard)
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") ;
1501 else
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. */
1515 if (guard)
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") ;
1521 else
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) ;