Fix http://gcc.gnu.org/PR43012
[cloog-ppl.git] / source / pprint.c
blob66ad83e40278dc8772be017856e5cdcd3b9a2247
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 /**
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 static void pprint_term(FILE *dst, struct clast_term *t)
67 if (t->var) {
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);
72 else {
73 value_print(dst, VALUE_FMT, t->val);
74 fprintf(dst, "*%s", t->var);
76 } else
77 value_print(dst, VALUE_FMT, t->val);
80 static void pprint_sum(FILE *dst, struct clast_reduction *r)
82 int i;
83 struct clast_term *t;
85 assert(r->n >= 1);
86 assert(r->elts[0]->type == expr_term);
87 t = (struct clast_term *) r->elts[0];
88 pprint_term(dst, t);
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))
94 fprintf(dst, "+");
95 pprint_term(dst, t);
99 static void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e);
101 static 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) {
107 switch (b->type) {
108 case clast_bin_fdiv:
109 s1 = "FLOOR(REAL(", s2 = ")/REAL(", s3 = "))";
110 break;
111 case clast_bin_cdiv:
112 s1 = "CEILING(REAL(", s2 = ")/REAL(", s3 = "))";
113 break;
114 case clast_bin_div:
115 if (group)
116 s1 = "(", s2 = ")/", s3 = "";
117 else
118 s1 = "", s2 = "/", s3 = "";
119 break;
120 case clast_bin_mod:
121 s1 = "MOD(", s2 = ", ", s3 = ")";
122 break;
124 } else {
125 switch (b->type) {
126 case clast_bin_fdiv:
127 s1 = "floord(", s2 = ",", s3 = ")";
128 break;
129 case clast_bin_cdiv:
130 s1 = "ceild(", s2 = ",", s3 = ")";
131 break;
132 case clast_bin_div:
133 if (group)
134 s1 = "(", s2 = ")/", s3 = "";
135 else
136 s1 = "", s2 = "/", s3 = "";
137 break;
138 case clast_bin_mod:
139 if (group)
140 s1 = "(", s2 = ")%", s3 = "";
141 else
142 s1 = "", s2 = "%", s3 = "";
143 break;
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 static void pprint_minmax_f(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
155 int i;
156 if (r->n == 0)
157 return;
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) {
161 fprintf(dst, ",");
162 pprint_expr(info, dst, r->elts[i]);
164 fprintf(dst, ")");
167 static void pprint_minmax_c(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
169 int i;
170 for (i = 1; i < r->n; ++i)
171 fprintf(dst, r->type == clast_red_max ? "max(" : "min(");
172 if (r->n > 0)
173 pprint_expr(info, dst, r->elts[0]);
174 for (i = 1; i < r->n; ++i) {
175 fprintf(dst, ",");
176 pprint_expr(info, dst, r->elts[i]);
177 fprintf(dst, ")");
181 static void pprint_reduction(struct cloogoptions *i, FILE *dst, struct clast_reduction *r)
183 switch (r->type) {
184 case clast_red_sum:
185 pprint_sum(dst, r);
186 break;
187 case clast_red_min:
188 case clast_red_max:
189 if (r->n == 1) {
190 pprint_expr(i, dst, r->elts[0]);
191 break;
193 if (i->language == LANGUAGE_FORTRAN)
194 pprint_minmax_f(i, dst, r);
195 else
196 pprint_minmax_c(i, dst, r);
197 break;
198 default:
199 assert(0);
203 void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e)
205 if (!e)
206 return;
207 switch (e->type) {
208 case expr_term:
209 pprint_term(dst, (struct clast_term*) e);
210 break;
211 case expr_red:
212 pprint_reduction(i, dst, (struct clast_reduction*) e);
213 break;
214 case expr_bin:
215 pprint_binary(i, dst, (struct clast_binary*) e);
216 break;
217 default:
218 assert(0);
222 static void pprint_equation(struct cloogoptions *i, FILE *dst, struct clast_equation *eq)
224 pprint_expr(i, dst, eq->LHS);
225 if (eq->sign == 0)
226 fprintf(dst, " == ");
227 else if (eq->sign > 0)
228 fprintf(dst, " >= ");
229 else
230 fprintf(dst, " <= ");
231 pprint_expr(i, dst, eq->RHS);
234 static void pprint_assignment(struct cloogoptions *i, FILE *dst,
235 struct clast_assignment *a)
237 if (a->LHS)
238 fprintf(dst, "%s = ", a->LHS);
239 pprint_expr(i, dst, a->RHS);
242 static 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", cloog_statement_number (u->statement));
247 if (options->cpp || u->substitutions)
248 fprintf(dst, "(");
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);
252 if (t->next)
253 fprintf(dst, ",");
255 if (options->cpp || u->substitutions)
256 fprintf(dst, ")");
257 if (options->language != LANGUAGE_FORTRAN)
258 fprintf(dst, " ;");
259 fprintf(dst, "\n");
262 void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
263 struct clast_stmt *s);
265 static void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
266 struct clast_guard *g)
268 int k;
269 if (options->language == LANGUAGE_FORTRAN)
270 fprintf(dst,"IF ");
271 else
272 fprintf(dst,"if ");
273 if (g->n > 1)
274 fprintf(dst,"(");
275 for (k = 0; k < g->n; ++k) {
276 if (k > 0) {
277 if (options->language == LANGUAGE_FORTRAN)
278 fprintf(dst," .AND. ");
279 else
280 fprintf(dst," && ");
282 fprintf(dst,"(");
283 pprint_equation(options, dst, &g->eq[k]);
284 fprintf(dst,")");
286 if (g->n > 1)
287 fprintf(dst,")");
288 if (options->language == LANGUAGE_FORTRAN)
289 fprintf(dst," THEN\n");
290 else
291 fprintf(dst," {\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");
298 else
299 fprintf(dst,"}\n");
302 static void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
303 struct clast_for *f)
305 if (options->language == LANGUAGE_FORTRAN)
306 fprintf(dst, "DO ");
307 else
308 fprintf(dst, "for (");
310 if (f->LB) {
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");
315 exit(1);
318 if (options->language == LANGUAGE_FORTRAN)
319 fprintf(dst,", ");
320 else
321 fprintf(dst,";");
323 if (f->UB) {
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");
329 exit(1);
332 if (options->language == LANGUAGE_FORTRAN) {
333 if (value_gt_si(f->stride, 1))
334 value_print(dst, VALUE_FMT, f->stride);
335 fprintf(dst,"\n");
337 else {
338 if (value_gt_si(f->stride, 1)) {
339 fprintf(dst,";%s+=", f->iterator);
340 value_print(dst, VALUE_FMT") {\n", f->stride);
341 } else
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") ;
350 else
351 fprintf(dst,"}\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))
359 continue;
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)
364 fprintf(dst, " ;");
365 fprintf(dst, "\n");
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)) {
373 fprintf(dst, "{\n");
374 pprint_stmt_list(options, dst, indent + INDENT_STEP,
375 ((struct clast_block *)s)->body);
376 fprintf(dst, "%*s", indent, "");
377 fprintf(dst, "}\n");
378 } else {
379 assert(0);
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);