clast: allow clast_term to represent multiple of any clast_expr
[cloog.git] / source / pprint.c
blob075b20aef4e05af52c948a759ef7ec73736d5ae6
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 <assert.h>
50 # include "../include/cloog/cloog.h"
53 /******************************************************************************
54 * Types *
55 ******************************************************************************/
59 void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e);
61 void pprint_name(FILE *dst, struct clast_name *n)
63 fprintf(dst, "%s", n->name);
66 /**
67 * This function returns a string containing the printing of a value (possibly
68 * an iterator or a parameter with its coefficient or a constant).
69 * - val is the coefficient or constant value,
70 * - name is a string containing the name of the iterator or of the parameter,
72 void pprint_term(struct cloogoptions *i, FILE *dst, struct clast_term *t)
74 if (t->var) {
75 int group = t->var->type == expr_red &&
76 ((struct clast_reduction*) t->var)->n > 1;
77 if (cloog_int_is_one(t->val))
79 else if (cloog_int_is_neg_one(t->val))
80 fprintf(dst, "-");
81 else {
82 cloog_int_print(dst, t->val);
83 fprintf(dst, "*");
85 if (group)
86 fprintf(dst, "(");
87 pprint_expr(i, dst, t->var);
88 if (group)
89 fprintf(dst, ")");
90 } else
91 cloog_int_print(dst, t->val);
94 void pprint_sum(struct cloogoptions *opt, FILE *dst, struct clast_reduction *r)
96 int i;
97 struct clast_term *t;
99 assert(r->n >= 1);
100 assert(r->elts[0]->type == expr_term);
101 t = (struct clast_term *) r->elts[0];
102 pprint_term(opt, dst, t);
104 for (i = 1; i < r->n; ++i) {
105 assert(r->elts[i]->type == expr_term);
106 t = (struct clast_term *) r->elts[i];
107 if (cloog_int_is_pos(t->val))
108 fprintf(dst, "+");
109 pprint_term(opt, dst, t);
113 void pprint_binary(struct cloogoptions *i, FILE *dst, struct clast_binary *b)
115 const char *s1 = NULL, *s2 = NULL, *s3 = NULL;
116 int group = b->LHS->type == expr_red &&
117 ((struct clast_reduction*) b->LHS)->n > 1;
118 if (i->language == LANGUAGE_FORTRAN) {
119 switch (b->type) {
120 case clast_bin_fdiv:
121 s1 = "FLOOR(REAL(", s2 = ")/REAL(", s3 = "))";
122 break;
123 case clast_bin_cdiv:
124 s1 = "CEILING(REAL(", s2 = ")/REAL(", s3 = "))";
125 break;
126 case clast_bin_div:
127 if (group)
128 s1 = "(", s2 = ")/", s3 = "";
129 else
130 s1 = "", s2 = "/", s3 = "";
131 break;
132 case clast_bin_mod:
133 s1 = "MOD(", s2 = ", ", s3 = ")";
134 break;
136 } else {
137 switch (b->type) {
138 case clast_bin_fdiv:
139 s1 = "floord(", s2 = ",", s3 = ")";
140 break;
141 case clast_bin_cdiv:
142 s1 = "ceild(", s2 = ",", s3 = ")";
143 break;
144 case clast_bin_div:
145 if (group)
146 s1 = "(", s2 = ")/", s3 = "";
147 else
148 s1 = "", s2 = "/", s3 = "";
149 break;
150 case clast_bin_mod:
151 if (group)
152 s1 = "(", s2 = ")%", s3 = "";
153 else
154 s1 = "", s2 = "%", s3 = "";
155 break;
158 fprintf(dst, "%s", s1);
159 pprint_expr(i, dst, b->LHS);
160 fprintf(dst, "%s", s2);
161 cloog_int_print(dst, b->RHS);
162 fprintf(dst, "%s", s3);
165 void pprint_minmax_f(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
167 int i;
168 if (r->n == 0)
169 return;
170 fprintf(dst, r->type == clast_red_max ? "MAX(" : "MIN(");
171 pprint_expr(info, dst, r->elts[0]);
172 for (i = 1; i < r->n; ++i) {
173 fprintf(dst, ",");
174 pprint_expr(info, dst, r->elts[i]);
176 fprintf(dst, ")");
179 void pprint_minmax_c(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
181 int i;
182 for (i = 1; i < r->n; ++i)
183 fprintf(dst, r->type == clast_red_max ? "max(" : "min(");
184 if (r->n > 0)
185 pprint_expr(info, dst, r->elts[0]);
186 for (i = 1; i < r->n; ++i) {
187 fprintf(dst, ",");
188 pprint_expr(info, dst, r->elts[i]);
189 fprintf(dst, ")");
193 void pprint_reduction(struct cloogoptions *i, FILE *dst, struct clast_reduction *r)
195 switch (r->type) {
196 case clast_red_sum:
197 pprint_sum(i, dst, r);
198 break;
199 case clast_red_min:
200 case clast_red_max:
201 if (r->n == 1) {
202 pprint_expr(i, dst, r->elts[0]);
203 break;
205 if (i->language == LANGUAGE_FORTRAN)
206 pprint_minmax_f(i, dst, r);
207 else
208 pprint_minmax_c(i, dst, r);
209 break;
210 default:
211 assert(0);
215 void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e)
217 if (!e)
218 return;
219 switch (e->type) {
220 case expr_name:
221 pprint_name(dst, (struct clast_name*) e);
222 break;
223 case expr_term:
224 pprint_term(i, dst, (struct clast_term*) e);
225 break;
226 case expr_red:
227 pprint_reduction(i, dst, (struct clast_reduction*) e);
228 break;
229 case expr_bin:
230 pprint_binary(i, dst, (struct clast_binary*) e);
231 break;
232 default:
233 assert(0);
237 void pprint_equation(struct cloogoptions *i, FILE *dst, struct clast_equation *eq)
239 pprint_expr(i, dst, eq->LHS);
240 if (eq->sign == 0)
241 fprintf(dst, " == ");
242 else if (eq->sign > 0)
243 fprintf(dst, " >= ");
244 else
245 fprintf(dst, " <= ");
246 pprint_expr(i, dst, eq->RHS);
249 void pprint_assignment(struct cloogoptions *i, FILE *dst,
250 struct clast_assignment *a)
252 if (a->LHS)
253 fprintf(dst, "%s = ", a->LHS);
254 pprint_expr(i, dst, a->RHS);
257 void pprint_user_stmt(struct cloogoptions *options, FILE *dst,
258 struct clast_user_stmt *u)
260 struct clast_stmt *t;
261 fprintf(dst, "S%d", u->statement->number);
262 if (options->cpp || u->substitutions)
263 fprintf(dst, "(");
264 for (t = u->substitutions; t; t = t->next) {
265 assert(CLAST_STMT_IS_A(t, stmt_ass));
266 pprint_assignment(options, dst, (struct clast_assignment *)t);
267 if (t->next)
268 fprintf(dst, ",");
270 if (options->cpp || u->substitutions)
271 fprintf(dst, ")");
272 if (options->language != LANGUAGE_FORTRAN)
273 fprintf(dst, " ;");
274 fprintf(dst, "\n");
277 void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
278 struct clast_stmt *s);
280 void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
281 struct clast_guard *g)
283 int k;
284 if (options->language == LANGUAGE_FORTRAN)
285 fprintf(dst,"IF ");
286 else
287 fprintf(dst,"if ");
288 if (g->n > 1)
289 fprintf(dst,"(");
290 for (k = 0; k < g->n; ++k) {
291 if (k > 0) {
292 if (options->language == LANGUAGE_FORTRAN)
293 fprintf(dst," .AND. ");
294 else
295 fprintf(dst," && ");
297 fprintf(dst,"(");
298 pprint_equation(options, dst, &g->eq[k]);
299 fprintf(dst,")");
301 if (g->n > 1)
302 fprintf(dst,")");
303 if (options->language == LANGUAGE_FORTRAN)
304 fprintf(dst," THEN\n");
305 else
306 fprintf(dst," {\n");
308 pprint_stmt_list(options, dst, indent + INDENT_STEP, g->then);
310 fprintf(dst, "%*s", indent, "");
311 if (options->language == LANGUAGE_FORTRAN)
312 fprintf(dst,"END IF\n");
313 else
314 fprintf(dst,"}\n");
317 void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
318 struct clast_for *f)
320 if (options->language == LANGUAGE_FORTRAN)
321 fprintf(dst, "DO ");
322 else
323 fprintf(dst, "for (");
325 if (f->LB) {
326 fprintf(dst, "%s=", f->iterator);
327 pprint_expr(options, dst, f->LB);
328 } else if (options->language == LANGUAGE_FORTRAN)
329 cloog_die("unbounded loops not allowed in FORTRAN.\n");
331 if (options->language == LANGUAGE_FORTRAN)
332 fprintf(dst,", ");
333 else
334 fprintf(dst,";");
336 if (f->UB) {
337 if (options->language != LANGUAGE_FORTRAN)
338 fprintf(dst,"%s<=", f->iterator);
339 pprint_expr(options, dst, f->UB);
340 } else if (options->language == LANGUAGE_FORTRAN)
341 cloog_die("unbounded loops not allowed in FORTRAN.\n");
343 if (options->language == LANGUAGE_FORTRAN) {
344 if (cloog_int_gt_si(f->stride, 1))
345 cloog_int_print(dst, f->stride);
346 fprintf(dst,"\n");
348 else {
349 if (cloog_int_gt_si(f->stride, 1)) {
350 fprintf(dst,";%s+=", f->iterator);
351 cloog_int_print(dst, f->stride);
352 fprintf(dst, ") {\n");
353 } else
354 fprintf(dst, ";%s++) {\n", f->iterator);
357 pprint_stmt_list(options, dst, indent + INDENT_STEP, f->body);
359 fprintf(dst, "%*s", indent, "");
360 if (options->language == LANGUAGE_FORTRAN)
361 fprintf(dst,"END DO\n") ;
362 else
363 fprintf(dst,"}\n") ;
366 void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
367 struct clast_stmt *s)
369 for ( ; s; s = s->next) {
370 if (CLAST_STMT_IS_A(s, stmt_root))
371 continue;
372 fprintf(dst, "%*s", indent, "");
373 if (CLAST_STMT_IS_A(s, stmt_ass)) {
374 pprint_assignment(options, dst, (struct clast_assignment *) s);
375 if (options->language != LANGUAGE_FORTRAN)
376 fprintf(dst, " ;");
377 fprintf(dst, "\n");
378 } else if (CLAST_STMT_IS_A(s, stmt_user)) {
379 pprint_user_stmt(options, dst, (struct clast_user_stmt *) s);
380 } else if (CLAST_STMT_IS_A(s, stmt_for)) {
381 pprint_for(options, dst, indent, (struct clast_for *) s);
382 } else if (CLAST_STMT_IS_A(s, stmt_guard)) {
383 pprint_guard(options, dst, indent, (struct clast_guard *) s);
384 } else if (CLAST_STMT_IS_A(s, stmt_block)) {
385 fprintf(dst, "{\n");
386 pprint_stmt_list(options, dst, indent + INDENT_STEP,
387 ((struct clast_block *)s)->body);
388 fprintf(dst, "%*s", indent, "");
389 fprintf(dst, "}\n");
390 } else {
391 assert(0);
397 /******************************************************************************
398 * Pretty Printing (dirty) functions *
399 ******************************************************************************/
401 void pprint(FILE *foo, struct clast_stmt *root, int indent, CloogOptions *options)
403 pprint_stmt_list(options, foo, indent, root);