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.
50 # include "../include/cloog/cloog.h"
53 /******************************************************************************
55 ******************************************************************************/
60 * This function returns a string containing the printing of a value (possibly
61 * an iterator or a parameter with its coefficient or a constant).
62 * - val is the coefficient or constant value,
63 * - name is a string containing the name of the iterator or of the parameter,
65 void pprint_term(FILE *dst
, struct clast_term
*t
)
68 if (value_one_p(t
->val
))
69 fprintf(dst
, "%s", t
->var
);
70 else if (value_mone_p(t
->val
))
71 fprintf(dst
, "-%s", t
->var
);
73 value_print(dst
, VALUE_FMT
, t
->val
);
74 fprintf(dst
, "*%s", t
->var
);
77 value_print(dst
, VALUE_FMT
, t
->val
);
80 void pprint_sum(FILE *dst
, struct clast_reduction
*r
)
86 assert(r
->elts
[0]->type
== expr_term
);
87 t
= (struct clast_term
*) r
->elts
[0];
90 for (i
= 1; i
< r
->n
; ++i
) {
91 assert(r
->elts
[i
]->type
== expr_term
);
92 t
= (struct clast_term
*) r
->elts
[i
];
93 if (value_pos_p(t
->val
))
99 void pprint_expr(struct cloogoptions
*i
, FILE *dst
, struct clast_expr
*e
);
101 void pprint_binary(struct cloogoptions
*i
, FILE *dst
, struct clast_binary
*b
)
103 const char *s1
= NULL
, *s2
= NULL
, *s3
= NULL
;
104 int group
= b
->LHS
->type
== expr_red
&&
105 ((struct clast_reduction
*) b
->LHS
)->n
> 1;
106 if (i
->language
== LANGUAGE_FORTRAN
) {
109 s1
= "FLOOR(REAL(", s2
= ")/REAL(", s3
= "))";
112 s1
= "CEILING(REAL(", s2
= ")/REAL(", s3
= "))";
116 s1
= "(", s2
= ")/", s3
= "";
118 s1
= "", s2
= "/", s3
= "";
121 s1
= "MOD(", s2
= ", ", s3
= ")";
127 s1
= "floord(", s2
= ",", s3
= ")";
130 s1
= "ceild(", s2
= ",", s3
= ")";
134 s1
= "(", s2
= ")/", s3
= "";
136 s1
= "", s2
= "/", s3
= "";
140 s1
= "(", s2
= ")%", s3
= "";
142 s1
= "", s2
= "%", s3
= "";
146 fprintf(dst
, "%s", s1
);
147 pprint_expr(i
, dst
, b
->LHS
);
148 fprintf(dst
, "%s", s2
);
149 value_print(dst
, VALUE_FMT
, b
->RHS
);
150 fprintf(dst
, "%s", s3
);
153 void pprint_minmax_f(struct cloogoptions
*info
, FILE *dst
, struct clast_reduction
*r
)
158 fprintf(dst
, r
->type
== clast_red_max
? "MAX(" : "MIN(");
159 pprint_expr(info
, dst
, r
->elts
[0]);
160 for (i
= 1; i
< r
->n
; ++i
) {
162 pprint_expr(info
, dst
, r
->elts
[i
]);
167 void pprint_minmax_c(struct cloogoptions
*info
, FILE *dst
, struct clast_reduction
*r
)
170 for (i
= 1; i
< r
->n
; ++i
)
171 fprintf(dst
, r
->type
== clast_red_max
? "max(" : "min(");
173 pprint_expr(info
, dst
, r
->elts
[0]);
174 for (i
= 1; i
< r
->n
; ++i
) {
176 pprint_expr(info
, dst
, r
->elts
[i
]);
181 void pprint_reduction(struct cloogoptions
*i
, FILE *dst
, struct clast_reduction
*r
)
190 pprint_expr(i
, dst
, r
->elts
[0]);
193 if (i
->language
== LANGUAGE_FORTRAN
)
194 pprint_minmax_f(i
, dst
, r
);
196 pprint_minmax_c(i
, dst
, r
);
203 void pprint_expr(struct cloogoptions
*i
, FILE *dst
, struct clast_expr
*e
)
209 pprint_term(dst
, (struct clast_term
*) e
);
212 pprint_reduction(i
, dst
, (struct clast_reduction
*) e
);
215 pprint_binary(i
, dst
, (struct clast_binary
*) e
);
222 void pprint_equation(struct cloogoptions
*i
, FILE *dst
, struct clast_equation
*eq
)
224 pprint_expr(i
, dst
, eq
->LHS
);
226 fprintf(dst
, " == ");
227 else if (eq
->sign
> 0)
228 fprintf(dst
, " >= ");
230 fprintf(dst
, " <= ");
231 pprint_expr(i
, dst
, eq
->RHS
);
234 void pprint_assignment(struct cloogoptions
*i
, FILE *dst
,
235 struct clast_assignment
*a
)
238 fprintf(dst
, "%s = ", a
->LHS
);
239 pprint_expr(i
, dst
, a
->RHS
);
242 void pprint_user_stmt(struct cloogoptions
*options
, FILE *dst
,
243 struct clast_user_stmt
*u
)
245 struct clast_stmt
*t
;
246 fprintf(dst
, "S%d", u
->statement
->number
);
247 if (options
->cpp
|| u
->substitutions
)
249 for (t
= u
->substitutions
; t
; t
= t
->next
) {
250 assert(CLAST_STMT_IS_A(t
, stmt_ass
));
251 pprint_assignment(options
, dst
, (struct clast_assignment
*)t
);
255 if (options
->cpp
|| u
->substitutions
)
257 if (options
->language
!= LANGUAGE_FORTRAN
)
262 void pprint_stmt_list(struct cloogoptions
*options
, FILE *dst
, int indent
,
263 struct clast_stmt
*s
);
265 void pprint_guard(struct cloogoptions
*options
, FILE *dst
, int indent
,
266 struct clast_guard
*g
)
269 if (options
->language
== LANGUAGE_FORTRAN
)
275 for (k
= 0; k
< g
->n
; ++k
) {
277 if (options
->language
== LANGUAGE_FORTRAN
)
278 fprintf(dst
," .AND. ");
283 pprint_equation(options
, dst
, &g
->eq
[k
]);
288 if (options
->language
== LANGUAGE_FORTRAN
)
289 fprintf(dst
," THEN\n");
293 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
, g
->then
);
295 fprintf(dst
, "%*s", indent
, "");
296 if (options
->language
== LANGUAGE_FORTRAN
)
297 fprintf(dst
,"END IF\n");
302 void pprint_for(struct cloogoptions
*options
, FILE *dst
, int indent
,
305 if (options
->language
== LANGUAGE_FORTRAN
)
308 fprintf(dst
, "for (");
311 fprintf(dst
, "%s=", f
->iterator
);
312 pprint_expr(options
, dst
, f
->LB
);
313 } else if (options
->language
== LANGUAGE_FORTRAN
) {
314 fprintf(stderr
,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
318 if (options
->language
== LANGUAGE_FORTRAN
)
324 if (options
->language
!= LANGUAGE_FORTRAN
)
325 fprintf(dst
,"%s<=", f
->iterator
);
326 pprint_expr(options
, dst
, f
->UB
);
327 } else if (options
->language
== LANGUAGE_FORTRAN
) {
328 fprintf(stderr
,"[CLooG]ERROR: unbounded loops not allowed in FORTRAN.\n");
332 if (options
->language
== LANGUAGE_FORTRAN
) {
333 if (value_gt_si(f
->stride
, 1))
334 value_print(dst
, VALUE_FMT
, f
->stride
);
338 if (value_gt_si(f
->stride
, 1)) {
339 fprintf(dst
,";%s+=", f
->iterator
);
340 value_print(dst
, VALUE_FMT
") {\n", f
->stride
);
342 fprintf(dst
, ";%s++) {\n", f
->iterator
);
345 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
, f
->body
);
347 fprintf(dst
, "%*s", indent
, "");
348 if (options
->language
== LANGUAGE_FORTRAN
)
349 fprintf(dst
,"END DO\n") ;
354 void pprint_stmt_list(struct cloogoptions
*options
, FILE *dst
, int indent
,
355 struct clast_stmt
*s
)
357 for ( ; s
; s
= s
->next
) {
358 if (CLAST_STMT_IS_A(s
, stmt_root
))
360 fprintf(dst
, "%*s", indent
, "");
361 if (CLAST_STMT_IS_A(s
, stmt_ass
)) {
362 pprint_assignment(options
, dst
, (struct clast_assignment
*) s
);
363 if (options
->language
!= LANGUAGE_FORTRAN
)
366 } else if (CLAST_STMT_IS_A(s
, stmt_user
)) {
367 pprint_user_stmt(options
, dst
, (struct clast_user_stmt
*) s
);
368 } else if (CLAST_STMT_IS_A(s
, stmt_for
)) {
369 pprint_for(options
, dst
, indent
, (struct clast_for
*) s
);
370 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
371 pprint_guard(options
, dst
, indent
, (struct clast_guard
*) s
);
372 } else if (CLAST_STMT_IS_A(s
, stmt_block
)) {
374 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
,
375 ((struct clast_block
*)s
)->body
);
376 fprintf(dst
, "%*s", indent
, "");
384 /******************************************************************************
385 * Memory leaks hunting *
386 ******************************************************************************/
389 * These global variables are devoted to memory leaks hunting: we
390 * want to know at each moment how many Value variables have been allocated
391 * since in GMP mode they have to be freed (see domain.c for the declaration).
392 * - July 3rd->11th 2003: first version (memory leaks hunt and correction).
395 extern int cloog_value_allocated
;
396 extern int cloog_value_freed
;
397 extern int cloog_value_max
;
400 /******************************************************************************
401 * Pretty Printing (dirty) functions *
402 ******************************************************************************/
404 void pprint(FILE *foo
, struct clast_stmt
*root
, int indent
, CloogOptions
*options
)
406 pprint_stmt_list(options
, foo
, indent
, root
);