12 static void print_ast_expr_int(ostream
&os
, __isl_keep isl_ast_expr
*expr
)
16 v
= isl_ast_expr_get_val(expr
);
17 os
<< isl_val_get_num_si(v
);
21 static void print_ast_expr_id(ostream
&os
, __isl_keep isl_ast_expr
*expr
)
25 id
= isl_ast_expr_get_id(expr
);
26 os
<< isl_id_get_name(id
);
30 /* In ESPAM, the "div" and "mod" operators have the following meaning.
32 * int div(double a, double b) {
33 * return (int) (((a)<0) ? ((a)-(b)+1)/(b) : (a)/(b));
35 * int mod(double a, double b) {
36 * return (int)fmod(a, b);
39 * That is, "div" rounds down, while "mod" rounds towards zero.
41 static const char *op_name(enum isl_ast_op_type type
)
50 case isl_ast_op_pdiv_q
:
51 case isl_ast_op_fdiv_q
:
53 case isl_ast_op_pdiv_r
:
54 case isl_ast_op_zdiv_r
:
61 static void print_ast_expr(ostream
&os
, __isl_keep isl_ast_expr
*expr
);
63 static void print_ast_expr_op(ostream
&os
, __isl_keep isl_ast_expr
*expr
)
65 enum isl_ast_op_type type
;
68 type
= isl_ast_expr_get_op_type(expr
);
73 arg
= isl_ast_expr_get_op_arg(expr
, 0);
74 print_ast_expr(os
, arg
);
75 isl_ast_expr_free(arg
);
77 arg
= isl_ast_expr_get_op_arg(expr
, 1);
78 print_ast_expr(os
, arg
);
79 isl_ast_expr_free(arg
);
81 case isl_ast_op_pdiv_q
:
82 case isl_ast_op_pdiv_r
:
83 case isl_ast_op_fdiv_q
:
84 case isl_ast_op_zdiv_r
:
87 arg
= isl_ast_expr_get_op_arg(expr
, 0);
88 print_ast_expr(os
, arg
);
89 isl_ast_expr_free(arg
);
91 arg
= isl_ast_expr_get_op_arg(expr
, 1);
92 print_ast_expr(os
, arg
);
93 isl_ast_expr_free(arg
);
97 fprintf(stderr
, "unhandled operation\n");
98 isl_ast_expr_dump(expr
);
103 static void print_ast_expr(ostream
&os
, __isl_keep isl_ast_expr
*expr
)
105 enum isl_ast_expr_type type
;
107 type
= isl_ast_expr_get_type(expr
);
109 case isl_ast_expr_int
:
110 print_ast_expr_int(os
, expr
);
112 case isl_ast_expr_id
:
113 print_ast_expr_id(os
, expr
);
115 case isl_ast_expr_op
:
116 print_ast_expr_op(os
, expr
);
118 case isl_ast_expr_error
:
123 static string
expr2string(__isl_keep isl_ast_expr
*expr
)
125 std::ostringstream strm
;
127 print_ast_expr(strm
, expr
);
132 static void write_ast_node(xmlTextWriterPtr writer
,
133 __isl_keep isl_ast_node
*block
);
135 static bool is_max(__isl_keep isl_ast_expr
*expr
)
137 if (isl_ast_expr_get_type(expr
) != isl_ast_expr_op
)
139 return isl_ast_expr_get_op_type(expr
) == isl_ast_op_max
;
142 static bool is_min(__isl_keep isl_ast_expr
*expr
)
144 if (isl_ast_expr_get_type(expr
) != isl_ast_expr_op
)
146 return isl_ast_expr_get_op_type(expr
) == isl_ast_op_min
;
149 static __isl_give isl_ast_expr
*extract_arg(__isl_take isl_ast_expr
*expr
,
154 arg
= isl_ast_expr_get_op_arg(expr
, pos
);
155 isl_ast_expr_free(expr
);
160 static bool is_comp(enum isl_ast_op_type type
)
172 static const char *comp_sign(enum isl_ast_op_type type
)
186 /* Write out the start of an if node representing the test
188 * lhs == rhs if sign is "0"
189 * lhs <= rhs if sign is "-1" and strict is false
190 * lhs < rhs if sign is "-1" and strict is true
191 * lhs >= rhs if sign is "1"
193 * strict is only set by any of the callers when sign is "-1".
194 * The end of the if node can be written out using write_ast_node_if_foot.
196 static void write_ast_node_if_head(xmlTextWriterPtr writer
,
197 __isl_keep isl_ast_expr
*lhs
, __isl_keep isl_ast_expr
*rhs
,
198 const char *sign
, bool strict
= false)
203 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"if");
206 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"LHS",
207 BAD_CAST
expr2string(lhs
).c_str());
210 s
= expr2string(rhs
);
213 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"RHS",
217 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"sign",
222 static void write_ast_node_if_head(xmlTextWriterPtr writer
,
223 __isl_keep isl_ast_expr
*expr
)
226 isl_ast_expr
*lhs
, *rhs
;
227 enum isl_ast_op_type type
;
230 lhs
= isl_ast_expr_get_op_arg(expr
, 0);
231 rhs
= isl_ast_expr_get_op_arg(expr
, 1);
233 type
= isl_ast_expr_get_op_type(expr
);
234 assert(is_comp(type
));
235 sign
= comp_sign(type
);
237 write_ast_node_if_head(writer
, lhs
, rhs
, sign
);
239 isl_ast_expr_free(lhs
);
240 isl_ast_expr_free(rhs
);
243 static void write_ast_node_if_foot(xmlTextWriterPtr writer
)
247 rc
= xmlTextWriterEndElement(writer
);
251 /* Return a string representation of (part of) the upper bound
252 * of the for node "node".
254 * If the upper bound is a non-zero constant, we return the empty string.
255 * Otherwise, we assume it is a comparison, either "<=" (in which
256 * case we set ub_strict to false) or "<" (in which case we set ub_strict
258 * If the right-hand side is a min-expression, we set ub_min
259 * and return a string representation of the first argument
260 * of the min-expression.
261 * Otherwise, we set ub_min to false and return a string representation
262 * of the entire right-hand side.
264 static string
ast_node_for_upper_bound(xmlTextWriterPtr writer
,
265 __isl_keep isl_ast_node
*node
, bool &ub_strict
, bool &ub_min
)
269 enum isl_ast_op_type type
;
271 expr
= isl_ast_node_for_get_cond(node
);
273 if (isl_ast_expr_get_type(expr
) == isl_ast_expr_int
) {
275 v
= isl_ast_expr_get_val(expr
);
276 assert(!isl_val_is_zero(v
));
278 isl_ast_expr_free(expr
);
284 assert(isl_ast_expr_get_type(expr
) == isl_ast_expr_op
);
285 type
= isl_ast_expr_get_op_type(expr
);
286 assert(type
== isl_ast_op_le
|| type
== isl_ast_op_lt
);
287 ub_strict
= type
== isl_ast_op_lt
;
288 expr
= extract_arg(expr
, 1);
289 ub_min
= is_min(expr
);
291 expr
= extract_arg(expr
, 0);
292 ub
= expr2string(expr
);
295 isl_ast_expr_free(expr
);
300 /* Write out a for node.
301 * ESPAM expects only a single expression for the lower and the upper
302 * bound. If these are a minimum/maximum of several expressions in "node",
303 * then we only write out one of these expressions in the for node
304 * and write out the others in nested if nodes.
306 static void write_ast_node_for(xmlTextWriterPtr writer
,
307 __isl_keep isl_ast_node
*node
)
311 isl_ast_expr
*expr
, *it
;
314 bool lb_max
, ub_strict
, ub_min
;
317 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"for");
320 it
= isl_ast_node_for_get_iterator(node
);
321 id
= isl_ast_expr_get_id(it
);
322 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"iterator",
323 BAD_CAST
isl_id_get_name(id
));
327 expr
= isl_ast_node_for_get_init(node
);
328 lb_max
= is_max(expr
);
330 expr
= extract_arg(expr
, 0);
331 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"LB",
332 BAD_CAST
expr2string(expr
).c_str());
334 isl_ast_expr_free(expr
);
336 ub
= ast_node_for_upper_bound(writer
, node
, ub_strict
, ub_min
);
337 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"UB",
338 BAD_CAST ub
.c_str());
341 expr
= isl_ast_node_for_get_inc(node
);
342 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"stride",
343 BAD_CAST
expr2string(expr
).c_str());
345 isl_ast_expr_free(expr
);
349 expr
= isl_ast_node_for_get_init(node
);
350 n
= isl_ast_expr_get_op_n_arg(expr
) - 1;
352 for (int i
= 0; i
< n
; ++i
) {
354 arg
= isl_ast_expr_get_op_arg(expr
, 1 + i
);
355 write_ast_node_if_head(writer
, it
, arg
, "1");
356 isl_ast_expr_free(arg
);
358 isl_ast_expr_free(expr
);
363 expr
= isl_ast_node_for_get_cond(node
);
364 expr
= extract_arg(expr
, 1);
365 n
= isl_ast_expr_get_op_n_arg(expr
) - 1;
367 for (int i
= 0; i
< n
; ++i
) {
369 arg
= isl_ast_expr_get_op_arg(expr
, 1 + i
);
370 write_ast_node_if_head(writer
, it
, arg
, "-1",
372 isl_ast_expr_free(arg
);
374 isl_ast_expr_free(expr
);
377 body
= isl_ast_node_for_get_body(node
);
378 write_ast_node(writer
, body
);
379 isl_ast_node_free(body
);
381 for (int i
= 0; i
< extra_foot
; ++i
)
382 write_ast_node_if_foot(writer
);
384 rc
= xmlTextWriterEndElement(writer
);
387 isl_ast_expr_free(it
);
390 /* Write out the (conjunction of) condition(s) "cond"
391 * as a sequence of heads of if nodes and return the number
392 * of if nodes started.
394 static int write_ast_node_if_heads(xmlTextWriterPtr writer
,
395 __isl_take isl_ast_expr
*cond
)
398 enum isl_ast_op_type type
;
400 assert(isl_ast_expr_get_type(cond
) == isl_ast_expr_op
);
401 type
= isl_ast_expr_get_op_type(cond
);
403 write_ast_node_if_head(writer
, cond
);
406 assert(type
== isl_ast_op_and
);
407 assert(isl_ast_expr_get_op_n_arg(cond
) == 2);
409 for (int i
= 0; i
< 2; ++i
) {
412 arg
= isl_ast_expr_get_op_arg(cond
, i
);
413 n
+= write_ast_node_if_heads(writer
, arg
);
416 isl_ast_expr_free(cond
);
421 /* Write out an if node.
422 * If "node" represents a conjunction of conditions, then an if node
423 * is created for each of them.
425 static void write_ast_node_if(xmlTextWriterPtr writer
,
426 __isl_keep isl_ast_node
*node
)
433 cond
= isl_ast_node_if_get_cond(node
);
434 n
= write_ast_node_if_heads(writer
, cond
);
436 body
= isl_ast_node_if_get_then(node
);
437 write_ast_node(writer
, body
);
438 isl_ast_node_free(body
);
440 for (int i
= 0; i
< n
; ++i
)
441 write_ast_node_if_foot(writer
);
444 static void write_ast_node_user(xmlTextWriterPtr writer
,
445 __isl_keep isl_ast_node
*node
)
449 isl_ast_expr
*expr
, *arg
;
453 expr
= isl_ast_node_user_get_expr(node
);
454 arg
= isl_ast_expr_get_op_arg(expr
, 0);
455 id
= isl_ast_expr_get_id(arg
);
456 name
= isl_id_get_name(id
);
458 if ((I
= strchr(name
, 'I')) && I
[1] == 'D') {
459 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"var");
462 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
465 } else if (!strchr(name
, 'P')) {
466 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"stmt");
469 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"node",
473 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"port");
476 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
481 rc
= xmlTextWriterEndElement(writer
);
485 isl_ast_expr_free(arg
);
486 isl_ast_expr_free(expr
);
489 static void write_ast_node_block(xmlTextWriterPtr writer
,
490 __isl_keep isl_ast_node
*block
)
493 isl_ast_node_list
*list
;
495 list
= isl_ast_node_block_get_children(block
);
496 n
= isl_ast_node_list_n_ast_node(list
);
497 for (int i
= 0; i
< n
; ++i
) {
500 node
= isl_ast_node_list_get_ast_node(list
, i
);
501 write_ast_node(writer
, node
);
502 isl_ast_node_free(node
);
504 isl_ast_node_list_free(list
);
507 static void write_ast_node(xmlTextWriterPtr writer
,
508 __isl_keep isl_ast_node
*node
)
510 enum isl_ast_node_type type
;
512 type
= isl_ast_node_get_type(node
);
514 case isl_ast_node_for
:
515 write_ast_node_for(writer
, node
);
517 case isl_ast_node_if
:
518 write_ast_node_if(writer
, node
);
520 case isl_ast_node_block
:
521 write_ast_node_block(writer
, node
);
523 case isl_ast_node_user
:
524 write_ast_node_user(writer
, node
);
526 case isl_ast_node_mark
:
527 node
= isl_ast_node_mark_get_node(node
);
528 write_ast_node(writer
, node
);
529 isl_ast_node_free(node
);
531 case isl_ast_node_error
:
536 void writeAST(xmlTextWriterPtr writer
, __isl_keep isl_ast_node
*node
)
540 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"ast");
543 write_ast_node(writer
, node
);
545 rc
= xmlTextWriterEndElement(writer
);