export isl_ast_node_alloc_user as isl_ast_node_user_from_expr
[isl.git] / isl_ast.c
blob1019b2903ad65b8c2ef926615f43bdf6bb3d7941
1 /*
2 * Copyright 2012-2013 Ecole Normale Superieure
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
8 */
10 #include <string.h>
12 #include <isl/id.h>
13 #include <isl/val.h>
14 #include <isl_ast_private.h>
16 #undef EL_BASE
17 #define EL_BASE ast_expr
19 #include <isl_list_templ.c>
21 #undef EL_BASE
22 #define EL_BASE ast_node
24 #include <isl_list_templ.c>
26 isl_ctx *isl_ast_print_options_get_ctx(
27 __isl_keep isl_ast_print_options *options)
29 return options ? options->ctx : NULL;
32 __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
34 isl_ast_print_options *options;
36 options = isl_calloc_type(ctx, isl_ast_print_options);
37 if (!options)
38 return NULL;
40 options->ctx = ctx;
41 isl_ctx_ref(ctx);
42 options->ref = 1;
44 return options;
47 __isl_give isl_ast_print_options *isl_ast_print_options_dup(
48 __isl_keep isl_ast_print_options *options)
50 isl_ctx *ctx;
51 isl_ast_print_options *dup;
53 if (!options)
54 return NULL;
56 ctx = isl_ast_print_options_get_ctx(options);
57 dup = isl_ast_print_options_alloc(ctx);
58 if (!dup)
59 return NULL;
61 dup->print_for = options->print_for;
62 dup->print_for_user = options->print_for_user;
63 dup->print_user = options->print_user;
64 dup->print_user_user = options->print_user_user;
66 return dup;
69 __isl_give isl_ast_print_options *isl_ast_print_options_cow(
70 __isl_take isl_ast_print_options *options)
72 if (!options)
73 return NULL;
75 if (options->ref == 1)
76 return options;
77 options->ref--;
78 return isl_ast_print_options_dup(options);
81 __isl_give isl_ast_print_options *isl_ast_print_options_copy(
82 __isl_keep isl_ast_print_options *options)
84 if (!options)
85 return NULL;
87 options->ref++;
88 return options;
91 __isl_null isl_ast_print_options *isl_ast_print_options_free(
92 __isl_take isl_ast_print_options *options)
94 if (!options)
95 return NULL;
97 if (--options->ref > 0)
98 return NULL;
100 isl_ctx_deref(options->ctx);
102 free(options);
103 return NULL;
106 /* Set the print_user callback of "options" to "print_user".
108 * If this callback is set, then it is used to print user nodes in the AST.
109 * Otherwise, the expression associated to the user node is printed.
111 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
112 __isl_take isl_ast_print_options *options,
113 __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
114 __isl_take isl_ast_print_options *options,
115 __isl_keep isl_ast_node *node, void *user),
116 void *user)
118 options = isl_ast_print_options_cow(options);
119 if (!options)
120 return NULL;
122 options->print_user = print_user;
123 options->print_user_user = user;
125 return options;
128 /* Set the print_for callback of "options" to "print_for".
130 * If this callback is set, then it used to print for nodes in the AST.
132 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
133 __isl_take isl_ast_print_options *options,
134 __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
135 __isl_take isl_ast_print_options *options,
136 __isl_keep isl_ast_node *node, void *user),
137 void *user)
139 options = isl_ast_print_options_cow(options);
140 if (!options)
141 return NULL;
143 options->print_for = print_for;
144 options->print_for_user = user;
146 return options;
149 /* Create a new operation expression of operation type "op",
150 * with arguments "args".
152 static __isl_give isl_ast_expr *alloc_op(enum isl_ast_expr_op_type op,
153 __isl_take isl_ast_expr_list *args)
155 isl_ctx *ctx;
156 isl_ast_expr *expr;
158 if (!args)
159 return NULL;
161 ctx = isl_ast_expr_list_get_ctx(args);
162 expr = isl_calloc_type(ctx, isl_ast_expr);
163 if (!expr)
164 goto error;
166 expr->ctx = ctx;
167 isl_ctx_ref(ctx);
168 expr->ref = 1;
169 expr->type = isl_ast_expr_op;
170 expr->u.op.op = op;
171 expr->u.op.args = args;
173 return expr;
174 error:
175 isl_ast_expr_list_free(args);
176 return NULL;
179 /* Create a new operation expression of operation type "op",
180 * which will end up having "n_arg" arguments.
181 * The caller still needs to add those arguments.
183 __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
184 enum isl_ast_expr_op_type op, int n_arg)
186 isl_ast_expr_list *args;
188 args = isl_ast_expr_list_alloc(ctx, n_arg);
189 return alloc_op(op, args);
192 __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
194 if (!expr)
195 return NULL;
197 expr->ref++;
198 return expr;
201 __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
203 isl_ast_expr *dup;
205 if (!expr)
206 return NULL;
208 switch (expr->type) {
209 case isl_ast_expr_int:
210 dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
211 break;
212 case isl_ast_expr_id:
213 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
214 break;
215 case isl_ast_expr_op:
216 dup = alloc_op(expr->u.op.op,
217 isl_ast_expr_list_copy(expr->u.op.args));
218 break;
219 case isl_ast_expr_error:
220 dup = NULL;
223 if (!dup)
224 return NULL;
226 return dup;
229 __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
231 if (!expr)
232 return NULL;
234 if (expr->ref == 1)
235 return expr;
236 expr->ref--;
237 return isl_ast_expr_dup(expr);
240 __isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
242 if (!expr)
243 return NULL;
245 if (--expr->ref > 0)
246 return NULL;
248 isl_ctx_deref(expr->ctx);
250 switch (expr->type) {
251 case isl_ast_expr_int:
252 isl_val_free(expr->u.v);
253 break;
254 case isl_ast_expr_id:
255 isl_id_free(expr->u.id);
256 break;
257 case isl_ast_expr_op:
258 isl_ast_expr_list_free(expr->u.op.args);
259 break;
260 case isl_ast_expr_error:
261 break;
264 free(expr);
265 return NULL;
268 isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
270 return expr ? expr->ctx : NULL;
273 enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
275 return expr ? expr->type : isl_ast_expr_error;
278 /* Return the integer value represented by "expr".
280 __isl_give isl_val *isl_ast_expr_int_get_val(__isl_keep isl_ast_expr *expr)
282 if (!expr)
283 return NULL;
284 if (expr->type != isl_ast_expr_int)
285 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
286 "expression not an int", return NULL);
287 return isl_val_copy(expr->u.v);
290 /* This is an alternative name for the function above.
292 __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
294 return isl_ast_expr_int_get_val(expr);
297 __isl_give isl_id *isl_ast_expr_id_get_id(__isl_keep isl_ast_expr *expr)
299 if (!expr)
300 return NULL;
301 if (expr->type != isl_ast_expr_id)
302 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
303 "expression not an identifier", return NULL);
305 return isl_id_copy(expr->u.id);
308 /* This is an alternative name for the function above.
310 __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
312 return isl_ast_expr_id_get_id(expr);
315 /* Check that "expr" is of type isl_ast_expr_op.
317 static isl_stat isl_ast_expr_check_op(__isl_keep isl_ast_expr *expr)
319 if (!expr)
320 return isl_stat_error;
321 if (expr->type != isl_ast_expr_op)
322 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
323 "expression not an operation", return isl_stat_error);
324 return isl_stat_ok;
327 /* Return the type of operation represented by "expr".
329 enum isl_ast_expr_op_type isl_ast_expr_op_get_type(
330 __isl_keep isl_ast_expr *expr)
332 if (isl_ast_expr_check_op(expr) < 0)
333 return isl_ast_expr_op_error;
334 return expr->u.op.op;
337 /* This is an alternative name for the function above.
339 enum isl_ast_expr_op_type isl_ast_expr_get_op_type(
340 __isl_keep isl_ast_expr *expr)
342 return isl_ast_expr_op_get_type(expr);
345 /* Return the number of arguments of the operation represented by "expr".
347 isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr)
349 if (isl_ast_expr_check_op(expr) < 0)
350 return isl_size_error;
351 return isl_ast_expr_list_size(expr->u.op.args);
354 /* This is an alternative name for the function above.
356 isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
358 return isl_ast_expr_op_get_n_arg(expr);
361 /* Return the argument at position "pos" of the operation represented by "expr".
363 __isl_give isl_ast_expr *isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr *expr,
364 int pos)
366 if (isl_ast_expr_check_op(expr) < 0)
367 return NULL;
369 return isl_ast_expr_list_get_at(expr->u.op.args, pos);
372 /* This is an alternative name for the function above.
374 __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
375 int pos)
377 return isl_ast_expr_op_get_arg(expr, pos);
380 /* Return a copy of the arguments of the operation represented by "expr".
382 static __isl_give isl_ast_expr_list *isl_ast_expr_op_get_args(
383 __isl_keep isl_ast_expr *expr)
385 if (isl_ast_expr_check_op(expr) < 0)
386 return NULL;
387 return isl_ast_expr_list_copy(expr->u.op.args);
390 /* Return the arguments of the operation expression "expr".
391 * This may be either a copy or the arguments themselves
392 * if there is only one reference to "expr".
393 * This allows the arguments to be modified inplace
394 * if both "expr" and its arguments have only a single reference.
395 * The caller is not allowed to modify "expr" between this call and
396 * the subsequent call to isl_ast_expr_op_restore_args.
397 * The only exception is that isl_ast_expr_free can be called instead.
399 static __isl_give isl_ast_expr_list *isl_ast_expr_op_take_args(
400 __isl_keep isl_ast_expr *expr)
402 isl_ast_expr_list *args;
404 if (isl_ast_expr_check_op(expr) < 0)
405 return NULL;
406 if (expr->ref != 1)
407 return isl_ast_expr_op_get_args(expr);
408 args = expr->u.op.args;
409 expr->u.op.args = NULL;
410 return args;
413 /* Set the arguments of the operation expression "expr" to "args",
414 * where the arguments of "args" may be missing
415 * due to a preceding call to isl_ast_expr_op_take_args.
416 * However, in this case, "expr" only has a single reference and
417 * then the call to isl_ast_expr_cow has no effect.
419 static __isl_give isl_ast_expr *isl_ast_expr_op_restore_args(
420 __isl_take isl_ast_expr *expr, __isl_take isl_ast_expr_list *args)
422 if (isl_ast_expr_check_op(expr) < 0 || !args)
423 goto error;
424 if (expr->u.op.args == args) {
425 isl_ast_expr_list_free(args);
426 return expr;
429 expr = isl_ast_expr_cow(expr);
430 if (!expr)
431 goto error;
433 isl_ast_expr_list_free(expr->u.op.args);
434 expr->u.op.args = args;
436 return expr;
437 error:
438 isl_ast_expr_free(expr);
439 isl_ast_expr_list_free(args);
440 return NULL;
443 /* Add "arg" to the arguments of the operation expression "expr".
445 __isl_give isl_ast_expr *isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr,
446 __isl_take isl_ast_expr *arg)
448 isl_ast_expr_list *args;
450 args = isl_ast_expr_op_take_args(expr);
451 args = isl_ast_expr_list_add(args, arg);
452 expr = isl_ast_expr_op_restore_args(expr, args);
454 return expr;
457 /* Replace the argument at position "pos" of "expr" by "arg".
459 __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
460 int pos, __isl_take isl_ast_expr *arg)
462 isl_ast_expr_list *args;
464 args = isl_ast_expr_op_take_args(expr);
465 args = isl_ast_expr_list_set_at(args, pos, arg);
466 expr = isl_ast_expr_op_restore_args(expr, args);
468 return expr;
471 /* Are the lists of AST expressions "list1" and "list2" the same?
473 static isl_bool isl_ast_expr_list_is_equal(__isl_keep isl_ast_expr_list *list1,
474 __isl_keep isl_ast_expr_list *list2)
476 int i;
477 isl_size n1, n2;
479 if (!list1 || !list2)
480 return isl_bool_error;
481 if (list1 == list2)
482 return isl_bool_true;
484 n1 = isl_ast_expr_list_size(list1);
485 n2 = isl_ast_expr_list_size(list2);
486 if (n1 < 0 || n2 < 0)
487 return isl_bool_error;
488 if (n1 != n2)
489 return isl_bool_false;
490 for (i = 0; i < n1; ++i) {
491 isl_ast_expr *expr1, *expr2;
492 isl_bool equal;
494 expr1 = isl_ast_expr_list_get_at(list1, i);
495 expr2 = isl_ast_expr_list_get_at(list2, i);
496 equal = isl_ast_expr_is_equal(expr1, expr2);
497 isl_ast_expr_free(expr1);
498 isl_ast_expr_free(expr2);
499 if (equal < 0 || !equal)
500 return equal;
503 return isl_bool_true;
506 /* Is "expr1" equal to "expr2"?
508 isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
509 __isl_keep isl_ast_expr *expr2)
511 if (!expr1 || !expr2)
512 return isl_bool_error;
514 if (expr1 == expr2)
515 return isl_bool_true;
516 if (expr1->type != expr2->type)
517 return isl_bool_false;
518 switch (expr1->type) {
519 case isl_ast_expr_int:
520 return isl_val_eq(expr1->u.v, expr2->u.v);
521 case isl_ast_expr_id:
522 return isl_bool_ok(expr1->u.id == expr2->u.id);
523 case isl_ast_expr_op:
524 if (expr1->u.op.op != expr2->u.op.op)
525 return isl_bool_false;
526 return isl_ast_expr_list_is_equal(expr1->u.op.args,
527 expr2->u.op.args);
528 case isl_ast_expr_error:
529 return isl_bool_error;
532 isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal,
533 "unhandled case", return isl_bool_error);
536 /* Create a new id expression representing "id".
538 __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
540 isl_ctx *ctx;
541 isl_ast_expr *expr;
543 if (!id)
544 return NULL;
546 ctx = isl_id_get_ctx(id);
547 expr = isl_calloc_type(ctx, isl_ast_expr);
548 if (!expr)
549 goto error;
551 expr->ctx = ctx;
552 isl_ctx_ref(ctx);
553 expr->ref = 1;
554 expr->type = isl_ast_expr_id;
555 expr->u.id = id;
557 return expr;
558 error:
559 isl_id_free(id);
560 return NULL;
563 /* Create a new integer expression representing "i".
565 __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
567 isl_ast_expr *expr;
569 expr = isl_calloc_type(ctx, isl_ast_expr);
570 if (!expr)
571 return NULL;
573 expr->ctx = ctx;
574 isl_ctx_ref(ctx);
575 expr->ref = 1;
576 expr->type = isl_ast_expr_int;
577 expr->u.v = isl_val_int_from_si(ctx, i);
578 if (!expr->u.v)
579 return isl_ast_expr_free(expr);
581 return expr;
584 /* Create a new integer expression representing "v".
586 __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
588 isl_ctx *ctx;
589 isl_ast_expr *expr;
591 if (!v)
592 return NULL;
593 if (!isl_val_is_int(v))
594 isl_die(isl_val_get_ctx(v), isl_error_invalid,
595 "expecting integer value", goto error);
597 ctx = isl_val_get_ctx(v);
598 expr = isl_calloc_type(ctx, isl_ast_expr);
599 if (!expr)
600 goto error;
602 expr->ctx = ctx;
603 isl_ctx_ref(ctx);
604 expr->ref = 1;
605 expr->type = isl_ast_expr_int;
606 expr->u.v = v;
608 return expr;
609 error:
610 isl_val_free(v);
611 return NULL;
614 /* Create an expression representing the unary operation "type" applied to
615 * "arg".
617 __isl_give isl_ast_expr *isl_ast_expr_alloc_unary(
618 enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg)
620 isl_ctx *ctx;
621 isl_ast_expr *expr = NULL;
622 isl_ast_expr_list *args;
624 if (!arg)
625 return NULL;
627 ctx = isl_ast_expr_get_ctx(arg);
628 expr = isl_ast_expr_alloc_op(ctx, type, 1);
630 args = isl_ast_expr_op_take_args(expr);
631 args = isl_ast_expr_list_add(args, arg);
632 expr = isl_ast_expr_op_restore_args(expr, args);
634 return expr;
637 /* Create an expression representing the negation of "arg".
639 __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
641 return isl_ast_expr_alloc_unary(isl_ast_expr_op_minus, arg);
644 /* Create an expression representing the address of "expr".
646 __isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
648 if (!expr)
649 return NULL;
651 if (isl_ast_expr_get_type(expr) != isl_ast_expr_op ||
652 isl_ast_expr_get_op_type(expr) != isl_ast_expr_op_access)
653 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
654 "can only take address of access expressions",
655 return isl_ast_expr_free(expr));
657 return isl_ast_expr_alloc_unary(isl_ast_expr_op_address_of, expr);
660 /* Create an expression representing the binary operation "type"
661 * applied to "expr1" and "expr2".
663 __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(
664 enum isl_ast_expr_op_type type,
665 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
667 isl_ctx *ctx;
668 isl_ast_expr *expr = NULL;
669 isl_ast_expr_list *args;
671 if (!expr1 || !expr2)
672 goto error;
674 ctx = isl_ast_expr_get_ctx(expr1);
675 expr = isl_ast_expr_alloc_op(ctx, type, 2);
677 args = isl_ast_expr_op_take_args(expr);
678 args = isl_ast_expr_list_add(args, expr1);
679 args = isl_ast_expr_list_add(args, expr2);
680 expr = isl_ast_expr_op_restore_args(expr, args);
682 return expr;
683 error:
684 isl_ast_expr_free(expr1);
685 isl_ast_expr_free(expr2);
686 return NULL;
689 /* Create an expression representing the sum of "expr1" and "expr2".
691 __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
692 __isl_take isl_ast_expr *expr2)
694 return isl_ast_expr_alloc_binary(isl_ast_expr_op_add, expr1, expr2);
697 /* Create an expression representing the difference of "expr1" and "expr2".
699 __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
700 __isl_take isl_ast_expr *expr2)
702 return isl_ast_expr_alloc_binary(isl_ast_expr_op_sub, expr1, expr2);
705 /* Create an expression representing the product of "expr1" and "expr2".
707 __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
708 __isl_take isl_ast_expr *expr2)
710 return isl_ast_expr_alloc_binary(isl_ast_expr_op_mul, expr1, expr2);
713 /* Create an expression representing the quotient of "expr1" and "expr2".
715 __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
716 __isl_take isl_ast_expr *expr2)
718 return isl_ast_expr_alloc_binary(isl_ast_expr_op_div, expr1, expr2);
721 /* Create an expression representing the quotient of the integer
722 * division of "expr1" by "expr2", where "expr1" is known to be
723 * non-negative.
725 __isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
726 __isl_take isl_ast_expr *expr2)
728 return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_q, expr1, expr2);
731 /* Create an expression representing the remainder of the integer
732 * division of "expr1" by "expr2", where "expr1" is known to be
733 * non-negative.
735 __isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
736 __isl_take isl_ast_expr *expr2)
738 return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_r, expr1, expr2);
741 /* Create an expression representing the conjunction of "expr1" and "expr2".
743 __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
744 __isl_take isl_ast_expr *expr2)
746 return isl_ast_expr_alloc_binary(isl_ast_expr_op_and, expr1, expr2);
749 /* Create an expression representing the conjunction of "expr1" and "expr2",
750 * where "expr2" is evaluated only if "expr1" is evaluated to true.
752 __isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
753 __isl_take isl_ast_expr *expr2)
755 return isl_ast_expr_alloc_binary(isl_ast_expr_op_and_then, expr1, expr2);
758 /* Create an expression representing the disjunction of "expr1" and "expr2".
760 __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
761 __isl_take isl_ast_expr *expr2)
763 return isl_ast_expr_alloc_binary(isl_ast_expr_op_or, expr1, expr2);
766 /* Create an expression representing the disjunction of "expr1" and "expr2",
767 * where "expr2" is evaluated only if "expr1" is evaluated to false.
769 __isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
770 __isl_take isl_ast_expr *expr2)
772 return isl_ast_expr_alloc_binary(isl_ast_expr_op_or_else, expr1, expr2);
775 /* Create an expression representing "expr1" less than or equal to "expr2".
777 __isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
778 __isl_take isl_ast_expr *expr2)
780 return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, expr1, expr2);
783 /* Create an expression representing "expr1" less than "expr2".
785 __isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
786 __isl_take isl_ast_expr *expr2)
788 return isl_ast_expr_alloc_binary(isl_ast_expr_op_lt, expr1, expr2);
791 /* Create an expression representing "expr1" greater than or equal to "expr2".
793 __isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1,
794 __isl_take isl_ast_expr *expr2)
796 return isl_ast_expr_alloc_binary(isl_ast_expr_op_ge, expr1, expr2);
799 /* Create an expression representing "expr1" greater than "expr2".
801 __isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1,
802 __isl_take isl_ast_expr *expr2)
804 return isl_ast_expr_alloc_binary(isl_ast_expr_op_gt, expr1, expr2);
807 /* Create an expression representing "expr1" equal to "expr2".
809 __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
810 __isl_take isl_ast_expr *expr2)
812 return isl_ast_expr_alloc_binary(isl_ast_expr_op_eq, expr1, expr2);
815 /* Create an expression of type "type" with as arguments "arg0" followed
816 * by "arguments".
818 static __isl_give isl_ast_expr *ast_expr_with_arguments(
819 enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg0,
820 __isl_take isl_ast_expr_list *arguments)
822 arguments = isl_ast_expr_list_insert(arguments, 0, arg0);
823 return alloc_op(type, arguments);
826 /* Create an expression representing an access to "array" with index
827 * expressions "indices".
829 __isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
830 __isl_take isl_ast_expr_list *indices)
832 return ast_expr_with_arguments(isl_ast_expr_op_access, array, indices);
835 /* Create an expression representing a call to "function" with argument
836 * expressions "arguments".
838 __isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
839 __isl_take isl_ast_expr_list *arguments)
841 return ast_expr_with_arguments(isl_ast_expr_op_call, function, arguments);
844 /* Wrapper around isl_ast_expr_substitute_ids for use
845 * as an isl_ast_expr_list_map callback.
847 static __isl_give isl_ast_expr *substitute_ids(__isl_take isl_ast_expr *expr,
848 void *user)
850 isl_id_to_ast_expr *id2expr = user;
852 return isl_ast_expr_substitute_ids(expr,
853 isl_id_to_ast_expr_copy(id2expr));
856 /* For each subexpression of "expr" of type isl_ast_expr_id,
857 * if it appears in "id2expr", then replace it by the corresponding
858 * expression.
860 __isl_give isl_ast_expr *isl_ast_expr_substitute_ids(
861 __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr)
863 isl_maybe_isl_ast_expr m;
864 isl_ast_expr_list *args;
866 if (!expr || !id2expr)
867 goto error;
869 switch (expr->type) {
870 case isl_ast_expr_int:
871 break;
872 case isl_ast_expr_id:
873 m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id);
874 if (m.valid < 0)
875 goto error;
876 if (!m.valid)
877 break;
878 isl_ast_expr_free(expr);
879 expr = m.value;
880 break;
881 case isl_ast_expr_op:
882 args = isl_ast_expr_op_take_args(expr);
883 args = isl_ast_expr_list_map(args, &substitute_ids, id2expr);
884 expr = isl_ast_expr_op_restore_args(expr, args);
885 break;
886 case isl_ast_expr_error:
887 expr = isl_ast_expr_free(expr);
888 break;
891 isl_id_to_ast_expr_free(id2expr);
892 return expr;
893 error:
894 isl_ast_expr_free(expr);
895 isl_id_to_ast_expr_free(id2expr);
896 return NULL;
899 isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
901 return node ? node->ctx : NULL;
904 enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
906 return node ? node->type : isl_ast_node_error;
909 __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
910 enum isl_ast_node_type type)
912 isl_ast_node *node;
914 node = isl_calloc_type(ctx, isl_ast_node);
915 if (!node)
916 return NULL;
918 node->ctx = ctx;
919 isl_ctx_ref(ctx);
920 node->ref = 1;
921 node->type = type;
923 return node;
926 /* Create an if node with the given guard.
928 * The then body needs to be filled in later.
930 __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
932 isl_ast_node *node;
934 if (!guard)
935 return NULL;
937 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
938 if (!node)
939 goto error;
940 node->u.i.guard = guard;
942 return node;
943 error:
944 isl_ast_expr_free(guard);
945 return NULL;
948 /* Create a for node with the given iterator.
950 * The remaining fields need to be filled in later.
952 __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
954 isl_ast_node *node;
955 isl_ctx *ctx;
957 if (!id)
958 return NULL;
960 ctx = isl_id_get_ctx(id);
961 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
962 if (!node)
963 goto error;
965 node->u.f.iterator = isl_ast_expr_from_id(id);
966 if (!node->u.f.iterator)
967 return isl_ast_node_free(node);
969 return node;
970 error:
971 isl_id_free(id);
972 return NULL;
975 /* Create a mark node, marking "node" with "id".
977 __isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id,
978 __isl_take isl_ast_node *node)
980 isl_ctx *ctx;
981 isl_ast_node *mark;
983 if (!id || !node)
984 goto error;
986 ctx = isl_id_get_ctx(id);
987 mark = isl_ast_node_alloc(ctx, isl_ast_node_mark);
988 if (!mark)
989 goto error;
991 mark->u.m.mark = id;
992 mark->u.m.node = node;
994 return mark;
995 error:
996 isl_id_free(id);
997 isl_ast_node_free(node);
998 return NULL;
1001 /* Create a user node evaluating "expr".
1003 __isl_give isl_ast_node *isl_ast_node_user_from_expr(
1004 __isl_take isl_ast_expr *expr)
1006 isl_ctx *ctx;
1007 isl_ast_node *node;
1009 if (!expr)
1010 return NULL;
1012 ctx = isl_ast_expr_get_ctx(expr);
1013 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
1014 if (!node)
1015 goto error;
1017 node->u.e.expr = expr;
1019 return node;
1020 error:
1021 isl_ast_expr_free(expr);
1022 return NULL;
1025 /* This is an alternative name for the function above.
1027 __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
1029 return isl_ast_node_user_from_expr(expr);
1032 /* Create a block node with the given children.
1034 __isl_give isl_ast_node *isl_ast_node_alloc_block(
1035 __isl_take isl_ast_node_list *list)
1037 isl_ast_node *node;
1038 isl_ctx *ctx;
1040 if (!list)
1041 return NULL;
1043 ctx = isl_ast_node_list_get_ctx(list);
1044 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
1045 if (!node)
1046 goto error;
1048 node->u.b.children = list;
1050 return node;
1051 error:
1052 isl_ast_node_list_free(list);
1053 return NULL;
1056 /* Represent the given list of nodes as a single node, either by
1057 * extract the node from a single element list or by creating
1058 * a block node with the list of nodes as children.
1060 __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
1061 __isl_take isl_ast_node_list *list)
1063 isl_size n;
1064 isl_ast_node *node;
1066 n = isl_ast_node_list_n_ast_node(list);
1067 if (n < 0)
1068 goto error;
1069 if (n != 1)
1070 return isl_ast_node_alloc_block(list);
1072 node = isl_ast_node_list_get_ast_node(list, 0);
1073 isl_ast_node_list_free(list);
1075 return node;
1076 error:
1077 isl_ast_node_list_free(list);
1078 return NULL;
1081 __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
1083 if (!node)
1084 return NULL;
1086 node->ref++;
1087 return node;
1090 /* Return a fresh copy of "node".
1092 * In the case of a degenerate for node, take into account
1093 * that "cond" and "inc" are NULL.
1095 __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
1097 isl_ast_node *dup;
1099 if (!node)
1100 return NULL;
1102 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
1103 if (!dup)
1104 return NULL;
1106 switch (node->type) {
1107 case isl_ast_node_if:
1108 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
1109 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
1110 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
1111 if (!dup->u.i.guard || !dup->u.i.then ||
1112 (node->u.i.else_node && !dup->u.i.else_node))
1113 return isl_ast_node_free(dup);
1114 break;
1115 case isl_ast_node_for:
1116 dup->u.f.degenerate = node->u.f.degenerate;
1117 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
1118 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
1119 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
1120 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.body)
1121 return isl_ast_node_free(dup);
1122 if (node->u.f.degenerate)
1123 break;
1124 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
1125 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
1126 if (!dup->u.f.cond || !dup->u.f.inc)
1127 return isl_ast_node_free(dup);
1128 break;
1129 case isl_ast_node_block:
1130 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
1131 if (!dup->u.b.children)
1132 return isl_ast_node_free(dup);
1133 break;
1134 case isl_ast_node_mark:
1135 dup->u.m.mark = isl_id_copy(node->u.m.mark);
1136 dup->u.m.node = isl_ast_node_copy(node->u.m.node);
1137 if (!dup->u.m.mark || !dup->u.m.node)
1138 return isl_ast_node_free(dup);
1139 break;
1140 case isl_ast_node_user:
1141 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
1142 if (!dup->u.e.expr)
1143 return isl_ast_node_free(dup);
1144 break;
1145 case isl_ast_node_error:
1146 break;
1149 if (!node->annotation)
1150 return dup;
1151 dup->annotation = isl_id_copy(node->annotation);
1152 if (!dup->annotation)
1153 return isl_ast_node_free(dup);
1155 return dup;
1158 __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
1160 if (!node)
1161 return NULL;
1163 if (node->ref == 1)
1164 return node;
1165 node->ref--;
1166 return isl_ast_node_dup(node);
1169 __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node)
1171 if (!node)
1172 return NULL;
1174 if (--node->ref > 0)
1175 return NULL;
1177 switch (node->type) {
1178 case isl_ast_node_if:
1179 isl_ast_expr_free(node->u.i.guard);
1180 isl_ast_node_free(node->u.i.then);
1181 isl_ast_node_free(node->u.i.else_node);
1182 break;
1183 case isl_ast_node_for:
1184 isl_ast_expr_free(node->u.f.iterator);
1185 isl_ast_expr_free(node->u.f.init);
1186 isl_ast_expr_free(node->u.f.cond);
1187 isl_ast_expr_free(node->u.f.inc);
1188 isl_ast_node_free(node->u.f.body);
1189 break;
1190 case isl_ast_node_block:
1191 isl_ast_node_list_free(node->u.b.children);
1192 break;
1193 case isl_ast_node_mark:
1194 isl_id_free(node->u.m.mark);
1195 isl_ast_node_free(node->u.m.node);
1196 break;
1197 case isl_ast_node_user:
1198 isl_ast_expr_free(node->u.e.expr);
1199 break;
1200 case isl_ast_node_error:
1201 break;
1204 isl_id_free(node->annotation);
1205 isl_ctx_deref(node->ctx);
1206 free(node);
1208 return NULL;
1211 /* Check that "node" is of type "type", printing "msg" if not.
1213 static isl_stat isl_ast_node_check_type(__isl_keep isl_ast_node *node,
1214 enum isl_ast_node_type type, const char *msg)
1216 if (!node)
1217 return isl_stat_error;
1218 if (node->type != type)
1219 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, msg,
1220 return isl_stat_error);
1221 return isl_stat_ok;
1224 /* Check that "node" is of type isl_ast_node_block.
1226 static isl_stat isl_ast_node_check_block(__isl_keep isl_ast_node *node)
1228 return isl_ast_node_check_type(node, isl_ast_node_block,
1229 "not a block node");
1232 /* Check that "node" is of type isl_ast_node_if.
1234 static isl_stat isl_ast_node_check_if(__isl_keep isl_ast_node *node)
1236 return isl_ast_node_check_type(node, isl_ast_node_if, "not an if node");
1239 /* Check that "node" is of type isl_ast_node_for.
1241 static isl_stat isl_ast_node_check_for(__isl_keep isl_ast_node *node)
1243 return isl_ast_node_check_type(node, isl_ast_node_for,
1244 "not a for node");
1247 /* Check that "node" is of type isl_ast_node_mark.
1249 static isl_stat isl_ast_node_check_mark(__isl_keep isl_ast_node *node)
1251 return isl_ast_node_check_type(node, isl_ast_node_mark,
1252 "not a mark node");
1255 /* Check that "node" is of type isl_ast_node_user.
1257 static isl_stat isl_ast_node_check_user(__isl_keep isl_ast_node *node)
1259 return isl_ast_node_check_type(node, isl_ast_node_user,
1260 "not a user node");
1263 /* Return the body of the for-node "node",
1264 * This may be either a copy or the body itself
1265 * if there is only one reference to "node".
1266 * This allows the body to be modified inplace
1267 * if both "node" and its body have only a single reference.
1268 * The caller is not allowed to modify "node" between this call and
1269 * the subsequent call to isl_ast_node_for_restore_body.
1270 * The only exception is that isl_ast_node_free can be called instead.
1272 static __isl_give isl_ast_node *isl_ast_node_for_take_body(
1273 __isl_keep isl_ast_node *node)
1275 isl_ast_node *body;
1277 if (isl_ast_node_check_for(node) < 0)
1278 return NULL;
1279 if (node->ref != 1)
1280 return isl_ast_node_for_get_body(node);
1281 body = node->u.f.body;
1282 node->u.f.body = NULL;
1283 return body;
1286 /* Set the body of the for-node "node" to "body",
1287 * where the body of "node" may be missing
1288 * due to a preceding call to isl_ast_node_for_take_body.
1289 * However, in this case, "node" only has a single reference and
1290 * then the call to isl_ast_node_cow has no effect.
1292 static __isl_give isl_ast_node *isl_ast_node_for_restore_body(
1293 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
1295 if (isl_ast_node_check_for(node) < 0 || !body)
1296 goto error;
1297 if (node->u.f.body == body) {
1298 isl_ast_node_free(body);
1299 return node;
1302 node = isl_ast_node_cow(node);
1303 if (!node)
1304 goto error;
1306 isl_ast_node_free(node->u.f.body);
1307 node->u.f.body = body;
1309 return node;
1310 error:
1311 isl_ast_node_free(node);
1312 isl_ast_node_free(body);
1313 return NULL;
1316 /* Replace the body of the for node "node" by "body".
1318 __isl_give isl_ast_node *isl_ast_node_for_set_body(
1319 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
1321 return isl_ast_node_for_restore_body(node, body);
1324 __isl_give isl_ast_node *isl_ast_node_for_get_body(
1325 __isl_keep isl_ast_node *node)
1327 if (isl_ast_node_check_for(node) < 0)
1328 return NULL;
1329 return isl_ast_node_copy(node->u.f.body);
1332 /* Mark the given for node as being degenerate.
1334 __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
1335 __isl_take isl_ast_node *node)
1337 node = isl_ast_node_cow(node);
1338 if (!node)
1339 return NULL;
1340 node->u.f.degenerate = 1;
1341 return node;
1344 isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
1346 if (isl_ast_node_check_for(node) < 0)
1347 return isl_bool_error;
1348 return isl_bool_ok(node->u.f.degenerate);
1351 __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
1352 __isl_keep isl_ast_node *node)
1354 if (isl_ast_node_check_for(node) < 0)
1355 return NULL;
1356 return isl_ast_expr_copy(node->u.f.iterator);
1359 __isl_give isl_ast_expr *isl_ast_node_for_get_init(
1360 __isl_keep isl_ast_node *node)
1362 if (isl_ast_node_check_for(node) < 0)
1363 return NULL;
1364 return isl_ast_expr_copy(node->u.f.init);
1367 /* Return the condition expression of the given for node.
1369 * If the for node is degenerate, then the condition is not explicitly
1370 * stored in the node. Instead, it is constructed as
1372 * iterator <= init
1374 __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
1375 __isl_keep isl_ast_node *node)
1377 if (isl_ast_node_check_for(node) < 0)
1378 return NULL;
1379 if (!node->u.f.degenerate)
1380 return isl_ast_expr_copy(node->u.f.cond);
1382 return isl_ast_expr_alloc_binary(isl_ast_expr_op_le,
1383 isl_ast_expr_copy(node->u.f.iterator),
1384 isl_ast_expr_copy(node->u.f.init));
1387 /* Return the increment of the given for node.
1389 * If the for node is degenerate, then the increment is not explicitly
1390 * stored in the node. We simply return "1".
1392 __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
1393 __isl_keep isl_ast_node *node)
1395 if (isl_ast_node_check_for(node) < 0)
1396 return NULL;
1397 if (!node->u.f.degenerate)
1398 return isl_ast_expr_copy(node->u.f.inc);
1399 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
1402 /* Return the then-branch of the if-node "node",
1403 * This may be either a copy or the branch itself
1404 * if there is only one reference to "node".
1405 * This allows the branch to be modified inplace
1406 * if both "node" and its then-branch have only a single reference.
1407 * The caller is not allowed to modify "node" between this call and
1408 * the subsequent call to isl_ast_node_if_restore_then_node.
1409 * The only exception is that isl_ast_node_free can be called instead.
1411 static __isl_give isl_ast_node *isl_ast_node_if_take_then_node(
1412 __isl_keep isl_ast_node *node)
1414 isl_ast_node *then_node;
1416 if (isl_ast_node_check_if(node) < 0)
1417 return NULL;
1418 if (node->ref != 1)
1419 return isl_ast_node_if_get_then_node(node);
1420 then_node = node->u.i.then;
1421 node->u.i.then = NULL;
1422 return then_node;
1425 /* Set the then-branch of the if-node "node" to "child",
1426 * where the then-branch of "node" may be missing
1427 * due to a preceding call to isl_ast_node_if_take_then_node.
1428 * However, in this case, "node" only has a single reference and
1429 * then the call to isl_ast_node_cow has no effect.
1431 static __isl_give isl_ast_node *isl_ast_node_if_restore_then_node(
1432 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1434 if (isl_ast_node_check_if(node) < 0 || !child)
1435 goto error;
1436 if (node->u.i.then == child) {
1437 isl_ast_node_free(child);
1438 return node;
1441 node = isl_ast_node_cow(node);
1442 if (!node)
1443 goto error;
1445 isl_ast_node_free(node->u.i.then);
1446 node->u.i.then = child;
1448 return node;
1449 error:
1450 isl_ast_node_free(node);
1451 isl_ast_node_free(child);
1452 return NULL;
1455 /* Replace the then branch of the if node "node" by "child".
1457 __isl_give isl_ast_node *isl_ast_node_if_set_then(
1458 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1460 return isl_ast_node_if_restore_then_node(node, child);
1463 /* Return the then-node of the given if-node.
1465 __isl_give isl_ast_node *isl_ast_node_if_get_then_node(
1466 __isl_keep isl_ast_node *node)
1468 if (isl_ast_node_check_if(node) < 0)
1469 return NULL;
1470 return isl_ast_node_copy(node->u.i.then);
1473 /* This is an alternative name for the function above.
1475 __isl_give isl_ast_node *isl_ast_node_if_get_then(
1476 __isl_keep isl_ast_node *node)
1478 return isl_ast_node_if_get_then_node(node);
1481 /* Does the given if-node have an else-node?
1483 isl_bool isl_ast_node_if_has_else_node(__isl_keep isl_ast_node *node)
1485 if (isl_ast_node_check_if(node) < 0)
1486 return isl_bool_error;
1487 return isl_bool_ok(node->u.i.else_node != NULL);
1490 /* This is an alternative name for the function above.
1492 isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node)
1494 return isl_ast_node_if_has_else_node(node);
1497 /* Return the else-node of the given if-node,
1498 * assuming there is one.
1500 __isl_give isl_ast_node *isl_ast_node_if_get_else_node(
1501 __isl_keep isl_ast_node *node)
1503 if (isl_ast_node_check_if(node) < 0)
1504 return NULL;
1505 return isl_ast_node_copy(node->u.i.else_node);
1508 /* This is an alternative name for the function above.
1510 __isl_give isl_ast_node *isl_ast_node_if_get_else(
1511 __isl_keep isl_ast_node *node)
1513 return isl_ast_node_if_get_else_node(node);
1516 /* Return the else-branch of the if-node "node",
1517 * This may be either a copy or the branch itself
1518 * if there is only one reference to "node".
1519 * This allows the branch to be modified inplace
1520 * if both "node" and its else-branch have only a single reference.
1521 * The caller is not allowed to modify "node" between this call and
1522 * the subsequent call to isl_ast_node_if_restore_else_node.
1523 * The only exception is that isl_ast_node_free can be called instead.
1525 static __isl_give isl_ast_node *isl_ast_node_if_take_else_node(
1526 __isl_keep isl_ast_node *node)
1528 isl_ast_node *else_node;
1530 if (isl_ast_node_check_if(node) < 0)
1531 return NULL;
1532 if (node->ref != 1)
1533 return isl_ast_node_if_get_else_node(node);
1534 else_node = node->u.i.else_node;
1535 node->u.i.else_node = NULL;
1536 return else_node;
1539 /* Set the else-branch of the if-node "node" to "child",
1540 * where the else-branch of "node" may be missing
1541 * due to a preceding call to isl_ast_node_if_take_else_node.
1542 * However, in this case, "node" only has a single reference and
1543 * then the call to isl_ast_node_cow has no effect.
1545 static __isl_give isl_ast_node *isl_ast_node_if_restore_else_node(
1546 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1548 if (isl_ast_node_check_if(node) < 0 || !child)
1549 goto error;
1550 if (node->u.i.else_node == child) {
1551 isl_ast_node_free(child);
1552 return node;
1555 node = isl_ast_node_cow(node);
1556 if (!node)
1557 goto error;
1559 isl_ast_node_free(node->u.i.else_node);
1560 node->u.i.else_node = child;
1562 return node;
1563 error:
1564 isl_ast_node_free(node);
1565 isl_ast_node_free(child);
1566 return NULL;
1569 __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
1570 __isl_keep isl_ast_node *node)
1572 if (isl_ast_node_check_if(node) < 0)
1573 return NULL;
1574 return isl_ast_expr_copy(node->u.i.guard);
1577 __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
1578 __isl_keep isl_ast_node *node)
1580 if (isl_ast_node_check_block(node) < 0)
1581 return NULL;
1582 return isl_ast_node_list_copy(node->u.b.children);
1585 /* Return the children of the block-node "node",
1586 * This may be either a copy or the children themselves
1587 * if there is only one reference to "node".
1588 * This allows the children to be modified inplace
1589 * if both "node" and its children have only a single reference.
1590 * The caller is not allowed to modify "node" between this call and
1591 * the subsequent call to isl_ast_node_block_restore_children.
1592 * The only exception is that isl_ast_node_free can be called instead.
1594 static __isl_give isl_ast_node_list *isl_ast_node_block_take_children(
1595 __isl_keep isl_ast_node *node)
1597 isl_ast_node_list *children;
1599 if (isl_ast_node_check_block(node) < 0)
1600 return NULL;
1601 if (node->ref != 1)
1602 return isl_ast_node_block_get_children(node);
1603 children = node->u.b.children;
1604 node->u.b.children = NULL;
1605 return children;
1608 /* Set the children of the block-node "node" to "children",
1609 * where the children of "node" may be missing
1610 * due to a preceding call to isl_ast_node_block_take_children.
1611 * However, in this case, "node" only has a single reference and
1612 * then the call to isl_ast_node_cow has no effect.
1614 static __isl_give isl_ast_node *isl_ast_node_block_restore_children(
1615 __isl_take isl_ast_node *node, __isl_take isl_ast_node_list *children)
1617 if (isl_ast_node_check_block(node) < 0 || !children)
1618 goto error;
1619 if (node->u.b.children == children) {
1620 isl_ast_node_list_free(children);
1621 return node;
1624 node = isl_ast_node_cow(node);
1625 if (!node)
1626 goto error;
1628 isl_ast_node_list_free(node->u.b.children);
1629 node->u.b.children = children;
1631 return node;
1632 error:
1633 isl_ast_node_free(node);
1634 isl_ast_node_list_free(children);
1635 return NULL;
1638 __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
1639 __isl_keep isl_ast_node *node)
1641 if (isl_ast_node_check_user(node) < 0)
1642 return NULL;
1644 return isl_ast_expr_copy(node->u.e.expr);
1647 /* Return the mark identifier of the mark node "node".
1649 __isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
1651 if (isl_ast_node_check_mark(node) < 0)
1652 return NULL;
1654 return isl_id_copy(node->u.m.mark);
1657 /* Return the node marked by mark node "node".
1659 __isl_give isl_ast_node *isl_ast_node_mark_get_node(
1660 __isl_keep isl_ast_node *node)
1662 if (isl_ast_node_check_mark(node) < 0)
1663 return NULL;
1665 return isl_ast_node_copy(node->u.m.node);
1668 /* Return the child of the mark-node "node",
1669 * This may be either a copy or the child itself
1670 * if there is only one reference to "node".
1671 * This allows the child to be modified inplace
1672 * if both "node" and its child have only a single reference.
1673 * The caller is not allowed to modify "node" between this call and
1674 * the subsequent call to isl_ast_node_mark_restore_node.
1675 * The only exception is that isl_ast_node_free can be called instead.
1677 static __isl_give isl_ast_node *isl_ast_node_mark_take_node(
1678 __isl_keep isl_ast_node *node)
1680 isl_ast_node *child;
1682 if (isl_ast_node_check_mark(node) < 0)
1683 return NULL;
1684 if (node->ref != 1)
1685 return isl_ast_node_mark_get_node(node);
1686 child = node->u.m.node;
1687 node->u.m.node = NULL;
1688 return child;
1691 /* Set the child of the mark-node "node" to "child",
1692 * where the child of "node" may be missing
1693 * due to a preceding call to isl_ast_node_mark_take_node.
1694 * However, in this case, "node" only has a single reference and
1695 * then the call to isl_ast_node_cow has no effect.
1697 static __isl_give isl_ast_node *isl_ast_node_mark_restore_node(
1698 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1700 if (isl_ast_node_check_mark(node) < 0 || !child)
1701 goto error;
1702 if (node->u.m.node == child) {
1703 isl_ast_node_free(child);
1704 return node;
1707 node = isl_ast_node_cow(node);
1708 if (!node)
1709 goto error;
1711 isl_ast_node_free(node->u.m.node);
1712 node->u.m.node = child;
1714 return node;
1715 error:
1716 isl_ast_node_free(node);
1717 isl_ast_node_free(child);
1718 return NULL;
1721 __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
1723 return node ? isl_id_copy(node->annotation) : NULL;
1726 /* Replace node->annotation by "annotation".
1728 __isl_give isl_ast_node *isl_ast_node_set_annotation(
1729 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1731 node = isl_ast_node_cow(node);
1732 if (!node || !annotation)
1733 goto error;
1735 isl_id_free(node->annotation);
1736 node->annotation = annotation;
1738 return node;
1739 error:
1740 isl_id_free(annotation);
1741 return isl_ast_node_free(node);
1744 static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node,
1745 __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1746 int *more, void *user),
1747 __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1748 void *user),
1749 void *user);
1751 /* Traverse the elements of "list" and all their descendants
1752 * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1753 * whenever a node is left.
1755 * Return the updated node.
1757 static __isl_give isl_ast_node_list *traverse_list(
1758 __isl_take isl_ast_node_list *list,
1759 __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1760 int *more, void *user),
1761 __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1762 void *user),
1763 void *user)
1765 int i;
1766 isl_size n;
1768 n = isl_ast_node_list_size(list);
1769 if (n < 0)
1770 return isl_ast_node_list_free(list);
1772 for (i = 0; i < n; ++i) {
1773 isl_ast_node *node;
1775 node = isl_ast_node_list_get_at(list, i);
1776 node = traverse(node, enter, leave, user);
1777 list = isl_ast_node_list_set_at(list, i, node);
1780 return list;
1783 /* Traverse the descendants of "node" (including the node itself)
1784 * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1785 * whenever a node is left.
1787 * If "enter" sets the "more" argument to zero, then the subtree rooted
1788 * at the given node is skipped.
1790 * Return the updated node.
1792 static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node,
1793 __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1794 int *more, void *user),
1795 __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1796 void *user),
1797 void *user)
1799 int more;
1800 isl_bool has_else;
1801 isl_ast_node *child;
1802 isl_ast_node_list *children;
1804 node = enter(node, &more, user);
1805 if (!node)
1806 return NULL;
1807 if (!more)
1808 return node;
1810 switch (node->type) {
1811 case isl_ast_node_for:
1812 child = isl_ast_node_for_take_body(node);
1813 child = traverse(child, enter, leave, user);
1814 node = isl_ast_node_for_restore_body(node, child);
1815 return leave(node, user);
1816 case isl_ast_node_if:
1817 child = isl_ast_node_if_take_then_node(node);
1818 child = traverse(child, enter, leave, user);
1819 node = isl_ast_node_if_restore_then_node(node, child);
1820 has_else = isl_ast_node_if_has_else_node(node);
1821 if (has_else < 0)
1822 return isl_ast_node_free(node);
1823 if (!has_else)
1824 return leave(node, user);
1825 child = isl_ast_node_if_take_else_node(node);
1826 child = traverse(child, enter, leave, user);
1827 node = isl_ast_node_if_restore_else_node(node, child);
1828 return leave(node, user);
1829 case isl_ast_node_block:
1830 children = isl_ast_node_block_take_children(node);
1831 children = traverse_list(children, enter, leave, user);
1832 node = isl_ast_node_block_restore_children(node, children);
1833 return leave(node, user);
1834 case isl_ast_node_mark:
1835 child = isl_ast_node_mark_take_node(node);
1836 child = traverse(child, enter, leave, user);
1837 node = isl_ast_node_mark_restore_node(node, child);
1838 return leave(node, user);
1839 case isl_ast_node_user:
1840 return leave(node, user);
1841 case isl_ast_node_error:
1842 return isl_ast_node_free(node);
1845 return node;
1848 /* Internal data structure storing the arguments of
1849 * isl_ast_node_foreach_descendant_top_down.
1851 struct isl_ast_node_preorder_data {
1852 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user);
1853 void *user;
1856 /* Enter "node" and set *more to continue traversing its descendants.
1858 * In the case of a depth first preorder traversal, call data->fn and
1859 * let it decide whether to continue.
1861 static __isl_give isl_ast_node *preorder_enter(__isl_take isl_ast_node *node,
1862 int *more, void *user)
1864 struct isl_ast_node_preorder_data *data = user;
1865 isl_bool m;
1867 if (!node)
1868 return NULL;
1869 m = data->fn(node, data->user);
1870 if (m < 0)
1871 return isl_ast_node_free(node);
1872 *more = m;
1873 return node;
1876 /* Leave "node".
1878 * In the case of a depth first preorder traversal, nothing needs to be done.
1880 static __isl_give isl_ast_node *preorder_leave(__isl_take isl_ast_node *node,
1881 void *user)
1883 return node;
1886 /* Traverse the descendants of "node" (including the node itself)
1887 * in depth first preorder.
1889 * If "fn" returns isl_bool_error on any of the nodes, then the traversal
1890 * is aborted.
1891 * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
1892 * at that node is skipped.
1894 * Return isl_stat_ok on success and isl_stat_error on failure.
1896 isl_stat isl_ast_node_foreach_descendant_top_down(
1897 __isl_keep isl_ast_node *node,
1898 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1900 struct isl_ast_node_preorder_data data = { fn, user };
1902 node = isl_ast_node_copy(node);
1903 node = traverse(node, &preorder_enter, &preorder_leave, &data);
1904 isl_ast_node_free(node);
1906 return isl_stat_non_null(node);
1909 /* Internal data structure storing the arguments of
1910 * isl_ast_node_map_descendant_bottom_up.
1912 struct isl_ast_node_postorder_data {
1913 __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node,
1914 void *user);
1915 void *user;
1918 /* Enter "node" and set *more to continue traversing its descendants.
1920 * In the case of a depth-first post-order traversal,
1921 * nothing needs to be done and traversal always continues.
1923 static __isl_give isl_ast_node *postorder_enter(__isl_take isl_ast_node *node,
1924 int *more, void *user)
1926 *more = 1;
1927 return node;
1930 /* Leave "node".
1932 * In the case of a depth-first post-order traversal, call data->fn.
1934 static __isl_give isl_ast_node *postorder_leave(__isl_take isl_ast_node *node,
1935 void *user)
1937 struct isl_ast_node_postorder_data *data = user;
1939 if (!node)
1940 return NULL;
1942 node = data->fn(node, data->user);
1943 return node;
1946 /* Traverse the descendants of "node" (including the node itself)
1947 * in depth-first post-order, where the user callback is allowed to modify the
1948 * visited node.
1950 * Return the updated node.
1952 __isl_give isl_ast_node *isl_ast_node_map_descendant_bottom_up(
1953 __isl_take isl_ast_node *node,
1954 __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node,
1955 void *user), void *user)
1957 struct isl_ast_node_postorder_data data = { fn, user };
1959 return traverse(node, &postorder_enter, &postorder_leave, &data);
1962 /* Textual C representation of the various operators.
1964 static char *op_str_c[] = {
1965 [isl_ast_expr_op_and] = "&&",
1966 [isl_ast_expr_op_and_then] = "&&",
1967 [isl_ast_expr_op_or] = "||",
1968 [isl_ast_expr_op_or_else] = "||",
1969 [isl_ast_expr_op_max] = "max",
1970 [isl_ast_expr_op_min] = "min",
1971 [isl_ast_expr_op_minus] = "-",
1972 [isl_ast_expr_op_add] = "+",
1973 [isl_ast_expr_op_sub] = "-",
1974 [isl_ast_expr_op_mul] = "*",
1975 [isl_ast_expr_op_fdiv_q] = "floord",
1976 [isl_ast_expr_op_pdiv_q] = "/",
1977 [isl_ast_expr_op_pdiv_r] = "%",
1978 [isl_ast_expr_op_zdiv_r] = "%",
1979 [isl_ast_expr_op_div] = "/",
1980 [isl_ast_expr_op_eq] = "==",
1981 [isl_ast_expr_op_le] = "<=",
1982 [isl_ast_expr_op_ge] = ">=",
1983 [isl_ast_expr_op_lt] = "<",
1984 [isl_ast_expr_op_gt] = ">",
1985 [isl_ast_expr_op_member] = ".",
1986 [isl_ast_expr_op_address_of] = "&"
1989 /* Precedence in C of the various operators.
1990 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1991 * Lowest value means highest precedence.
1993 static int op_prec[] = {
1994 [isl_ast_expr_op_and] = 13,
1995 [isl_ast_expr_op_and_then] = 13,
1996 [isl_ast_expr_op_or] = 14,
1997 [isl_ast_expr_op_or_else] = 14,
1998 [isl_ast_expr_op_max] = 2,
1999 [isl_ast_expr_op_min] = 2,
2000 [isl_ast_expr_op_minus] = 3,
2001 [isl_ast_expr_op_add] = 6,
2002 [isl_ast_expr_op_sub] = 6,
2003 [isl_ast_expr_op_mul] = 5,
2004 [isl_ast_expr_op_div] = 5,
2005 [isl_ast_expr_op_fdiv_q] = 2,
2006 [isl_ast_expr_op_pdiv_q] = 5,
2007 [isl_ast_expr_op_pdiv_r] = 5,
2008 [isl_ast_expr_op_zdiv_r] = 5,
2009 [isl_ast_expr_op_cond] = 15,
2010 [isl_ast_expr_op_select] = 15,
2011 [isl_ast_expr_op_eq] = 9,
2012 [isl_ast_expr_op_le] = 8,
2013 [isl_ast_expr_op_ge] = 8,
2014 [isl_ast_expr_op_lt] = 8,
2015 [isl_ast_expr_op_gt] = 8,
2016 [isl_ast_expr_op_call] = 2,
2017 [isl_ast_expr_op_access] = 2,
2018 [isl_ast_expr_op_member] = 2,
2019 [isl_ast_expr_op_address_of] = 3
2022 /* Is the operator left-to-right associative?
2024 static int op_left[] = {
2025 [isl_ast_expr_op_and] = 1,
2026 [isl_ast_expr_op_and_then] = 1,
2027 [isl_ast_expr_op_or] = 1,
2028 [isl_ast_expr_op_or_else] = 1,
2029 [isl_ast_expr_op_max] = 1,
2030 [isl_ast_expr_op_min] = 1,
2031 [isl_ast_expr_op_minus] = 0,
2032 [isl_ast_expr_op_add] = 1,
2033 [isl_ast_expr_op_sub] = 1,
2034 [isl_ast_expr_op_mul] = 1,
2035 [isl_ast_expr_op_div] = 1,
2036 [isl_ast_expr_op_fdiv_q] = 1,
2037 [isl_ast_expr_op_pdiv_q] = 1,
2038 [isl_ast_expr_op_pdiv_r] = 1,
2039 [isl_ast_expr_op_zdiv_r] = 1,
2040 [isl_ast_expr_op_cond] = 0,
2041 [isl_ast_expr_op_select] = 0,
2042 [isl_ast_expr_op_eq] = 1,
2043 [isl_ast_expr_op_le] = 1,
2044 [isl_ast_expr_op_ge] = 1,
2045 [isl_ast_expr_op_lt] = 1,
2046 [isl_ast_expr_op_gt] = 1,
2047 [isl_ast_expr_op_call] = 1,
2048 [isl_ast_expr_op_access] = 1,
2049 [isl_ast_expr_op_member] = 1,
2050 [isl_ast_expr_op_address_of] = 0
2053 static int is_and(enum isl_ast_expr_op_type op)
2055 return op == isl_ast_expr_op_and || op == isl_ast_expr_op_and_then;
2058 static int is_or(enum isl_ast_expr_op_type op)
2060 return op == isl_ast_expr_op_or || op == isl_ast_expr_op_or_else;
2063 static int is_add_sub(enum isl_ast_expr_op_type op)
2065 return op == isl_ast_expr_op_add || op == isl_ast_expr_op_sub;
2068 static int is_div_mod(enum isl_ast_expr_op_type op)
2070 return op == isl_ast_expr_op_div ||
2071 op == isl_ast_expr_op_pdiv_r ||
2072 op == isl_ast_expr_op_zdiv_r;
2075 static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
2076 __isl_keep isl_ast_expr *expr);
2078 /* Do we need/want parentheses around "expr" as a subexpression of
2079 * an "op" operation? If "left" is set, then "expr" is the left-most
2080 * operand.
2082 * We only need parentheses if "expr" represents an operation.
2084 * If op has a higher precedence than expr->u.op.op, then we need
2085 * parentheses.
2086 * If op and expr->u.op.op have the same precedence, but the operations
2087 * are performed in an order that is different from the associativity,
2088 * then we need parentheses.
2090 * An and inside an or technically does not require parentheses,
2091 * but some compilers complain about that, so we add them anyway.
2093 * Computations such as "a / b * c" and "a % b + c" can be somewhat
2094 * difficult to read, so we add parentheses for those as well.
2096 static int sub_expr_need_parens(enum isl_ast_expr_op_type op,
2097 __isl_keep isl_ast_expr *expr, int left)
2099 if (expr->type != isl_ast_expr_op)
2100 return 0;
2102 if (op_prec[expr->u.op.op] > op_prec[op])
2103 return 1;
2104 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
2105 return 1;
2107 if (is_or(op) && is_and(expr->u.op.op))
2108 return 1;
2109 if (op == isl_ast_expr_op_mul && expr->u.op.op != isl_ast_expr_op_mul &&
2110 op_prec[expr->u.op.op] == op_prec[op])
2111 return 1;
2112 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
2113 return 1;
2115 return 0;
2118 /* Print the subexpression at position "pos" of operation expression "expr"
2119 * in C format.
2120 * If "left" is set, then "expr" is the left-most operand.
2122 static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p,
2123 __isl_keep isl_ast_expr *expr, int pos, int left)
2125 int need_parens;
2126 isl_ast_expr *arg;
2128 if (!expr)
2129 return isl_printer_free(p);
2131 arg = isl_ast_expr_list_get_at(expr->u.op.args, pos);
2132 need_parens = sub_expr_need_parens(expr->u.op.op, arg, left);
2134 if (need_parens)
2135 p = isl_printer_print_str(p, "(");
2136 p = print_ast_expr_c(p, arg);
2137 if (need_parens)
2138 p = isl_printer_print_str(p, ")");
2140 isl_ast_expr_free(arg);
2142 return p;
2145 #define isl_ast_expr_op_last isl_ast_expr_op_address_of
2147 /* Data structure that holds the user-specified textual
2148 * representations for the operators in C format.
2149 * The entries are either NULL or copies of strings.
2150 * A NULL entry means that the default name should be used.
2152 struct isl_ast_expr_op_names {
2153 char *op_str[isl_ast_expr_op_last + 1];
2156 /* Create an empty struct isl_ast_expr_op_names.
2158 static void *create_names(isl_ctx *ctx)
2160 return isl_calloc_type(ctx, struct isl_ast_expr_op_names);
2163 /* Free a struct isl_ast_expr_op_names along with all memory
2164 * owned by the struct.
2166 static void free_names(void *user)
2168 int i;
2169 struct isl_ast_expr_op_names *names = user;
2171 if (!user)
2172 return;
2174 for (i = 0; i <= isl_ast_expr_op_last; ++i)
2175 free(names->op_str[i]);
2176 free(user);
2179 /* Create an identifier that is used to store
2180 * an isl_ast_expr_op_names note.
2182 static __isl_give isl_id *names_id(isl_ctx *ctx)
2184 return isl_id_alloc(ctx, "isl_ast_expr_op_type_names", NULL);
2187 /* Ensure that "p" has a note identified by "id".
2188 * If there is no such note yet, then it is created by "note_create" and
2189 * scheduled do be freed by "note_free".
2191 static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p,
2192 __isl_keep isl_id *id, void *(*note_create)(isl_ctx *),
2193 void (*note_free)(void *))
2195 isl_ctx *ctx;
2196 isl_id *note_id;
2197 isl_bool has_note;
2198 void *note;
2200 has_note = isl_printer_has_note(p, id);
2201 if (has_note < 0)
2202 return isl_printer_free(p);
2203 if (has_note)
2204 return p;
2206 ctx = isl_printer_get_ctx(p);
2207 note = note_create(ctx);
2208 if (!note)
2209 return isl_printer_free(p);
2210 note_id = isl_id_alloc(ctx, NULL, note);
2211 if (!note_id)
2212 note_free(note);
2213 else
2214 note_id = isl_id_set_free_user(note_id, note_free);
2216 p = isl_printer_set_note(p, isl_id_copy(id), note_id);
2218 return p;
2221 /* Ensure that "p" has an isl_ast_expr_op_names note identified by "id".
2223 static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p,
2224 __isl_keep isl_id *id)
2226 return alloc_note(p, id, &create_names, &free_names);
2229 /* Retrieve the note identified by "id" from "p".
2230 * The note is assumed to exist.
2232 static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id)
2234 void *note;
2236 id = isl_printer_get_note(p, isl_id_copy(id));
2237 note = isl_id_get_user(id);
2238 isl_id_free(id);
2240 return note;
2243 /* Use "name" to print operations of type "type" to "p".
2245 * Store the name in an isl_ast_expr_op_names note attached to "p", such that
2246 * it can be retrieved by get_op_str.
2248 __isl_give isl_printer *isl_ast_expr_op_type_set_print_name(
2249 __isl_take isl_printer *p, enum isl_ast_expr_op_type type,
2250 __isl_keep const char *name)
2252 isl_id *id;
2253 struct isl_ast_expr_op_names *names;
2255 if (!p)
2256 return NULL;
2257 if (type > isl_ast_expr_op_last)
2258 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
2259 "invalid type", return isl_printer_free(p));
2261 id = names_id(isl_printer_get_ctx(p));
2262 p = alloc_names(p, id);
2263 names = get_note(p, id);
2264 isl_id_free(id);
2265 if (!names)
2266 return isl_printer_free(p);
2267 free(names->op_str[type]);
2268 names->op_str[type] = strdup(name);
2270 return p;
2273 /* This is an alternative name for the function above.
2275 __isl_give isl_printer *isl_ast_op_type_set_print_name(
2276 __isl_take isl_printer *p, enum isl_ast_expr_op_type type,
2277 __isl_keep const char *name)
2279 return isl_ast_expr_op_type_set_print_name(p, type, name);
2282 /* Return the textual representation of "type" in C format.
2284 * If there is a user-specified name in an isl_ast_expr_op_names note
2285 * associated to "p", then return that.
2286 * Otherwise, return the default name in op_str_c.
2288 static const char *get_op_str_c(__isl_keep isl_printer *p,
2289 enum isl_ast_expr_op_type type)
2291 isl_id *id;
2292 isl_bool has_names;
2293 struct isl_ast_expr_op_names *names = NULL;
2295 id = names_id(isl_printer_get_ctx(p));
2296 has_names = isl_printer_has_note(p, id);
2297 if (has_names >= 0 && has_names)
2298 names = get_note(p, id);
2299 isl_id_free(id);
2300 if (names && names->op_str[type])
2301 return names->op_str[type];
2302 return op_str_c[type];
2305 /* Print the expression at position "pos" in "list" in C format.
2307 static __isl_give isl_printer *print_at_c(__isl_take isl_printer *p,
2308 __isl_keep isl_ast_expr_list *list, int pos)
2310 isl_ast_expr *expr;
2312 expr = isl_ast_expr_list_get_at(list, pos);
2313 p = print_ast_expr_c(p, expr);
2314 isl_ast_expr_free(expr);
2316 return p;
2319 /* Print a min or max reduction "expr" in C format.
2321 static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p,
2322 __isl_keep isl_ast_expr *expr)
2324 int i = 0;
2325 isl_size n;
2327 n = isl_ast_expr_list_size(expr->u.op.args);
2328 if (n < 0)
2329 return isl_printer_free(p);
2331 for (i = 1; i < n; ++i) {
2332 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
2333 p = isl_printer_print_str(p, "(");
2335 p = print_at_c(p, expr->u.op.args, 0);
2336 for (i = 1; i < n; ++i) {
2337 p = isl_printer_print_str(p, ", ");
2338 p = print_at_c(p, expr->u.op.args, i);
2339 p = isl_printer_print_str(p, ")");
2342 return p;
2345 /* Print a function call "expr" in C format.
2347 * The first argument represents the function to be called.
2349 static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p,
2350 __isl_keep isl_ast_expr *expr)
2352 int i = 0;
2353 isl_size n;
2355 n = isl_ast_expr_list_size(expr->u.op.args);
2356 if (n < 0)
2357 return isl_printer_free(p);
2359 p = print_at_c(p, expr->u.op.args, 0);
2360 p = isl_printer_print_str(p, "(");
2361 for (i = 1; i < n; ++i) {
2362 if (i != 1)
2363 p = isl_printer_print_str(p, ", ");
2364 p = print_at_c(p, expr->u.op.args, i);
2366 p = isl_printer_print_str(p, ")");
2368 return p;
2371 /* Print an array access "expr" in C format.
2373 * The first argument represents the array being accessed.
2375 static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p,
2376 __isl_keep isl_ast_expr *expr)
2378 int i = 0;
2379 isl_size n;
2381 n = isl_ast_expr_list_size(expr->u.op.args);
2382 if (n < 0)
2383 return isl_printer_free(p);
2385 p = print_at_c(p, expr->u.op.args, 0);
2386 for (i = 1; i < n; ++i) {
2387 p = isl_printer_print_str(p, "[");
2388 p = print_at_c(p, expr->u.op.args, i);
2389 p = isl_printer_print_str(p, "]");
2392 return p;
2395 /* Print "expr" to "p" in C format.
2397 static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
2398 __isl_keep isl_ast_expr *expr)
2400 isl_size n;
2402 if (!p)
2403 return NULL;
2404 if (!expr)
2405 return isl_printer_free(p);
2407 switch (expr->type) {
2408 case isl_ast_expr_op:
2409 if (expr->u.op.op == isl_ast_expr_op_call) {
2410 p = print_call_c(p, expr);
2411 break;
2413 if (expr->u.op.op == isl_ast_expr_op_access) {
2414 p = print_access_c(p, expr);
2415 break;
2417 n = isl_ast_expr_list_size(expr->u.op.args);
2418 if (n < 0)
2419 return isl_printer_free(p);
2420 if (n == 1) {
2421 p = isl_printer_print_str(p,
2422 get_op_str_c(p, expr->u.op.op));
2423 p = print_sub_expr_c(p, expr, 0, 0);
2424 break;
2426 if (expr->u.op.op == isl_ast_expr_op_fdiv_q) {
2427 const char *name;
2429 name = get_op_str_c(p, isl_ast_expr_op_fdiv_q);
2430 p = isl_printer_print_str(p, name);
2431 p = isl_printer_print_str(p, "(");
2432 p = print_at_c(p, expr->u.op.args, 0);
2433 p = isl_printer_print_str(p, ", ");
2434 p = print_at_c(p, expr->u.op.args, 1);
2435 p = isl_printer_print_str(p, ")");
2436 break;
2438 if (expr->u.op.op == isl_ast_expr_op_max ||
2439 expr->u.op.op == isl_ast_expr_op_min) {
2440 p = print_min_max_c(p, expr);
2441 break;
2443 if (expr->u.op.op == isl_ast_expr_op_cond ||
2444 expr->u.op.op == isl_ast_expr_op_select) {
2445 p = print_at_c(p, expr->u.op.args, 0);
2446 p = isl_printer_print_str(p, " ? ");
2447 p = print_at_c(p, expr->u.op.args, 1);
2448 p = isl_printer_print_str(p, " : ");
2449 p = print_at_c(p, expr->u.op.args, 2);
2450 break;
2452 if (n != 2)
2453 isl_die(isl_printer_get_ctx(p), isl_error_internal,
2454 "operation should have two arguments",
2455 return isl_printer_free(p));
2456 p = print_sub_expr_c(p, expr, 0, 1);
2457 if (expr->u.op.op != isl_ast_expr_op_member)
2458 p = isl_printer_print_str(p, " ");
2459 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
2460 if (expr->u.op.op != isl_ast_expr_op_member)
2461 p = isl_printer_print_str(p, " ");
2462 p = print_sub_expr_c(p, expr, 1, 0);
2463 break;
2464 case isl_ast_expr_id:
2465 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
2466 break;
2467 case isl_ast_expr_int:
2468 p = isl_printer_print_val(p, expr->u.v);
2469 break;
2470 case isl_ast_expr_error:
2471 break;
2474 return p;
2477 /* Textual representation of the isl_ast_expr_op_type elements
2478 * for use in a YAML representation of an isl_ast_expr.
2480 static char *op_str[] = {
2481 [isl_ast_expr_op_and] = "and",
2482 [isl_ast_expr_op_and_then] = "and_then",
2483 [isl_ast_expr_op_or] = "or",
2484 [isl_ast_expr_op_or_else] = "or_else",
2485 [isl_ast_expr_op_max] = "max",
2486 [isl_ast_expr_op_min] = "min",
2487 [isl_ast_expr_op_minus] = "minus",
2488 [isl_ast_expr_op_add] = "add",
2489 [isl_ast_expr_op_sub] = "sub",
2490 [isl_ast_expr_op_mul] = "mul",
2491 [isl_ast_expr_op_div] = "div",
2492 [isl_ast_expr_op_fdiv_q] = "fdiv_q",
2493 [isl_ast_expr_op_pdiv_q] = "pdiv_q",
2494 [isl_ast_expr_op_pdiv_r] = "pdiv_r",
2495 [isl_ast_expr_op_zdiv_r] = "zdiv_r",
2496 [isl_ast_expr_op_cond] = "cond",
2497 [isl_ast_expr_op_select] = "select",
2498 [isl_ast_expr_op_eq] = "eq",
2499 [isl_ast_expr_op_le] = "le",
2500 [isl_ast_expr_op_lt] = "lt",
2501 [isl_ast_expr_op_ge] = "ge",
2502 [isl_ast_expr_op_gt] = "gt",
2503 [isl_ast_expr_op_call] = "call",
2504 [isl_ast_expr_op_access] = "access",
2505 [isl_ast_expr_op_member] = "member",
2506 [isl_ast_expr_op_address_of] = "address_of"
2509 static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
2510 __isl_keep isl_ast_expr *expr);
2512 /* Print the arguments of "expr" to "p" in isl format.
2514 * If there are no arguments, then nothing needs to be printed.
2515 * Otherwise add an "args" key to the current mapping with as value
2516 * the list of arguments of "expr".
2518 static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p,
2519 __isl_keep isl_ast_expr *expr)
2521 int i;
2522 isl_size n;
2524 n = isl_ast_expr_get_op_n_arg(expr);
2525 if (n < 0)
2526 return isl_printer_free(p);
2527 if (n == 0)
2528 return p;
2530 p = isl_printer_print_str(p, "args");
2531 p = isl_printer_yaml_next(p);
2532 p = isl_printer_yaml_start_sequence(p);
2533 for (i = 0; i < n; ++i) {
2534 isl_ast_expr *arg;
2536 arg = isl_ast_expr_get_op_arg(expr, i);
2537 p = print_ast_expr_isl(p, arg);
2538 isl_ast_expr_free(arg);
2539 p = isl_printer_yaml_next(p);
2541 p = isl_printer_yaml_end_sequence(p);
2543 return p;
2546 /* Print "expr" to "p" in isl format.
2548 * In particular, print the isl_ast_expr as a YAML document.
2550 static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
2551 __isl_keep isl_ast_expr *expr)
2553 enum isl_ast_expr_type type;
2554 enum isl_ast_expr_op_type op;
2555 isl_id *id;
2556 isl_val *v;
2558 if (!expr)
2559 return isl_printer_free(p);
2561 p = isl_printer_yaml_start_mapping(p);
2562 type = isl_ast_expr_get_type(expr);
2563 switch (type) {
2564 case isl_ast_expr_error:
2565 return isl_printer_free(p);
2566 case isl_ast_expr_op:
2567 op = isl_ast_expr_get_op_type(expr);
2568 if (op == isl_ast_expr_op_error)
2569 return isl_printer_free(p);
2570 p = isl_printer_print_str(p, "op");
2571 p = isl_printer_yaml_next(p);
2572 p = isl_printer_print_str(p, op_str[op]);
2573 p = isl_printer_yaml_next(p);
2574 p = print_arguments(p, expr);
2575 break;
2576 case isl_ast_expr_id:
2577 p = isl_printer_print_str(p, "id");
2578 p = isl_printer_yaml_next(p);
2579 id = isl_ast_expr_get_id(expr);
2580 p = isl_printer_print_id(p, id);
2581 isl_id_free(id);
2582 break;
2583 case isl_ast_expr_int:
2584 p = isl_printer_print_str(p, "val");
2585 p = isl_printer_yaml_next(p);
2586 v = isl_ast_expr_get_val(expr);
2587 p = isl_printer_print_val(p, v);
2588 isl_val_free(v);
2589 break;
2591 p = isl_printer_yaml_end_mapping(p);
2593 return p;
2596 /* Print "expr" to "p".
2598 * Only an isl and a C format are supported.
2600 __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
2601 __isl_keep isl_ast_expr *expr)
2603 int format;
2605 if (!p)
2606 return NULL;
2608 format = isl_printer_get_output_format(p);
2609 switch (format) {
2610 case ISL_FORMAT_ISL:
2611 p = print_ast_expr_isl(p, expr);
2612 break;
2613 case ISL_FORMAT_C:
2614 p = print_ast_expr_c(p, expr);
2615 break;
2616 default:
2617 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2618 "output format not supported for ast_expr",
2619 return isl_printer_free(p));
2622 return p;
2625 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2626 __isl_keep isl_ast_node *node);
2628 /* Print a YAML sequence containing the entries in "list" to "p".
2630 static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p,
2631 __isl_keep isl_ast_node_list *list)
2633 int i;
2634 isl_size n;
2636 n = isl_ast_node_list_n_ast_node(list);
2637 if (n < 0)
2638 return isl_printer_free(p);
2640 p = isl_printer_yaml_start_sequence(p);
2641 for (i = 0; i < n; ++i) {
2642 isl_ast_node *node;
2644 node = isl_ast_node_list_get_ast_node(list, i);
2645 p = print_ast_node_isl(p, node);
2646 isl_ast_node_free(node);
2647 p = isl_printer_yaml_next(p);
2649 p = isl_printer_yaml_end_sequence(p);
2651 return p;
2654 /* Print "node" to "p" in "isl format".
2656 * In particular, print the isl_ast_node as a YAML document.
2658 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2659 __isl_keep isl_ast_node *node)
2661 switch (node->type) {
2662 case isl_ast_node_for:
2663 p = isl_printer_yaml_start_mapping(p);
2664 p = isl_printer_print_str(p, "iterator");
2665 p = isl_printer_yaml_next(p);
2666 p = isl_printer_print_ast_expr(p, node->u.f.iterator);
2667 p = isl_printer_yaml_next(p);
2668 if (node->u.f.degenerate) {
2669 p = isl_printer_print_str(p, "value");
2670 p = isl_printer_yaml_next(p);
2671 p = isl_printer_print_ast_expr(p, node->u.f.init);
2672 p = isl_printer_yaml_next(p);
2673 } else {
2674 p = isl_printer_print_str(p, "init");
2675 p = isl_printer_yaml_next(p);
2676 p = isl_printer_print_ast_expr(p, node->u.f.init);
2677 p = isl_printer_yaml_next(p);
2678 p = isl_printer_print_str(p, "cond");
2679 p = isl_printer_yaml_next(p);
2680 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2681 p = isl_printer_yaml_next(p);
2682 p = isl_printer_print_str(p, "inc");
2683 p = isl_printer_yaml_next(p);
2684 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2685 p = isl_printer_yaml_next(p);
2687 if (node->u.f.body) {
2688 p = isl_printer_print_str(p, "body");
2689 p = isl_printer_yaml_next(p);
2690 p = isl_printer_print_ast_node(p, node->u.f.body);
2691 p = isl_printer_yaml_next(p);
2693 p = isl_printer_yaml_end_mapping(p);
2694 break;
2695 case isl_ast_node_mark:
2696 p = isl_printer_yaml_start_mapping(p);
2697 p = isl_printer_print_str(p, "mark");
2698 p = isl_printer_yaml_next(p);
2699 p = isl_printer_print_id(p, node->u.m.mark);
2700 p = isl_printer_yaml_next(p);
2701 p = isl_printer_print_str(p, "node");
2702 p = isl_printer_yaml_next(p);
2703 p = isl_printer_print_ast_node(p, node->u.m.node);
2704 p = isl_printer_yaml_end_mapping(p);
2705 break;
2706 case isl_ast_node_user:
2707 p = isl_printer_yaml_start_mapping(p);
2708 p = isl_printer_print_str(p, "user");
2709 p = isl_printer_yaml_next(p);
2710 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2711 p = isl_printer_yaml_end_mapping(p);
2712 break;
2713 case isl_ast_node_if:
2714 p = isl_printer_yaml_start_mapping(p);
2715 p = isl_printer_print_str(p, "guard");
2716 p = isl_printer_yaml_next(p);
2717 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2718 p = isl_printer_yaml_next(p);
2719 if (node->u.i.then) {
2720 p = isl_printer_print_str(p, "then");
2721 p = isl_printer_yaml_next(p);
2722 p = isl_printer_print_ast_node(p, node->u.i.then);
2723 p = isl_printer_yaml_next(p);
2725 if (node->u.i.else_node) {
2726 p = isl_printer_print_str(p, "else");
2727 p = isl_printer_yaml_next(p);
2728 p = isl_printer_print_ast_node(p, node->u.i.else_node);
2730 p = isl_printer_yaml_end_mapping(p);
2731 break;
2732 case isl_ast_node_block:
2733 p = print_ast_node_list(p, node->u.b.children);
2734 break;
2735 case isl_ast_node_error:
2736 break;
2738 return p;
2741 /* Do we need to print a block around the body "node" of a for or if node?
2743 * If the node is a block, then we need to print a block.
2744 * Also if the node is a degenerate for then we will print it as
2745 * an assignment followed by the body of the for loop, so we need a block
2746 * as well.
2747 * If the node is an if node with an else, then we print a block
2748 * to avoid spurious dangling else warnings emitted by some compilers.
2749 * If the node is a mark, then in principle, we would have to check
2750 * the child of the mark node. However, even if the child would not
2751 * require us to print a block, for readability it is probably best
2752 * to print a block anyway.
2753 * If the ast_always_print_block option has been set, then we print a block.
2755 static int need_block(__isl_keep isl_ast_node *node)
2757 isl_ctx *ctx;
2759 if (node->type == isl_ast_node_block)
2760 return 1;
2761 if (node->type == isl_ast_node_for && node->u.f.degenerate)
2762 return 1;
2763 if (node->type == isl_ast_node_if && node->u.i.else_node)
2764 return 1;
2765 if (node->type == isl_ast_node_mark)
2766 return 1;
2768 ctx = isl_ast_node_get_ctx(node);
2769 return isl_options_get_ast_always_print_block(ctx);
2772 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2773 __isl_keep isl_ast_node *node,
2774 __isl_keep isl_ast_print_options *options, int in_block, int in_list);
2775 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2776 __isl_keep isl_ast_node *node,
2777 __isl_keep isl_ast_print_options *options, int new_line,
2778 int force_block);
2780 /* Print the body "node" of a for or if node.
2781 * If "else_node" is set, then it is printed as well.
2782 * If "force_block" is set, then print out the body as a block.
2784 * We first check if we need to print out a block.
2785 * We always print out a block if there is an else node to make
2786 * sure that the else node is matched to the correct if node.
2787 * For consistency, the corresponding else node is also printed as a block.
2789 * If the else node is itself an if, then we print it as
2791 * } else if (..) {
2794 * Otherwise the else node is printed as
2796 * } else {
2797 * node
2800 static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
2801 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
2802 __isl_keep isl_ast_print_options *options, int force_block)
2804 if (!node)
2805 return isl_printer_free(p);
2807 if (!force_block && !else_node && !need_block(node)) {
2808 p = isl_printer_end_line(p);
2809 p = isl_printer_indent(p, 2);
2810 p = isl_ast_node_print(node, p,
2811 isl_ast_print_options_copy(options));
2812 p = isl_printer_indent(p, -2);
2813 return p;
2816 p = isl_printer_print_str(p, " {");
2817 p = isl_printer_end_line(p);
2818 p = isl_printer_indent(p, 2);
2819 p = print_ast_node_c(p, node, options, 1, 0);
2820 p = isl_printer_indent(p, -2);
2821 p = isl_printer_start_line(p);
2822 p = isl_printer_print_str(p, "}");
2823 if (else_node) {
2824 if (else_node->type == isl_ast_node_if) {
2825 p = isl_printer_print_str(p, " else ");
2826 p = print_if_c(p, else_node, options, 0, 1);
2827 } else {
2828 p = isl_printer_print_str(p, " else");
2829 p = print_body_c(p, else_node, NULL, options, 1);
2831 } else
2832 p = isl_printer_end_line(p);
2834 return p;
2837 /* Print the start of a compound statement.
2839 static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
2841 p = isl_printer_start_line(p);
2842 p = isl_printer_print_str(p, "{");
2843 p = isl_printer_end_line(p);
2844 p = isl_printer_indent(p, 2);
2846 return p;
2849 /* Print the end of a compound statement.
2851 static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
2853 p = isl_printer_indent(p, -2);
2854 p = isl_printer_start_line(p);
2855 p = isl_printer_print_str(p, "}");
2856 p = isl_printer_end_line(p);
2858 return p;
2861 /* Print the for node "node".
2863 * If the for node is degenerate, it is printed as
2865 * type iterator = init;
2866 * body
2868 * Otherwise, it is printed as
2870 * for (type iterator = init; cond; iterator += inc)
2871 * body
2873 * "in_block" is set if we are currently inside a block.
2874 * "in_list" is set if the current node is not alone in the block.
2875 * If we are not in a block or if the current not is not alone in the block
2876 * then we print a block around a degenerate for loop such that the variable
2877 * declaration will not conflict with any potential other declaration
2878 * of the same variable.
2880 static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
2881 __isl_keep isl_ast_node *node,
2882 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2884 isl_id *id;
2885 const char *name;
2886 const char *type;
2888 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
2889 if (!node->u.f.degenerate) {
2890 id = isl_ast_expr_get_id(node->u.f.iterator);
2891 name = isl_id_get_name(id);
2892 isl_id_free(id);
2893 p = isl_printer_start_line(p);
2894 p = isl_printer_print_str(p, "for (");
2895 p = isl_printer_print_str(p, type);
2896 p = isl_printer_print_str(p, " ");
2897 p = isl_printer_print_str(p, name);
2898 p = isl_printer_print_str(p, " = ");
2899 p = isl_printer_print_ast_expr(p, node->u.f.init);
2900 p = isl_printer_print_str(p, "; ");
2901 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2902 p = isl_printer_print_str(p, "; ");
2903 p = isl_printer_print_str(p, name);
2904 p = isl_printer_print_str(p, " += ");
2905 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2906 p = isl_printer_print_str(p, ")");
2907 p = print_body_c(p, node->u.f.body, NULL, options, 0);
2908 } else {
2909 id = isl_ast_expr_get_id(node->u.f.iterator);
2910 name = isl_id_get_name(id);
2911 isl_id_free(id);
2912 if (!in_block || in_list)
2913 p = start_block(p);
2914 p = isl_printer_start_line(p);
2915 p = isl_printer_print_str(p, type);
2916 p = isl_printer_print_str(p, " ");
2917 p = isl_printer_print_str(p, name);
2918 p = isl_printer_print_str(p, " = ");
2919 p = isl_printer_print_ast_expr(p, node->u.f.init);
2920 p = isl_printer_print_str(p, ";");
2921 p = isl_printer_end_line(p);
2922 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
2923 if (!in_block || in_list)
2924 p = end_block(p);
2927 return p;
2930 /* Print the if node "node".
2931 * If "new_line" is set then the if node should be printed on a new line.
2932 * If "force_block" is set, then print out the body as a block.
2934 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2935 __isl_keep isl_ast_node *node,
2936 __isl_keep isl_ast_print_options *options, int new_line,
2937 int force_block)
2939 if (new_line)
2940 p = isl_printer_start_line(p);
2941 p = isl_printer_print_str(p, "if (");
2942 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2943 p = isl_printer_print_str(p, ")");
2944 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options,
2945 force_block);
2947 return p;
2950 /* Print the "node" to "p".
2952 * "in_block" is set if we are currently inside a block.
2953 * If so, we do not print a block around the children of a block node.
2954 * We do this to avoid an extra block around the body of a degenerate
2955 * for node.
2957 * "in_list" is set if the current node is not alone in the block.
2959 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2960 __isl_keep isl_ast_node *node,
2961 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2963 switch (node->type) {
2964 case isl_ast_node_for:
2965 if (options->print_for)
2966 return options->print_for(p,
2967 isl_ast_print_options_copy(options),
2968 node, options->print_for_user);
2969 p = print_for_c(p, node, options, in_block, in_list);
2970 break;
2971 case isl_ast_node_if:
2972 p = print_if_c(p, node, options, 1, 0);
2973 break;
2974 case isl_ast_node_block:
2975 if (!in_block)
2976 p = start_block(p);
2977 p = isl_ast_node_list_print(node->u.b.children, p, options);
2978 if (!in_block)
2979 p = end_block(p);
2980 break;
2981 case isl_ast_node_mark:
2982 p = isl_printer_start_line(p);
2983 p = isl_printer_print_str(p, "// ");
2984 p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark));
2985 p = isl_printer_end_line(p);
2986 p = print_ast_node_c(p, node->u.m.node, options, 0, in_list);
2987 break;
2988 case isl_ast_node_user:
2989 if (options->print_user)
2990 return options->print_user(p,
2991 isl_ast_print_options_copy(options),
2992 node, options->print_user_user);
2993 p = isl_printer_start_line(p);
2994 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2995 p = isl_printer_print_str(p, ";");
2996 p = isl_printer_end_line(p);
2997 break;
2998 case isl_ast_node_error:
2999 break;
3001 return p;
3004 /* Print the for node "node" to "p".
3006 __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
3007 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3009 if (isl_ast_node_check_for(node) < 0 || !options)
3010 goto error;
3011 p = print_for_c(p, node, options, 0, 0);
3012 isl_ast_print_options_free(options);
3013 return p;
3014 error:
3015 isl_ast_print_options_free(options);
3016 isl_printer_free(p);
3017 return NULL;
3020 /* Print the if node "node" to "p".
3022 __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
3023 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3025 if (isl_ast_node_check_if(node) < 0 || !options)
3026 goto error;
3027 p = print_if_c(p, node, options, 1, 0);
3028 isl_ast_print_options_free(options);
3029 return p;
3030 error:
3031 isl_ast_print_options_free(options);
3032 isl_printer_free(p);
3033 return NULL;
3036 /* Print "node" to "p".
3038 * "node" is assumed to be either the outermost node in an AST or
3039 * a node that is known not to be a block.
3040 * If "node" is a block (and is therefore outermost) and
3041 * if the ast_print_outermost_block options is not set,
3042 * then act as if the printing occurs inside a block, such
3043 * that no "extra" block will get printed.
3045 __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
3046 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3048 int in_block = 0;
3050 if (!options || !node)
3051 goto error;
3052 if (node->type == isl_ast_node_block) {
3053 isl_ctx *ctx;
3055 ctx = isl_ast_node_get_ctx(node);
3056 in_block = !isl_options_get_ast_print_outermost_block(ctx);
3058 p = print_ast_node_c(p, node, options, in_block, 0);
3059 isl_ast_print_options_free(options);
3060 return p;
3061 error:
3062 isl_ast_print_options_free(options);
3063 isl_printer_free(p);
3064 return NULL;
3067 /* Print "node" to "p".
3069 __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
3070 __isl_keep isl_ast_node *node)
3072 int format;
3073 isl_ast_print_options *options;
3075 if (!p)
3076 return NULL;
3078 format = isl_printer_get_output_format(p);
3079 switch (format) {
3080 case ISL_FORMAT_ISL:
3081 p = print_ast_node_isl(p, node);
3082 break;
3083 case ISL_FORMAT_C:
3084 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
3085 p = isl_ast_node_print(node, p, options);
3086 break;
3087 default:
3088 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3089 "output format not supported for ast_node",
3090 return isl_printer_free(p));
3093 return p;
3096 /* Print the list of nodes "list" to "p".
3098 __isl_give isl_printer *isl_ast_node_list_print(
3099 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
3100 __isl_keep isl_ast_print_options *options)
3102 int i;
3104 if (!p || !list || !options)
3105 return isl_printer_free(p);
3107 for (i = 0; i < list->n; ++i)
3108 p = print_ast_node_c(p, list->p[i], options, 1, 1);
3110 return p;
3113 #define ISL_AST_MACRO_FDIV_Q (1 << 0)
3114 #define ISL_AST_MACRO_MIN (1 << 1)
3115 #define ISL_AST_MACRO_MAX (1 << 2)
3116 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FDIV_Q | \
3117 ISL_AST_MACRO_MIN | \
3118 ISL_AST_MACRO_MAX)
3120 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros);
3122 /* Wrapper around ast_expr_required_macros for use
3123 * as an isl_ast_expr_list_foreach callback.
3125 static isl_stat entry_required_macros(__isl_take isl_ast_expr *expr, void *user)
3127 int *macros = user;
3129 *macros = ast_expr_required_macros(expr, *macros);
3130 isl_ast_expr_free(expr);
3132 return isl_stat_ok;
3135 /* If "expr" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3136 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3138 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
3140 if (macros == ISL_AST_MACRO_ALL)
3141 return macros;
3143 if (expr->type != isl_ast_expr_op)
3144 return macros;
3146 if (expr->u.op.op == isl_ast_expr_op_min)
3147 macros |= ISL_AST_MACRO_MIN;
3148 if (expr->u.op.op == isl_ast_expr_op_max)
3149 macros |= ISL_AST_MACRO_MAX;
3150 if (expr->u.op.op == isl_ast_expr_op_fdiv_q)
3151 macros |= ISL_AST_MACRO_FDIV_Q;
3153 isl_ast_expr_list_foreach(expr->u.op.args,
3154 &entry_required_macros, &macros);
3156 return macros;
3159 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
3160 int macros);
3162 /* If "node" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3163 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3165 static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
3167 if (macros == ISL_AST_MACRO_ALL)
3168 return macros;
3170 switch (node->type) {
3171 case isl_ast_node_for:
3172 macros = ast_expr_required_macros(node->u.f.init, macros);
3173 if (!node->u.f.degenerate) {
3174 macros = ast_expr_required_macros(node->u.f.cond,
3175 macros);
3176 macros = ast_expr_required_macros(node->u.f.inc,
3177 macros);
3179 macros = ast_node_required_macros(node->u.f.body, macros);
3180 break;
3181 case isl_ast_node_if:
3182 macros = ast_expr_required_macros(node->u.i.guard, macros);
3183 macros = ast_node_required_macros(node->u.i.then, macros);
3184 if (node->u.i.else_node)
3185 macros = ast_node_required_macros(node->u.i.else_node,
3186 macros);
3187 break;
3188 case isl_ast_node_block:
3189 macros = ast_node_list_required_macros(node->u.b.children,
3190 macros);
3191 break;
3192 case isl_ast_node_mark:
3193 macros = ast_node_required_macros(node->u.m.node, macros);
3194 break;
3195 case isl_ast_node_user:
3196 macros = ast_expr_required_macros(node->u.e.expr, macros);
3197 break;
3198 case isl_ast_node_error:
3199 break;
3202 return macros;
3205 /* If "list" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3206 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3208 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
3209 int macros)
3211 int i;
3213 for (i = 0; i < list->n; ++i)
3214 macros = ast_node_required_macros(list->p[i], macros);
3216 return macros;
3219 /* Data structure for keeping track of whether a macro definition
3220 * for a given type has already been printed.
3221 * The value is zero if no definition has been printed and non-zero otherwise.
3223 struct isl_ast_expr_op_printed {
3224 char printed[isl_ast_expr_op_last + 1];
3227 /* Create an empty struct isl_ast_expr_op_printed.
3229 static void *create_printed(isl_ctx *ctx)
3231 return isl_calloc_type(ctx, struct isl_ast_expr_op_printed);
3234 /* Free a struct isl_ast_expr_op_printed.
3236 static void free_printed(void *user)
3238 free(user);
3241 /* Ensure that "p" has an isl_ast_expr_op_printed note identified by "id".
3243 static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p,
3244 __isl_keep isl_id *id)
3246 return alloc_note(p, id, &create_printed, &free_printed);
3249 /* Create an identifier that is used to store
3250 * an isl_ast_expr_op_printed note.
3252 static __isl_give isl_id *printed_id(isl_ctx *ctx)
3254 return isl_id_alloc(ctx, "isl_ast_expr_op_type_printed", NULL);
3257 /* Did the user specify that a macro definition should only be
3258 * printed once and has a macro definition for "type" already
3259 * been printed to "p"?
3260 * If definitions should only be printed once, but a definition
3261 * for "p" has not yet been printed, then mark it as having been
3262 * printed so that it will not printed again.
3263 * The actual printing is taken care of by the caller.
3265 static isl_bool already_printed_once(__isl_keep isl_printer *p,
3266 enum isl_ast_expr_op_type type)
3268 isl_ctx *ctx;
3269 isl_id *id;
3270 struct isl_ast_expr_op_printed *printed;
3272 if (!p)
3273 return isl_bool_error;
3275 ctx = isl_printer_get_ctx(p);
3276 if (!isl_options_get_ast_print_macro_once(ctx))
3277 return isl_bool_false;
3279 if (type > isl_ast_expr_op_last)
3280 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
3281 "invalid type", return isl_bool_error);
3283 id = printed_id(isl_printer_get_ctx(p));
3284 p = alloc_printed(p, id);
3285 printed = get_note(p, id);
3286 isl_id_free(id);
3287 if (!printed)
3288 return isl_bool_error;
3290 if (printed->printed[type])
3291 return isl_bool_true;
3293 printed->printed[type] = 1;
3294 return isl_bool_false;
3297 /* Print a macro definition for the operator "type".
3299 * If the user has specified that a macro definition should
3300 * only be printed once to any given printer and if the macro definition
3301 * has already been printed to "p", then do not print the definition.
3303 __isl_give isl_printer *isl_ast_expr_op_type_print_macro(
3304 enum isl_ast_expr_op_type type, __isl_take isl_printer *p)
3306 isl_bool skip;
3308 skip = already_printed_once(p, type);
3309 if (skip < 0)
3310 return isl_printer_free(p);
3311 if (skip)
3312 return p;
3314 switch (type) {
3315 case isl_ast_expr_op_min:
3316 p = isl_printer_start_line(p);
3317 p = isl_printer_print_str(p, "#define ");
3318 p = isl_printer_print_str(p, get_op_str_c(p, type));
3319 p = isl_printer_print_str(p,
3320 "(x,y) ((x) < (y) ? (x) : (y))");
3321 p = isl_printer_end_line(p);
3322 break;
3323 case isl_ast_expr_op_max:
3324 p = isl_printer_start_line(p);
3325 p = isl_printer_print_str(p, "#define ");
3326 p = isl_printer_print_str(p, get_op_str_c(p, type));
3327 p = isl_printer_print_str(p,
3328 "(x,y) ((x) > (y) ? (x) : (y))");
3329 p = isl_printer_end_line(p);
3330 break;
3331 case isl_ast_expr_op_fdiv_q:
3332 p = isl_printer_start_line(p);
3333 p = isl_printer_print_str(p, "#define ");
3334 p = isl_printer_print_str(p, get_op_str_c(p, type));
3335 p = isl_printer_print_str(p,
3336 "(n,d) "
3337 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
3338 p = isl_printer_end_line(p);
3339 break;
3340 default:
3341 break;
3344 return p;
3347 /* This is an alternative name for the function above.
3349 __isl_give isl_printer *isl_ast_op_type_print_macro(
3350 enum isl_ast_expr_op_type type, __isl_take isl_printer *p)
3352 return isl_ast_expr_op_type_print_macro(type, p);
3355 /* Call "fn" for each type of operation represented in the "macros"
3356 * bit vector.
3358 static isl_stat foreach_ast_expr_op_type(int macros,
3359 isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3361 if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_expr_op_min, user) < 0)
3362 return isl_stat_error;
3363 if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_expr_op_max, user) < 0)
3364 return isl_stat_error;
3365 if (macros & ISL_AST_MACRO_FDIV_Q &&
3366 fn(isl_ast_expr_op_fdiv_q, user) < 0)
3367 return isl_stat_error;
3369 return isl_stat_ok;
3372 /* Call "fn" for each type of operation that appears in "expr"
3373 * and that requires a macro definition.
3375 isl_stat isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr *expr,
3376 isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3378 int macros;
3380 if (!expr)
3381 return isl_stat_error;
3383 macros = ast_expr_required_macros(expr, 0);
3384 return foreach_ast_expr_op_type(macros, fn, user);
3387 /* This is an alternative name for the function above.
3389 isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr,
3390 isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3392 return isl_ast_expr_foreach_ast_expr_op_type(expr, fn, user);
3395 /* Call "fn" for each type of operation that appears in "node"
3396 * and that requires a macro definition.
3398 isl_stat isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node *node,
3399 isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3401 int macros;
3403 if (!node)
3404 return isl_stat_error;
3406 macros = ast_node_required_macros(node, 0);
3407 return foreach_ast_expr_op_type(macros, fn, user);
3410 /* This is an alternative name for the function above.
3412 isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
3413 isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3415 return isl_ast_node_foreach_ast_expr_op_type(node, fn, user);
3418 static isl_stat ast_op_type_print_macro(enum isl_ast_expr_op_type type,
3419 void *user)
3421 isl_printer **p = user;
3423 *p = isl_ast_expr_op_type_print_macro(type, *p);
3425 return isl_stat_ok;
3428 /* Print macro definitions for all the macros used in the result
3429 * of printing "expr".
3431 __isl_give isl_printer *isl_ast_expr_print_macros(
3432 __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
3434 if (isl_ast_expr_foreach_ast_expr_op_type(expr,
3435 &ast_op_type_print_macro, &p) < 0)
3436 return isl_printer_free(p);
3437 return p;
3440 /* Print macro definitions for all the macros used in the result
3441 * of printing "node".
3443 __isl_give isl_printer *isl_ast_node_print_macros(
3444 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
3446 if (isl_ast_node_foreach_ast_expr_op_type(node,
3447 &ast_op_type_print_macro, &p) < 0)
3448 return isl_printer_free(p);
3449 return p;
3452 /* Return a string containing C code representing this isl_ast_expr.
3454 __isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr)
3456 isl_printer *p;
3457 char *str;
3459 if (!expr)
3460 return NULL;
3462 p = isl_printer_to_str(isl_ast_expr_get_ctx(expr));
3463 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
3464 p = isl_printer_print_ast_expr(p, expr);
3466 str = isl_printer_get_str(p);
3468 isl_printer_free(p);
3470 return str;
3473 /* Return a string containing C code representing this isl_ast_node.
3475 __isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node)
3477 isl_printer *p;
3478 char *str;
3480 if (!node)
3481 return NULL;
3483 p = isl_printer_to_str(isl_ast_node_get_ctx(node));
3484 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
3485 p = isl_printer_print_ast_node(p, node);
3487 str = isl_printer_get_str(p);
3489 isl_printer_free(p);
3491 return str;