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 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. *
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. *
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 *
32 * CLooG, the Chunky Loop Generator *
33 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
35 ******************************************************************************/
36 /* CAUTION: the english used for comments is probably the worst you ever read,
37 * please feel free to correct and improve it !
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.
51 # include "../include/cloog/cloog.h"
56 #include <osl/statement.h>
61 static void pprint_name(FILE *dst
, struct clast_name
*n
);
62 static void pprint_term(struct cloogoptions
*i
, FILE *dst
, struct clast_term
*t
);
63 static void pprint_sum(struct cloogoptions
*opt
,
64 FILE *dst
, struct clast_reduction
*r
);
65 static void pprint_binary(struct cloogoptions
*i
,
66 FILE *dst
, struct clast_binary
*b
);
67 static void pprint_minmax_f(struct cloogoptions
*info
,
68 FILE *dst
, struct clast_reduction
*r
);
69 static void pprint_minmax_c(struct cloogoptions
*info
,
70 FILE *dst
, struct clast_reduction
*r
);
71 static void pprint_reduction(struct cloogoptions
*i
,
72 FILE *dst
, struct clast_reduction
*r
);
73 static void pprint_expr(struct cloogoptions
*i
, FILE *dst
, struct clast_expr
*e
);
74 static void pprint_equation(struct cloogoptions
*i
,
75 FILE *dst
, struct clast_equation
*eq
);
76 static void pprint_assignment(struct cloogoptions
*i
, FILE *dst
,
77 struct clast_assignment
*a
);
78 static void pprint_user_stmt(struct cloogoptions
*options
, FILE *dst
,
79 struct clast_user_stmt
*u
);
80 static void pprint_guard(struct cloogoptions
*options
, FILE *dst
, int indent
,
81 struct clast_guard
*g
);
82 static void pprint_for(struct cloogoptions
*options
, FILE *dst
, int indent
,
84 static void pprint_stmt_list(struct cloogoptions
*options
, FILE *dst
, int indent
,
85 struct clast_stmt
*s
);
88 void pprint_name(FILE *dst
, struct clast_name
*n
)
90 fprintf(dst
, "%s", n
->name
);
94 * This function returns a string containing the printing of a value (possibly
95 * an iterator or a parameter with its coefficient or a constant).
96 * - val is the coefficient or constant value,
97 * - name is a string containing the name of the iterator or of the parameter,
99 void pprint_term(struct cloogoptions
*i
, FILE *dst
, struct clast_term
*t
)
102 int group
= t
->var
->type
== clast_expr_red
&&
103 ((struct clast_reduction
*) t
->var
)->n
> 1;
104 if (cloog_int_is_one(t
->val
))
106 else if (cloog_int_is_neg_one(t
->val
))
109 cloog_int_print(dst
, t
->val
);
114 pprint_expr(i
, dst
, t
->var
);
118 cloog_int_print(dst
, t
->val
);
121 void pprint_sum(struct cloogoptions
*opt
, FILE *dst
, struct clast_reduction
*r
)
124 struct clast_term
*t
;
127 assert(r
->elts
[0]->type
== clast_expr_term
);
128 t
= (struct clast_term
*) r
->elts
[0];
129 pprint_term(opt
, dst
, t
);
131 for (i
= 1; i
< r
->n
; ++i
) {
132 assert(r
->elts
[i
]->type
== clast_expr_term
);
133 t
= (struct clast_term
*) r
->elts
[i
];
134 if (cloog_int_is_pos(t
->val
))
136 pprint_term(opt
, dst
, t
);
140 void pprint_binary(struct cloogoptions
*i
, FILE *dst
, struct clast_binary
*b
)
142 const char *s1
= NULL
, *s2
= NULL
, *s3
= NULL
;
143 int group
= b
->LHS
->type
== clast_expr_red
&&
144 ((struct clast_reduction
*) b
->LHS
)->n
> 1;
145 if (i
->language
== CLOOG_LANGUAGE_FORTRAN
) {
148 s1
= "FLOOR(REAL(", s2
= ")/REAL(", s3
= "))";
151 s1
= "CEILING(REAL(", s2
= ")/REAL(", s3
= "))";
155 s1
= "(", s2
= ")/", s3
= "";
157 s1
= "", s2
= "/", s3
= "";
160 s1
= "MOD(", s2
= ", ", s3
= ")";
166 s1
= "floord(", s2
= ",", s3
= ")";
169 s1
= "ceild(", s2
= ",", s3
= ")";
173 s1
= "(", s2
= ")/", s3
= "";
175 s1
= "", s2
= "/", s3
= "";
179 s1
= "(", s2
= ")%", s3
= "";
181 s1
= "", s2
= "%", s3
= "";
185 fprintf(dst
, "%s", s1
);
186 pprint_expr(i
, dst
, b
->LHS
);
187 fprintf(dst
, "%s", s2
);
188 cloog_int_print(dst
, b
->RHS
);
189 fprintf(dst
, "%s", s3
);
192 void pprint_minmax_f(struct cloogoptions
*info
, FILE *dst
, struct clast_reduction
*r
)
197 fprintf(dst
, r
->type
== clast_red_max
? "MAX(" : "MIN(");
198 pprint_expr(info
, dst
, r
->elts
[0]);
199 for (i
= 1; i
< r
->n
; ++i
) {
201 pprint_expr(info
, dst
, r
->elts
[i
]);
206 void pprint_minmax_c(struct cloogoptions
*info
, FILE *dst
, struct clast_reduction
*r
)
209 for (i
= 1; i
< r
->n
; ++i
)
210 fprintf(dst
, r
->type
== clast_red_max
? "max(" : "min(");
212 pprint_expr(info
, dst
, r
->elts
[0]);
213 for (i
= 1; i
< r
->n
; ++i
) {
215 pprint_expr(info
, dst
, r
->elts
[i
]);
220 void pprint_reduction(struct cloogoptions
*i
, FILE *dst
, struct clast_reduction
*r
)
224 pprint_sum(i
, dst
, r
);
229 pprint_expr(i
, dst
, r
->elts
[0]);
232 if (i
->language
== CLOOG_LANGUAGE_FORTRAN
)
233 pprint_minmax_f(i
, dst
, r
);
235 pprint_minmax_c(i
, dst
, r
);
242 void pprint_expr(struct cloogoptions
*i
, FILE *dst
, struct clast_expr
*e
)
247 case clast_expr_name
:
248 pprint_name(dst
, (struct clast_name
*) e
);
250 case clast_expr_term
:
251 pprint_term(i
, dst
, (struct clast_term
*) e
);
254 pprint_reduction(i
, dst
, (struct clast_reduction
*) e
);
257 pprint_binary(i
, dst
, (struct clast_binary
*) e
);
264 void pprint_equation(struct cloogoptions
*i
, FILE *dst
, struct clast_equation
*eq
)
266 pprint_expr(i
, dst
, eq
->LHS
);
268 fprintf(dst
, " == ");
269 else if (eq
->sign
> 0)
270 fprintf(dst
, " >= ");
272 fprintf(dst
, " <= ");
273 pprint_expr(i
, dst
, eq
->RHS
);
276 void pprint_assignment(struct cloogoptions
*i
, FILE *dst
,
277 struct clast_assignment
*a
)
280 fprintf(dst
, "%s = ", a
->LHS
);
281 pprint_expr(i
, dst
, a
->RHS
);
286 * pprint_osl_body function:
287 * this function pretty-prints the OpenScop body of a given statement.
288 * It returns 1 if it succeeds to find an OpenScop body to print for
289 * that statement, 0 otherwise.
290 * \param[in] options CLooG Options.
291 * \param[in] dst Output stream.
292 * \param[in] u Statement to print the OpenScop body.
293 * \return 1 on success to pretty-print an OpenScop body for u, 0 otherwise.
295 int pprint_osl_body(struct cloogoptions
*options
, FILE *dst
,
296 struct clast_user_stmt
*u
) {
300 struct clast_stmt
*t
;
301 osl_scop_p scop
= options
->scop
;
302 osl_statement_p stmt
;
305 if ((scop
!= NULL
) &&
306 (osl_statement_number(scop
->statement
) >= u
->statement
->number
)) {
307 stmt
= scop
->statement
;
309 /* Go to the convenient statement in the SCoP. */
310 for (i
= 1; i
< u
->statement
->number
; i
++)
313 /* Ensure it has a printable body. */
314 if ((osl_generic_has_URI(stmt
->body
, OSL_URI_BODY
)) &&
315 ((body
= stmt
->body
->data
) != NULL
) &&
316 (body
->expression
!= NULL
) &&
317 (body
->iterators
!= NULL
)) {
318 expr
= osl_util_identifier_substitution(body
->expression
->string
[0],
319 body
->iterators
->string
);
321 /* Print the body expression, substituting the @...@ markers. */
325 expr
+= sscanf(expr
, "@%d", &iterator
) + 2; /* 2 for the @s */
326 t
= u
->substitutions
;
327 for (i
= 0; i
< iterator
; i
++)
329 pprint_assignment(options
, dst
, (struct clast_assignment
*)t
);
331 fprintf(dst
, "%c", *expr
++);
343 void pprint_user_stmt(struct cloogoptions
*options
, FILE *dst
,
344 struct clast_user_stmt
*u
)
346 struct clast_stmt
*t
;
348 if (pprint_osl_body(options
, dst
, u
))
351 if (u
->statement
->name
)
352 fprintf(dst
, "%s", u
->statement
->name
);
354 fprintf(dst
, "S%d", u
->statement
->number
);
356 for (t
= u
->substitutions
; t
; t
= t
->next
) {
357 assert(CLAST_STMT_IS_A(t
, stmt_ass
));
358 pprint_assignment(options
, dst
, (struct clast_assignment
*)t
);
363 if (options
->language
!= CLOOG_LANGUAGE_FORTRAN
)
368 void pprint_guard(struct cloogoptions
*options
, FILE *dst
, int indent
,
369 struct clast_guard
*g
)
372 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
378 for (k
= 0; k
< g
->n
; ++k
) {
380 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
381 fprintf(dst
," .AND. ");
386 pprint_equation(options
, dst
, &g
->eq
[k
]);
391 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
392 fprintf(dst
," THEN\n");
396 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
, g
->then
);
398 fprintf(dst
, "%*s", indent
, "");
399 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
400 fprintf(dst
,"END IF\n");
405 void pprint_for(struct cloogoptions
*options
, FILE *dst
, int indent
,
408 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
411 fprintf(dst
, "for (");
414 fprintf(dst
, "%s=", f
->iterator
);
415 pprint_expr(options
, dst
, f
->LB
);
416 } else if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
417 cloog_die("unbounded loops not allowed in FORTRAN.\n");
419 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
425 if (options
->language
!= CLOOG_LANGUAGE_FORTRAN
)
426 fprintf(dst
,"%s<=", f
->iterator
);
427 pprint_expr(options
, dst
, f
->UB
);
428 } else if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
429 cloog_die("unbounded loops not allowed in FORTRAN.\n");
431 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
) {
432 if (cloog_int_gt_si(f
->stride
, 1))
433 cloog_int_print(dst
, f
->stride
);
437 if (cloog_int_gt_si(f
->stride
, 1)) {
438 fprintf(dst
,";%s+=", f
->iterator
);
439 cloog_int_print(dst
, f
->stride
);
440 fprintf(dst
, ") {\n");
442 fprintf(dst
, ";%s++) {\n", f
->iterator
);
445 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
, f
->body
);
447 fprintf(dst
, "%*s", indent
, "");
448 if (options
->language
== CLOOG_LANGUAGE_FORTRAN
)
449 fprintf(dst
,"END DO\n") ;
454 void pprint_stmt_list(struct cloogoptions
*options
, FILE *dst
, int indent
,
455 struct clast_stmt
*s
)
457 for ( ; s
; s
= s
->next
) {
458 if (CLAST_STMT_IS_A(s
, stmt_root
))
460 fprintf(dst
, "%*s", indent
, "");
461 if (CLAST_STMT_IS_A(s
, stmt_ass
)) {
462 pprint_assignment(options
, dst
, (struct clast_assignment
*) s
);
463 if (options
->language
!= CLOOG_LANGUAGE_FORTRAN
)
466 } else if (CLAST_STMT_IS_A(s
, stmt_user
)) {
467 pprint_user_stmt(options
, dst
, (struct clast_user_stmt
*) s
);
468 } else if (CLAST_STMT_IS_A(s
, stmt_for
)) {
469 pprint_for(options
, dst
, indent
, (struct clast_for
*) s
);
470 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
471 pprint_guard(options
, dst
, indent
, (struct clast_guard
*) s
);
472 } else if (CLAST_STMT_IS_A(s
, stmt_block
)) {
474 pprint_stmt_list(options
, dst
, indent
+ INDENT_STEP
,
475 ((struct clast_block
*)s
)->body
);
476 fprintf(dst
, "%*s", indent
, "");
485 /******************************************************************************
486 * Pretty Printing (dirty) functions *
487 ******************************************************************************/
489 void clast_pprint(FILE *foo
, struct clast_stmt
*root
,
490 int indent
, CloogOptions
*options
)
492 pprint_stmt_list(options
, foo
, indent
, root
);