b52041f57d5588d326edda57af783b103d6fd86b
[isl.git] / isl_ast.c
blobb52041f57d5588d326edda57af783b103d6fd86b
1 /*
2 * Copyright 2012-2013 Ecole Normale Superieure
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
8 */
10 #include <isl_ast_private.h>
12 #undef BASE
13 #define BASE ast_expr
15 #include <isl_list_templ.c>
17 #undef BASE
18 #define BASE ast_node
20 #include <isl_list_templ.c>
22 isl_ctx *isl_ast_print_options_get_ctx(
23 __isl_keep isl_ast_print_options *options)
25 return options ? options->ctx : NULL;
28 __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
30 isl_ast_print_options *options;
32 options = isl_calloc_type(ctx, isl_ast_print_options);
33 if (!options)
34 return NULL;
36 options->ctx = ctx;
37 isl_ctx_ref(ctx);
38 options->ref = 1;
40 return options;
43 __isl_give isl_ast_print_options *isl_ast_print_options_dup(
44 __isl_keep isl_ast_print_options *options)
46 isl_ctx *ctx;
47 isl_ast_print_options *dup;
49 if (!options)
50 return NULL;
52 ctx = isl_ast_print_options_get_ctx(options);
53 dup = isl_ast_print_options_alloc(ctx);
54 if (!dup)
55 return NULL;
57 dup->print_for = options->print_for;
58 dup->print_for_user = options->print_for_user;
59 dup->print_user = options->print_user;
60 dup->print_user_user = options->print_user_user;
62 return dup;
65 __isl_give isl_ast_print_options *isl_ast_print_options_cow(
66 __isl_take isl_ast_print_options *options)
68 if (!options)
69 return NULL;
71 if (options->ref == 1)
72 return options;
73 options->ref--;
74 return isl_ast_print_options_dup(options);
77 __isl_give isl_ast_print_options *isl_ast_print_options_copy(
78 __isl_keep isl_ast_print_options *options)
80 if (!options)
81 return NULL;
83 options->ref++;
84 return options;
87 void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options)
89 if (!options)
90 return NULL;
92 if (--options->ref > 0)
93 return NULL;
95 isl_ctx_deref(options->ctx);
97 free(options);
98 return NULL;
101 /* Set the print_user callback of "options" to "print_user".
103 * If this callback is set, then it used to print user nodes in the AST.
104 * Otherwise, the expression associated to the user node is printed.
106 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
107 __isl_take isl_ast_print_options *options,
108 __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
109 __isl_take isl_ast_print_options *options,
110 __isl_keep isl_ast_node *node, void *user),
111 void *user)
113 options = isl_ast_print_options_cow(options);
114 if (!options)
115 return NULL;
117 options->print_user = print_user;
118 options->print_user_user = user;
120 return options;
123 /* Set the print_for callback of "options" to "print_for".
125 * If this callback is set, then it used to print for nodes in the AST.
127 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
128 __isl_take isl_ast_print_options *options,
129 __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
130 __isl_take isl_ast_print_options *options,
131 __isl_keep isl_ast_node *node, void *user),
132 void *user)
134 options = isl_ast_print_options_cow(options);
135 if (!options)
136 return NULL;
138 options->print_for = print_for;
139 options->print_for_user = user;
141 return options;
144 __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
146 if (!expr)
147 return NULL;
149 expr->ref++;
150 return expr;
153 __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
155 int i;
156 isl_ctx *ctx;
157 isl_ast_expr *dup;
159 if (!expr)
160 return NULL;
162 ctx = isl_ast_expr_get_ctx(expr);
163 switch (expr->type) {
164 case isl_ast_expr_int:
165 dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
166 break;
167 case isl_ast_expr_id:
168 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
169 break;
170 case isl_ast_expr_op:
171 dup = isl_ast_expr_alloc_op(ctx,
172 expr->u.op.op, expr->u.op.n_arg);
173 if (!dup)
174 return NULL;
175 for (i = 0; i < expr->u.op.n_arg; ++i)
176 dup->u.op.args[i] =
177 isl_ast_expr_copy(expr->u.op.args[i]);
178 break;
179 case isl_ast_expr_error:
180 dup = NULL;
183 if (!dup)
184 return NULL;
186 return dup;
189 __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
191 if (!expr)
192 return NULL;
194 if (expr->ref == 1)
195 return expr;
196 expr->ref--;
197 return isl_ast_expr_dup(expr);
200 void *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
202 int i;
204 if (!expr)
205 return NULL;
207 if (--expr->ref > 0)
208 return NULL;
210 isl_ctx_deref(expr->ctx);
212 switch (expr->type) {
213 case isl_ast_expr_int:
214 isl_val_free(expr->u.v);
215 break;
216 case isl_ast_expr_id:
217 isl_id_free(expr->u.id);
218 break;
219 case isl_ast_expr_op:
220 for (i = 0; i < expr->u.op.n_arg; ++i)
221 isl_ast_expr_free(expr->u.op.args[i]);
222 free(expr->u.op.args);
223 break;
224 case isl_ast_expr_error:
225 break;
228 free(expr);
229 return NULL;
232 isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
234 return expr ? expr->ctx : NULL;
237 enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
239 return expr ? expr->type : isl_ast_expr_error;
242 /* Return the integer value represented by "expr".
244 __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
246 if (!expr)
247 return NULL;
248 if (expr->type != isl_ast_expr_int)
249 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
250 "expression not an int", return NULL);
251 return isl_val_copy(expr->u.v);
254 __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
256 if (!expr)
257 return NULL;
258 if (expr->type != isl_ast_expr_id)
259 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
260 "expression not an identifier", return NULL);
262 return isl_id_copy(expr->u.id);
265 enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
267 if (!expr)
268 return isl_ast_op_error;
269 if (expr->type != isl_ast_expr_op)
270 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
271 "expression not an operation", return isl_ast_op_error);
272 return expr->u.op.op;
275 int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
277 if (!expr)
278 return -1;
279 if (expr->type != isl_ast_expr_op)
280 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
281 "expression not an operation", return -1);
282 return expr->u.op.n_arg;
285 __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
286 int pos)
288 if (!expr)
289 return NULL;
290 if (expr->type != isl_ast_expr_op)
291 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
292 "expression not an operation", return NULL);
293 if (pos < 0 || pos >= expr->u.op.n_arg)
294 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
295 "index out of bounds", return NULL);
297 return isl_ast_expr_copy(expr->u.op.args[pos]);
300 /* Replace the argument at position "pos" of "expr" by "arg".
302 __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
303 int pos, __isl_take isl_ast_expr *arg)
305 expr = isl_ast_expr_cow(expr);
306 if (!expr || !arg)
307 goto error;
308 if (expr->type != isl_ast_expr_op)
309 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
310 "expression not an operation", goto error);
311 if (pos < 0 || pos >= expr->u.op.n_arg)
312 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
313 "index out of bounds", goto error);
315 isl_ast_expr_free(expr->u.op.args[pos]);
316 expr->u.op.args[pos] = arg;
318 return expr;
319 error:
320 isl_ast_expr_free(arg);
321 return isl_ast_expr_free(expr);
324 /* Is "expr1" equal to "expr2"?
326 int isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
327 __isl_keep isl_ast_expr *expr2)
329 int i;
331 if (!expr1 || !expr2)
332 return -1;
334 if (expr1 == expr2)
335 return 1;
336 if (expr1->type != expr2->type)
337 return 0;
338 switch (expr1->type) {
339 case isl_ast_expr_int:
340 return isl_val_eq(expr1->u.v, expr2->u.v);
341 case isl_ast_expr_id:
342 return expr1->u.id == expr2->u.id;
343 case isl_ast_expr_op:
344 if (expr1->u.op.op != expr2->u.op.op)
345 return 0;
346 if (expr1->u.op.n_arg != expr2->u.op.n_arg)
347 return 0;
348 for (i = 0; i < expr1->u.op.n_arg; ++i) {
349 int equal;
350 equal = isl_ast_expr_is_equal(expr1->u.op.args[i],
351 expr2->u.op.args[i]);
352 return 0;
353 if (equal < 0 || !equal)
354 return equal;
356 return 1;
357 case isl_ast_expr_error:
358 return -1;
362 /* Create a new operation expression of operation type "op",
363 * with "n_arg" as yet unspecified arguments.
365 __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
366 enum isl_ast_op_type op, int n_arg)
368 isl_ast_expr *expr;
370 expr = isl_calloc_type(ctx, isl_ast_expr);
371 if (!expr)
372 return NULL;
374 expr->ctx = ctx;
375 isl_ctx_ref(ctx);
376 expr->ref = 1;
377 expr->type = isl_ast_expr_op;
378 expr->u.op.op = op;
379 expr->u.op.n_arg = n_arg;
380 expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg);
382 if (n_arg && !expr->u.op.args)
383 return isl_ast_expr_free(expr);
385 return expr;
388 /* Create a new id expression representing "id".
390 __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
392 isl_ctx *ctx;
393 isl_ast_expr *expr;
395 if (!id)
396 return NULL;
398 ctx = isl_id_get_ctx(id);
399 expr = isl_calloc_type(ctx, isl_ast_expr);
400 if (!expr)
401 return isl_id_free(id);
403 expr->ctx = ctx;
404 isl_ctx_ref(ctx);
405 expr->ref = 1;
406 expr->type = isl_ast_expr_id;
407 expr->u.id = id;
409 return expr;
412 /* Create a new integer expression representing "i".
414 __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
416 isl_ast_expr *expr;
418 expr = isl_calloc_type(ctx, isl_ast_expr);
419 if (!expr)
420 return NULL;
422 expr->ctx = ctx;
423 isl_ctx_ref(ctx);
424 expr->ref = 1;
425 expr->type = isl_ast_expr_int;
426 expr->u.v = isl_val_int_from_si(ctx, i);
427 if (!expr->u.v)
428 return isl_ast_expr_free(expr);
430 return expr;
433 /* Create a new integer expression representing "v".
435 __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
437 isl_ctx *ctx;
438 isl_ast_expr *expr;
440 if (!v)
441 return NULL;
442 if (!isl_val_is_int(v))
443 isl_die(isl_val_get_ctx(v), isl_error_invalid,
444 "expecting integer value", return isl_val_free(v));
446 ctx = isl_val_get_ctx(v);
447 expr = isl_calloc_type(ctx, isl_ast_expr);
448 if (!expr)
449 return isl_val_free(v);
451 expr->ctx = ctx;
452 isl_ctx_ref(ctx);
453 expr->ref = 1;
454 expr->type = isl_ast_expr_int;
455 expr->u.v = v;
457 return expr;
460 /* Create an expression representing the negation of "arg".
462 __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
464 isl_ctx *ctx;
465 isl_ast_expr *expr = NULL;
467 if (!arg)
468 return NULL;
470 ctx = isl_ast_expr_get_ctx(arg);
471 expr = isl_ast_expr_alloc_op(ctx, isl_ast_op_minus, 1);
472 if (!expr)
473 goto error;
475 expr->u.op.args[0] = arg;
477 return expr;
478 error:
479 isl_ast_expr_free(arg);
480 return NULL;
483 /* Create an expression representing the binary operation "type"
484 * applied to "expr1" and "expr2".
486 __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
487 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
489 isl_ctx *ctx;
490 isl_ast_expr *expr = NULL;
492 if (!expr1 || !expr2)
493 goto error;
495 ctx = isl_ast_expr_get_ctx(expr1);
496 expr = isl_ast_expr_alloc_op(ctx, type, 2);
497 if (!expr)
498 goto error;
500 expr->u.op.args[0] = expr1;
501 expr->u.op.args[1] = expr2;
503 return expr;
504 error:
505 isl_ast_expr_free(expr1);
506 isl_ast_expr_free(expr2);
507 return NULL;
510 /* Create an expression representing the sum of "expr1" and "expr2".
512 __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
513 __isl_take isl_ast_expr *expr2)
515 return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
518 /* Create an expression representing the difference of "expr1" and "expr2".
520 __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
521 __isl_take isl_ast_expr *expr2)
523 return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
526 /* Create an expression representing the product of "expr1" and "expr2".
528 __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
529 __isl_take isl_ast_expr *expr2)
531 return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
534 /* Create an expression representing the quotient of "expr1" and "expr2".
536 __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
537 __isl_take isl_ast_expr *expr2)
539 return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
542 /* Create an expression representing the conjunction of "expr1" and "expr2".
544 __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
545 __isl_take isl_ast_expr *expr2)
547 return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
550 /* Create an expression representing the disjunction of "expr1" and "expr2".
552 __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
553 __isl_take isl_ast_expr *expr2)
555 return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
558 isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
560 return node ? node->ctx : NULL;
563 enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
565 return node ? node->type : isl_ast_node_error;
568 __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
569 enum isl_ast_node_type type)
571 isl_ast_node *node;
573 node = isl_calloc_type(ctx, isl_ast_node);
574 if (!node)
575 return NULL;
577 node->ctx = ctx;
578 isl_ctx_ref(ctx);
579 node->ref = 1;
580 node->type = type;
582 return node;
585 /* Create an if node with the given guard.
587 * The then body needs to be filled in later.
589 __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
591 isl_ast_node *node;
593 if (!guard)
594 return NULL;
596 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
597 if (!node)
598 goto error;
599 node->u.i.guard = guard;
601 return node;
602 error:
603 isl_ast_expr_free(guard);
604 return NULL;
607 /* Create a for node with the given iterator.
609 * The remaining fields need to be filled in later.
611 __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
613 isl_ast_node *node;
614 isl_ctx *ctx;
616 if (!id)
617 return NULL;
619 ctx = isl_id_get_ctx(id);
620 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
621 if (!node)
622 return NULL;
624 node->u.f.iterator = isl_ast_expr_from_id(id);
625 if (!node->u.f.iterator)
626 return isl_ast_node_free(node);
628 return node;
631 /* Create a user node evaluating "expr".
633 __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
635 isl_ctx *ctx;
636 isl_ast_node *node;
638 if (!expr)
639 return NULL;
641 ctx = isl_ast_expr_get_ctx(expr);
642 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
643 if (!node)
644 goto error;
646 node->u.e.expr = expr;
648 return node;
649 error:
650 isl_ast_expr_free(expr);
651 return NULL;
654 /* Create a block node with the given children.
656 __isl_give isl_ast_node *isl_ast_node_alloc_block(
657 __isl_take isl_ast_node_list *list)
659 isl_ast_node *node;
660 isl_ctx *ctx;
662 if (!list)
663 return NULL;
665 ctx = isl_ast_node_list_get_ctx(list);
666 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
667 if (!node)
668 goto error;
670 node->u.b.children = list;
672 return node;
673 error:
674 isl_ast_node_list_free(list);
675 return NULL;
678 /* Represent the given list of nodes as a single node, either by
679 * extract the node from a single element list or by creating
680 * a block node with the list of nodes as children.
682 __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
683 __isl_take isl_ast_node_list *list)
685 isl_ast_node *node;
687 if (isl_ast_node_list_n_ast_node(list) != 1)
688 return isl_ast_node_alloc_block(list);
690 node = isl_ast_node_list_get_ast_node(list, 0);
691 isl_ast_node_list_free(list);
693 return node;
696 __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
698 if (!node)
699 return NULL;
701 node->ref++;
702 return node;
705 __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
707 isl_ast_node *dup;
709 if (!node)
710 return NULL;
712 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
713 if (!dup)
714 return NULL;
716 switch (node->type) {
717 case isl_ast_node_if:
718 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
719 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
720 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
721 if (!dup->u.i.guard || !dup->u.i.then ||
722 (node->u.i.else_node && !dup->u.i.else_node))
723 return isl_ast_node_free(dup);
724 break;
725 case isl_ast_node_for:
726 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
727 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
728 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
729 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
730 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
731 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
732 !dup->u.f.inc || !dup->u.f.body)
733 return isl_ast_node_free(dup);
734 break;
735 case isl_ast_node_block:
736 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
737 if (!dup->u.b.children)
738 return isl_ast_node_free(dup);
739 break;
740 case isl_ast_node_user:
741 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
742 if (!dup->u.e.expr)
743 return isl_ast_node_free(dup);
744 break;
745 case isl_ast_node_error:
746 break;
749 return dup;
752 __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
754 if (!node)
755 return NULL;
757 if (node->ref == 1)
758 return node;
759 node->ref--;
760 return isl_ast_node_dup(node);
763 void *isl_ast_node_free(__isl_take isl_ast_node *node)
765 if (!node)
766 return NULL;
768 if (--node->ref > 0)
769 return NULL;
771 switch (node->type) {
772 case isl_ast_node_if:
773 isl_ast_expr_free(node->u.i.guard);
774 isl_ast_node_free(node->u.i.then);
775 isl_ast_node_free(node->u.i.else_node);
776 break;
777 case isl_ast_node_for:
778 isl_ast_expr_free(node->u.f.iterator);
779 isl_ast_expr_free(node->u.f.init);
780 isl_ast_expr_free(node->u.f.cond);
781 isl_ast_expr_free(node->u.f.inc);
782 isl_ast_node_free(node->u.f.body);
783 break;
784 case isl_ast_node_block:
785 isl_ast_node_list_free(node->u.b.children);
786 break;
787 case isl_ast_node_user:
788 isl_ast_expr_free(node->u.e.expr);
789 break;
790 case isl_ast_node_error:
791 break;
794 isl_id_free(node->annotation);
795 isl_ctx_deref(node->ctx);
796 free(node);
798 return NULL;
801 /* Replace the body of the for node "node" by "body".
803 __isl_give isl_ast_node *isl_ast_node_for_set_body(
804 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
806 node = isl_ast_node_cow(node);
807 if (!node || !body)
808 goto error;
809 if (node->type != isl_ast_node_for)
810 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
811 "not a for node", goto error);
813 isl_ast_node_free(node->u.f.body);
814 node->u.f.body = body;
816 return node;
817 error:
818 isl_ast_node_free(node);
819 isl_ast_node_free(body);
820 return NULL;
823 __isl_give isl_ast_node *isl_ast_node_for_get_body(
824 __isl_keep isl_ast_node *node)
826 if (!node)
827 return NULL;
828 if (node->type != isl_ast_node_for)
829 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
830 "not a for node", return NULL);
831 return isl_ast_node_copy(node->u.f.body);
834 /* Mark the given for node as being degenerate.
836 __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
837 __isl_take isl_ast_node *node)
839 node = isl_ast_node_cow(node);
840 if (!node)
841 return NULL;
842 node->u.f.degenerate = 1;
843 return node;
846 int isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
848 if (!node)
849 return -1;
850 if (node->type != isl_ast_node_for)
851 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
852 "not a for node", return -1);
853 return node->u.f.degenerate;
856 __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
857 __isl_keep isl_ast_node *node)
859 if (!node)
860 return NULL;
861 if (node->type != isl_ast_node_for)
862 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
863 "not a for node", return NULL);
864 return isl_ast_expr_copy(node->u.f.iterator);
867 __isl_give isl_ast_expr *isl_ast_node_for_get_init(
868 __isl_keep isl_ast_node *node)
870 if (!node)
871 return NULL;
872 if (node->type != isl_ast_node_for)
873 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
874 "not a for node", return NULL);
875 return isl_ast_expr_copy(node->u.f.init);
878 /* Return the condition expression of the given for node.
880 * If the for node is degenerate, then the condition is not explicitly
881 * stored in the node. Instead, it is constructed as
883 * iterator <= init
885 __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
886 __isl_keep isl_ast_node *node)
888 if (!node)
889 return NULL;
890 if (node->type != isl_ast_node_for)
891 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
892 "not a for node", return NULL);
893 if (!node->u.f.degenerate)
894 return isl_ast_expr_copy(node->u.f.cond);
896 return isl_ast_expr_alloc_binary(isl_ast_op_le,
897 isl_ast_expr_copy(node->u.f.iterator),
898 isl_ast_expr_copy(node->u.f.init));
901 /* Return the increment of the given for node.
903 * If the for node is degenerate, then the increment is not explicitly
904 * stored in the node. We simply return "1".
906 __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
907 __isl_keep isl_ast_node *node)
909 if (!node)
910 return NULL;
911 if (node->type != isl_ast_node_for)
912 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
913 "not a for node", return NULL);
914 if (!node->u.f.degenerate)
915 return isl_ast_expr_copy(node->u.f.inc);
916 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
919 /* Replace the then branch of the if node "node" by "child".
921 __isl_give isl_ast_node *isl_ast_node_if_set_then(
922 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
924 node = isl_ast_node_cow(node);
925 if (!node || !child)
926 goto error;
927 if (node->type != isl_ast_node_if)
928 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
929 "not an if node", goto error);
931 isl_ast_node_free(node->u.i.then);
932 node->u.i.then = child;
934 return node;
935 error:
936 isl_ast_node_free(node);
937 isl_ast_node_free(child);
938 return NULL;
941 __isl_give isl_ast_node *isl_ast_node_if_get_then(
942 __isl_keep isl_ast_node *node)
944 if (!node)
945 return NULL;
946 if (node->type != isl_ast_node_if)
947 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
948 "not an if node", return NULL);
949 return isl_ast_node_copy(node->u.i.then);
952 int isl_ast_node_if_has_else(
953 __isl_keep isl_ast_node *node)
955 if (!node)
956 return -1;
957 if (node->type != isl_ast_node_if)
958 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
959 "not an if node", return -1);
960 return node->u.i.else_node != NULL;
963 __isl_give isl_ast_node *isl_ast_node_if_get_else(
964 __isl_keep isl_ast_node *node)
966 if (!node)
967 return NULL;
968 if (node->type != isl_ast_node_if)
969 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
970 "not an if node", return NULL);
971 return isl_ast_node_copy(node->u.i.else_node);
974 __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
975 __isl_keep isl_ast_node *node)
977 if (!node)
978 return NULL;
979 if (node->type != isl_ast_node_if)
980 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
981 "not a guard node", return NULL);
982 return isl_ast_expr_copy(node->u.i.guard);
985 __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
986 __isl_keep isl_ast_node *node)
988 if (!node)
989 return NULL;
990 if (node->type != isl_ast_node_block)
991 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
992 "not a block node", return NULL);
993 return isl_ast_node_list_copy(node->u.b.children);
996 __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
997 __isl_keep isl_ast_node *node)
999 if (!node)
1000 return NULL;
1002 return isl_ast_expr_copy(node->u.e.expr);
1005 __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
1007 return node ? isl_id_copy(node->annotation) : NULL;
1010 /* Replace node->annotation by "annotation".
1012 __isl_give isl_ast_node *isl_ast_node_set_annotation(
1013 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1015 node = isl_ast_node_cow(node);
1016 if (!node || !annotation)
1017 goto error;
1019 isl_id_free(node->annotation);
1020 node->annotation = annotation;
1022 return node;
1023 error:
1024 isl_id_free(annotation);
1025 return isl_ast_node_free(node);
1028 /* Textual C representation of the various operators.
1030 static char *op_str[] = {
1031 [isl_ast_op_and] = "&&",
1032 [isl_ast_op_and_then] = "&&",
1033 [isl_ast_op_or] = "||",
1034 [isl_ast_op_or_else] = "||",
1035 [isl_ast_op_max] = "max",
1036 [isl_ast_op_min] = "min",
1037 [isl_ast_op_minus] = "-",
1038 [isl_ast_op_add] = "+",
1039 [isl_ast_op_sub] = "-",
1040 [isl_ast_op_mul] = "*",
1041 [isl_ast_op_pdiv_q] = "/",
1042 [isl_ast_op_pdiv_r] = "%",
1043 [isl_ast_op_div] = "/",
1044 [isl_ast_op_eq] = "==",
1045 [isl_ast_op_le] = "<=",
1046 [isl_ast_op_ge] = ">=",
1047 [isl_ast_op_lt] = "<",
1048 [isl_ast_op_gt] = ">"
1051 /* Precedence in C of the various operators.
1052 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1053 * Lowest value means highest precedence.
1055 static int op_prec[] = {
1056 [isl_ast_op_and] = 13,
1057 [isl_ast_op_and_then] = 13,
1058 [isl_ast_op_or] = 14,
1059 [isl_ast_op_or_else] = 14,
1060 [isl_ast_op_max] = 2,
1061 [isl_ast_op_min] = 2,
1062 [isl_ast_op_minus] = 3,
1063 [isl_ast_op_add] = 6,
1064 [isl_ast_op_sub] = 6,
1065 [isl_ast_op_mul] = 5,
1066 [isl_ast_op_div] = 5,
1067 [isl_ast_op_fdiv_q] = 2,
1068 [isl_ast_op_pdiv_q] = 5,
1069 [isl_ast_op_pdiv_r] = 5,
1070 [isl_ast_op_cond] = 15,
1071 [isl_ast_op_select] = 15,
1072 [isl_ast_op_eq] = 9,
1073 [isl_ast_op_le] = 8,
1074 [isl_ast_op_ge] = 8,
1075 [isl_ast_op_lt] = 8,
1076 [isl_ast_op_gt] = 8,
1077 [isl_ast_op_call] = 2
1080 /* Is the operator left-to-right associative?
1082 static int op_left[] = {
1083 [isl_ast_op_and] = 1,
1084 [isl_ast_op_and_then] = 1,
1085 [isl_ast_op_or] = 1,
1086 [isl_ast_op_or_else] = 1,
1087 [isl_ast_op_max] = 1,
1088 [isl_ast_op_min] = 1,
1089 [isl_ast_op_minus] = 0,
1090 [isl_ast_op_add] = 1,
1091 [isl_ast_op_sub] = 1,
1092 [isl_ast_op_mul] = 1,
1093 [isl_ast_op_div] = 1,
1094 [isl_ast_op_fdiv_q] = 1,
1095 [isl_ast_op_pdiv_q] = 1,
1096 [isl_ast_op_pdiv_r] = 1,
1097 [isl_ast_op_cond] = 0,
1098 [isl_ast_op_select] = 0,
1099 [isl_ast_op_eq] = 1,
1100 [isl_ast_op_le] = 1,
1101 [isl_ast_op_ge] = 1,
1102 [isl_ast_op_lt] = 1,
1103 [isl_ast_op_gt] = 1,
1104 [isl_ast_op_call] = 1
1107 static int is_and(enum isl_ast_op_type op)
1109 return op == isl_ast_op_and || op == isl_ast_op_and_then;
1112 static int is_or(enum isl_ast_op_type op)
1114 return op == isl_ast_op_or || op == isl_ast_op_or_else;
1117 static int is_add_sub(enum isl_ast_op_type op)
1119 return op == isl_ast_op_add || op == isl_ast_op_sub;
1122 static int is_div_mod(enum isl_ast_op_type op)
1124 return op == isl_ast_op_div || op == isl_ast_op_pdiv_r;
1127 /* Do we need/want parentheses around "expr" as a subexpression of
1128 * an "op" operation? If "left" is set, then "expr" is the left-most
1129 * operand.
1131 * We only need parentheses if "expr" represents an operation.
1133 * If op has a higher precedence than expr->u.op.op, then we need
1134 * parentheses.
1135 * If op and expr->u.op.op have the same precedence, but the operations
1136 * are performed in an order that is different from the associativity,
1137 * then we need parentheses.
1139 * An and inside an or technically does not require parentheses,
1140 * but some compilers complain about that, so we add them anyway.
1142 * Computations such as "a / b * c" and "a % b + c" can be somewhat
1143 * difficult to read, so we add parentheses for those as well.
1145 static int sub_expr_need_parens(enum isl_ast_op_type op,
1146 __isl_keep isl_ast_expr *expr, int left)
1148 if (expr->type != isl_ast_expr_op)
1149 return 0;
1151 if (op_prec[expr->u.op.op] > op_prec[op])
1152 return 1;
1153 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
1154 return 1;
1156 if (is_or(op) && is_and(expr->u.op.op))
1157 return 1;
1158 if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
1159 op_prec[expr->u.op.op] == op_prec[op])
1160 return 1;
1161 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
1162 return 1;
1164 return 0;
1167 /* Print "expr" as a subexpression of an "op" operation.
1168 * If "left" is set, then "expr" is the left-most operand.
1170 static __isl_give isl_printer *print_sub_expr(__isl_take isl_printer *p,
1171 enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
1173 int need_parens;
1175 need_parens = sub_expr_need_parens(op, expr, left);
1177 if (need_parens)
1178 p = isl_printer_print_str(p, "(");
1179 p = isl_printer_print_ast_expr(p, expr);
1180 if (need_parens)
1181 p = isl_printer_print_str(p, ")");
1182 return p;
1185 /* Print a min or max reduction "expr".
1187 static __isl_give isl_printer *print_min_max(__isl_take isl_printer *p,
1188 __isl_keep isl_ast_expr *expr)
1190 int i = 0;
1192 for (i = 1; i < expr->u.op.n_arg; ++i) {
1193 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1194 p = isl_printer_print_str(p, "(");
1196 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1197 for (i = 1; i < expr->u.op.n_arg; ++i) {
1198 p = isl_printer_print_str(p, ", ");
1199 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1200 p = isl_printer_print_str(p, ")");
1203 return p;
1206 /* Print a function call "expr".
1208 * The first argument represents the function to be called.
1210 static __isl_give isl_printer *print_call(__isl_take isl_printer *p,
1211 __isl_keep isl_ast_expr *expr)
1213 int i = 0;
1215 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1216 p = isl_printer_print_str(p, "(");
1217 for (i = 1; i < expr->u.op.n_arg; ++i) {
1218 if (i != 1)
1219 p = isl_printer_print_str(p, ", ");
1220 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1222 p = isl_printer_print_str(p, ")");
1224 return p;
1227 /* Print "expr" to "p".
1229 * If we are printing in isl format, then we also print an indication
1230 * of the size of the expression (if it was computed).
1232 __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
1233 __isl_keep isl_ast_expr *expr)
1235 if (!p)
1236 return NULL;
1237 if (!expr)
1238 return isl_printer_free(p);
1240 switch (expr->type) {
1241 case isl_ast_expr_op:
1242 if (expr->u.op.op == isl_ast_op_call) {
1243 p = print_call(p, expr);
1244 break;
1246 if (expr->u.op.n_arg == 1) {
1247 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1248 p = print_sub_expr(p, expr->u.op.op,
1249 expr->u.op.args[0], 0);
1250 break;
1252 if (expr->u.op.op == isl_ast_op_fdiv_q) {
1253 p = isl_printer_print_str(p, "floord(");
1254 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1255 p = isl_printer_print_str(p, ", ");
1256 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1257 p = isl_printer_print_str(p, ")");
1258 break;
1260 if (expr->u.op.op == isl_ast_op_max ||
1261 expr->u.op.op == isl_ast_op_min) {
1262 p = print_min_max(p, expr);
1263 break;
1265 if (expr->u.op.op == isl_ast_op_cond ||
1266 expr->u.op.op == isl_ast_op_select) {
1267 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1268 p = isl_printer_print_str(p, " ? ");
1269 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1270 p = isl_printer_print_str(p, " : ");
1271 p = isl_printer_print_ast_expr(p, expr->u.op.args[2]);
1272 break;
1274 if (expr->u.op.n_arg != 2)
1275 isl_die(isl_printer_get_ctx(p), isl_error_internal,
1276 "operation should have two arguments",
1277 goto error);
1278 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[0], 1);
1279 p = isl_printer_print_str(p, " ");
1280 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1281 p = isl_printer_print_str(p, " ");
1282 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[1], 0);
1283 break;
1284 case isl_ast_expr_id:
1285 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
1286 break;
1287 case isl_ast_expr_int:
1288 p = isl_printer_print_val(p, expr->u.v);
1289 break;
1290 case isl_ast_expr_error:
1291 break;
1294 return p;
1295 error:
1296 isl_printer_free(p);
1297 return NULL;
1300 /* Print "node" to "p" in "isl format".
1302 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
1303 __isl_keep isl_ast_node *node)
1305 p = isl_printer_print_str(p, "(");
1306 switch (node->type) {
1307 case isl_ast_node_for:
1308 if (node->u.f.degenerate) {
1309 p = isl_printer_print_ast_expr(p, node->u.f.init);
1310 } else {
1311 p = isl_printer_print_str(p, "init: ");
1312 p = isl_printer_print_ast_expr(p, node->u.f.init);
1313 p = isl_printer_print_str(p, ", ");
1314 p = isl_printer_print_str(p, "cond: ");
1315 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1316 p = isl_printer_print_str(p, ", ");
1317 p = isl_printer_print_str(p, "inc: ");
1318 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1320 if (node->u.f.body) {
1321 p = isl_printer_print_str(p, ", ");
1322 p = isl_printer_print_str(p, "body: ");
1323 p = isl_printer_print_ast_node(p, node->u.f.body);
1325 break;
1326 case isl_ast_node_user:
1327 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1328 break;
1329 case isl_ast_node_if:
1330 p = isl_printer_print_str(p, "guard: ");
1331 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1332 if (node->u.i.then) {
1333 p = isl_printer_print_str(p, ", ");
1334 p = isl_printer_print_str(p, "then: ");
1335 p = isl_printer_print_ast_node(p, node->u.i.then);
1337 if (node->u.i.else_node) {
1338 p = isl_printer_print_str(p, ", ");
1339 p = isl_printer_print_str(p, "else: ");
1340 p = isl_printer_print_ast_node(p, node->u.i.else_node);
1342 break;
1343 case isl_ast_node_block:
1344 p = isl_printer_print_ast_node_list(p, node->u.b.children);
1345 break;
1346 default:
1347 break;
1349 p = isl_printer_print_str(p, ")");
1350 return p;
1353 /* Do we need to print a block around the body "node" of a for or if node?
1355 * If the node is a block, then we need to print a block.
1356 * Also if the node is a degenerate for then we will print it as
1357 * an assignment followed by the body of the for loop, so we need a block
1358 * as well.
1360 static int need_block(__isl_keep isl_ast_node *node)
1362 if (node->type == isl_ast_node_block)
1363 return 1;
1364 if (node->type == isl_ast_node_for && node->u.f.degenerate)
1365 return 1;
1366 return 0;
1369 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1370 __isl_keep isl_ast_node *node,
1371 __isl_keep isl_ast_print_options *options, int in_block, int in_list);
1372 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1373 __isl_keep isl_ast_node *node,
1374 __isl_keep isl_ast_print_options *options, int new_line);
1376 /* Print the body "node" of a for or if node.
1377 * If "else_node" is set, then it is printed as well.
1379 * We first check if we need to print out a block.
1380 * We always print out a block if there is an else node to make
1381 * sure that the else node is matched to the correct if node.
1383 * If the else node is itself an if, then we print it as
1385 * } else if (..)
1387 * Otherwise the else node is printed as
1389 * } else
1390 * node
1392 static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
1393 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
1394 __isl_keep isl_ast_print_options *options)
1396 if (!node)
1397 return isl_printer_free(p);
1399 if (!else_node && !need_block(node)) {
1400 p = isl_printer_end_line(p);
1401 p = isl_printer_indent(p, 2);
1402 p = isl_ast_node_print(node, p,
1403 isl_ast_print_options_copy(options));
1404 p = isl_printer_indent(p, -2);
1405 return p;
1408 p = isl_printer_print_str(p, " {");
1409 p = isl_printer_end_line(p);
1410 p = isl_printer_indent(p, 2);
1411 p = print_ast_node_c(p, node, options, 1, 0);
1412 p = isl_printer_indent(p, -2);
1413 p = isl_printer_start_line(p);
1414 p = isl_printer_print_str(p, "}");
1415 if (else_node) {
1416 if (else_node->type == isl_ast_node_if) {
1417 p = isl_printer_print_str(p, " else ");
1418 p = print_if_c(p, else_node, options, 0);
1419 } else {
1420 p = isl_printer_print_str(p, " else");
1421 p = print_body_c(p, else_node, NULL, options);
1423 } else
1424 p = isl_printer_end_line(p);
1426 return p;
1429 /* Print the start of a compound statement.
1431 static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
1433 p = isl_printer_start_line(p);
1434 p = isl_printer_print_str(p, "{");
1435 p = isl_printer_end_line(p);
1436 p = isl_printer_indent(p, 2);
1438 return p;
1441 /* Print the end of a compound statement.
1443 static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
1445 p = isl_printer_indent(p, -2);
1446 p = isl_printer_start_line(p);
1447 p = isl_printer_print_str(p, "}");
1448 p = isl_printer_end_line(p);
1450 return p;
1453 /* Print the for node "node".
1455 * If the for node is degenerate, it is printed as
1457 * type iterator = init;
1458 * body
1460 * Otherwise, it is printed as
1462 * for (type iterator = init; cond; iterator += inc)
1463 * body
1465 * "in_block" is set if we are currently inside a block.
1466 * "in_list" is set if the current node is not alone in the block.
1467 * If we are not in a block or if the current not is not alone in the block
1468 * then we print a block around a degenerate for loop such that the variable
1469 * declaration will not conflict with any potential other declaration
1470 * of the same variable.
1472 static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
1473 __isl_keep isl_ast_node *node,
1474 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
1476 isl_id *id;
1477 const char *name;
1478 const char *type;
1480 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
1481 if (!node->u.f.degenerate) {
1482 id = isl_ast_expr_get_id(node->u.f.iterator);
1483 name = isl_id_get_name(id);
1484 isl_id_free(id);
1485 p = isl_printer_start_line(p);
1486 p = isl_printer_print_str(p, "for (");
1487 p = isl_printer_print_str(p, type);
1488 p = isl_printer_print_str(p, " ");
1489 p = isl_printer_print_str(p, name);
1490 p = isl_printer_print_str(p, " = ");
1491 p = isl_printer_print_ast_expr(p, node->u.f.init);
1492 p = isl_printer_print_str(p, "; ");
1493 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1494 p = isl_printer_print_str(p, "; ");
1495 p = isl_printer_print_str(p, name);
1496 p = isl_printer_print_str(p, " += ");
1497 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1498 p = isl_printer_print_str(p, ")");
1499 p = print_body_c(p, node->u.f.body, NULL, options);
1500 } else {
1501 id = isl_ast_expr_get_id(node->u.f.iterator);
1502 name = isl_id_get_name(id);
1503 isl_id_free(id);
1504 if (!in_block || in_list)
1505 p = start_block(p);
1506 p = isl_printer_start_line(p);
1507 p = isl_printer_print_str(p, type);
1508 p = isl_printer_print_str(p, " ");
1509 p = isl_printer_print_str(p, name);
1510 p = isl_printer_print_str(p, " = ");
1511 p = isl_printer_print_ast_expr(p, node->u.f.init);
1512 p = isl_printer_print_str(p, ";");
1513 p = isl_printer_end_line(p);
1514 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
1515 if (!in_block || in_list)
1516 p = end_block(p);
1519 return p;
1522 /* Print the if node "node".
1523 * If "new_line" is set then the if node should be printed on a new line.
1525 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1526 __isl_keep isl_ast_node *node,
1527 __isl_keep isl_ast_print_options *options, int new_line)
1529 if (new_line)
1530 p = isl_printer_start_line(p);
1531 p = isl_printer_print_str(p, "if (");
1532 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1533 p = isl_printer_print_str(p, ")");
1534 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options);
1536 return p;
1539 /* Print the "node" to "p".
1541 * "in_block" is set if we are currently inside a block.
1542 * If so, we do not print a block around the children of a block node.
1543 * We do this to avoid an extra block around the body of a degenerate
1544 * for node.
1546 * "in_list" is set if the current node is not alone in the block.
1548 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1549 __isl_keep isl_ast_node *node,
1550 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
1552 switch (node->type) {
1553 case isl_ast_node_for:
1554 if (options->print_for)
1555 return options->print_for(p,
1556 isl_ast_print_options_copy(options),
1557 node, options->print_for_user);
1558 p = print_for_c(p, node, options, in_block, in_list);
1559 break;
1560 case isl_ast_node_if:
1561 p = print_if_c(p, node, options, 1);
1562 break;
1563 case isl_ast_node_block:
1564 if (!in_block)
1565 p = start_block(p);
1566 p = isl_ast_node_list_print(node->u.b.children, p, options);
1567 if (!in_block)
1568 p = end_block(p);
1569 break;
1570 case isl_ast_node_user:
1571 if (options->print_user)
1572 return options->print_user(p,
1573 isl_ast_print_options_copy(options),
1574 node, options->print_user_user);
1575 p = isl_printer_start_line(p);
1576 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1577 p = isl_printer_print_str(p, ";");
1578 p = isl_printer_end_line(p);
1579 break;
1580 case isl_ast_node_error:
1581 break;
1583 return p;
1586 /* Print the for node "node" to "p".
1588 __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
1589 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1591 if (!node || !options)
1592 goto error;
1593 if (node->type != isl_ast_node_for)
1594 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1595 "not a for node", goto error);
1596 p = print_for_c(p, node, options, 0, 0);
1597 isl_ast_print_options_free(options);
1598 return p;
1599 error:
1600 isl_ast_print_options_free(options);
1601 isl_printer_free(p);
1602 return NULL;
1605 /* Print the if node "node" to "p".
1607 __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
1608 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1610 if (!node || !options)
1611 goto error;
1612 if (node->type != isl_ast_node_if)
1613 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1614 "not an if node", goto error);
1615 p = print_if_c(p, node, options, 1);
1616 isl_ast_print_options_free(options);
1617 return p;
1618 error:
1619 isl_ast_print_options_free(options);
1620 isl_printer_free(p);
1621 return NULL;
1624 /* Print "node" to "p".
1626 __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
1627 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1629 if (!options || !node)
1630 goto error;
1631 p = print_ast_node_c(p, node, options, 0, 0);
1632 isl_ast_print_options_free(options);
1633 return p;
1634 error:
1635 isl_ast_print_options_free(options);
1636 isl_printer_free(p);
1637 return NULL;
1640 /* Print "node" to "p".
1642 __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
1643 __isl_keep isl_ast_node *node)
1645 int format;
1646 isl_ast_print_options *options;
1648 if (!p)
1649 return NULL;
1651 format = isl_printer_get_output_format(p);
1652 switch (format) {
1653 case ISL_FORMAT_ISL:
1654 p = print_ast_node_isl(p, node);
1655 break;
1656 case ISL_FORMAT_C:
1657 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
1658 p = isl_ast_node_print(node, p, options);
1659 break;
1660 default:
1661 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
1662 "output format not supported for ast_node",
1663 return isl_printer_free(p));
1666 return p;
1669 /* Print the list of nodes "list" to "p".
1671 __isl_give isl_printer *isl_ast_node_list_print(
1672 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
1673 __isl_keep isl_ast_print_options *options)
1675 int i;
1677 if (!p || !list || !options)
1678 return isl_printer_free(p);
1680 for (i = 0; i < list->n; ++i)
1681 p = print_ast_node_c(p, list->p[i], options, 1, 1);
1683 return p;
1686 #define ISL_AST_MACRO_FLOORD (1 << 0)
1687 #define ISL_AST_MACRO_MIN (1 << 1)
1688 #define ISL_AST_MACRO_MAX (1 << 2)
1689 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FLOORD | \
1690 ISL_AST_MACRO_MIN | \
1691 ISL_AST_MACRO_MAX)
1693 /* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1694 * then set the corresponding bit in "macros".
1696 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
1698 int i;
1700 if (macros == ISL_AST_MACRO_ALL)
1701 return macros;
1703 if (expr->type != isl_ast_expr_op)
1704 return macros;
1706 if (expr->u.op.op == isl_ast_op_min)
1707 macros |= ISL_AST_MACRO_MIN;
1708 if (expr->u.op.op == isl_ast_op_max)
1709 macros |= ISL_AST_MACRO_MAX;
1710 if (expr->u.op.op == isl_ast_op_fdiv_q)
1711 macros |= ISL_AST_MACRO_FLOORD;
1713 for (i = 0; i < expr->u.op.n_arg; ++i)
1714 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
1716 return macros;
1719 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1720 int macros);
1722 /* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1723 * then set the corresponding bit in "macros".
1725 static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
1727 if (macros == ISL_AST_MACRO_ALL)
1728 return macros;
1730 switch (node->type) {
1731 case isl_ast_node_for:
1732 macros = ast_expr_required_macros(node->u.f.init, macros);
1733 if (!node->u.f.degenerate) {
1734 macros = ast_expr_required_macros(node->u.f.cond,
1735 macros);
1736 macros = ast_expr_required_macros(node->u.f.inc,
1737 macros);
1739 macros = ast_node_required_macros(node->u.f.body, macros);
1740 break;
1741 case isl_ast_node_if:
1742 macros = ast_expr_required_macros(node->u.i.guard, macros);
1743 macros = ast_node_required_macros(node->u.i.then, macros);
1744 if (node->u.i.else_node)
1745 macros = ast_node_required_macros(node->u.i.else_node,
1746 macros);
1747 break;
1748 case isl_ast_node_block:
1749 macros = ast_node_list_required_macros(node->u.b.children,
1750 macros);
1751 break;
1752 case isl_ast_node_user:
1753 macros = ast_expr_required_macros(node->u.e.expr, macros);
1754 break;
1755 case isl_ast_node_error:
1756 break;
1759 return macros;
1762 /* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1763 * then set the corresponding bit in "macros".
1765 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1766 int macros)
1768 int i;
1770 for (i = 0; i < list->n; ++i)
1771 macros = ast_node_required_macros(list->p[i], macros);
1773 return macros;
1776 /* Print a macro definition for the operator "type".
1778 __isl_give isl_printer *isl_ast_op_type_print_macro(
1779 enum isl_ast_op_type type, __isl_take isl_printer *p)
1781 switch (type) {
1782 case isl_ast_op_min:
1783 p = isl_printer_start_line(p);
1784 p = isl_printer_print_str(p,
1785 "#define min(x,y) ((x) < (y) ? (x) : (y))");
1786 p = isl_printer_end_line(p);
1787 break;
1788 case isl_ast_op_max:
1789 p = isl_printer_start_line(p);
1790 p = isl_printer_print_str(p,
1791 "#define max(x,y) ((x) > (y) ? (x) : (y))");
1792 p = isl_printer_end_line(p);
1793 break;
1794 case isl_ast_op_fdiv_q:
1795 p = isl_printer_start_line(p);
1796 p = isl_printer_print_str(p,
1797 "#define floord(n,d) "
1798 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
1799 p = isl_printer_end_line(p);
1800 break;
1801 default:
1802 break;
1805 return p;
1808 /* Call "fn" for each type of operation that appears in "node"
1809 * and that requires a macro definition.
1811 int isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
1812 int (*fn)(enum isl_ast_op_type type, void *user), void *user)
1814 int macros;
1816 if (!node)
1817 return -1;
1819 macros = ast_node_required_macros(node, 0);
1821 if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0)
1822 return -1;
1823 if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0)
1824 return -1;
1825 if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0)
1826 return -1;
1828 return 0;
1831 static int ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
1833 isl_printer **p = user;
1835 *p = isl_ast_op_type_print_macro(type, *p);
1837 return 0;
1840 /* Print macro definitions for all the macros used in the result
1841 * of printing "node.
1843 __isl_give isl_printer *isl_ast_node_print_macros(
1844 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
1846 if (isl_ast_node_foreach_ast_op_type(node,
1847 &ast_op_type_print_macro, &p) < 0)
1848 return isl_printer_free(p);
1849 return p;