1 
2    /**-------------------------------------------------------------------**
3     **                              CLooG                                **
4     **-------------------------------------------------------------------**
5     **                             pprint.c                              **
6     **-------------------------------------------------------------------**
7     **                  First version: october 26th 2001                 **
8     **-------------------------------------------------------------------**/
9 
10 
11 /******************************************************************************
12  *               CLooG : the Chunky Loop Generator (experimental)             *
13  ******************************************************************************
14  *                                                                            *
15  * Copyright (C) 2001-2005 Cedric Bastoul                                     *
16  *                                                                            *
17  * This library is free software; you can redistribute it and/or              *
18  * modify it under the terms of the GNU Lesser General Public                 *
19  * License as published by the Free Software Foundation; either               *
20  * version 2.1 of the License, or (at your option) any later version.         *
21  *                                                                            *
22  * This library is distributed in the hope that it will be useful,            *
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU          *
25  * Lesser General Public License for more details.                            *
26  *                                                                            *
27  * You should have received a copy of the GNU Lesser General Public           *
28  * License along with this library; if not, write to the Free Software        *
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor,                         *
30  * Boston, MA  02110-1301  USA                                                *
31  *                                                                            *
32  * CLooG, the Chunky Loop Generator                                           *
33  * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr                         *
34  *                                                                            *
35  ******************************************************************************/
36 /* CAUTION: the english used for comments is probably the worst you ever read,
37  *          please feel free to correct and improve it !
38  */
39 
40 /* June    22nd 2005: General adaptation for GMP.
41  * October 26th 2005: General adaptation from CloogDomain to Matrix data
42  *                    structure for all constraint systems.
43  * October 27th 2005: General adaptation from CloogEqual to Matrix data
44  *                    structure for equality spreading.
45  */
46 
47 # include <stdlib.h>
48 # include <stdio.h>
49 # include <string.h>
50 #include <assert.h>
51 # include "../include/cloog/cloog.h"
52 
53 #ifdef OSL_SUPPORT
54 #include <osl/util.h>
55 #include <osl/body.h>
56 #include <osl/extensions/extbody.h>
57 #include <osl/statement.h>
58 #include <osl/scop.h>
59 #endif
60 
61 
62 static void pprint_name(FILE *dst, struct clast_name *n);
63 static void pprint_term(struct cloogoptions *i, FILE *dst, struct clast_term *t);
64 static void pprint_sum(struct cloogoptions *opt,
65 			FILE *dst, struct clast_reduction *r);
66 static void pprint_binary(struct cloogoptions *i,
67 			FILE *dst, struct clast_binary *b);
68 static void pprint_minmax_f(struct cloogoptions *info,
69 			FILE *dst, struct clast_reduction *r);
70 static void pprint_minmax_c(struct cloogoptions *info,
71 			FILE *dst, struct clast_reduction *r);
72 static void pprint_reduction(struct cloogoptions *i,
73 			FILE *dst, struct clast_reduction *r);
74 static void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e);
75 static void pprint_equation(struct cloogoptions *i,
76 			FILE *dst, struct clast_equation *eq);
77 static void pprint_assignment(struct cloogoptions *i, FILE *dst,
78 			struct clast_assignment *a);
79 static void pprint_user_stmt(struct cloogoptions *options, FILE *dst,
80 		       struct clast_user_stmt *u);
81 static void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
82 		   struct clast_guard *g);
83 static void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
84 		 struct clast_for *f);
85 static void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
86 		       struct clast_stmt *s);
87 
88 
pprint_name(FILE * dst,struct clast_name * n)89 void pprint_name(FILE *dst, struct clast_name *n)
90 {
91     fprintf(dst, "%s", n->name);
92 }
93 
94 /**
95  * This function returns a string containing the printing of a value (possibly
96  * an iterator or a parameter with its coefficient or a constant).
97  * - val is the coefficient or constant value,
98  * - name is a string containing the name of the iterator or of the parameter,
99  */
pprint_term(struct cloogoptions * i,FILE * dst,struct clast_term * t)100 void pprint_term(struct cloogoptions *i, FILE *dst, struct clast_term *t)
101 {
102     if (t->var) {
103 	int group = t->var->type == clast_expr_red &&
104 		    ((struct clast_reduction*) t->var)->n > 1;
105 	if (cloog_int_is_one(t->val))
106 	    ;
107 	else if (cloog_int_is_neg_one(t->val))
108 	    fprintf(dst, "-");
109         else {
110 	    cloog_int_print(dst, t->val);
111 	    fprintf(dst, "*");
112 	}
113 	if (group)
114 	    fprintf(dst, "(");
115 	pprint_expr(i, dst, t->var);
116 	if (group)
117 	    fprintf(dst, ")");
118     } else
119 	cloog_int_print(dst, t->val);
120 }
121 
pprint_sum(struct cloogoptions * opt,FILE * dst,struct clast_reduction * r)122 void pprint_sum(struct cloogoptions *opt, FILE *dst, struct clast_reduction *r)
123 {
124     int i;
125     struct clast_term *t;
126 
127     assert(r->n >= 1);
128     assert(r->elts[0]->type == clast_expr_term);
129     t = (struct clast_term *) r->elts[0];
130     pprint_term(opt, dst, t);
131 
132     for (i = 1; i < r->n; ++i) {
133 	assert(r->elts[i]->type == clast_expr_term);
134 	t = (struct clast_term *) r->elts[i];
135 	if (cloog_int_is_pos(t->val))
136 	    fprintf(dst, "+");
137 	pprint_term(opt, dst, t);
138     }
139 }
140 
pprint_binary(struct cloogoptions * i,FILE * dst,struct clast_binary * b)141 void pprint_binary(struct cloogoptions *i, FILE *dst, struct clast_binary *b)
142 {
143     const char *s1 = NULL, *s2 = NULL, *s3 = NULL;
144     int group = b->LHS->type == clast_expr_red &&
145 		((struct clast_reduction*) b->LHS)->n > 1;
146     if (i->language == CLOOG_LANGUAGE_FORTRAN) {
147 	switch (b->type) {
148 	case clast_bin_fdiv:
149 	    s1 = "FLOOR(REAL(", s2 = ")/REAL(", s3 = "))";
150 	    break;
151 	case clast_bin_cdiv:
152 	    s1 = "CEILING(REAL(", s2 = ")/REAL(", s3 = "))";
153 	    break;
154 	case clast_bin_div:
155 	    if (group)
156 		s1 = "(", s2 = ")/", s3 = "";
157 	    else
158 		s1 = "", s2 = "/", s3 = "";
159 	    break;
160 	case clast_bin_mod:
161 	    s1 = "MOD(", s2 = ", ", s3 = ")";
162 	    break;
163 	}
164     } else {
165 	switch (b->type) {
166 	case clast_bin_fdiv:
167 	    s1 = "floord(", s2 = ",", s3 = ")";
168 	    break;
169 	case clast_bin_cdiv:
170 	    s1 = "ceild(", s2 = ",", s3 = ")";
171 	    break;
172 	case clast_bin_div:
173 	    if (group)
174 		s1 = "(", s2 = ")/", s3 = "";
175 	    else
176 		s1 = "", s2 = "/", s3 = "";
177 	    break;
178 	case clast_bin_mod:
179 	    if (group)
180 		s1 = "(", s2 = ")%", s3 = "";
181 	    else
182 		s1 = "", s2 = "%", s3 = "";
183 	    break;
184 	}
185     }
186     fprintf(dst, "%s", s1);
187     pprint_expr(i, dst, b->LHS);
188     fprintf(dst, "%s", s2);
189     cloog_int_print(dst, b->RHS);
190     fprintf(dst, "%s", s3);
191 }
192 
pprint_minmax_f(struct cloogoptions * info,FILE * dst,struct clast_reduction * r)193 void pprint_minmax_f(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
194 {
195     int i;
196     if (r->n == 0)
197 	return;
198     fprintf(dst, r->type == clast_red_max ? "MAX(" : "MIN(");
199     pprint_expr(info, dst, r->elts[0]);
200     for (i = 1; i < r->n; ++i) {
201 	fprintf(dst, ",");
202 	pprint_expr(info, dst, r->elts[i]);
203     }
204     fprintf(dst, ")");
205 }
206 
pprint_minmax_c(struct cloogoptions * info,FILE * dst,struct clast_reduction * r)207 void pprint_minmax_c(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
208 {
209     int i;
210     for (i = 1; i < r->n; ++i)
211 	fprintf(dst, r->type == clast_red_max ? "max(" : "min(");
212     if (r->n > 0)
213 	pprint_expr(info, dst, r->elts[0]);
214     for (i = 1; i < r->n; ++i) {
215 	fprintf(dst, ",");
216 	pprint_expr(info, dst, r->elts[i]);
217 	fprintf(dst, ")");
218     }
219 }
220 
pprint_reduction(struct cloogoptions * i,FILE * dst,struct clast_reduction * r)221 void pprint_reduction(struct cloogoptions *i, FILE *dst, struct clast_reduction *r)
222 {
223     switch (r->type) {
224     case clast_red_sum:
225 	pprint_sum(i, dst, r);
226 	break;
227     case clast_red_min:
228     case clast_red_max:
229 	if (r->n == 1) {
230 	    pprint_expr(i, dst, r->elts[0]);
231 	    break;
232 	}
233 	if (i->language == CLOOG_LANGUAGE_FORTRAN)
234 	    pprint_minmax_f(i, dst, r);
235 	else
236 	    pprint_minmax_c(i, dst, r);
237 	break;
238     default:
239 	assert(0);
240     }
241 }
242 
pprint_expr(struct cloogoptions * i,FILE * dst,struct clast_expr * e)243 void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e)
244 {
245     if (!e)
246 	return;
247     switch (e->type) {
248     case clast_expr_name:
249 	pprint_name(dst, (struct clast_name*) e);
250 	break;
251     case clast_expr_term:
252 	pprint_term(i, dst, (struct clast_term*) e);
253 	break;
254     case clast_expr_red:
255 	pprint_reduction(i, dst, (struct clast_reduction*) e);
256 	break;
257     case clast_expr_bin:
258 	pprint_binary(i, dst, (struct clast_binary*) e);
259 	break;
260     default:
261 	assert(0);
262     }
263 }
264 
pprint_equation(struct cloogoptions * i,FILE * dst,struct clast_equation * eq)265 void pprint_equation(struct cloogoptions *i, FILE *dst, struct clast_equation *eq)
266 {
267     pprint_expr(i, dst, eq->LHS);
268     if (eq->sign == 0)
269 	fprintf(dst, " == ");
270     else if (eq->sign > 0)
271 	fprintf(dst, " >= ");
272     else
273 	fprintf(dst, " <= ");
274     pprint_expr(i, dst, eq->RHS);
275 }
276 
pprint_assignment(struct cloogoptions * i,FILE * dst,struct clast_assignment * a)277 void pprint_assignment(struct cloogoptions *i, FILE *dst,
278 			struct clast_assignment *a)
279 {
280     if (a->LHS)
281 	fprintf(dst, "%s = ", a->LHS);
282     pprint_expr(i, dst, a->RHS);
283 }
284 
285 
286 /**
287  * pprint_osl_body function:
288  * this function pretty-prints the OpenScop body of a given statement.
289  * It returns 1 if it succeeds to find an OpenScop body to print for
290  * that statement, 0 otherwise.
291  * \param[in] options CLooG Options.
292  * \param[in] dst     Output stream.
293  * \param[in] u       Statement to print the OpenScop body.
294  * \return 1 on success to pretty-print an OpenScop body for u, 0 otherwise.
295  */
pprint_osl_body(struct cloogoptions * options,FILE * dst,struct clast_user_stmt * u)296 int pprint_osl_body(struct cloogoptions *options, FILE *dst,
297                     struct clast_user_stmt *u) {
298 #ifdef OSL_SUPPORT
299   int i;
300   char *expr, *tmp;
301   struct clast_stmt *t;
302   osl_scop_p scop = options->scop;
303   osl_statement_p stmt;
304   osl_body_p body;
305 
306   if ((scop != NULL) &&
307       (osl_statement_number(scop->statement) >= u->statement->number)) {
308     stmt = scop->statement;
309 
310     /* Go to the convenient statement in the SCoP. */
311     for (i = 1; i < u->statement->number; i++)
312       stmt = stmt->next;
313 
314     /* Ensure it has a printable body. */
315     body = osl_statement_get_body(stmt);
316     if ((body != NULL) &&
317         (body->expression != NULL) &&
318         (body->iterators != NULL)) {
319       expr = osl_util_identifier_substitution(body->expression->string[0],
320                                               body->iterators->string);
321       tmp = expr;
322       /* Print the body expression, substituting the @...@ markers. */
323       while (*expr) {
324         if (*expr == '@') {
325           int iterator;
326           expr += sscanf(expr, "@%d", &iterator) + 2; /* 2 for the @s */
327           t = u->substitutions;
328           for (i = 0; i < iterator; i++)
329             t = t->next;
330           pprint_assignment(options, dst, (struct clast_assignment *)t);
331         } else {
332           fprintf(dst, "%c", *expr++);
333         }
334       }
335       fprintf(dst, "\n");
336       free(tmp);
337       return 1;
338     }
339   }
340 #endif
341   return 0;
342 }
343 
344 /* pprint_parentheses_are_safer function:
345  * this function returns 1 if it decides that it would be safer to put
346  * parentheses around the clast_assignment when it is used as a macro
347  * parameter, 0 otherwise.
348  * \param[in] s Pointer to the clast_assignment to check.
349  * \return 1 if we should print parentheses around s, 0 otherwise.
350  */
pprint_parentheses_are_safer(struct clast_assignment * s)351 static int pprint_parentheses_are_safer(struct clast_assignment * s) {
352   /* Expressions of the form X = Y should not be used in macros, so we
353    * consider readability first for them and avoid parentheses.
354    * Also, expressions having only one term can live without parentheses.
355    */
356   if ((s->LHS) ||
357       (s->RHS->type == clast_expr_term) ||
358       ((s->RHS->type == clast_expr_red) &&
359        (((struct clast_reduction *)(s->RHS))->n == 1) &&
360        (((struct clast_reduction *)(s->RHS))->elts[0]->type ==
361         clast_expr_term)))
362     return 0;
363 
364   return 1;
365 }
366 
pprint_user_stmt(struct cloogoptions * options,FILE * dst,struct clast_user_stmt * u)367 void pprint_user_stmt(struct cloogoptions *options, FILE *dst,
368 		       struct clast_user_stmt *u)
369 {
370     int parenthesis_to_close = 0;
371     struct clast_stmt *t;
372 
373     if (pprint_osl_body(options, dst, u))
374       return;
375 
376     if (u->statement->name)
377 	fprintf(dst, "%s", u->statement->name);
378     else
379 	fprintf(dst, "S%d", u->statement->number);
380     fprintf(dst, "(");
381     for (t = u->substitutions; t; t = t->next) {
382 	assert(CLAST_STMT_IS_A(t, stmt_ass));
383         if (pprint_parentheses_are_safer((struct clast_assignment *)t)) {
384 	  fprintf(dst, "(");
385           parenthesis_to_close = 1;
386         }
387 	pprint_assignment(options, dst, (struct clast_assignment *)t);
388 	if (t->next) {
389             if (parenthesis_to_close) {
390 	      fprintf(dst, ")");
391               parenthesis_to_close = 0;
392             }
393 	    fprintf(dst, ",");
394         }
395     }
396     if (parenthesis_to_close)
397       fprintf(dst, ")");
398     fprintf(dst, ")");
399     if (options->language != CLOOG_LANGUAGE_FORTRAN)
400 	fprintf(dst, ";");
401     fprintf(dst, "\n");
402 }
403 
pprint_guard(struct cloogoptions * options,FILE * dst,int indent,struct clast_guard * g)404 void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
405 		   struct clast_guard *g)
406 {
407     int k;
408     if (options->language == CLOOG_LANGUAGE_FORTRAN)
409 	fprintf(dst,"IF ");
410     else
411 	fprintf(dst,"if ");
412     if (g->n > 1)
413 	fprintf(dst,"(");
414     for (k = 0; k < g->n; ++k) {
415 	if (k > 0) {
416 	    if (options->language == CLOOG_LANGUAGE_FORTRAN)
417 		fprintf(dst," .AND. ");
418 	    else
419 		fprintf(dst," && ");
420 	}
421 	fprintf(dst,"(");
422         pprint_equation(options, dst, &g->eq[k]);
423 	fprintf(dst,")");
424     }
425     if (g->n > 1)
426 	fprintf(dst,")");
427     if (options->language == CLOOG_LANGUAGE_FORTRAN)
428 	fprintf(dst," THEN\n");
429     else
430 	fprintf(dst," {\n");
431 
432     pprint_stmt_list(options, dst, indent + INDENT_STEP, g->then);
433 
434     fprintf(dst, "%*s", indent, "");
435     if (options->language == CLOOG_LANGUAGE_FORTRAN)
436 	fprintf(dst,"END IF\n");
437     else
438 	fprintf(dst,"}\n");
439 }
440 
pprint_for(struct cloogoptions * options,FILE * dst,int indent,struct clast_for * f)441 void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
442 		 struct clast_for *f)
443 {
444     if (options->language == CLOOG_LANGUAGE_C) {
445         if (f->time_var_name) {
446             fprintf(dst, "IF_TIME(%s_start = cloog_util_rtclock());\n",
447                     (f->time_var_name) ? f->time_var_name : "");
448         }
449         if ((f->parallel & CLAST_PARALLEL_OMP) && (f->parallel & CLAST_PARALLEL_USER)
450                && !(f->parallel & CLAST_PARALLEL_MPI)) {
451             if (f->LB) {
452                 fprintf(dst, "lbp=");
453                 pprint_expr(options, dst, f->LB);
454                 fprintf(dst, ";\n");
455             }
456             if (f->UB) {
457                 fprintf(dst, "%*s", indent, "");
458                 fprintf(dst, "ubp=");
459                 pprint_expr(options, dst, f->UB);
460                 fprintf(dst, ";\n");
461             }
462             fprintf(dst, "#pragma %s%s%s%s%s%s%s\n",
463                     (f->user_directive)? f->user_directive : "omp parallel for",
464                     (f->private_vars)? " private(":"",
465                     (f->private_vars)? f->private_vars: "",
466                     (f->private_vars)? ")":"",
467                     (f->reduction_vars)? " reduction(": "",
468                     (f->reduction_vars)? f->reduction_vars: "",
469                     (f->reduction_vars)? ")": "");
470 
471             fprintf(dst, "%*s", indent, "");
472         }
473         if ((f->parallel & CLAST_PARALLEL_OMP) && !(f->parallel & CLAST_PARALLEL_MPI)
474                && !(f->parallel & CLAST_PARALLEL_USER)) {
475             if (f->LB) {
476                 fprintf(dst, "lbp=");
477                 pprint_expr(options, dst, f->LB);
478                 fprintf(dst, ";\n");
479             }
480             if (f->UB) {
481                 fprintf(dst, "%*s", indent, "");
482                 fprintf(dst, "ubp=");
483                 pprint_expr(options, dst, f->UB);
484                 fprintf(dst, ";\n");
485             }
486             fprintf(dst, "#pragma omp parallel for%s%s%s%s%s%s\n",
487                     (f->private_vars)? " private(":"",
488                     (f->private_vars)? f->private_vars: "",
489                     (f->private_vars)? ")":"",
490                     (f->reduction_vars)? " reduction(": "",
491                     (f->reduction_vars)? f->reduction_vars: "",
492                     (f->reduction_vars)? ")": "");
493             fprintf(dst, "%*s", indent, "");
494         }
495         if ((f->parallel & CLAST_PARALLEL_VEC) && !(f->parallel & CLAST_PARALLEL_OMP)
496                && !(f->parallel & CLAST_PARALLEL_MPI)) {
497             if (f->LB) {
498                 fprintf(dst, "lbv=");
499                 pprint_expr(options, dst, f->LB);
500                 fprintf(dst, ";\n");
501             }
502             if (f->UB) {
503                 fprintf(dst, "%*s", indent, "");
504                 fprintf(dst, "ubv=");
505                 pprint_expr(options, dst, f->UB);
506                 fprintf(dst, ";\n");
507             }
508             fprintf(dst, "%*s#pragma ivdep\n", indent, "");
509             fprintf(dst, "%*s#pragma vector always\n", indent, "");
510             fprintf(dst, "%*s", indent, "");
511         }
512         if (f->parallel & CLAST_PARALLEL_MPI) {
513             if (f->LB) {
514                 fprintf(dst, "_lb_dist=");
515                 pprint_expr(options, dst, f->LB);
516                 fprintf(dst, ";\n");
517             }
518             if (f->UB) {
519                 fprintf(dst, "%*s", indent, "");
520                 fprintf(dst, "_ub_dist=");
521                 pprint_expr(options, dst, f->UB);
522                 fprintf(dst, ";\n");
523             }
524             fprintf(dst, "%*s", indent, "");
525             fprintf(dst, "polyrt_loop_dist(_lb_dist, _ub_dist, nprocs, my_rank, &lbp, &ubp);\n");
526             if (f->parallel & CLAST_PARALLEL_OMP) {
527                 fprintf(dst, "#pragma omp parallel for%s%s%s%s%s%s\n",
528                         (f->private_vars)? " private(":"",
529                         (f->private_vars)? f->private_vars: "",
530                         (f->private_vars)? ")":"",
531                         (f->reduction_vars)? " reduction(": "",
532                         (f->reduction_vars)? f->reduction_vars: "",
533                         (f->reduction_vars)? ")": "");
534             }
535             fprintf(dst, "%*s", indent, "");
536         }
537 
538     }
539 
540     if (options->language == CLOOG_LANGUAGE_FORTRAN)
541 	fprintf(dst, "DO ");
542     else
543 	fprintf(dst, "for (");
544 
545     if (f->LB) {
546 	fprintf(dst, "%s=", f->iterator);
547         if (f->parallel & (CLAST_PARALLEL_OMP | CLAST_PARALLEL_MPI)) {
548             fprintf(dst, "lbp");
549         }else if (f->parallel & CLAST_PARALLEL_VEC){
550             fprintf(dst, "lbv");
551         }else{
552 	pprint_expr(options, dst, f->LB);
553         }
554     } else if (options->language == CLOOG_LANGUAGE_FORTRAN)
555 	cloog_die("unbounded loops not allowed in FORTRAN.\n");
556 
557     if (options->language == CLOOG_LANGUAGE_FORTRAN)
558 	fprintf(dst,", ");
559     else
560 	fprintf(dst,";");
561 
562     if (f->UB) {
563 	if (options->language != CLOOG_LANGUAGE_FORTRAN)
564 	    fprintf(dst,"%s<=", f->iterator);
565 
566         if (f->parallel & (CLAST_PARALLEL_OMP | CLAST_PARALLEL_MPI)) {
567             fprintf(dst, "ubp");
568         }else if (f->parallel & CLAST_PARALLEL_VEC){
569             fprintf(dst, "ubv");
570         }else{
571             pprint_expr(options, dst, f->UB);
572         }
573     }else if (options->language == CLOOG_LANGUAGE_FORTRAN)
574 	cloog_die("unbounded loops not allowed in FORTRAN.\n");
575 
576     if (options->language == CLOOG_LANGUAGE_FORTRAN) {
577 	if (cloog_int_gt_si(f->stride, 1))
578 	    cloog_int_print(dst, f->stride);
579 	fprintf(dst,"\n");
580     }
581     else {
582 	if (cloog_int_gt_si(f->stride, 1)) {
583 	    fprintf(dst,";%s+=", f->iterator);
584 	    cloog_int_print(dst, f->stride);
585 	    fprintf(dst, ") {\n");
586       } else
587 	fprintf(dst, ";%s++) {\n", f->iterator);
588     }
589 
590     pprint_stmt_list(options, dst, indent + INDENT_STEP, f->body);
591 
592     fprintf(dst, "%*s", indent, "");
593     if (options->language == CLOOG_LANGUAGE_FORTRAN)
594 	fprintf(dst,"END DO\n") ;
595     else
596 	fprintf(dst,"}\n") ;
597 
598     if (options->language == CLOOG_LANGUAGE_C) {
599         if (f->time_var_name) {
600             fprintf(dst, "IF_TIME(%s += cloog_util_rtclock() - %s_start);\n",
601                     (f->time_var_name) ? f->time_var_name : "",
602                     (f->time_var_name) ? f->time_var_name : "");
603         }
604     }
605 }
606 
pprint_stmt_list(struct cloogoptions * options,FILE * dst,int indent,struct clast_stmt * s)607 void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
608 		       struct clast_stmt *s)
609 {
610     for ( ; s; s = s->next) {
611 	if (CLAST_STMT_IS_A(s, stmt_root))
612 	    continue;
613 	fprintf(dst, "%*s", indent, "");
614 	if (CLAST_STMT_IS_A(s, stmt_ass)) {
615 	    pprint_assignment(options, dst, (struct clast_assignment *) s);
616 	    if (options->language != CLOOG_LANGUAGE_FORTRAN)
617 		fprintf(dst, ";");
618 	    fprintf(dst, "\n");
619 	} else if (CLAST_STMT_IS_A(s, stmt_user)) {
620 	    pprint_user_stmt(options, dst, (struct clast_user_stmt *) s);
621 	} else if (CLAST_STMT_IS_A(s, stmt_for)) {
622 	    pprint_for(options, dst, indent, (struct clast_for *) s);
623 	} else if (CLAST_STMT_IS_A(s, stmt_guard)) {
624 	    pprint_guard(options, dst, indent, (struct clast_guard *) s);
625 	} else if (CLAST_STMT_IS_A(s, stmt_block)) {
626 	    fprintf(dst, "{\n");
627 	    pprint_stmt_list(options, dst, indent + INDENT_STEP,
628 				((struct clast_block *)s)->body);
629 	    fprintf(dst, "%*s", indent, "");
630 	    fprintf(dst, "}\n");
631 	} else {
632 	    assert(0);
633 	}
634     }
635 }
636 
637 
638 /******************************************************************************
639  *                       Pretty Printing (dirty) functions                    *
640  ******************************************************************************/
641 
clast_pprint(FILE * foo,struct clast_stmt * root,int indent,CloogOptions * options)642 void clast_pprint(FILE *foo, struct clast_stmt *root,
643 		  int indent, CloogOptions *options)
644 {
645     pprint_stmt_list(options, foo, indent, root);
646 }
647 
648 
clast_pprint_expr(struct cloogoptions * i,FILE * dst,struct clast_expr * e)649 void clast_pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e)
650 {
651     pprint_expr(i, dst, e);
652 }
653