2 * Copyright 2010-2011 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include "clast_printer.h"
13 void print_cloog_macros(FILE *dst
)
15 fprintf(dst
, "#define floord(n,d) "
16 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))\n");
17 fprintf(dst
, "#define ceild(n,d) "
18 "(((n)<0) ? -((-(n))/(d)) : ((n)+(d)-1)/(d))\n");
19 fprintf(dst
, "#define max(x,y) "
20 "((x) > (y) ? (x) : (y))\n");
21 fprintf(dst
, "#define min(x,y) "
22 "((x) < (y) ? (x) : (y))\n");
25 static void print_expr(struct clast_expr
*e
, FILE *dst
);
26 static void print_stmt(struct clast_printer_info
*info
, struct clast_stmt
*s
);
28 void print_indent(FILE *dst
, int indent
)
30 fprintf(dst
, "%*s", indent
, "");
33 static void print_name(struct clast_name
*n
, FILE *dst
)
35 fprintf(dst
, "%s", n
->name
);
38 static void print_term(struct clast_term
*t
, FILE *dst
)
41 cloog_int_print(dst
, t
->val
);
43 if (!cloog_int_is_one(t
->val
)) {
44 cloog_int_print(dst
, t
->val
);
47 if (t
->var
->type
== clast_expr_red
)
49 print_expr(t
->var
, dst
);
50 if (t
->var
->type
== clast_expr_red
)
55 static void print_bin(struct clast_binary
*b
, FILE *dst
)
57 const char *s1
, *s2
, *s3
;
60 s1
= "(", s2
= ")%", s3
= "";
63 s1
= "(", s2
= ")/(", s3
= ")";
66 s1
= "ceild(", s2
= ", ", s3
= ")";
69 s1
= "floord(", s2
= ", ", s3
= ")";
74 fprintf(dst
, "%s", s1
);
75 print_expr(b
->LHS
, dst
);
76 fprintf(dst
, "%s", s2
);
77 cloog_int_print(dst
, b
->RHS
);
78 fprintf(dst
, "%s", s3
);
81 static void print_red(struct clast_reduction
*r
, FILE *dst
)
84 const char *s1
, *s2
, *s3
;
87 print_expr(r
->elts
[0], dst
);
93 s1
= "", s2
= " + ", s3
= "";
96 s1
= "max(", s2
= ", ", s3
= ")";
99 s1
= "min(", s2
= ", ", s3
= ")";
105 for (i
= 1; i
< r
->n
; ++i
)
106 fprintf(dst
, "%s", s1
);
107 print_expr(r
->elts
[0], dst
);
108 for (i
= 1; i
< r
->n
; ++i
) {
109 if (r
->type
== clast_red_sum
&&
110 r
->elts
[i
]->type
== clast_expr_term
&&
111 cloog_int_is_neg(((struct clast_term
*) r
->elts
[i
])->val
)) {
112 struct clast_term
*t
= (struct clast_term
*) r
->elts
[i
];
113 cloog_int_neg(t
->val
, t
->val
);
115 print_expr(r
->elts
[i
], dst
);
116 cloog_int_neg(t
->val
, t
->val
);
118 fprintf(dst
, "%s", s2
);
119 print_expr(r
->elts
[i
], dst
);
121 fprintf(dst
, "%s", s3
);
125 static void print_expr(struct clast_expr
*e
, FILE *dst
)
128 case clast_expr_name
:
129 print_name((struct clast_name
*) e
, dst
);
131 case clast_expr_term
:
132 print_term((struct clast_term
*) e
, dst
);
135 print_red((struct clast_reduction
*) e
, dst
);
138 print_bin((struct clast_binary
*) e
, dst
);
145 static void print_ass(struct clast_assignment
*a
, FILE *dst
, int indent
,
148 print_indent(dst
, indent
);
150 fprintf(dst
, "int ");
151 fprintf(dst
, "%s = ", a
->LHS
);
152 print_expr(a
->RHS
, dst
);
156 static void print_guard(struct clast_printer_info
*info
, struct clast_guard
*g
)
161 print_indent(info
->dst
, info
->indent
);
162 fprintf(info
->dst
, "if (");
163 for (i
= 0; i
< n
; ++i
) {
165 fprintf(info
->dst
," && ");
167 fprintf(info
->dst
,"(");
168 print_expr(g
->eq
[i
].LHS
, info
->dst
);
169 if (g
->eq
[i
].sign
== 0)
170 fprintf(info
->dst
," == ");
171 else if (g
->eq
[i
].sign
> 0)
172 fprintf(info
->dst
," >= ");
174 fprintf(info
->dst
," <= ");
175 print_expr(g
->eq
[i
].RHS
, info
->dst
);
177 fprintf(info
->dst
,")");
179 fprintf(info
->dst
, ") {\n");
181 print_stmt(info
, g
->then
);
183 print_indent(info
->dst
, info
->indent
);
184 fprintf(info
->dst
, "}\n");
187 static void print_for(struct clast_printer_info
*info
, struct clast_for
*f
)
189 assert(f
->LB
&& f
->UB
);
190 print_indent(info
->dst
, info
->indent
);
191 fprintf(info
->dst
, "for (int %s = ", f
->iterator
);
192 print_expr(f
->LB
, info
->dst
);
193 fprintf(info
->dst
, "; %s <= ", f
->iterator
);
194 print_expr(f
->UB
, info
->dst
);
195 fprintf(info
->dst
, "; %s", f
->iterator
);
196 if (cloog_int_is_one(f
->stride
))
197 fprintf(info
->dst
, "++");
199 fprintf(info
->dst
, " += ");
200 cloog_int_print(info
->dst
, f
->stride
);
202 fprintf(info
->dst
, ") {\n");
204 if (info
->print_for_head
)
205 info
->print_for_head(info
, f
);
206 print_stmt(info
, f
->body
);
207 if (info
->print_for_foot
)
208 info
->print_for_foot(info
, f
);
210 print_indent(info
->dst
, info
->indent
);
211 fprintf(info
->dst
, "}\n");
214 static void print_user_stmt(struct clast_user_stmt
*u
, FILE *dst
, int indent
)
216 struct clast_stmt
*t
;
218 print_indent(dst
, indent
);
219 fprintf(dst
, "%s", u
->statement
->name
);
221 for (t
= u
->substitutions
; t
; t
= t
->next
) {
222 assert(CLAST_STMT_IS_A(t
, stmt_ass
));
223 print_expr(((struct clast_assignment
*) t
)->RHS
, dst
);
227 fprintf(dst
, ");\n");
230 static void print_stmt(struct clast_printer_info
*info
, struct clast_stmt
*s
)
234 for ( ; s
; s
= s
->next
) {
235 if (CLAST_STMT_IS_A(s
, stmt_root
))
237 if (CLAST_STMT_IS_A(s
, stmt_ass
)) {
238 print_ass((struct clast_assignment
*) s
, info
->dst
,
239 info
->indent
, first_ass
);
241 } else if (CLAST_STMT_IS_A(s
, stmt_user
)) {
242 struct clast_user_stmt
*user_stmt
;
243 user_stmt
= (struct clast_user_stmt
*) s
;
245 if (info
->print_user_stmt_list
) {
246 info
->print_user_stmt_list(info
, user_stmt
);
248 } else if (info
->print_user_stmt
)
249 info
->print_user_stmt(info
, user_stmt
);
251 print_user_stmt(user_stmt
, info
->dst
,
253 } else if (CLAST_STMT_IS_A(s
, stmt_for
)) {
254 print_for(info
, (struct clast_for
*) s
);
255 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
256 print_guard(info
, (struct clast_guard
*) s
);
263 void print_clast(struct clast_printer_info
*info
, struct clast_stmt
*s
)
268 __isl_give isl_set
*extract_host_domain(struct clast_user_stmt
*u
)
270 return isl_set_from_cloog_domain(cloog_domain_copy(u
->domain
));
273 /* Extract the set of scattering dimension values for which the given
274 * statement is executed, where the statement may be either a user statement
275 * or a guard containing a sequence of (possibly guarded) user statements.
277 static __isl_give isl_set
*extract_nested_host_domain(struct clast_stmt
*s
)
279 if (CLAST_STMT_IS_A(s
, stmt_user
)) {
280 struct clast_user_stmt
*u
= (struct clast_user_stmt
*) s
;
281 return extract_host_domain(u
);
282 } else if (CLAST_STMT_IS_A(s
, stmt_guard
)) {
283 struct clast_guard
*g
= (struct clast_guard
*) s
;
284 return extract_entire_host_domain(g
->then
);
289 /* Extract the set of scattering dimension values for which the given
290 * sequence of user statements is executed.
291 * Some of the user statements in the sequence may be guarded
292 * so we return the union of this set over all user statements.
294 __isl_give isl_set
*extract_entire_host_domain(struct clast_stmt
*s
)
296 isl_set
*host_domain
= NULL
;
298 for (; s
; s
= s
->next
) {
301 set_i
= extract_nested_host_domain(s
);
306 host_domain
= isl_set_union(host_domain
, set_i
);
310 return isl_set_coalesce(host_domain
);