add isl_ast_expr_from_val
[isl.git] / isl_ast.c
blob385ea7381a6d14758a236bafadcdbadfa2ff149e
1 #include <isl_ast_private.h>
2 #include <isl/val_int.h>
4 #undef BASE
5 #define BASE ast_expr
7 #include <isl_list_templ.c>
9 #undef BASE
10 #define BASE ast_node
12 #include <isl_list_templ.c>
14 isl_ctx *isl_ast_print_options_get_ctx(
15 __isl_keep isl_ast_print_options *options)
17 return options ? options->ctx : NULL;
20 __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
22 isl_ast_print_options *options;
24 options = isl_calloc_type(ctx, isl_ast_print_options);
25 if (!options)
26 return NULL;
28 options->ctx = ctx;
29 isl_ctx_ref(ctx);
30 options->ref = 1;
32 return options;
35 __isl_give isl_ast_print_options *isl_ast_print_options_dup(
36 __isl_keep isl_ast_print_options *options)
38 isl_ctx *ctx;
39 isl_ast_print_options *dup;
41 if (!options)
42 return NULL;
44 ctx = isl_ast_print_options_get_ctx(options);
45 dup = isl_ast_print_options_alloc(ctx);
46 if (!dup)
47 return NULL;
49 dup->print_for = options->print_for;
50 dup->print_for_user = options->print_for_user;
51 dup->print_user = options->print_user;
52 dup->print_user_user = options->print_user_user;
54 return dup;
57 __isl_give isl_ast_print_options *isl_ast_print_options_cow(
58 __isl_take isl_ast_print_options *options)
60 if (!options)
61 return NULL;
63 if (options->ref == 1)
64 return options;
65 options->ref--;
66 return isl_ast_print_options_dup(options);
69 __isl_give isl_ast_print_options *isl_ast_print_options_copy(
70 __isl_keep isl_ast_print_options *options)
72 if (!options)
73 return NULL;
75 options->ref++;
76 return options;
79 void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options)
81 if (!options)
82 return NULL;
84 if (--options->ref > 0)
85 return NULL;
87 isl_ctx_deref(options->ctx);
89 free(options);
90 return NULL;
93 /* Set the print_user callback of "options" to "print_user".
95 * If this callback is set, then it used to print user nodes in the AST.
96 * Otherwise, the expression associated to the user node is printed.
98 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
99 __isl_take isl_ast_print_options *options,
100 __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
101 __isl_take isl_ast_print_options *options,
102 __isl_keep isl_ast_node *node, void *user),
103 void *user)
105 options = isl_ast_print_options_cow(options);
106 if (!options)
107 return NULL;
109 options->print_user = print_user;
110 options->print_user_user = user;
112 return options;
115 /* Set the print_for callback of "options" to "print_for".
117 * If this callback is set, then it used to print for nodes in the AST.
119 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
120 __isl_take isl_ast_print_options *options,
121 __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
122 __isl_take isl_ast_print_options *options,
123 __isl_keep isl_ast_node *node, void *user),
124 void *user)
126 options = isl_ast_print_options_cow(options);
127 if (!options)
128 return NULL;
130 options->print_for = print_for;
131 options->print_for_user = user;
133 return options;
136 __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
138 if (!expr)
139 return NULL;
141 expr->ref++;
142 return expr;
145 __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
147 int i;
148 isl_ctx *ctx;
149 isl_ast_expr *dup;
151 if (!expr)
152 return NULL;
154 ctx = isl_ast_expr_get_ctx(expr);
155 switch (expr->type) {
156 case isl_ast_expr_int:
157 dup = isl_ast_expr_alloc_int(ctx, expr->u.i);
158 break;
159 case isl_ast_expr_id:
160 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
161 break;
162 case isl_ast_expr_op:
163 dup = isl_ast_expr_alloc_op(ctx,
164 expr->u.op.op, expr->u.op.n_arg);
165 if (!dup)
166 return NULL;
167 for (i = 0; i < expr->u.op.n_arg; ++i)
168 dup->u.op.args[i] =
169 isl_ast_expr_copy(expr->u.op.args[i]);
170 break;
171 case isl_ast_expr_error:
172 dup = NULL;
175 if (!dup)
176 return NULL;
178 return dup;
181 __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
183 if (!expr)
184 return NULL;
186 if (expr->ref == 1)
187 return expr;
188 expr->ref--;
189 return isl_ast_expr_dup(expr);
192 void *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
194 int i;
196 if (!expr)
197 return NULL;
199 if (--expr->ref > 0)
200 return NULL;
202 isl_ctx_deref(expr->ctx);
204 switch (expr->type) {
205 case isl_ast_expr_int:
206 isl_int_clear(expr->u.i);
207 break;
208 case isl_ast_expr_id:
209 isl_id_free(expr->u.id);
210 break;
211 case isl_ast_expr_op:
212 for (i = 0; i < expr->u.op.n_arg; ++i)
213 isl_ast_expr_free(expr->u.op.args[i]);
214 free(expr->u.op.args);
215 break;
216 case isl_ast_expr_error:
217 break;
220 free(expr);
221 return NULL;
224 isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
226 return expr ? expr->ctx : NULL;
229 enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
231 return expr ? expr->type : isl_ast_expr_error;
234 int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v)
236 if (!expr)
237 return -1;
238 if (expr->type != isl_ast_expr_int)
239 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
240 "expression not an int", return -1);
241 isl_int_set(*v, expr->u.i);
242 return 0;
245 /* Return the integer value represented by "expr".
247 __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
249 isl_ctx *ctx;
251 if (!expr)
252 return NULL;
253 ctx = isl_ast_expr_get_ctx(expr);
254 if (expr->type != isl_ast_expr_int)
255 isl_die(ctx, isl_error_invalid,
256 "expression not an int", return NULL);
257 return isl_val_int_from_isl_int(ctx, expr->u.i);
260 __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
262 if (!expr)
263 return NULL;
264 if (expr->type != isl_ast_expr_id)
265 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
266 "expression not an identifier", return NULL);
268 return isl_id_copy(expr->u.id);
271 enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
273 if (!expr)
274 return isl_ast_op_error;
275 if (expr->type != isl_ast_expr_op)
276 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
277 "expression not an operation", return isl_ast_op_error);
278 return expr->u.op.op;
281 int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
283 if (!expr)
284 return -1;
285 if (expr->type != isl_ast_expr_op)
286 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
287 "expression not an operation", return -1);
288 return expr->u.op.n_arg;
291 __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
292 int pos)
294 if (!expr)
295 return NULL;
296 if (expr->type != isl_ast_expr_op)
297 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
298 "expression not an operation", return NULL);
299 if (pos < 0 || pos >= expr->u.op.n_arg)
300 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
301 "index out of bounds", return NULL);
303 return isl_ast_expr_copy(expr->u.op.args[pos]);
306 /* Replace the argument at position "pos" of "expr" by "arg".
308 __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
309 int pos, __isl_take isl_ast_expr *arg)
311 expr = isl_ast_expr_cow(expr);
312 if (!expr || !arg)
313 goto error;
314 if (expr->type != isl_ast_expr_op)
315 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
316 "expression not an operation", goto error);
317 if (pos < 0 || pos >= expr->u.op.n_arg)
318 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
319 "index out of bounds", goto error);
321 isl_ast_expr_free(expr->u.op.args[pos]);
322 expr->u.op.args[pos] = arg;
324 return expr;
325 error:
326 isl_ast_expr_free(arg);
327 return isl_ast_expr_free(expr);
330 /* Create a new operation expression of operation type "op",
331 * with "n_arg" as yet unspecified arguments.
333 __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
334 enum isl_ast_op_type op, int n_arg)
336 isl_ast_expr *expr;
338 expr = isl_calloc_type(ctx, isl_ast_expr);
339 if (!expr)
340 return NULL;
342 expr->ctx = ctx;
343 isl_ctx_ref(ctx);
344 expr->ref = 1;
345 expr->type = isl_ast_expr_op;
346 expr->u.op.op = op;
347 expr->u.op.n_arg = n_arg;
348 expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg);
350 if (!expr->u.op.args)
351 return isl_ast_expr_free(expr);
353 return expr;
356 /* Create a new id expression representing "id".
358 __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
360 isl_ctx *ctx;
361 isl_ast_expr *expr;
363 if (!id)
364 return NULL;
366 ctx = isl_id_get_ctx(id);
367 expr = isl_calloc_type(ctx, isl_ast_expr);
368 if (!expr)
369 return isl_id_free(id);
371 expr->ctx = ctx;
372 isl_ctx_ref(ctx);
373 expr->ref = 1;
374 expr->type = isl_ast_expr_id;
375 expr->u.id = id;
377 return expr;
380 /* Create a new integer expression representing "i".
382 __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
384 isl_ast_expr *expr;
386 expr = isl_calloc_type(ctx, isl_ast_expr);
387 if (!expr)
388 return NULL;
390 expr->ctx = ctx;
391 isl_ctx_ref(ctx);
392 expr->ref = 1;
393 expr->type = isl_ast_expr_int;
395 isl_int_init(expr->u.i);
396 isl_int_set_si(expr->u.i, i);
398 return expr;
401 /* Create a new integer expression representing "i".
403 __isl_give isl_ast_expr *isl_ast_expr_alloc_int(isl_ctx *ctx, isl_int i)
405 isl_ast_expr *expr;
407 expr = isl_calloc_type(ctx, isl_ast_expr);
408 if (!expr)
409 return NULL;
411 expr->ctx = ctx;
412 isl_ctx_ref(ctx);
413 expr->ref = 1;
414 expr->type = isl_ast_expr_int;
416 isl_int_init(expr->u.i);
417 isl_int_set(expr->u.i, i);
419 return expr;
422 /* Create a new integer expression representing "v".
424 __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
426 isl_ctx *ctx;
427 isl_ast_expr *expr;
429 if (!v)
430 return NULL;
431 if (!isl_val_is_int(v))
432 isl_die(isl_val_get_ctx(v), isl_error_invalid,
433 "expecting integer value", return isl_val_free(v));
435 ctx = isl_val_get_ctx(v);
436 expr = isl_calloc_type(ctx, isl_ast_expr);
437 if (!expr)
438 return isl_val_free(v);
440 expr->ctx = ctx;
441 isl_ctx_ref(ctx);
442 expr->ref = 1;
443 expr->type = isl_ast_expr_int;
445 isl_int_init(expr->u.i);
446 isl_int_set(expr->u.i, v->n);
448 isl_val_free(v);
449 return expr;
452 /* Create an expression representing the negation of "arg".
454 __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
456 isl_ctx *ctx;
457 isl_ast_expr *expr = NULL;
459 if (!arg)
460 return NULL;
462 ctx = isl_ast_expr_get_ctx(arg);
463 expr = isl_ast_expr_alloc_op(ctx, isl_ast_op_minus, 1);
464 if (!expr)
465 goto error;
467 expr->u.op.args[0] = arg;
469 return expr;
470 error:
471 isl_ast_expr_free(arg);
472 return NULL;
475 /* Create an expression representing the binary operation "type"
476 * applied to "expr1" and "expr2".
478 __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
479 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
481 isl_ctx *ctx;
482 isl_ast_expr *expr = NULL;
484 if (!expr1 || !expr2)
485 goto error;
487 ctx = isl_ast_expr_get_ctx(expr1);
488 expr = isl_ast_expr_alloc_op(ctx, type, 2);
489 if (!expr)
490 goto error;
492 expr->u.op.args[0] = expr1;
493 expr->u.op.args[1] = expr2;
495 return expr;
496 error:
497 isl_ast_expr_free(expr1);
498 isl_ast_expr_free(expr2);
499 return NULL;
502 /* Create an expression representing the sum of "expr1" and "expr2".
504 __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
505 __isl_take isl_ast_expr *expr2)
507 return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
510 /* Create an expression representing the difference of "expr1" and "expr2".
512 __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
513 __isl_take isl_ast_expr *expr2)
515 return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
518 /* Create an expression representing the product of "expr1" and "expr2".
520 __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
521 __isl_take isl_ast_expr *expr2)
523 return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
526 /* Create an expression representing the quotient of "expr1" and "expr2".
528 __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
529 __isl_take isl_ast_expr *expr2)
531 return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
534 /* Create an expression representing the conjunction of "expr1" and "expr2".
536 __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
537 __isl_take isl_ast_expr *expr2)
539 return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
542 /* Create an expression representing the disjunction of "expr1" and "expr2".
544 __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
545 __isl_take isl_ast_expr *expr2)
547 return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
550 isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
552 return node ? node->ctx : NULL;
555 enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
557 return node ? node->type : isl_ast_node_error;
560 __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
561 enum isl_ast_node_type type)
563 isl_ast_node *node;
565 node = isl_calloc_type(ctx, isl_ast_node);
566 if (!node)
567 return NULL;
569 node->ctx = ctx;
570 isl_ctx_ref(ctx);
571 node->ref = 1;
572 node->type = type;
574 return node;
577 /* Create an if node with the given guard.
579 * The then body needs to be filled in later.
581 __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
583 isl_ast_node *node;
585 if (!guard)
586 return NULL;
588 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
589 if (!node)
590 goto error;
591 node->u.i.guard = guard;
593 return node;
594 error:
595 isl_ast_expr_free(guard);
596 return NULL;
599 /* Create a for node with the given iterator.
601 * The remaining fields need to be filled in later.
603 __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
605 isl_ast_node *node;
606 isl_ctx *ctx;
608 if (!id)
609 return NULL;
611 ctx = isl_id_get_ctx(id);
612 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
613 if (!node)
614 return NULL;
616 node->u.f.iterator = isl_ast_expr_from_id(id);
617 if (!node->u.f.iterator)
618 return isl_ast_node_free(node);
620 return node;
623 /* Create a user node evaluating "expr".
625 __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
627 isl_ctx *ctx;
628 isl_ast_node *node;
630 if (!expr)
631 return NULL;
633 ctx = isl_ast_expr_get_ctx(expr);
634 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
635 if (!node)
636 goto error;
638 node->u.e.expr = expr;
640 return node;
641 error:
642 isl_ast_expr_free(expr);
643 return NULL;
646 /* Create a block node with the given children.
648 __isl_give isl_ast_node *isl_ast_node_alloc_block(
649 __isl_take isl_ast_node_list *list)
651 isl_ast_node *node;
652 isl_ctx *ctx;
654 if (!list)
655 return NULL;
657 ctx = isl_ast_node_list_get_ctx(list);
658 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
659 if (!node)
660 goto error;
662 node->u.b.children = list;
664 return node;
665 error:
666 isl_ast_node_list_free(list);
667 return NULL;
670 /* Represent the given list of nodes as a single node, either by
671 * extract the node from a single element list or by creating
672 * a block node with the list of nodes as children.
674 __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
675 __isl_take isl_ast_node_list *list)
677 isl_ast_node *node;
679 if (isl_ast_node_list_n_ast_node(list) != 1)
680 return isl_ast_node_alloc_block(list);
682 node = isl_ast_node_list_get_ast_node(list, 0);
683 isl_ast_node_list_free(list);
685 return node;
688 __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
690 if (!node)
691 return NULL;
693 node->ref++;
694 return node;
697 __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
699 isl_ast_node *dup;
701 if (!node)
702 return NULL;
704 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
705 if (!dup)
706 return NULL;
708 switch (node->type) {
709 case isl_ast_node_if:
710 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
711 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
712 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
713 if (!dup->u.i.guard || !dup->u.i.then ||
714 (node->u.i.else_node && !dup->u.i.else_node))
715 return isl_ast_node_free(dup);
716 break;
717 case isl_ast_node_for:
718 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
719 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
720 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
721 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
722 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
723 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
724 !dup->u.f.inc || !dup->u.f.body)
725 return isl_ast_node_free(dup);
726 break;
727 case isl_ast_node_block:
728 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
729 if (!dup->u.b.children)
730 return isl_ast_node_free(dup);
731 break;
732 case isl_ast_node_user:
733 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
734 if (!dup->u.e.expr)
735 return isl_ast_node_free(dup);
736 break;
737 case isl_ast_node_error:
738 break;
741 return dup;
744 __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
746 if (!node)
747 return NULL;
749 if (node->ref == 1)
750 return node;
751 node->ref--;
752 return isl_ast_node_dup(node);
755 void *isl_ast_node_free(__isl_take isl_ast_node *node)
757 if (!node)
758 return NULL;
760 if (--node->ref > 0)
761 return NULL;
763 switch (node->type) {
764 case isl_ast_node_if:
765 isl_ast_expr_free(node->u.i.guard);
766 isl_ast_node_free(node->u.i.then);
767 isl_ast_node_free(node->u.i.else_node);
768 break;
769 case isl_ast_node_for:
770 isl_ast_expr_free(node->u.f.iterator);
771 isl_ast_expr_free(node->u.f.init);
772 isl_ast_expr_free(node->u.f.cond);
773 isl_ast_expr_free(node->u.f.inc);
774 isl_ast_node_free(node->u.f.body);
775 break;
776 case isl_ast_node_block:
777 isl_ast_node_list_free(node->u.b.children);
778 break;
779 case isl_ast_node_user:
780 isl_ast_expr_free(node->u.e.expr);
781 break;
782 case isl_ast_node_error:
783 break;
786 isl_id_free(node->annotation);
787 isl_ctx_deref(node->ctx);
788 free(node);
790 return NULL;
793 /* Replace the body of the for node "node" by "body".
795 __isl_give isl_ast_node *isl_ast_node_for_set_body(
796 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
798 node = isl_ast_node_cow(node);
799 if (!node || !body)
800 goto error;
801 if (node->type != isl_ast_node_for)
802 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
803 "not a for node", goto error);
805 isl_ast_node_free(node->u.f.body);
806 node->u.f.body = body;
808 return node;
809 error:
810 isl_ast_node_free(node);
811 isl_ast_node_free(body);
812 return NULL;
815 __isl_give isl_ast_node *isl_ast_node_for_get_body(
816 __isl_keep isl_ast_node *node)
818 if (!node)
819 return NULL;
820 if (node->type != isl_ast_node_for)
821 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
822 "not a for node", return NULL);
823 return isl_ast_node_copy(node->u.f.body);
826 /* Mark the given for node as being degenerate.
828 __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
829 __isl_take isl_ast_node *node)
831 node = isl_ast_node_cow(node);
832 if (!node)
833 return NULL;
834 node->u.f.degenerate = 1;
835 return node;
838 int isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
840 if (!node)
841 return -1;
842 if (node->type != isl_ast_node_for)
843 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
844 "not a for node", return -1);
845 return node->u.f.degenerate;
848 __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
849 __isl_keep isl_ast_node *node)
851 if (!node)
852 return NULL;
853 if (node->type != isl_ast_node_for)
854 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
855 "not a for node", return NULL);
856 return isl_ast_expr_copy(node->u.f.iterator);
859 __isl_give isl_ast_expr *isl_ast_node_for_get_init(
860 __isl_keep isl_ast_node *node)
862 if (!node)
863 return NULL;
864 if (node->type != isl_ast_node_for)
865 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
866 "not a for node", return NULL);
867 return isl_ast_expr_copy(node->u.f.init);
870 /* Return the condition expression of the given for node.
872 * If the for node is degenerate, then the condition is not explicitly
873 * stored in the node. Instead, it is constructed as
875 * iterator <= init
877 __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
878 __isl_keep isl_ast_node *node)
880 if (!node)
881 return NULL;
882 if (node->type != isl_ast_node_for)
883 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
884 "not a for node", return NULL);
885 if (!node->u.f.degenerate)
886 return isl_ast_expr_copy(node->u.f.cond);
888 return isl_ast_expr_alloc_binary(isl_ast_op_le,
889 isl_ast_expr_copy(node->u.f.iterator),
890 isl_ast_expr_copy(node->u.f.init));
893 /* Return the increment of the given for node.
895 * If the for node is degenerate, then the increment is not explicitly
896 * stored in the node. We simply return "1".
898 __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
899 __isl_keep isl_ast_node *node)
901 if (!node)
902 return NULL;
903 if (node->type != isl_ast_node_for)
904 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
905 "not a for node", return NULL);
906 if (!node->u.f.degenerate)
907 return isl_ast_expr_copy(node->u.f.inc);
908 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
911 /* Replace the then branch of the if node "node" by "child".
913 __isl_give isl_ast_node *isl_ast_node_if_set_then(
914 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
916 node = isl_ast_node_cow(node);
917 if (!node || !child)
918 goto error;
919 if (node->type != isl_ast_node_if)
920 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
921 "not an if node", goto error);
923 isl_ast_node_free(node->u.i.then);
924 node->u.i.then = child;
926 return node;
927 error:
928 isl_ast_node_free(node);
929 isl_ast_node_free(child);
930 return NULL;
933 __isl_give isl_ast_node *isl_ast_node_if_get_then(
934 __isl_keep isl_ast_node *node)
936 if (!node)
937 return NULL;
938 if (node->type != isl_ast_node_if)
939 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
940 "not an if node", return NULL);
941 return isl_ast_node_copy(node->u.i.then);
944 int isl_ast_node_if_has_else(
945 __isl_keep isl_ast_node *node)
947 if (!node)
948 return -1;
949 if (node->type != isl_ast_node_if)
950 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
951 "not an if node", return -1);
952 return node->u.i.else_node != NULL;
955 __isl_give isl_ast_node *isl_ast_node_if_get_else(
956 __isl_keep isl_ast_node *node)
958 if (!node)
959 return NULL;
960 if (node->type != isl_ast_node_if)
961 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
962 "not an if node", return NULL);
963 return isl_ast_node_copy(node->u.i.else_node);
966 __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
967 __isl_keep isl_ast_node *node)
969 if (!node)
970 return NULL;
971 if (node->type != isl_ast_node_if)
972 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
973 "not a guard node", return NULL);
974 return isl_ast_expr_copy(node->u.i.guard);
977 __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
978 __isl_keep isl_ast_node *node)
980 if (!node)
981 return NULL;
982 if (node->type != isl_ast_node_block)
983 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
984 "not a block node", return NULL);
985 return isl_ast_node_list_copy(node->u.b.children);
988 __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
989 __isl_keep isl_ast_node *node)
991 if (!node)
992 return NULL;
994 return isl_ast_expr_copy(node->u.e.expr);
997 __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
999 return node ? isl_id_copy(node->annotation) : NULL;
1002 /* Replace node->annotation by "annotation".
1004 __isl_give isl_ast_node *isl_ast_node_set_annotation(
1005 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1007 node = isl_ast_node_cow(node);
1008 if (!node || !annotation)
1009 goto error;
1011 isl_id_free(node->annotation);
1012 node->annotation = annotation;
1014 return node;
1015 error:
1016 isl_id_free(annotation);
1017 return isl_ast_node_free(node);
1020 /* Textual C representation of the various operators.
1022 static char *op_str[] = {
1023 [isl_ast_op_and] = "&&",
1024 [isl_ast_op_and_then] = "&&",
1025 [isl_ast_op_or] = "||",
1026 [isl_ast_op_or_else] = "||",
1027 [isl_ast_op_max] = "max",
1028 [isl_ast_op_min] = "min",
1029 [isl_ast_op_minus] = "-",
1030 [isl_ast_op_add] = "+",
1031 [isl_ast_op_sub] = "-",
1032 [isl_ast_op_mul] = "*",
1033 [isl_ast_op_pdiv_q] = "/",
1034 [isl_ast_op_pdiv_r] = "%",
1035 [isl_ast_op_div] = "/",
1036 [isl_ast_op_eq] = "==",
1037 [isl_ast_op_le] = "<=",
1038 [isl_ast_op_ge] = ">=",
1039 [isl_ast_op_lt] = "<",
1040 [isl_ast_op_gt] = ">"
1043 /* Precedence in C of the various operators.
1044 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1045 * Lowest value means highest precedence.
1047 static int op_prec[] = {
1048 [isl_ast_op_and] = 13,
1049 [isl_ast_op_and_then] = 13,
1050 [isl_ast_op_or] = 14,
1051 [isl_ast_op_or_else] = 14,
1052 [isl_ast_op_max] = 2,
1053 [isl_ast_op_min] = 2,
1054 [isl_ast_op_minus] = 3,
1055 [isl_ast_op_add] = 6,
1056 [isl_ast_op_sub] = 6,
1057 [isl_ast_op_mul] = 5,
1058 [isl_ast_op_div] = 5,
1059 [isl_ast_op_fdiv_q] = 2,
1060 [isl_ast_op_pdiv_q] = 5,
1061 [isl_ast_op_pdiv_r] = 5,
1062 [isl_ast_op_cond] = 15,
1063 [isl_ast_op_select] = 15,
1064 [isl_ast_op_eq] = 9,
1065 [isl_ast_op_le] = 8,
1066 [isl_ast_op_ge] = 8,
1067 [isl_ast_op_lt] = 8,
1068 [isl_ast_op_gt] = 8,
1069 [isl_ast_op_call] = 2
1072 /* Is the operator left-to-right associative?
1074 static int op_left[] = {
1075 [isl_ast_op_and] = 1,
1076 [isl_ast_op_and_then] = 1,
1077 [isl_ast_op_or] = 1,
1078 [isl_ast_op_or_else] = 1,
1079 [isl_ast_op_max] = 1,
1080 [isl_ast_op_min] = 1,
1081 [isl_ast_op_minus] = 0,
1082 [isl_ast_op_add] = 1,
1083 [isl_ast_op_sub] = 1,
1084 [isl_ast_op_mul] = 1,
1085 [isl_ast_op_div] = 1,
1086 [isl_ast_op_fdiv_q] = 1,
1087 [isl_ast_op_pdiv_q] = 1,
1088 [isl_ast_op_pdiv_r] = 1,
1089 [isl_ast_op_cond] = 0,
1090 [isl_ast_op_select] = 0,
1091 [isl_ast_op_eq] = 1,
1092 [isl_ast_op_le] = 1,
1093 [isl_ast_op_ge] = 1,
1094 [isl_ast_op_lt] = 1,
1095 [isl_ast_op_gt] = 1,
1096 [isl_ast_op_call] = 1
1099 static int is_and(enum isl_ast_op_type op)
1101 return op == isl_ast_op_and || op == isl_ast_op_and_then;
1104 static int is_or(enum isl_ast_op_type op)
1106 return op == isl_ast_op_or || op == isl_ast_op_or_else;
1109 static int is_add_sub(enum isl_ast_op_type op)
1111 return op == isl_ast_op_add || op == isl_ast_op_sub;
1114 static int is_div_mod(enum isl_ast_op_type op)
1116 return op == isl_ast_op_div || op == isl_ast_op_pdiv_r;
1119 /* Do we need/want parentheses around "expr" as a subexpression of
1120 * an "op" operation? If "left" is set, then "expr" is the left-most
1121 * operand.
1123 * We only need parentheses if "expr" represents an operation.
1125 * If op has a higher precedence than expr->u.op.op, then we need
1126 * parentheses.
1127 * If op and expr->u.op.op have the same precedence, but the operations
1128 * are performed in an order that is different from the associativity,
1129 * then we need parentheses.
1131 * An and inside an or technically does not require parentheses,
1132 * but some compilers complain about that, so we add them anyway.
1134 * Computations such as "a / b * c" and "a % b + c" can be somewhat
1135 * difficult to read, so we add parentheses for those as well.
1137 static int sub_expr_need_parens(enum isl_ast_op_type op,
1138 __isl_keep isl_ast_expr *expr, int left)
1140 if (expr->type != isl_ast_expr_op)
1141 return 0;
1143 if (op_prec[expr->u.op.op] > op_prec[op])
1144 return 1;
1145 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
1146 return 1;
1148 if (is_or(op) && is_and(expr->u.op.op))
1149 return 1;
1150 if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
1151 op_prec[expr->u.op.op] == op_prec[op])
1152 return 1;
1153 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
1154 return 1;
1156 return 0;
1159 /* Print "expr" as a subexpression of an "op" operation.
1160 * If "left" is set, then "expr" is the left-most operand.
1162 static __isl_give isl_printer *print_sub_expr(__isl_take isl_printer *p,
1163 enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
1165 int need_parens;
1167 need_parens = sub_expr_need_parens(op, expr, left);
1169 if (need_parens)
1170 p = isl_printer_print_str(p, "(");
1171 p = isl_printer_print_ast_expr(p, expr);
1172 if (need_parens)
1173 p = isl_printer_print_str(p, ")");
1174 return p;
1177 /* Print a min or max reduction "expr".
1179 static __isl_give isl_printer *print_min_max(__isl_take isl_printer *p,
1180 __isl_keep isl_ast_expr *expr)
1182 int i = 0;
1184 for (i = 1; i < expr->u.op.n_arg; ++i) {
1185 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1186 p = isl_printer_print_str(p, "(");
1188 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1189 for (i = 1; i < expr->u.op.n_arg; ++i) {
1190 p = isl_printer_print_str(p, ", ");
1191 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1192 p = isl_printer_print_str(p, ")");
1195 return p;
1198 /* Print a function call "expr".
1200 * The first argument represents the function to be called.
1202 static __isl_give isl_printer *print_call(__isl_take isl_printer *p,
1203 __isl_keep isl_ast_expr *expr)
1205 int i = 0;
1207 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1208 p = isl_printer_print_str(p, "(");
1209 for (i = 1; i < expr->u.op.n_arg; ++i) {
1210 if (i != 1)
1211 p = isl_printer_print_str(p, ", ");
1212 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1214 p = isl_printer_print_str(p, ")");
1216 return p;
1219 /* Print "expr" to "p".
1221 * If we are printing in isl format, then we also print an indication
1222 * of the size of the expression (if it was computed).
1224 __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
1225 __isl_keep isl_ast_expr *expr)
1227 if (!p)
1228 return NULL;
1229 if (!expr)
1230 return isl_printer_free(p);
1232 switch (expr->type) {
1233 case isl_ast_expr_op:
1234 if (expr->u.op.op == isl_ast_op_call) {
1235 p = print_call(p, expr);
1236 break;
1238 if (expr->u.op.n_arg == 1) {
1239 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1240 p = print_sub_expr(p, expr->u.op.op,
1241 expr->u.op.args[0], 0);
1242 break;
1244 if (expr->u.op.op == isl_ast_op_fdiv_q) {
1245 p = isl_printer_print_str(p, "floord(");
1246 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1247 p = isl_printer_print_str(p, ", ");
1248 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1249 p = isl_printer_print_str(p, ")");
1250 break;
1252 if (expr->u.op.op == isl_ast_op_max ||
1253 expr->u.op.op == isl_ast_op_min) {
1254 p = print_min_max(p, expr);
1255 break;
1257 if (expr->u.op.op == isl_ast_op_cond ||
1258 expr->u.op.op == isl_ast_op_select) {
1259 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1260 p = isl_printer_print_str(p, " ? ");
1261 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1262 p = isl_printer_print_str(p, " : ");
1263 p = isl_printer_print_ast_expr(p, expr->u.op.args[2]);
1264 break;
1266 if (expr->u.op.n_arg != 2)
1267 isl_die(isl_printer_get_ctx(p), isl_error_internal,
1268 "operation should have two arguments",
1269 goto error);
1270 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[0], 1);
1271 p = isl_printer_print_str(p, " ");
1272 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1273 p = isl_printer_print_str(p, " ");
1274 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[1], 0);
1275 break;
1276 case isl_ast_expr_id:
1277 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
1278 break;
1279 case isl_ast_expr_int:
1280 p = isl_printer_print_isl_int(p, expr->u.i);
1281 break;
1282 case isl_ast_expr_error:
1283 break;
1286 return p;
1287 error:
1288 isl_printer_free(p);
1289 return NULL;
1292 /* Print "node" to "p" in "isl format".
1294 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
1295 __isl_keep isl_ast_node *node)
1297 p = isl_printer_print_str(p, "(");
1298 switch (node->type) {
1299 case isl_ast_node_for:
1300 if (node->u.f.degenerate) {
1301 p = isl_printer_print_ast_expr(p, node->u.f.init);
1302 } else {
1303 p = isl_printer_print_str(p, "init: ");
1304 p = isl_printer_print_ast_expr(p, node->u.f.init);
1305 p = isl_printer_print_str(p, ", ");
1306 p = isl_printer_print_str(p, "cond: ");
1307 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1308 p = isl_printer_print_str(p, ", ");
1309 p = isl_printer_print_str(p, "inc: ");
1310 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1312 if (node->u.f.body) {
1313 p = isl_printer_print_str(p, ", ");
1314 p = isl_printer_print_str(p, "body: ");
1315 p = isl_printer_print_ast_node(p, node->u.f.body);
1317 break;
1318 case isl_ast_node_user:
1319 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1320 break;
1321 case isl_ast_node_if:
1322 p = isl_printer_print_str(p, "guard: ");
1323 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1324 if (node->u.i.then) {
1325 p = isl_printer_print_str(p, ", ");
1326 p = isl_printer_print_str(p, "then: ");
1327 p = isl_printer_print_ast_node(p, node->u.i.then);
1329 if (node->u.i.else_node) {
1330 p = isl_printer_print_str(p, ", ");
1331 p = isl_printer_print_str(p, "else: ");
1332 p = isl_printer_print_ast_node(p, node->u.i.else_node);
1334 break;
1335 case isl_ast_node_block:
1336 p = isl_printer_print_ast_node_list(p, node->u.b.children);
1337 break;
1338 default:
1339 break;
1341 p = isl_printer_print_str(p, ")");
1342 return p;
1345 /* Do we need to print a block around the body "node" of a for or if node?
1347 * If the node is a block, then we need to print a block.
1348 * Also if the node is a degenerate for then we will print it as
1349 * an assignment followed by the body of the for loop, so we need a block
1350 * as well.
1352 static int need_block(__isl_keep isl_ast_node *node)
1354 if (node->type == isl_ast_node_block)
1355 return 1;
1356 if (node->type == isl_ast_node_for && node->u.f.degenerate)
1357 return 1;
1358 return 0;
1361 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1362 __isl_keep isl_ast_node *node,
1363 __isl_keep isl_ast_print_options *options, int in_block, int in_list);
1364 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1365 __isl_keep isl_ast_node *node,
1366 __isl_keep isl_ast_print_options *options, int new_line);
1368 /* Print the body "node" of a for or if node.
1369 * If "else_node" is set, then it is printed as well.
1371 * We first check if we need to print out a block.
1372 * We always print out a block if there is an else node to make
1373 * sure that the else node is matched to the correct if node.
1375 * If the else node is itself an if, then we print it as
1377 * } else if (..)
1379 * Otherwise the else node is printed as
1381 * } else
1382 * node
1384 static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
1385 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
1386 __isl_keep isl_ast_print_options *options)
1388 if (!node)
1389 return isl_printer_free(p);
1391 if (!else_node && !need_block(node)) {
1392 p = isl_printer_end_line(p);
1393 p = isl_printer_indent(p, 2);
1394 p = isl_ast_node_print(node, p,
1395 isl_ast_print_options_copy(options));
1396 p = isl_printer_indent(p, -2);
1397 return p;
1400 p = isl_printer_print_str(p, " {");
1401 p = isl_printer_end_line(p);
1402 p = isl_printer_indent(p, 2);
1403 p = print_ast_node_c(p, node, options, 1, 0);
1404 p = isl_printer_indent(p, -2);
1405 p = isl_printer_start_line(p);
1406 p = isl_printer_print_str(p, "}");
1407 if (else_node) {
1408 if (else_node->type == isl_ast_node_if) {
1409 p = isl_printer_print_str(p, " else ");
1410 p = print_if_c(p, else_node, options, 0);
1411 } else {
1412 p = isl_printer_print_str(p, " else");
1413 p = print_body_c(p, else_node, NULL, options);
1415 } else
1416 p = isl_printer_end_line(p);
1418 return p;
1421 /* Print the start of a compound statement.
1423 static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
1425 p = isl_printer_start_line(p);
1426 p = isl_printer_print_str(p, "{");
1427 p = isl_printer_end_line(p);
1428 p = isl_printer_indent(p, 2);
1430 return p;
1433 /* Print the end of a compound statement.
1435 static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
1437 p = isl_printer_indent(p, -2);
1438 p = isl_printer_start_line(p);
1439 p = isl_printer_print_str(p, "}");
1440 p = isl_printer_end_line(p);
1442 return p;
1445 /* Print the for node "node".
1447 * If the for node is degenerate, it is printed as
1449 * type iterator = init;
1450 * body
1452 * Otherwise, it is printed as
1454 * for (type iterator = init; cond; iterator += inc)
1455 * body
1457 * "in_block" is set if we are currently inside a block.
1458 * "in_list" is set if the current node is not alone in the block.
1459 * If we are not in a block or if the current not is not alone in the block
1460 * then we print a block around a degenerate for loop such that the variable
1461 * declaration will not conflict with any potential other declaration
1462 * of the same variable.
1464 static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
1465 __isl_keep isl_ast_node *node,
1466 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
1468 isl_id *id;
1469 const char *name;
1470 const char *type;
1472 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
1473 if (!node->u.f.degenerate) {
1474 id = isl_ast_expr_get_id(node->u.f.iterator);
1475 name = isl_id_get_name(id);
1476 isl_id_free(id);
1477 p = isl_printer_start_line(p);
1478 p = isl_printer_print_str(p, "for (");
1479 p = isl_printer_print_str(p, type);
1480 p = isl_printer_print_str(p, " ");
1481 p = isl_printer_print_str(p, name);
1482 p = isl_printer_print_str(p, " = ");
1483 p = isl_printer_print_ast_expr(p, node->u.f.init);
1484 p = isl_printer_print_str(p, "; ");
1485 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1486 p = isl_printer_print_str(p, "; ");
1487 p = isl_printer_print_str(p, name);
1488 p = isl_printer_print_str(p, " += ");
1489 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1490 p = isl_printer_print_str(p, ")");
1491 p = print_body_c(p, node->u.f.body, NULL, options);
1492 } else {
1493 id = isl_ast_expr_get_id(node->u.f.iterator);
1494 name = isl_id_get_name(id);
1495 isl_id_free(id);
1496 if (!in_block || in_list)
1497 p = start_block(p);
1498 p = isl_printer_start_line(p);
1499 p = isl_printer_print_str(p, type);
1500 p = isl_printer_print_str(p, " ");
1501 p = isl_printer_print_str(p, name);
1502 p = isl_printer_print_str(p, " = ");
1503 p = isl_printer_print_ast_expr(p, node->u.f.init);
1504 p = isl_printer_print_str(p, ";");
1505 p = isl_printer_end_line(p);
1506 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
1507 if (!in_block || in_list)
1508 p = end_block(p);
1511 return p;
1514 /* Print the if node "node".
1515 * If "new_line" is set then the if node should be printed on a new line.
1517 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1518 __isl_keep isl_ast_node *node,
1519 __isl_keep isl_ast_print_options *options, int new_line)
1521 if (new_line)
1522 p = isl_printer_start_line(p);
1523 p = isl_printer_print_str(p, "if (");
1524 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1525 p = isl_printer_print_str(p, ")");
1526 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options);
1528 return p;
1531 /* Print the "node" to "p".
1533 * "in_block" is set if we are currently inside a block.
1534 * If so, we do not print a block around the children of a block node.
1535 * We do this to avoid an extra block around the body of a degenerate
1536 * for node.
1538 * "in_list" is set if the current node is not alone in the block.
1540 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1541 __isl_keep isl_ast_node *node,
1542 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
1544 switch (node->type) {
1545 case isl_ast_node_for:
1546 if (options->print_for)
1547 return options->print_for(p,
1548 isl_ast_print_options_copy(options),
1549 node, options->print_for_user);
1550 p = print_for_c(p, node, options, in_block, in_list);
1551 break;
1552 case isl_ast_node_if:
1553 p = print_if_c(p, node, options, 1);
1554 break;
1555 case isl_ast_node_block:
1556 if (!in_block)
1557 p = start_block(p);
1558 p = isl_ast_node_list_print(node->u.b.children, p, options);
1559 if (!in_block)
1560 p = end_block(p);
1561 break;
1562 case isl_ast_node_user:
1563 if (options->print_user)
1564 return options->print_user(p,
1565 isl_ast_print_options_copy(options),
1566 node, options->print_user_user);
1567 p = isl_printer_start_line(p);
1568 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1569 p = isl_printer_print_str(p, ";");
1570 p = isl_printer_end_line(p);
1571 break;
1572 case isl_ast_node_error:
1573 break;
1575 return p;
1578 /* Print the for node "node" to "p".
1580 __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
1581 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1583 if (!node || !options)
1584 goto error;
1585 if (node->type != isl_ast_node_for)
1586 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1587 "not a for node", goto error);
1588 p = print_for_c(p, node, options, 0, 0);
1589 isl_ast_print_options_free(options);
1590 return p;
1591 error:
1592 isl_ast_print_options_free(options);
1593 isl_printer_free(p);
1594 return NULL;
1597 /* Print the if node "node" to "p".
1599 __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
1600 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1602 if (!node || !options)
1603 goto error;
1604 if (node->type != isl_ast_node_if)
1605 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1606 "not an if node", goto error);
1607 p = print_if_c(p, node, options, 1);
1608 isl_ast_print_options_free(options);
1609 return p;
1610 error:
1611 isl_ast_print_options_free(options);
1612 isl_printer_free(p);
1613 return NULL;
1616 /* Print "node" to "p".
1618 __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
1619 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1621 if (!options || !node)
1622 goto error;
1623 p = print_ast_node_c(p, node, options, 0, 0);
1624 isl_ast_print_options_free(options);
1625 return p;
1626 error:
1627 isl_ast_print_options_free(options);
1628 isl_printer_free(p);
1629 return NULL;
1632 /* Print "node" to "p".
1634 __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
1635 __isl_keep isl_ast_node *node)
1637 int format;
1638 isl_ast_print_options *options;
1640 if (!p)
1641 return NULL;
1643 format = isl_printer_get_output_format(p);
1644 switch (format) {
1645 case ISL_FORMAT_ISL:
1646 p = print_ast_node_isl(p, node);
1647 break;
1648 case ISL_FORMAT_C:
1649 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
1650 p = isl_ast_node_print(node, p, options);
1651 break;
1652 default:
1653 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
1654 "output format not supported for ast_node",
1655 return isl_printer_free(p));
1658 return p;
1661 /* Print the list of nodes "list" to "p".
1663 __isl_give isl_printer *isl_ast_node_list_print(
1664 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
1665 __isl_keep isl_ast_print_options *options)
1667 int i;
1669 if (!p || !list || !options)
1670 return isl_printer_free(p);
1672 for (i = 0; i < list->n; ++i)
1673 p = print_ast_node_c(p, list->p[i], options, 1, 1);
1675 return p;
1678 #define ISL_AST_MACRO_FLOORD (1 << 0)
1679 #define ISL_AST_MACRO_MIN (1 << 1)
1680 #define ISL_AST_MACRO_MAX (1 << 2)
1681 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FLOORD | \
1682 ISL_AST_MACRO_MIN | \
1683 ISL_AST_MACRO_MAX)
1685 /* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1686 * then set the corresponding bit in "macros".
1688 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
1690 int i;
1692 if (macros == ISL_AST_MACRO_ALL)
1693 return macros;
1695 if (expr->type != isl_ast_expr_op)
1696 return macros;
1698 if (expr->u.op.op == isl_ast_op_min)
1699 macros |= ISL_AST_MACRO_MIN;
1700 if (expr->u.op.op == isl_ast_op_max)
1701 macros |= ISL_AST_MACRO_MAX;
1702 if (expr->u.op.op == isl_ast_op_fdiv_q)
1703 macros |= ISL_AST_MACRO_FLOORD;
1705 for (i = 0; i < expr->u.op.n_arg; ++i)
1706 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
1708 return macros;
1711 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1712 int macros);
1714 /* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1715 * then set the corresponding bit in "macros".
1717 static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
1719 if (macros == ISL_AST_MACRO_ALL)
1720 return macros;
1722 switch (node->type) {
1723 case isl_ast_node_for:
1724 macros = ast_expr_required_macros(node->u.f.init, macros);
1725 if (!node->u.f.degenerate) {
1726 macros = ast_expr_required_macros(node->u.f.cond,
1727 macros);
1728 macros = ast_expr_required_macros(node->u.f.inc,
1729 macros);
1731 macros = ast_node_required_macros(node->u.f.body, macros);
1732 break;
1733 case isl_ast_node_if:
1734 macros = ast_expr_required_macros(node->u.i.guard, macros);
1735 macros = ast_node_required_macros(node->u.i.then, macros);
1736 if (node->u.i.else_node)
1737 macros = ast_node_required_macros(node->u.i.else_node,
1738 macros);
1739 break;
1740 case isl_ast_node_block:
1741 macros = ast_node_list_required_macros(node->u.b.children,
1742 macros);
1743 break;
1744 case isl_ast_node_user:
1745 macros = ast_expr_required_macros(node->u.e.expr, macros);
1746 break;
1747 case isl_ast_node_error:
1748 break;
1751 return macros;
1754 /* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1755 * then set the corresponding bit in "macros".
1757 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1758 int macros)
1760 int i;
1762 for (i = 0; i < list->n; ++i)
1763 macros = ast_node_required_macros(list->p[i], macros);
1765 return macros;
1768 /* Print a macro definition for the operator "type".
1770 __isl_give isl_printer *isl_ast_op_type_print_macro(
1771 enum isl_ast_op_type type, __isl_take isl_printer *p)
1773 switch (type) {
1774 case isl_ast_op_min:
1775 p = isl_printer_start_line(p);
1776 p = isl_printer_print_str(p,
1777 "#define min(x,y) ((x) < (y) ? (x) : (y))");
1778 p = isl_printer_end_line(p);
1779 break;
1780 case isl_ast_op_max:
1781 p = isl_printer_start_line(p);
1782 p = isl_printer_print_str(p,
1783 "#define max(x,y) ((x) > (y) ? (x) : (y))");
1784 p = isl_printer_end_line(p);
1785 break;
1786 case isl_ast_op_fdiv_q:
1787 p = isl_printer_start_line(p);
1788 p = isl_printer_print_str(p,
1789 "#define floord(n,d) "
1790 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
1791 p = isl_printer_end_line(p);
1792 break;
1793 default:
1794 break;
1797 return p;
1800 /* Call "fn" for each type of operation that appears in "node"
1801 * and that requires a macro definition.
1803 int isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
1804 int (*fn)(enum isl_ast_op_type type, void *user), void *user)
1806 int macros;
1808 if (!node)
1809 return -1;
1811 macros = ast_node_required_macros(node, 0);
1813 if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0)
1814 return -1;
1815 if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0)
1816 return -1;
1817 if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0)
1818 return -1;
1820 return 0;
1823 static int ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
1825 isl_printer **p = user;
1827 *p = isl_ast_op_type_print_macro(type, *p);
1829 return 0;
1832 /* Print macro definitions for all the macros used in the result
1833 * of printing "node.
1835 __isl_give isl_printer *isl_ast_node_print_macros(
1836 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
1838 if (isl_ast_node_foreach_ast_op_type(node,
1839 &ast_op_type_print_macro, &p) < 0)
1840 return isl_printer_free(p);
1841 return p;