argument parsing: set structure field even if setter is available
[isl.git] / isl_ast.c
blob85a568cf8c51aa1422428f77ecdeca33c465140c
1 #include <isl_ast_private.h>
2 #include <isl_list_private.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 __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
247 if (!expr)
248 return NULL;
249 if (expr->type != isl_ast_expr_id)
250 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
251 "expression not an identifier", return NULL);
253 return isl_id_copy(expr->u.id);
256 enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
258 if (!expr)
259 return isl_ast_op_error;
260 if (expr->type != isl_ast_expr_op)
261 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
262 "expression not an operation", return isl_ast_op_error);
263 return expr->u.op.op;
266 int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
268 if (!expr)
269 return -1;
270 if (expr->type != isl_ast_expr_op)
271 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
272 "expression not an operation", return -1);
273 return expr->u.op.n_arg;
276 __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
277 int pos)
279 if (!expr)
280 return NULL;
281 if (expr->type != isl_ast_expr_op)
282 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
283 "expression not an operation", return NULL);
284 if (pos < 0 || pos >= expr->u.op.n_arg)
285 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
286 "index out of bounds", return NULL);
288 return isl_ast_expr_copy(expr->u.op.args[pos]);
291 /* Replace the argument at position "pos" of "expr" by "arg".
293 __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
294 int pos, __isl_take isl_ast_expr *arg)
296 expr = isl_ast_expr_cow(expr);
297 if (!expr || !arg)
298 goto error;
299 if (expr->type != isl_ast_expr_op)
300 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
301 "expression not an operation", goto error);
302 if (pos < 0 || pos >= expr->u.op.n_arg)
303 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
304 "index out of bounds", goto error);
306 isl_ast_expr_free(expr->u.op.args[pos]);
307 expr->u.op.args[pos] = arg;
309 return expr;
310 error:
311 isl_ast_expr_free(arg);
312 return isl_ast_expr_free(expr);
315 /* Create a new operation expression of operation type "op",
316 * with "n_arg" as yet unspecified arguments.
318 __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
319 enum isl_ast_op_type op, int n_arg)
321 isl_ast_expr *expr;
323 expr = isl_calloc_type(ctx, isl_ast_expr);
324 if (!expr)
325 return NULL;
327 expr->ctx = ctx;
328 isl_ctx_ref(ctx);
329 expr->ref = 1;
330 expr->type = isl_ast_expr_op;
331 expr->u.op.op = op;
332 expr->u.op.n_arg = n_arg;
333 expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg);
335 if (!expr->u.op.args)
336 return isl_ast_expr_free(expr);
338 return expr;
341 /* Create a new id expression representing "id".
343 __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
345 isl_ctx *ctx;
346 isl_ast_expr *expr;
348 if (!id)
349 return NULL;
351 ctx = isl_id_get_ctx(id);
352 expr = isl_calloc_type(ctx, isl_ast_expr);
353 if (!expr)
354 return isl_id_free(id);
356 expr->ctx = ctx;
357 isl_ctx_ref(ctx);
358 expr->ref = 1;
359 expr->type = isl_ast_expr_id;
360 expr->u.id = id;
362 return expr;
365 /* Create a new integer expression representing "i".
367 __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
369 isl_ast_expr *expr;
371 expr = isl_calloc_type(ctx, isl_ast_expr);
372 if (!expr)
373 return NULL;
375 expr->ctx = ctx;
376 isl_ctx_ref(ctx);
377 expr->ref = 1;
378 expr->type = isl_ast_expr_int;
380 isl_int_init(expr->u.i);
381 isl_int_set_si(expr->u.i, i);
383 return expr;
386 /* Create a new integer expression representing "i".
388 __isl_give isl_ast_expr *isl_ast_expr_alloc_int(isl_ctx *ctx, isl_int i)
390 isl_ast_expr *expr;
392 expr = isl_calloc_type(ctx, isl_ast_expr);
393 if (!expr)
394 return NULL;
396 expr->ctx = ctx;
397 isl_ctx_ref(ctx);
398 expr->ref = 1;
399 expr->type = isl_ast_expr_int;
401 isl_int_init(expr->u.i);
402 isl_int_set(expr->u.i, i);
404 return expr;
407 /* Create an expression representing the negation of "arg".
409 __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
411 isl_ctx *ctx;
412 isl_ast_expr *expr = NULL;
414 if (!arg)
415 return NULL;
417 ctx = isl_ast_expr_get_ctx(arg);
418 expr = isl_ast_expr_alloc_op(ctx, isl_ast_op_minus, 1);
419 if (!expr)
420 goto error;
422 expr->u.op.args[0] = arg;
424 return expr;
425 error:
426 isl_ast_expr_free(arg);
427 return NULL;
430 /* Create an expression representing the binary operation "type"
431 * applied to "expr1" and "expr2".
433 __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
434 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
436 isl_ctx *ctx;
437 isl_ast_expr *expr = NULL;
439 if (!expr1 || !expr2)
440 goto error;
442 ctx = isl_ast_expr_get_ctx(expr1);
443 expr = isl_ast_expr_alloc_op(ctx, type, 2);
444 if (!expr)
445 goto error;
447 expr->u.op.args[0] = expr1;
448 expr->u.op.args[1] = expr2;
450 return expr;
451 error:
452 isl_ast_expr_free(expr1);
453 isl_ast_expr_free(expr2);
454 return NULL;
457 /* Create an expression representing the sum of "expr1" and "expr2".
459 __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
460 __isl_take isl_ast_expr *expr2)
462 return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
465 /* Create an expression representing the difference of "expr1" and "expr2".
467 __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
468 __isl_take isl_ast_expr *expr2)
470 return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
473 /* Create an expression representing the product of "expr1" and "expr2".
475 __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
476 __isl_take isl_ast_expr *expr2)
478 return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
481 /* Create an expression representing the quotient of "expr1" and "expr2".
483 __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
484 __isl_take isl_ast_expr *expr2)
486 return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
489 /* Create an expression representing the conjunction of "expr1" and "expr2".
491 __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
492 __isl_take isl_ast_expr *expr2)
494 return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
497 /* Create an expression representing the disjunction of "expr1" and "expr2".
499 __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
500 __isl_take isl_ast_expr *expr2)
502 return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
505 isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
507 return node ? node->ctx : NULL;
510 enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
512 return node ? node->type : isl_ast_node_error;
515 __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
516 enum isl_ast_node_type type)
518 isl_ast_node *node;
520 node = isl_calloc_type(ctx, isl_ast_node);
521 if (!node)
522 return NULL;
524 node->ctx = ctx;
525 isl_ctx_ref(ctx);
526 node->ref = 1;
527 node->type = type;
529 return node;
532 /* Create an if node with the given guard.
534 * The then body needs to be filled in later.
536 __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
538 isl_ast_node *node;
540 if (!guard)
541 return NULL;
543 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
544 if (!node)
545 goto error;
546 node->u.i.guard = guard;
548 return node;
549 error:
550 isl_ast_expr_free(guard);
551 return NULL;
554 /* Create a for node with the given iterator.
556 * The remaining fields need to be filled in later.
558 __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
560 isl_ast_node *node;
561 isl_ctx *ctx;
563 if (!id)
564 return NULL;
566 ctx = isl_id_get_ctx(id);
567 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
568 if (!node)
569 return NULL;
571 node->u.f.iterator = isl_ast_expr_from_id(id);
572 if (!node->u.f.iterator)
573 return isl_ast_node_free(node);
575 return node;
578 /* Create a user node evaluating "expr".
580 __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
582 isl_ctx *ctx;
583 isl_ast_node *node;
585 if (!expr)
586 return NULL;
588 ctx = isl_ast_expr_get_ctx(expr);
589 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
590 if (!node)
591 goto error;
593 node->u.e.expr = expr;
595 return node;
596 error:
597 isl_ast_expr_free(expr);
598 return NULL;
601 /* Create a block node with the given children.
603 __isl_give isl_ast_node *isl_ast_node_alloc_block(
604 __isl_take isl_ast_node_list *list)
606 isl_ast_node *node;
607 isl_ctx *ctx;
609 if (!list)
610 return NULL;
612 ctx = isl_ast_node_list_get_ctx(list);
613 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
614 if (!node)
615 goto error;
617 node->u.b.children = list;
619 return node;
620 error:
621 isl_ast_node_list_free(list);
622 return NULL;
625 /* Represent the given list of nodes as a single node, either by
626 * extract the node from a single element list or by creating
627 * a block node with the list of nodes as children.
629 __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
630 __isl_take isl_ast_node_list *list)
632 isl_ast_node *node;
634 if (isl_ast_node_list_n_ast_node(list) != 1)
635 return isl_ast_node_alloc_block(list);
637 node = isl_ast_node_list_get_ast_node(list, 0);
638 isl_ast_node_list_free(list);
640 return node;
643 __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
645 if (!node)
646 return NULL;
648 node->ref++;
649 return node;
652 __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
654 isl_ast_node *dup;
656 if (!node)
657 return NULL;
659 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
660 if (!dup)
661 return NULL;
663 switch (node->type) {
664 case isl_ast_node_if:
665 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
666 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
667 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
668 if (!dup->u.i.guard || !dup->u.i.then ||
669 (node->u.i.else_node && !dup->u.i.else_node))
670 return isl_ast_node_free(dup);
671 break;
672 case isl_ast_node_for:
673 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
674 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
675 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
676 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
677 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
678 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
679 !dup->u.f.inc || !dup->u.f.body)
680 return isl_ast_node_free(dup);
681 break;
682 case isl_ast_node_block:
683 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
684 if (!dup->u.b.children)
685 return isl_ast_node_free(dup);
686 break;
687 case isl_ast_node_user:
688 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
689 if (!dup->u.e.expr)
690 return isl_ast_node_free(dup);
691 break;
692 case isl_ast_node_error:
693 break;
696 return dup;
699 __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
701 if (!node)
702 return NULL;
704 if (node->ref == 1)
705 return node;
706 node->ref--;
707 return isl_ast_node_dup(node);
710 void *isl_ast_node_free(__isl_take isl_ast_node *node)
712 if (!node)
713 return NULL;
715 if (--node->ref > 0)
716 return NULL;
718 switch (node->type) {
719 case isl_ast_node_if:
720 isl_ast_expr_free(node->u.i.guard);
721 isl_ast_node_free(node->u.i.then);
722 isl_ast_node_free(node->u.i.else_node);
723 break;
724 case isl_ast_node_for:
725 isl_ast_expr_free(node->u.f.iterator);
726 isl_ast_expr_free(node->u.f.init);
727 isl_ast_expr_free(node->u.f.cond);
728 isl_ast_expr_free(node->u.f.inc);
729 isl_ast_node_free(node->u.f.body);
730 break;
731 case isl_ast_node_block:
732 isl_ast_node_list_free(node->u.b.children);
733 break;
734 case isl_ast_node_user:
735 isl_ast_expr_free(node->u.e.expr);
736 break;
737 case isl_ast_node_error:
738 break;
741 isl_id_free(node->annotation);
742 isl_ctx_deref(node->ctx);
743 free(node);
745 return NULL;
748 /* Replace the body of the for node "node" by "body".
750 __isl_give isl_ast_node *isl_ast_node_for_set_body(
751 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
753 node = isl_ast_node_cow(node);
754 if (!node || !body)
755 goto error;
756 if (node->type != isl_ast_node_for)
757 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
758 "not a for node", goto error);
760 isl_ast_node_free(node->u.f.body);
761 node->u.f.body = body;
763 return node;
764 error:
765 isl_ast_node_free(node);
766 isl_ast_node_free(body);
767 return NULL;
770 __isl_give isl_ast_node *isl_ast_node_for_get_body(
771 __isl_keep isl_ast_node *node)
773 if (!node)
774 return NULL;
775 if (node->type != isl_ast_node_for)
776 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
777 "not a for node", return NULL);
778 return isl_ast_node_copy(node->u.f.body);
781 /* Mark the given for node as being degenerate.
783 __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
784 __isl_take isl_ast_node *node)
786 node = isl_ast_node_cow(node);
787 if (!node)
788 return NULL;
789 node->u.f.degenerate = 1;
790 return node;
793 int isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
795 if (!node)
796 return -1;
797 if (node->type != isl_ast_node_for)
798 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
799 "not a for node", return -1);
800 return node->u.f.degenerate;
803 __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
804 __isl_keep isl_ast_node *node)
806 if (!node)
807 return NULL;
808 if (node->type != isl_ast_node_for)
809 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
810 "not a for node", return NULL);
811 return isl_ast_expr_copy(node->u.f.iterator);
814 __isl_give isl_ast_expr *isl_ast_node_for_get_init(
815 __isl_keep isl_ast_node *node)
817 if (!node)
818 return NULL;
819 if (node->type != isl_ast_node_for)
820 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
821 "not a for node", return NULL);
822 return isl_ast_expr_copy(node->u.f.init);
825 /* Return the condition expression of the given for node.
827 * If the for node is degenerate, then the condition is not explicitly
828 * stored in the node. Instead, it is constructed as
830 * iterator <= init
832 __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
833 __isl_keep isl_ast_node *node)
835 if (!node)
836 return NULL;
837 if (node->type != isl_ast_node_for)
838 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
839 "not a for node", return NULL);
840 if (!node->u.f.degenerate)
841 return isl_ast_expr_copy(node->u.f.cond);
843 return isl_ast_expr_alloc_binary(isl_ast_op_le,
844 isl_ast_expr_copy(node->u.f.iterator),
845 isl_ast_expr_copy(node->u.f.init));
848 /* Return the increment of the given for node.
850 * If the for node is degenerate, then the increment is not explicitly
851 * stored in the node. We simply return "1".
853 __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
854 __isl_keep isl_ast_node *node)
856 if (!node)
857 return NULL;
858 if (node->type != isl_ast_node_for)
859 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
860 "not a for node", return NULL);
861 if (!node->u.f.degenerate)
862 return isl_ast_expr_copy(node->u.f.inc);
863 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
866 /* Replace the then branch of the if node "node" by "child".
868 __isl_give isl_ast_node *isl_ast_node_if_set_then(
869 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
871 node = isl_ast_node_cow(node);
872 if (!node || !child)
873 goto error;
874 if (node->type != isl_ast_node_if)
875 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
876 "not an if node", goto error);
878 isl_ast_node_free(node->u.i.then);
879 node->u.i.then = child;
881 return node;
882 error:
883 isl_ast_node_free(node);
884 isl_ast_node_free(child);
885 return NULL;
888 __isl_give isl_ast_node *isl_ast_node_if_get_then(
889 __isl_keep isl_ast_node *node)
891 if (!node)
892 return NULL;
893 if (node->type != isl_ast_node_if)
894 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
895 "not an if node", return NULL);
896 return isl_ast_node_copy(node->u.i.then);
899 int isl_ast_node_if_has_else(
900 __isl_keep isl_ast_node *node)
902 if (!node)
903 return -1;
904 if (node->type != isl_ast_node_if)
905 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
906 "not an if node", return -1);
907 return node->u.i.else_node != NULL;
910 __isl_give isl_ast_node *isl_ast_node_if_get_else(
911 __isl_keep isl_ast_node *node)
913 if (!node)
914 return NULL;
915 if (node->type != isl_ast_node_if)
916 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
917 "not an if node", return NULL);
918 return isl_ast_node_copy(node->u.i.else_node);
921 __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
922 __isl_keep isl_ast_node *node)
924 if (!node)
925 return NULL;
926 if (node->type != isl_ast_node_if)
927 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
928 "not a guard node", return NULL);
929 return isl_ast_expr_copy(node->u.i.guard);
932 __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
933 __isl_keep isl_ast_node *node)
935 if (!node)
936 return NULL;
937 if (node->type != isl_ast_node_block)
938 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
939 "not a block node", return NULL);
940 return isl_ast_node_list_copy(node->u.b.children);
943 __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
944 __isl_keep isl_ast_node *node)
946 if (!node)
947 return NULL;
949 return isl_ast_expr_copy(node->u.e.expr);
952 __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
954 return node ? isl_id_copy(node->annotation) : NULL;
957 /* Replace node->annotation by "annotation".
959 __isl_give isl_ast_node *isl_ast_node_set_annotation(
960 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
962 node = isl_ast_node_cow(node);
963 if (!node || !annotation)
964 goto error;
966 isl_id_free(node->annotation);
967 node->annotation = annotation;
969 return node;
970 error:
971 isl_id_free(annotation);
972 return isl_ast_node_free(node);
975 /* Textual C representation of the various operators.
977 static char *op_str[] = {
978 [isl_ast_op_and] = "&&",
979 [isl_ast_op_and_then] = "&&",
980 [isl_ast_op_or] = "||",
981 [isl_ast_op_or_else] = "||",
982 [isl_ast_op_max] = "max",
983 [isl_ast_op_min] = "min",
984 [isl_ast_op_minus] = "-",
985 [isl_ast_op_add] = "+",
986 [isl_ast_op_sub] = "-",
987 [isl_ast_op_mul] = "*",
988 [isl_ast_op_pdiv_q] = "/",
989 [isl_ast_op_pdiv_r] = "%",
990 [isl_ast_op_div] = "/",
991 [isl_ast_op_eq] = "==",
992 [isl_ast_op_le] = "<=",
993 [isl_ast_op_ge] = ">=",
994 [isl_ast_op_lt] = "<",
995 [isl_ast_op_gt] = ">"
998 /* Precedence in C of the various operators.
999 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1000 * Lowest value means highest precedence.
1002 static int op_prec[] = {
1003 [isl_ast_op_and] = 13,
1004 [isl_ast_op_and_then] = 13,
1005 [isl_ast_op_or] = 14,
1006 [isl_ast_op_or_else] = 14,
1007 [isl_ast_op_max] = 2,
1008 [isl_ast_op_min] = 2,
1009 [isl_ast_op_minus] = 3,
1010 [isl_ast_op_add] = 6,
1011 [isl_ast_op_sub] = 6,
1012 [isl_ast_op_mul] = 5,
1013 [isl_ast_op_div] = 5,
1014 [isl_ast_op_fdiv_q] = 2,
1015 [isl_ast_op_pdiv_q] = 5,
1016 [isl_ast_op_pdiv_r] = 5,
1017 [isl_ast_op_cond] = 15,
1018 [isl_ast_op_select] = 15,
1019 [isl_ast_op_eq] = 9,
1020 [isl_ast_op_le] = 8,
1021 [isl_ast_op_ge] = 8,
1022 [isl_ast_op_lt] = 8,
1023 [isl_ast_op_gt] = 8,
1024 [isl_ast_op_call] = 2
1027 /* Is the operator left-to-right associative?
1029 static int op_left[] = {
1030 [isl_ast_op_and] = 1,
1031 [isl_ast_op_and_then] = 1,
1032 [isl_ast_op_or] = 1,
1033 [isl_ast_op_or_else] = 1,
1034 [isl_ast_op_max] = 1,
1035 [isl_ast_op_min] = 1,
1036 [isl_ast_op_minus] = 0,
1037 [isl_ast_op_add] = 1,
1038 [isl_ast_op_sub] = 1,
1039 [isl_ast_op_mul] = 1,
1040 [isl_ast_op_div] = 1,
1041 [isl_ast_op_fdiv_q] = 1,
1042 [isl_ast_op_pdiv_q] = 1,
1043 [isl_ast_op_pdiv_r] = 1,
1044 [isl_ast_op_cond] = 0,
1045 [isl_ast_op_select] = 0,
1046 [isl_ast_op_eq] = 1,
1047 [isl_ast_op_le] = 1,
1048 [isl_ast_op_ge] = 1,
1049 [isl_ast_op_lt] = 1,
1050 [isl_ast_op_gt] = 1,
1051 [isl_ast_op_call] = 1
1054 static int is_and(enum isl_ast_op_type op)
1056 return op == isl_ast_op_and || op == isl_ast_op_and_then;
1059 static int is_or(enum isl_ast_op_type op)
1061 return op == isl_ast_op_or || op == isl_ast_op_or_else;
1064 static int is_add_sub(enum isl_ast_op_type op)
1066 return op == isl_ast_op_add || op == isl_ast_op_sub;
1069 static int is_div_mod(enum isl_ast_op_type op)
1071 return op == isl_ast_op_div || op == isl_ast_op_pdiv_r;
1074 /* Do we need/want parentheses around "expr" as a subexpression of
1075 * an "op" operation? If "left" is set, then "expr" is the left-most
1076 * operand.
1078 * We only need parentheses if "expr" represents an operation.
1080 * If op has a higher precedence than expr->u.op.op, then we need
1081 * parentheses.
1082 * If op and expr->u.op.op have the same precedence, but the operations
1083 * are performed in an order that is different from the associativity,
1084 * then we need parentheses.
1086 * An and inside an or technically does not require parentheses,
1087 * but some compilers complain about that, so we add them anyway.
1089 * Computations such as "a / b * c" and "a % b + c" can be somewhat
1090 * difficult to read, so we add parentheses for those as well.
1092 static int sub_expr_need_parens(enum isl_ast_op_type op,
1093 __isl_keep isl_ast_expr *expr, int left)
1095 if (expr->type != isl_ast_expr_op)
1096 return 0;
1098 if (op_prec[expr->u.op.op] > op_prec[op])
1099 return 1;
1100 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
1101 return 1;
1103 if (is_or(op) && is_and(expr->u.op.op))
1104 return 1;
1105 if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
1106 op_prec[expr->u.op.op] == op_prec[op])
1107 return 1;
1108 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
1109 return 1;
1111 return 0;
1114 /* Print "expr" as a subexpression of an "op" operation.
1115 * If "left" is set, then "expr" is the left-most operand.
1117 static __isl_give isl_printer *print_sub_expr(__isl_take isl_printer *p,
1118 enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
1120 int need_parens;
1122 need_parens = sub_expr_need_parens(op, expr, left);
1124 if (need_parens)
1125 p = isl_printer_print_str(p, "(");
1126 p = isl_printer_print_ast_expr(p, expr);
1127 if (need_parens)
1128 p = isl_printer_print_str(p, ")");
1129 return p;
1132 /* Print a min or max reduction "expr".
1134 static __isl_give isl_printer *print_min_max(__isl_take isl_printer *p,
1135 __isl_keep isl_ast_expr *expr)
1137 int i = 0;
1139 for (i = 1; i < expr->u.op.n_arg; ++i) {
1140 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1141 p = isl_printer_print_str(p, "(");
1143 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1144 for (i = 1; i < expr->u.op.n_arg; ++i) {
1145 p = isl_printer_print_str(p, ", ");
1146 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1147 p = isl_printer_print_str(p, ")");
1150 return p;
1153 /* Print a function call "expr".
1155 * The first argument represents the function to be called.
1157 static __isl_give isl_printer *print_call(__isl_take isl_printer *p,
1158 __isl_keep isl_ast_expr *expr)
1160 int i = 0;
1162 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1163 p = isl_printer_print_str(p, "(");
1164 for (i = 1; i < expr->u.op.n_arg; ++i) {
1165 if (i != 1)
1166 p = isl_printer_print_str(p, ", ");
1167 p = isl_printer_print_ast_expr(p, expr->u.op.args[i]);
1169 p = isl_printer_print_str(p, ")");
1171 return p;
1174 /* Print "expr" to "p".
1176 * If we are printing in isl format, then we also print an indication
1177 * of the size of the expression (if it was computed).
1179 __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
1180 __isl_keep isl_ast_expr *expr)
1182 if (!p)
1183 return NULL;
1184 if (!expr)
1185 return isl_printer_free(p);
1187 switch (expr->type) {
1188 case isl_ast_expr_op:
1189 if (expr->u.op.op == isl_ast_op_call) {
1190 p = print_call(p, expr);
1191 break;
1193 if (expr->u.op.n_arg == 1) {
1194 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1195 p = print_sub_expr(p, expr->u.op.op,
1196 expr->u.op.args[0], 0);
1197 break;
1199 if (expr->u.op.op == isl_ast_op_fdiv_q) {
1200 p = isl_printer_print_str(p, "floord(");
1201 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1202 p = isl_printer_print_str(p, ", ");
1203 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1204 p = isl_printer_print_str(p, ")");
1205 break;
1207 if (expr->u.op.op == isl_ast_op_max ||
1208 expr->u.op.op == isl_ast_op_min) {
1209 p = print_min_max(p, expr);
1210 break;
1212 if (expr->u.op.op == isl_ast_op_cond ||
1213 expr->u.op.op == isl_ast_op_select) {
1214 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1215 p = isl_printer_print_str(p, " ? ");
1216 p = isl_printer_print_ast_expr(p, expr->u.op.args[1]);
1217 p = isl_printer_print_str(p, " : ");
1218 p = isl_printer_print_ast_expr(p, expr->u.op.args[2]);
1219 break;
1221 if (expr->u.op.n_arg != 2)
1222 isl_die(isl_printer_get_ctx(p), isl_error_internal,
1223 "operation should have two arguments",
1224 goto error);
1225 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[0], 1);
1226 p = isl_printer_print_str(p, " ");
1227 p = isl_printer_print_str(p, op_str[expr->u.op.op]);
1228 p = isl_printer_print_str(p, " ");
1229 p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[1], 0);
1230 break;
1231 case isl_ast_expr_id:
1232 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
1233 break;
1234 case isl_ast_expr_int:
1235 p = isl_printer_print_isl_int(p, expr->u.i);
1236 break;
1237 case isl_ast_expr_error:
1238 break;
1241 return p;
1242 error:
1243 isl_printer_free(p);
1244 return NULL;
1247 /* Print "node" to "p" in "isl format".
1249 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
1250 __isl_keep isl_ast_node *node)
1252 p = isl_printer_print_str(p, "(");
1253 switch (node->type) {
1254 case isl_ast_node_for:
1255 if (node->u.f.degenerate) {
1256 p = isl_printer_print_ast_expr(p, node->u.f.init);
1257 } else {
1258 p = isl_printer_print_str(p, "init: ");
1259 p = isl_printer_print_ast_expr(p, node->u.f.init);
1260 p = isl_printer_print_str(p, ", ");
1261 p = isl_printer_print_str(p, "cond: ");
1262 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1263 p = isl_printer_print_str(p, ", ");
1264 p = isl_printer_print_str(p, "inc: ");
1265 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1267 if (node->u.f.body) {
1268 p = isl_printer_print_str(p, ", ");
1269 p = isl_printer_print_str(p, "body: ");
1270 p = isl_printer_print_ast_node(p, node->u.f.body);
1272 break;
1273 case isl_ast_node_user:
1274 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1275 break;
1276 case isl_ast_node_if:
1277 p = isl_printer_print_str(p, "guard: ");
1278 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1279 if (node->u.i.then) {
1280 p = isl_printer_print_str(p, ", ");
1281 p = isl_printer_print_str(p, "then: ");
1282 p = isl_printer_print_ast_node(p, node->u.i.then);
1284 if (node->u.i.else_node) {
1285 p = isl_printer_print_str(p, ", ");
1286 p = isl_printer_print_str(p, "else: ");
1287 p = isl_printer_print_ast_node(p, node->u.i.else_node);
1289 break;
1290 case isl_ast_node_block:
1291 p = isl_printer_print_ast_node_list(p, node->u.b.children);
1292 break;
1293 default:
1294 break;
1296 p = isl_printer_print_str(p, ")");
1297 return p;
1300 /* Do we need to print a block around the body "node" of a for or if node?
1302 * If the node is a block, then we need to print a block.
1303 * Also if the node is a degenerate for then we will print it as
1304 * an assignment followed by the body of the for loop, so we need a block
1305 * as well.
1307 static int need_block(__isl_keep isl_ast_node *node)
1309 if (node->type == isl_ast_node_block)
1310 return 1;
1311 if (node->type == isl_ast_node_for && node->u.f.degenerate)
1312 return 1;
1313 return 0;
1316 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1317 __isl_keep isl_ast_node *node,
1318 __isl_keep isl_ast_print_options *options, int in_block);
1319 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1320 __isl_keep isl_ast_node *node,
1321 __isl_keep isl_ast_print_options *options, int new_line);
1323 /* Print the body "node" of a for or if node.
1324 * If "else_node" is set, then it is printed as well.
1326 * We first check if we need to print out a block.
1327 * We always print out a block if there is an else node to make
1328 * sure that the else node is matched to the correct if node.
1330 * If the else node is itself an if, then we print it as
1332 * } else if (..)
1334 * Otherwise the else node is printed as
1336 * } else
1337 * node
1339 static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
1340 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
1341 __isl_keep isl_ast_print_options *options)
1343 if (!node)
1344 return isl_printer_free(p);
1346 if (!else_node && !need_block(node)) {
1347 p = isl_printer_end_line(p);
1348 p = isl_printer_indent(p, 2);
1349 p = isl_ast_node_print(node, p,
1350 isl_ast_print_options_copy(options));
1351 p = isl_printer_indent(p, -2);
1352 return p;
1355 p = isl_printer_print_str(p, " {");
1356 p = isl_printer_end_line(p);
1357 p = isl_printer_indent(p, 2);
1358 p = print_ast_node_c(p, node, options, 1);
1359 p = isl_printer_indent(p, -2);
1360 p = isl_printer_start_line(p);
1361 p = isl_printer_print_str(p, "}");
1362 if (else_node) {
1363 if (else_node->type == isl_ast_node_if) {
1364 p = isl_printer_print_str(p, " else ");
1365 p = print_if_c(p, else_node, options, 0);
1366 } else {
1367 p = isl_printer_print_str(p, " else");
1368 p = print_body_c(p, else_node, NULL, options);
1370 } else
1371 p = isl_printer_end_line(p);
1373 return p;
1376 /* Print the for node "node".
1378 * If the for node is degenerate, it is printed as
1380 * type iterator = init;
1381 * body
1383 * Otherwise, it is printed as
1385 * for (type iterator = init; cond; iterator += inc)
1386 * body
1388 * "in_block" is set if we are currently inside a block.
1389 * We simply pass it along to print_ast_node_c in case of a degenerate
1390 * for loop.
1392 static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
1393 __isl_keep isl_ast_node *node,
1394 __isl_keep isl_ast_print_options *options, int in_block)
1396 isl_id *id;
1397 const char *name;
1398 const char *type;
1400 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
1401 if (!node->u.f.degenerate) {
1402 id = isl_ast_expr_get_id(node->u.f.iterator);
1403 name = isl_id_get_name(id);
1404 isl_id_free(id);
1405 p = isl_printer_start_line(p);
1406 p = isl_printer_print_str(p, "for (");
1407 p = isl_printer_print_str(p, type);
1408 p = isl_printer_print_str(p, " ");
1409 p = isl_printer_print_str(p, name);
1410 p = isl_printer_print_str(p, " = ");
1411 p = isl_printer_print_ast_expr(p, node->u.f.init);
1412 p = isl_printer_print_str(p, "; ");
1413 p = isl_printer_print_ast_expr(p, node->u.f.cond);
1414 p = isl_printer_print_str(p, "; ");
1415 p = isl_printer_print_str(p, name);
1416 p = isl_printer_print_str(p, " += ");
1417 p = isl_printer_print_ast_expr(p, node->u.f.inc);
1418 p = isl_printer_print_str(p, ")");
1419 p = print_body_c(p, node->u.f.body, NULL, options);
1420 } else {
1421 id = isl_ast_expr_get_id(node->u.f.iterator);
1422 name = isl_id_get_name(id);
1423 isl_id_free(id);
1424 p = isl_printer_start_line(p);
1425 p = isl_printer_print_str(p, type);
1426 p = isl_printer_print_str(p, " ");
1427 p = isl_printer_print_str(p, name);
1428 p = isl_printer_print_str(p, " = ");
1429 p = isl_printer_print_ast_expr(p, node->u.f.init);
1430 p = isl_printer_print_str(p, ";");
1431 p = isl_printer_end_line(p);
1432 p = print_ast_node_c(p, node->u.f.body, options, in_block);
1435 return p;
1438 /* Print the if node "node".
1439 * If "new_line" is set then the if node should be printed on a new line.
1441 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
1442 __isl_keep isl_ast_node *node,
1443 __isl_keep isl_ast_print_options *options, int new_line)
1445 if (new_line)
1446 p = isl_printer_start_line(p);
1447 p = isl_printer_print_str(p, "if (");
1448 p = isl_printer_print_ast_expr(p, node->u.i.guard);
1449 p = isl_printer_print_str(p, ")");
1450 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options);
1452 return p;
1455 /* Print the "node" to "p".
1457 * "in_block" is set if we are currently inside a block.
1458 * If so, we do not print a block around the children of a block node.
1459 * We do this to avoid an extra block around the body of a degenerate
1460 * for node.
1462 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
1463 __isl_keep isl_ast_node *node,
1464 __isl_keep isl_ast_print_options *options, int in_block)
1466 switch (node->type) {
1467 case isl_ast_node_for:
1468 if (options->print_for)
1469 return options->print_for(p,
1470 isl_ast_print_options_copy(options),
1471 node, options->print_for_user);
1472 p = print_for_c(p, node, options, in_block);
1473 break;
1474 case isl_ast_node_if:
1475 p = print_if_c(p, node, options, 1);
1476 break;
1477 case isl_ast_node_block:
1478 if (!in_block) {
1479 p = isl_printer_start_line(p);
1480 p = isl_printer_print_str(p, "{");
1481 p = isl_printer_end_line(p);
1482 p = isl_printer_indent(p, 2);
1484 p = isl_ast_node_list_print(node->u.b.children, p, options);
1485 if (!in_block) {
1486 p = isl_printer_indent(p, -2);
1487 p = isl_printer_start_line(p);
1488 p = isl_printer_print_str(p, "}");
1489 p = isl_printer_end_line(p);
1491 break;
1492 case isl_ast_node_user:
1493 if (options->print_user)
1494 return options->print_user(p,
1495 isl_ast_print_options_copy(options),
1496 node, options->print_user_user);
1497 p = isl_printer_start_line(p);
1498 p = isl_printer_print_ast_expr(p, node->u.e.expr);
1499 p = isl_printer_print_str(p, ";");
1500 p = isl_printer_end_line(p);
1501 break;
1502 case isl_ast_node_error:
1503 break;
1505 return p;
1508 /* Print the for node "node" to "p".
1510 __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
1511 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1513 if (!node || !options)
1514 goto error;
1515 if (node->type != isl_ast_node_for)
1516 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1517 "not a for node", goto error);
1518 p = print_for_c(p, node, options, 0);
1519 isl_ast_print_options_free(options);
1520 return p;
1521 error:
1522 isl_ast_print_options_free(options);
1523 isl_printer_free(p);
1524 return NULL;
1527 /* Print the if node "node" to "p".
1529 __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
1530 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1532 if (!node || !options)
1533 goto error;
1534 if (node->type != isl_ast_node_if)
1535 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1536 "not an if node", goto error);
1537 p = print_if_c(p, node, options, 1);
1538 isl_ast_print_options_free(options);
1539 return p;
1540 error:
1541 isl_ast_print_options_free(options);
1542 isl_printer_free(p);
1543 return NULL;
1546 /* Print "node" to "p".
1548 __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
1549 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
1551 if (!options || !node)
1552 goto error;
1553 p = print_ast_node_c(p, node, options, 0);
1554 isl_ast_print_options_free(options);
1555 return p;
1556 error:
1557 isl_ast_print_options_free(options);
1558 isl_printer_free(p);
1559 return NULL;
1562 /* Print "node" to "p".
1564 __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
1565 __isl_keep isl_ast_node *node)
1567 int format;
1568 isl_ast_print_options *options;
1570 if (!p)
1571 return NULL;
1573 format = isl_printer_get_output_format(p);
1574 switch (format) {
1575 case ISL_FORMAT_ISL:
1576 p = print_ast_node_isl(p, node);
1577 break;
1578 case ISL_FORMAT_C:
1579 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
1580 p = isl_ast_node_print(node, p, options);
1581 break;
1582 default:
1583 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
1584 "output format not supported for ast_node",
1585 return isl_printer_free(p));
1588 return p;
1591 /* Print the list of nodes "list" to "p".
1593 __isl_give isl_printer *isl_ast_node_list_print(
1594 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
1595 __isl_keep isl_ast_print_options *options)
1597 int i;
1599 if (!p || !list || !options)
1600 return isl_printer_free(p);
1602 for (i = 0; i < list->n; ++i)
1603 p = print_ast_node_c(p, list->p[i], options, 1);
1605 return p;
1608 #define ISL_AST_MACRO_FLOORD (1 << 0)
1609 #define ISL_AST_MACRO_MIN (1 << 1)
1610 #define ISL_AST_MACRO_MAX (1 << 2)
1611 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FLOORD | \
1612 ISL_AST_MACRO_MIN | \
1613 ISL_AST_MACRO_MAX)
1615 /* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1616 * then set the corresponding bit in "macros".
1618 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
1620 int i;
1622 if (macros == ISL_AST_MACRO_ALL)
1623 return macros;
1625 if (expr->type != isl_ast_expr_op)
1626 return macros;
1628 if (expr->u.op.op == isl_ast_op_min)
1629 macros |= ISL_AST_MACRO_MIN;
1630 if (expr->u.op.op == isl_ast_op_max)
1631 macros |= ISL_AST_MACRO_MAX;
1632 if (expr->u.op.op == isl_ast_op_fdiv_q)
1633 macros |= ISL_AST_MACRO_FLOORD;
1635 for (i = 0; i < expr->u.op.n_arg; ++i)
1636 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
1638 return macros;
1641 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1642 int macros);
1644 /* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1645 * then set the corresponding bit in "macros".
1647 static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
1649 if (macros == ISL_AST_MACRO_ALL)
1650 return macros;
1652 switch (node->type) {
1653 case isl_ast_node_for:
1654 macros = ast_expr_required_macros(node->u.f.init, macros);
1655 if (!node->u.f.degenerate) {
1656 macros = ast_expr_required_macros(node->u.f.cond,
1657 macros);
1658 macros = ast_expr_required_macros(node->u.f.inc,
1659 macros);
1661 macros = ast_node_required_macros(node->u.f.body, macros);
1662 break;
1663 case isl_ast_node_if:
1664 macros = ast_expr_required_macros(node->u.i.guard, macros);
1665 macros = ast_node_required_macros(node->u.i.then, macros);
1666 if (node->u.i.else_node)
1667 macros = ast_node_required_macros(node->u.i.else_node,
1668 macros);
1669 break;
1670 case isl_ast_node_block:
1671 macros = ast_node_list_required_macros(node->u.b.children,
1672 macros);
1673 break;
1674 case isl_ast_node_user:
1675 macros = ast_expr_required_macros(node->u.e.expr, macros);
1676 break;
1677 case isl_ast_node_error:
1678 break;
1681 return macros;
1684 /* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
1685 * then set the corresponding bit in "macros".
1687 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
1688 int macros)
1690 int i;
1692 for (i = 0; i < list->n; ++i)
1693 macros = ast_node_required_macros(list->p[i], macros);
1695 return macros;
1698 /* Print a macro definition for the operator "type".
1700 __isl_give isl_printer *isl_ast_op_type_print_macro(
1701 enum isl_ast_op_type type, __isl_take isl_printer *p)
1703 switch (type) {
1704 case isl_ast_op_min:
1705 p = isl_printer_start_line(p);
1706 p = isl_printer_print_str(p,
1707 "#define min(x,y) ((x) < (y) ? (x) : (y))");
1708 p = isl_printer_end_line(p);
1709 break;
1710 case isl_ast_op_max:
1711 p = isl_printer_start_line(p);
1712 p = isl_printer_print_str(p,
1713 "#define max(x,y) ((x) > (y) ? (x) : (y))");
1714 p = isl_printer_end_line(p);
1715 break;
1716 case isl_ast_op_fdiv_q:
1717 p = isl_printer_start_line(p);
1718 p = isl_printer_print_str(p,
1719 "#define floord(n,d) "
1720 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
1721 p = isl_printer_end_line(p);
1722 break;
1723 default:
1724 break;
1727 return p;
1730 /* Call "fn" for each type of operation that appears in "node"
1731 * and that requires a macro definition.
1733 int isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
1734 int (*fn)(enum isl_ast_op_type type, void *user), void *user)
1736 int macros;
1738 if (!node)
1739 return -1;
1741 macros = ast_node_required_macros(node, 0);
1743 if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0)
1744 return -1;
1745 if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0)
1746 return -1;
1747 if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0)
1748 return -1;
1750 return 0;
1753 static int ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
1755 isl_printer **p = user;
1757 *p = isl_ast_op_type_print_macro(type, *p);
1759 return 0;
1762 /* Print macro definitions for all the macros used in the result
1763 * of printing "node.
1765 __isl_give isl_printer *isl_ast_node_print_macros(
1766 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
1768 if (isl_ast_node_foreach_ast_op_type(node,
1769 &ast_op_type_print_macro, &p) < 0)
1770 return isl_printer_free(p);
1771 return p;