isl_tab_pip.c: move tableau into isl_lexmin_data
[isl.git] / isl_ast.c
blob91d0e99b40a6ec2a7b96861b86385424f59da3f0
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/val.h>
13 #include <isl_ast_private.h>
15 #undef BASE
16 #define BASE ast_expr
18 #include <isl_list_templ.c>
20 #undef BASE
21 #define BASE ast_node
23 #include <isl_list_templ.c>
25 isl_ctx *isl_ast_print_options_get_ctx(
26 __isl_keep isl_ast_print_options *options)
28 return options ? options->ctx : NULL;
31 __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
33 isl_ast_print_options *options;
35 options = isl_calloc_type(ctx, isl_ast_print_options);
36 if (!options)
37 return NULL;
39 options->ctx = ctx;
40 isl_ctx_ref(ctx);
41 options->ref = 1;
43 return options;
46 __isl_give isl_ast_print_options *isl_ast_print_options_dup(
47 __isl_keep isl_ast_print_options *options)
49 isl_ctx *ctx;
50 isl_ast_print_options *dup;
52 if (!options)
53 return NULL;
55 ctx = isl_ast_print_options_get_ctx(options);
56 dup = isl_ast_print_options_alloc(ctx);
57 if (!dup)
58 return NULL;
60 dup->print_for = options->print_for;
61 dup->print_for_user = options->print_for_user;
62 dup->print_user = options->print_user;
63 dup->print_user_user = options->print_user_user;
65 return dup;
68 __isl_give isl_ast_print_options *isl_ast_print_options_cow(
69 __isl_take isl_ast_print_options *options)
71 if (!options)
72 return NULL;
74 if (options->ref == 1)
75 return options;
76 options->ref--;
77 return isl_ast_print_options_dup(options);
80 __isl_give isl_ast_print_options *isl_ast_print_options_copy(
81 __isl_keep isl_ast_print_options *options)
83 if (!options)
84 return NULL;
86 options->ref++;
87 return options;
90 __isl_null isl_ast_print_options *isl_ast_print_options_free(
91 __isl_take isl_ast_print_options *options)
93 if (!options)
94 return NULL;
96 if (--options->ref > 0)
97 return NULL;
99 isl_ctx_deref(options->ctx);
101 free(options);
102 return NULL;
105 /* Set the print_user callback of "options" to "print_user".
107 * If this callback is set, then it used to print user nodes in the AST.
108 * Otherwise, the expression associated to the user node is printed.
110 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
111 __isl_take isl_ast_print_options *options,
112 __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
113 __isl_take isl_ast_print_options *options,
114 __isl_keep isl_ast_node *node, void *user),
115 void *user)
117 options = isl_ast_print_options_cow(options);
118 if (!options)
119 return NULL;
121 options->print_user = print_user;
122 options->print_user_user = user;
124 return options;
127 /* Set the print_for callback of "options" to "print_for".
129 * If this callback is set, then it used to print for nodes in the AST.
131 __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
132 __isl_take isl_ast_print_options *options,
133 __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
134 __isl_take isl_ast_print_options *options,
135 __isl_keep isl_ast_node *node, void *user),
136 void *user)
138 options = isl_ast_print_options_cow(options);
139 if (!options)
140 return NULL;
142 options->print_for = print_for;
143 options->print_for_user = user;
145 return options;
148 __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
150 if (!expr)
151 return NULL;
153 expr->ref++;
154 return expr;
157 __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
159 int i;
160 isl_ctx *ctx;
161 isl_ast_expr *dup;
163 if (!expr)
164 return NULL;
166 ctx = isl_ast_expr_get_ctx(expr);
167 switch (expr->type) {
168 case isl_ast_expr_int:
169 dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
170 break;
171 case isl_ast_expr_id:
172 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
173 break;
174 case isl_ast_expr_op:
175 dup = isl_ast_expr_alloc_op(ctx,
176 expr->u.op.op, expr->u.op.n_arg);
177 if (!dup)
178 return NULL;
179 for (i = 0; i < expr->u.op.n_arg; ++i)
180 dup->u.op.args[i] =
181 isl_ast_expr_copy(expr->u.op.args[i]);
182 break;
183 case isl_ast_expr_error:
184 dup = NULL;
187 if (!dup)
188 return NULL;
190 return dup;
193 __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
195 if (!expr)
196 return NULL;
198 if (expr->ref == 1)
199 return expr;
200 expr->ref--;
201 return isl_ast_expr_dup(expr);
204 __isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
206 int i;
208 if (!expr)
209 return NULL;
211 if (--expr->ref > 0)
212 return NULL;
214 isl_ctx_deref(expr->ctx);
216 switch (expr->type) {
217 case isl_ast_expr_int:
218 isl_val_free(expr->u.v);
219 break;
220 case isl_ast_expr_id:
221 isl_id_free(expr->u.id);
222 break;
223 case isl_ast_expr_op:
224 if (expr->u.op.args)
225 for (i = 0; i < expr->u.op.n_arg; ++i)
226 isl_ast_expr_free(expr->u.op.args[i]);
227 free(expr->u.op.args);
228 break;
229 case isl_ast_expr_error:
230 break;
233 free(expr);
234 return NULL;
237 isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
239 return expr ? expr->ctx : NULL;
242 enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
244 return expr ? expr->type : isl_ast_expr_error;
247 /* Return the integer value represented by "expr".
249 __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
251 if (!expr)
252 return NULL;
253 if (expr->type != isl_ast_expr_int)
254 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
255 "expression not an int", return NULL);
256 return isl_val_copy(expr->u.v);
259 __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
261 if (!expr)
262 return NULL;
263 if (expr->type != isl_ast_expr_id)
264 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
265 "expression not an identifier", return NULL);
267 return isl_id_copy(expr->u.id);
270 enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
272 if (!expr)
273 return isl_ast_op_error;
274 if (expr->type != isl_ast_expr_op)
275 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
276 "expression not an operation", return isl_ast_op_error);
277 return expr->u.op.op;
280 int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
282 if (!expr)
283 return -1;
284 if (expr->type != isl_ast_expr_op)
285 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
286 "expression not an operation", return -1);
287 return expr->u.op.n_arg;
290 __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
291 int pos)
293 if (!expr)
294 return NULL;
295 if (expr->type != isl_ast_expr_op)
296 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
297 "expression not an operation", return NULL);
298 if (pos < 0 || pos >= expr->u.op.n_arg)
299 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
300 "index out of bounds", return NULL);
302 return isl_ast_expr_copy(expr->u.op.args[pos]);
305 /* Replace the argument at position "pos" of "expr" by "arg".
307 __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
308 int pos, __isl_take isl_ast_expr *arg)
310 expr = isl_ast_expr_cow(expr);
311 if (!expr || !arg)
312 goto error;
313 if (expr->type != isl_ast_expr_op)
314 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
315 "expression not an operation", goto error);
316 if (pos < 0 || pos >= expr->u.op.n_arg)
317 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
318 "index out of bounds", goto error);
320 isl_ast_expr_free(expr->u.op.args[pos]);
321 expr->u.op.args[pos] = arg;
323 return expr;
324 error:
325 isl_ast_expr_free(arg);
326 return isl_ast_expr_free(expr);
329 /* Is "expr1" equal to "expr2"?
331 isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
332 __isl_keep isl_ast_expr *expr2)
334 int i;
336 if (!expr1 || !expr2)
337 return isl_bool_error;
339 if (expr1 == expr2)
340 return isl_bool_true;
341 if (expr1->type != expr2->type)
342 return isl_bool_false;
343 switch (expr1->type) {
344 case isl_ast_expr_int:
345 return isl_val_eq(expr1->u.v, expr2->u.v);
346 case isl_ast_expr_id:
347 return expr1->u.id == expr2->u.id;
348 case isl_ast_expr_op:
349 if (expr1->u.op.op != expr2->u.op.op)
350 return isl_bool_false;
351 if (expr1->u.op.n_arg != expr2->u.op.n_arg)
352 return isl_bool_false;
353 for (i = 0; i < expr1->u.op.n_arg; ++i) {
354 isl_bool equal;
355 equal = isl_ast_expr_is_equal(expr1->u.op.args[i],
356 expr2->u.op.args[i]);
357 if (equal < 0 || !equal)
358 return equal;
360 return 1;
361 case isl_ast_expr_error:
362 return isl_bool_error;
365 isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal,
366 "unhandled case", return isl_bool_error);
369 /* Create a new operation expression of operation type "op",
370 * with "n_arg" as yet unspecified arguments.
372 __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
373 enum isl_ast_op_type op, int n_arg)
375 isl_ast_expr *expr;
377 expr = isl_calloc_type(ctx, isl_ast_expr);
378 if (!expr)
379 return NULL;
381 expr->ctx = ctx;
382 isl_ctx_ref(ctx);
383 expr->ref = 1;
384 expr->type = isl_ast_expr_op;
385 expr->u.op.op = op;
386 expr->u.op.n_arg = n_arg;
387 expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg);
389 if (n_arg && !expr->u.op.args)
390 return isl_ast_expr_free(expr);
392 return expr;
395 /* Create a new id expression representing "id".
397 __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
399 isl_ctx *ctx;
400 isl_ast_expr *expr;
402 if (!id)
403 return NULL;
405 ctx = isl_id_get_ctx(id);
406 expr = isl_calloc_type(ctx, isl_ast_expr);
407 if (!expr)
408 goto error;
410 expr->ctx = ctx;
411 isl_ctx_ref(ctx);
412 expr->ref = 1;
413 expr->type = isl_ast_expr_id;
414 expr->u.id = id;
416 return expr;
417 error:
418 isl_id_free(id);
419 return NULL;
422 /* Create a new integer expression representing "i".
424 __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
426 isl_ast_expr *expr;
428 expr = isl_calloc_type(ctx, isl_ast_expr);
429 if (!expr)
430 return NULL;
432 expr->ctx = ctx;
433 isl_ctx_ref(ctx);
434 expr->ref = 1;
435 expr->type = isl_ast_expr_int;
436 expr->u.v = isl_val_int_from_si(ctx, i);
437 if (!expr->u.v)
438 return isl_ast_expr_free(expr);
440 return expr;
443 /* Create a new integer expression representing "v".
445 __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
447 isl_ctx *ctx;
448 isl_ast_expr *expr;
450 if (!v)
451 return NULL;
452 if (!isl_val_is_int(v))
453 isl_die(isl_val_get_ctx(v), isl_error_invalid,
454 "expecting integer value", goto error);
456 ctx = isl_val_get_ctx(v);
457 expr = isl_calloc_type(ctx, isl_ast_expr);
458 if (!expr)
459 goto error;
461 expr->ctx = ctx;
462 isl_ctx_ref(ctx);
463 expr->ref = 1;
464 expr->type = isl_ast_expr_int;
465 expr->u.v = v;
467 return expr;
468 error:
469 isl_val_free(v);
470 return NULL;
473 /* Create an expression representing the unary operation "type" applied to
474 * "arg".
476 __isl_give isl_ast_expr *isl_ast_expr_alloc_unary(enum isl_ast_op_type type,
477 __isl_take isl_ast_expr *arg)
479 isl_ctx *ctx;
480 isl_ast_expr *expr = NULL;
482 if (!arg)
483 return NULL;
485 ctx = isl_ast_expr_get_ctx(arg);
486 expr = isl_ast_expr_alloc_op(ctx, type, 1);
487 if (!expr)
488 goto error;
490 expr->u.op.args[0] = arg;
492 return expr;
493 error:
494 isl_ast_expr_free(arg);
495 return NULL;
498 /* Create an expression representing the negation of "arg".
500 __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
502 return isl_ast_expr_alloc_unary(isl_ast_op_minus, arg);
505 /* Create an expression representing the address of "expr".
507 __isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
509 if (!expr)
510 return NULL;
512 if (isl_ast_expr_get_type(expr) != isl_ast_expr_op ||
513 isl_ast_expr_get_op_type(expr) != isl_ast_op_access)
514 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
515 "can only take address of access expressions",
516 return isl_ast_expr_free(expr));
518 return isl_ast_expr_alloc_unary(isl_ast_op_address_of, expr);
521 /* Create an expression representing the binary operation "type"
522 * applied to "expr1" and "expr2".
524 __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
525 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
527 isl_ctx *ctx;
528 isl_ast_expr *expr = NULL;
530 if (!expr1 || !expr2)
531 goto error;
533 ctx = isl_ast_expr_get_ctx(expr1);
534 expr = isl_ast_expr_alloc_op(ctx, type, 2);
535 if (!expr)
536 goto error;
538 expr->u.op.args[0] = expr1;
539 expr->u.op.args[1] = expr2;
541 return expr;
542 error:
543 isl_ast_expr_free(expr1);
544 isl_ast_expr_free(expr2);
545 return NULL;
548 /* Create an expression representing the sum of "expr1" and "expr2".
550 __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
551 __isl_take isl_ast_expr *expr2)
553 return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
556 /* Create an expression representing the difference of "expr1" and "expr2".
558 __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
559 __isl_take isl_ast_expr *expr2)
561 return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
564 /* Create an expression representing the product of "expr1" and "expr2".
566 __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
567 __isl_take isl_ast_expr *expr2)
569 return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
572 /* Create an expression representing the quotient of "expr1" and "expr2".
574 __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
575 __isl_take isl_ast_expr *expr2)
577 return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
580 /* Create an expression representing the quotient of the integer
581 * division of "expr1" by "expr2", where "expr1" is known to be
582 * non-negative.
584 __isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
585 __isl_take isl_ast_expr *expr2)
587 return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_q, expr1, expr2);
590 /* Create an expression representing the remainder of the integer
591 * division of "expr1" by "expr2", where "expr1" is known to be
592 * non-negative.
594 __isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
595 __isl_take isl_ast_expr *expr2)
597 return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr1, expr2);
600 /* Create an expression representing the conjunction of "expr1" and "expr2".
602 __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
603 __isl_take isl_ast_expr *expr2)
605 return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
608 /* Create an expression representing the conjunction of "expr1" and "expr2",
609 * where "expr2" is evaluated only if "expr1" is evaluated to true.
611 __isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
612 __isl_take isl_ast_expr *expr2)
614 return isl_ast_expr_alloc_binary(isl_ast_op_and_then, expr1, expr2);
617 /* Create an expression representing the disjunction of "expr1" and "expr2".
619 __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
620 __isl_take isl_ast_expr *expr2)
622 return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
625 /* Create an expression representing the disjunction of "expr1" and "expr2",
626 * where "expr2" is evaluated only if "expr1" is evaluated to false.
628 __isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
629 __isl_take isl_ast_expr *expr2)
631 return isl_ast_expr_alloc_binary(isl_ast_op_or_else, expr1, expr2);
634 /* Create an expression representing "expr1" less than or equal to "expr2".
636 __isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
637 __isl_take isl_ast_expr *expr2)
639 return isl_ast_expr_alloc_binary(isl_ast_op_le, expr1, expr2);
642 /* Create an expression representing "expr1" less than "expr2".
644 __isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
645 __isl_take isl_ast_expr *expr2)
647 return isl_ast_expr_alloc_binary(isl_ast_op_lt, expr1, expr2);
650 /* Create an expression representing "expr1" greater than or equal to "expr2".
652 __isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1,
653 __isl_take isl_ast_expr *expr2)
655 return isl_ast_expr_alloc_binary(isl_ast_op_ge, expr1, expr2);
658 /* Create an expression representing "expr1" greater than "expr2".
660 __isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1,
661 __isl_take isl_ast_expr *expr2)
663 return isl_ast_expr_alloc_binary(isl_ast_op_gt, expr1, expr2);
666 /* Create an expression representing "expr1" equal to "expr2".
668 __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
669 __isl_take isl_ast_expr *expr2)
671 return isl_ast_expr_alloc_binary(isl_ast_op_eq, expr1, expr2);
674 /* Create an expression of type "type" with as arguments "arg0" followed
675 * by "arguments".
677 static __isl_give isl_ast_expr *ast_expr_with_arguments(
678 enum isl_ast_op_type type, __isl_take isl_ast_expr *arg0,
679 __isl_take isl_ast_expr_list *arguments)
681 int i, n;
682 isl_ctx *ctx;
683 isl_ast_expr *res = NULL;
685 if (!arg0 || !arguments)
686 goto error;
688 ctx = isl_ast_expr_get_ctx(arg0);
689 n = isl_ast_expr_list_n_ast_expr(arguments);
690 res = isl_ast_expr_alloc_op(ctx, type, 1 + n);
691 if (!res)
692 goto error;
693 for (i = 0; i < n; ++i) {
694 isl_ast_expr *arg;
695 arg = isl_ast_expr_list_get_ast_expr(arguments, i);
696 res->u.op.args[1 + i] = arg;
697 if (!arg)
698 goto error;
700 res->u.op.args[0] = arg0;
702 isl_ast_expr_list_free(arguments);
703 return res;
704 error:
705 isl_ast_expr_free(arg0);
706 isl_ast_expr_list_free(arguments);
707 isl_ast_expr_free(res);
708 return NULL;
711 /* Create an expression representing an access to "array" with index
712 * expressions "indices".
714 __isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
715 __isl_take isl_ast_expr_list *indices)
717 return ast_expr_with_arguments(isl_ast_op_access, array, indices);
720 /* Create an expression representing a call to "function" with argument
721 * expressions "arguments".
723 __isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
724 __isl_take isl_ast_expr_list *arguments)
726 return ast_expr_with_arguments(isl_ast_op_call, function, arguments);
729 /* For each subexpression of "expr" of type isl_ast_expr_id,
730 * if it appears in "id2expr", then replace it by the corresponding
731 * expression.
733 __isl_give isl_ast_expr *isl_ast_expr_substitute_ids(
734 __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr)
736 int i;
737 isl_maybe_isl_ast_expr m;
739 if (!expr || !id2expr)
740 goto error;
742 switch (expr->type) {
743 case isl_ast_expr_int:
744 break;
745 case isl_ast_expr_id:
746 m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id);
747 if (m.valid < 0)
748 goto error;
749 if (!m.valid)
750 break;
751 isl_ast_expr_free(expr);
752 expr = m.value;
753 break;
754 case isl_ast_expr_op:
755 for (i = 0; i < expr->u.op.n_arg; ++i) {
756 isl_ast_expr *arg;
757 arg = isl_ast_expr_copy(expr->u.op.args[i]);
758 arg = isl_ast_expr_substitute_ids(arg,
759 isl_id_to_ast_expr_copy(id2expr));
760 if (arg == expr->u.op.args[i]) {
761 isl_ast_expr_free(arg);
762 continue;
764 if (!arg)
765 expr = isl_ast_expr_free(expr);
766 expr = isl_ast_expr_cow(expr);
767 if (!expr) {
768 isl_ast_expr_free(arg);
769 break;
771 isl_ast_expr_free(expr->u.op.args[i]);
772 expr->u.op.args[i] = arg;
774 break;
775 case isl_ast_expr_error:
776 expr = isl_ast_expr_free(expr);
777 break;
780 isl_id_to_ast_expr_free(id2expr);
781 return expr;
782 error:
783 isl_ast_expr_free(expr);
784 isl_id_to_ast_expr_free(id2expr);
785 return NULL;
788 isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
790 return node ? node->ctx : NULL;
793 enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
795 return node ? node->type : isl_ast_node_error;
798 __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
799 enum isl_ast_node_type type)
801 isl_ast_node *node;
803 node = isl_calloc_type(ctx, isl_ast_node);
804 if (!node)
805 return NULL;
807 node->ctx = ctx;
808 isl_ctx_ref(ctx);
809 node->ref = 1;
810 node->type = type;
812 return node;
815 /* Create an if node with the given guard.
817 * The then body needs to be filled in later.
819 __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
821 isl_ast_node *node;
823 if (!guard)
824 return NULL;
826 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
827 if (!node)
828 goto error;
829 node->u.i.guard = guard;
831 return node;
832 error:
833 isl_ast_expr_free(guard);
834 return NULL;
837 /* Create a for node with the given iterator.
839 * The remaining fields need to be filled in later.
841 __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
843 isl_ast_node *node;
844 isl_ctx *ctx;
846 if (!id)
847 return NULL;
849 ctx = isl_id_get_ctx(id);
850 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
851 if (!node)
852 goto error;
854 node->u.f.iterator = isl_ast_expr_from_id(id);
855 if (!node->u.f.iterator)
856 return isl_ast_node_free(node);
858 return node;
859 error:
860 isl_id_free(id);
861 return NULL;
864 /* Create a mark node, marking "node" with "id".
866 __isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id,
867 __isl_take isl_ast_node *node)
869 isl_ctx *ctx;
870 isl_ast_node *mark;
872 if (!id || !node)
873 goto error;
875 ctx = isl_id_get_ctx(id);
876 mark = isl_ast_node_alloc(ctx, isl_ast_node_mark);
877 if (!mark)
878 goto error;
880 mark->u.m.mark = id;
881 mark->u.m.node = node;
883 return mark;
884 error:
885 isl_id_free(id);
886 isl_ast_node_free(node);
887 return NULL;
890 /* Create a user node evaluating "expr".
892 __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
894 isl_ctx *ctx;
895 isl_ast_node *node;
897 if (!expr)
898 return NULL;
900 ctx = isl_ast_expr_get_ctx(expr);
901 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
902 if (!node)
903 goto error;
905 node->u.e.expr = expr;
907 return node;
908 error:
909 isl_ast_expr_free(expr);
910 return NULL;
913 /* Create a block node with the given children.
915 __isl_give isl_ast_node *isl_ast_node_alloc_block(
916 __isl_take isl_ast_node_list *list)
918 isl_ast_node *node;
919 isl_ctx *ctx;
921 if (!list)
922 return NULL;
924 ctx = isl_ast_node_list_get_ctx(list);
925 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
926 if (!node)
927 goto error;
929 node->u.b.children = list;
931 return node;
932 error:
933 isl_ast_node_list_free(list);
934 return NULL;
937 /* Represent the given list of nodes as a single node, either by
938 * extract the node from a single element list or by creating
939 * a block node with the list of nodes as children.
941 __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
942 __isl_take isl_ast_node_list *list)
944 isl_ast_node *node;
946 if (isl_ast_node_list_n_ast_node(list) != 1)
947 return isl_ast_node_alloc_block(list);
949 node = isl_ast_node_list_get_ast_node(list, 0);
950 isl_ast_node_list_free(list);
952 return node;
955 __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
957 if (!node)
958 return NULL;
960 node->ref++;
961 return node;
964 __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
966 isl_ast_node *dup;
968 if (!node)
969 return NULL;
971 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
972 if (!dup)
973 return NULL;
975 switch (node->type) {
976 case isl_ast_node_if:
977 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
978 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
979 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
980 if (!dup->u.i.guard || !dup->u.i.then ||
981 (node->u.i.else_node && !dup->u.i.else_node))
982 return isl_ast_node_free(dup);
983 break;
984 case isl_ast_node_for:
985 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
986 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
987 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
988 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
989 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
990 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
991 !dup->u.f.inc || !dup->u.f.body)
992 return isl_ast_node_free(dup);
993 break;
994 case isl_ast_node_block:
995 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
996 if (!dup->u.b.children)
997 return isl_ast_node_free(dup);
998 break;
999 case isl_ast_node_mark:
1000 dup->u.m.mark = isl_id_copy(node->u.m.mark);
1001 dup->u.m.node = isl_ast_node_copy(node->u.m.node);
1002 if (!dup->u.m.mark || !dup->u.m.node)
1003 return isl_ast_node_free(dup);
1004 break;
1005 case isl_ast_node_user:
1006 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
1007 if (!dup->u.e.expr)
1008 return isl_ast_node_free(dup);
1009 break;
1010 case isl_ast_node_error:
1011 break;
1014 return dup;
1017 __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
1019 if (!node)
1020 return NULL;
1022 if (node->ref == 1)
1023 return node;
1024 node->ref--;
1025 return isl_ast_node_dup(node);
1028 __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node)
1030 if (!node)
1031 return NULL;
1033 if (--node->ref > 0)
1034 return NULL;
1036 switch (node->type) {
1037 case isl_ast_node_if:
1038 isl_ast_expr_free(node->u.i.guard);
1039 isl_ast_node_free(node->u.i.then);
1040 isl_ast_node_free(node->u.i.else_node);
1041 break;
1042 case isl_ast_node_for:
1043 isl_ast_expr_free(node->u.f.iterator);
1044 isl_ast_expr_free(node->u.f.init);
1045 isl_ast_expr_free(node->u.f.cond);
1046 isl_ast_expr_free(node->u.f.inc);
1047 isl_ast_node_free(node->u.f.body);
1048 break;
1049 case isl_ast_node_block:
1050 isl_ast_node_list_free(node->u.b.children);
1051 break;
1052 case isl_ast_node_mark:
1053 isl_id_free(node->u.m.mark);
1054 isl_ast_node_free(node->u.m.node);
1055 break;
1056 case isl_ast_node_user:
1057 isl_ast_expr_free(node->u.e.expr);
1058 break;
1059 case isl_ast_node_error:
1060 break;
1063 isl_id_free(node->annotation);
1064 isl_ctx_deref(node->ctx);
1065 free(node);
1067 return NULL;
1070 /* Replace the body of the for node "node" by "body".
1072 __isl_give isl_ast_node *isl_ast_node_for_set_body(
1073 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
1075 node = isl_ast_node_cow(node);
1076 if (!node || !body)
1077 goto error;
1078 if (node->type != isl_ast_node_for)
1079 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1080 "not a for node", goto error);
1082 isl_ast_node_free(node->u.f.body);
1083 node->u.f.body = body;
1085 return node;
1086 error:
1087 isl_ast_node_free(node);
1088 isl_ast_node_free(body);
1089 return NULL;
1092 __isl_give isl_ast_node *isl_ast_node_for_get_body(
1093 __isl_keep isl_ast_node *node)
1095 if (!node)
1096 return NULL;
1097 if (node->type != isl_ast_node_for)
1098 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1099 "not a for node", return NULL);
1100 return isl_ast_node_copy(node->u.f.body);
1103 /* Mark the given for node as being degenerate.
1105 __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
1106 __isl_take isl_ast_node *node)
1108 node = isl_ast_node_cow(node);
1109 if (!node)
1110 return NULL;
1111 node->u.f.degenerate = 1;
1112 return node;
1115 isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
1117 if (!node)
1118 return isl_bool_error;
1119 if (node->type != isl_ast_node_for)
1120 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1121 "not a for node", return isl_bool_error);
1122 return node->u.f.degenerate;
1125 __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
1126 __isl_keep isl_ast_node *node)
1128 if (!node)
1129 return NULL;
1130 if (node->type != isl_ast_node_for)
1131 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1132 "not a for node", return NULL);
1133 return isl_ast_expr_copy(node->u.f.iterator);
1136 __isl_give isl_ast_expr *isl_ast_node_for_get_init(
1137 __isl_keep isl_ast_node *node)
1139 if (!node)
1140 return NULL;
1141 if (node->type != isl_ast_node_for)
1142 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1143 "not a for node", return NULL);
1144 return isl_ast_expr_copy(node->u.f.init);
1147 /* Return the condition expression of the given for node.
1149 * If the for node is degenerate, then the condition is not explicitly
1150 * stored in the node. Instead, it is constructed as
1152 * iterator <= init
1154 __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
1155 __isl_keep isl_ast_node *node)
1157 if (!node)
1158 return NULL;
1159 if (node->type != isl_ast_node_for)
1160 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1161 "not a for node", return NULL);
1162 if (!node->u.f.degenerate)
1163 return isl_ast_expr_copy(node->u.f.cond);
1165 return isl_ast_expr_alloc_binary(isl_ast_op_le,
1166 isl_ast_expr_copy(node->u.f.iterator),
1167 isl_ast_expr_copy(node->u.f.init));
1170 /* Return the increment of the given for node.
1172 * If the for node is degenerate, then the increment is not explicitly
1173 * stored in the node. We simply return "1".
1175 __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
1176 __isl_keep isl_ast_node *node)
1178 if (!node)
1179 return NULL;
1180 if (node->type != isl_ast_node_for)
1181 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1182 "not a for node", return NULL);
1183 if (!node->u.f.degenerate)
1184 return isl_ast_expr_copy(node->u.f.inc);
1185 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
1188 /* Replace the then branch of the if node "node" by "child".
1190 __isl_give isl_ast_node *isl_ast_node_if_set_then(
1191 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1193 node = isl_ast_node_cow(node);
1194 if (!node || !child)
1195 goto error;
1196 if (node->type != isl_ast_node_if)
1197 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1198 "not an if node", goto error);
1200 isl_ast_node_free(node->u.i.then);
1201 node->u.i.then = child;
1203 return node;
1204 error:
1205 isl_ast_node_free(node);
1206 isl_ast_node_free(child);
1207 return NULL;
1210 __isl_give isl_ast_node *isl_ast_node_if_get_then(
1211 __isl_keep isl_ast_node *node)
1213 if (!node)
1214 return NULL;
1215 if (node->type != isl_ast_node_if)
1216 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1217 "not an if node", return NULL);
1218 return isl_ast_node_copy(node->u.i.then);
1221 isl_bool isl_ast_node_if_has_else(
1222 __isl_keep isl_ast_node *node)
1224 if (!node)
1225 return isl_bool_error;
1226 if (node->type != isl_ast_node_if)
1227 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1228 "not an if node", return isl_bool_error);
1229 return node->u.i.else_node != NULL;
1232 __isl_give isl_ast_node *isl_ast_node_if_get_else(
1233 __isl_keep isl_ast_node *node)
1235 if (!node)
1236 return NULL;
1237 if (node->type != isl_ast_node_if)
1238 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1239 "not an if node", return NULL);
1240 return isl_ast_node_copy(node->u.i.else_node);
1243 __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
1244 __isl_keep isl_ast_node *node)
1246 if (!node)
1247 return NULL;
1248 if (node->type != isl_ast_node_if)
1249 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1250 "not a guard node", return NULL);
1251 return isl_ast_expr_copy(node->u.i.guard);
1254 __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
1255 __isl_keep isl_ast_node *node)
1257 if (!node)
1258 return NULL;
1259 if (node->type != isl_ast_node_block)
1260 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1261 "not a block node", return NULL);
1262 return isl_ast_node_list_copy(node->u.b.children);
1265 __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
1266 __isl_keep isl_ast_node *node)
1268 if (!node)
1269 return NULL;
1270 if (node->type != isl_ast_node_user)
1271 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1272 "not a user node", return NULL);
1274 return isl_ast_expr_copy(node->u.e.expr);
1277 /* Return the mark identifier of the mark node "node".
1279 __isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
1281 if (!node)
1282 return NULL;
1283 if (node->type != isl_ast_node_mark)
1284 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1285 "not a mark node", return NULL);
1287 return isl_id_copy(node->u.m.mark);
1290 /* Return the node marked by mark node "node".
1292 __isl_give isl_ast_node *isl_ast_node_mark_get_node(
1293 __isl_keep isl_ast_node *node)
1295 if (!node)
1296 return NULL;
1297 if (node->type != isl_ast_node_mark)
1298 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
1299 "not a mark node", return NULL);
1301 return isl_ast_node_copy(node->u.m.node);
1304 __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
1306 return node ? isl_id_copy(node->annotation) : NULL;
1309 /* Replace node->annotation by "annotation".
1311 __isl_give isl_ast_node *isl_ast_node_set_annotation(
1312 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1314 node = isl_ast_node_cow(node);
1315 if (!node || !annotation)
1316 goto error;
1318 isl_id_free(node->annotation);
1319 node->annotation = annotation;
1321 return node;
1322 error:
1323 isl_id_free(annotation);
1324 return isl_ast_node_free(node);
1327 /* Traverse the elements of "list" and all their descendants
1328 * in depth first preorder.
1330 * Return isl_stat_ok on success and isl_stat_error on failure.
1332 static isl_stat nodelist_foreach(__isl_keep isl_ast_node_list *list,
1333 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1335 int i;
1337 if (!list)
1338 return isl_stat_error;
1340 for (i = 0; i < list->n; ++i) {
1341 isl_stat ok;
1342 isl_ast_node *node = list->p[i];
1344 ok = isl_ast_node_foreach_descendant_top_down(node, fn, user);
1345 if (ok < 0)
1346 return isl_stat_error;
1349 return isl_stat_ok;
1352 /* Traverse the descendants of "node" (including the node itself)
1353 * in depth first preorder.
1355 * If "fn" returns isl_bool_error on any of the nodes, then the traversal
1356 * is aborted.
1357 * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
1358 * at that node is skipped.
1360 * Return isl_stat_ok on success and isl_stat_error on failure.
1362 isl_stat isl_ast_node_foreach_descendant_top_down(
1363 __isl_keep isl_ast_node *node,
1364 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1366 isl_bool more;
1367 isl_stat ok;
1369 if (!node)
1370 return isl_stat_error;
1372 more = fn(node, user);
1373 if (more < 0)
1374 return isl_stat_error;
1375 if (!more)
1376 return isl_stat_ok;
1378 switch (node->type) {
1379 case isl_ast_node_for:
1380 node = node->u.f.body;
1381 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1382 case isl_ast_node_if:
1383 ok = isl_ast_node_foreach_descendant_top_down(node->u.i.then,
1384 fn, user);
1385 if (ok < 0)
1386 return isl_stat_error;
1387 if (!node->u.i.else_node)
1388 return isl_stat_ok;
1389 node = node->u.i.else_node;
1390 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1391 case isl_ast_node_block:
1392 return nodelist_foreach(node->u.b.children, fn, user);
1393 case isl_ast_node_mark:
1394 node = node->u.m.node;
1395 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1396 case isl_ast_node_user:
1397 break;
1398 case isl_ast_node_error:
1399 return isl_stat_error;
1402 return isl_stat_ok;
1405 /* Textual C representation of the various operators.
1407 static char *op_str_c[] = {
1408 [isl_ast_op_and] = "&&",
1409 [isl_ast_op_and_then] = "&&",
1410 [isl_ast_op_or] = "||",
1411 [isl_ast_op_or_else] = "||",
1412 [isl_ast_op_max] = "max",
1413 [isl_ast_op_min] = "min",
1414 [isl_ast_op_minus] = "-",
1415 [isl_ast_op_add] = "+",
1416 [isl_ast_op_sub] = "-",
1417 [isl_ast_op_mul] = "*",
1418 [isl_ast_op_fdiv_q] = "floord",
1419 [isl_ast_op_pdiv_q] = "/",
1420 [isl_ast_op_pdiv_r] = "%",
1421 [isl_ast_op_zdiv_r] = "%",
1422 [isl_ast_op_div] = "/",
1423 [isl_ast_op_eq] = "==",
1424 [isl_ast_op_le] = "<=",
1425 [isl_ast_op_ge] = ">=",
1426 [isl_ast_op_lt] = "<",
1427 [isl_ast_op_gt] = ">",
1428 [isl_ast_op_member] = ".",
1429 [isl_ast_op_address_of] = "&"
1432 /* Precedence in C of the various operators.
1433 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1434 * Lowest value means highest precedence.
1436 static int op_prec[] = {
1437 [isl_ast_op_and] = 13,
1438 [isl_ast_op_and_then] = 13,
1439 [isl_ast_op_or] = 14,
1440 [isl_ast_op_or_else] = 14,
1441 [isl_ast_op_max] = 2,
1442 [isl_ast_op_min] = 2,
1443 [isl_ast_op_minus] = 3,
1444 [isl_ast_op_add] = 6,
1445 [isl_ast_op_sub] = 6,
1446 [isl_ast_op_mul] = 5,
1447 [isl_ast_op_div] = 5,
1448 [isl_ast_op_fdiv_q] = 2,
1449 [isl_ast_op_pdiv_q] = 5,
1450 [isl_ast_op_pdiv_r] = 5,
1451 [isl_ast_op_zdiv_r] = 5,
1452 [isl_ast_op_cond] = 15,
1453 [isl_ast_op_select] = 15,
1454 [isl_ast_op_eq] = 9,
1455 [isl_ast_op_le] = 8,
1456 [isl_ast_op_ge] = 8,
1457 [isl_ast_op_lt] = 8,
1458 [isl_ast_op_gt] = 8,
1459 [isl_ast_op_call] = 2,
1460 [isl_ast_op_access] = 2,
1461 [isl_ast_op_member] = 2,
1462 [isl_ast_op_address_of] = 3
1465 /* Is the operator left-to-right associative?
1467 static int op_left[] = {
1468 [isl_ast_op_and] = 1,
1469 [isl_ast_op_and_then] = 1,
1470 [isl_ast_op_or] = 1,
1471 [isl_ast_op_or_else] = 1,
1472 [isl_ast_op_max] = 1,
1473 [isl_ast_op_min] = 1,
1474 [isl_ast_op_minus] = 0,
1475 [isl_ast_op_add] = 1,
1476 [isl_ast_op_sub] = 1,
1477 [isl_ast_op_mul] = 1,
1478 [isl_ast_op_div] = 1,
1479 [isl_ast_op_fdiv_q] = 1,
1480 [isl_ast_op_pdiv_q] = 1,
1481 [isl_ast_op_pdiv_r] = 1,
1482 [isl_ast_op_zdiv_r] = 1,
1483 [isl_ast_op_cond] = 0,
1484 [isl_ast_op_select] = 0,
1485 [isl_ast_op_eq] = 1,
1486 [isl_ast_op_le] = 1,
1487 [isl_ast_op_ge] = 1,
1488 [isl_ast_op_lt] = 1,
1489 [isl_ast_op_gt] = 1,
1490 [isl_ast_op_call] = 1,
1491 [isl_ast_op_access] = 1,
1492 [isl_ast_op_member] = 1,
1493 [isl_ast_op_address_of] = 0
1496 static int is_and(enum isl_ast_op_type op)
1498 return op == isl_ast_op_and || op == isl_ast_op_and_then;
1501 static int is_or(enum isl_ast_op_type op)
1503 return op == isl_ast_op_or || op == isl_ast_op_or_else;
1506 static int is_add_sub(enum isl_ast_op_type op)
1508 return op == isl_ast_op_add || op == isl_ast_op_sub;
1511 static int is_div_mod(enum isl_ast_op_type op)
1513 return op == isl_ast_op_div ||
1514 op == isl_ast_op_pdiv_r ||
1515 op == isl_ast_op_zdiv_r;
1518 static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
1519 __isl_keep isl_ast_expr *expr);
1521 /* Do we need/want parentheses around "expr" as a subexpression of
1522 * an "op" operation? If "left" is set, then "expr" is the left-most
1523 * operand.
1525 * We only need parentheses if "expr" represents an operation.
1527 * If op has a higher precedence than expr->u.op.op, then we need
1528 * parentheses.
1529 * If op and expr->u.op.op have the same precedence, but the operations
1530 * are performed in an order that is different from the associativity,
1531 * then we need parentheses.
1533 * An and inside an or technically does not require parentheses,
1534 * but some compilers complain about that, so we add them anyway.
1536 * Computations such as "a / b * c" and "a % b + c" can be somewhat
1537 * difficult to read, so we add parentheses for those as well.
1539 static int sub_expr_need_parens(enum isl_ast_op_type op,
1540 __isl_keep isl_ast_expr *expr, int left)
1542 if (expr->type != isl_ast_expr_op)
1543 return 0;
1545 if (op_prec[expr->u.op.op] > op_prec[op])
1546 return 1;
1547 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
1548 return 1;
1550 if (is_or(op) && is_and(expr->u.op.op))
1551 return 1;
1552 if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
1553 op_prec[expr->u.op.op] == op_prec[op])
1554 return 1;
1555 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
1556 return 1;
1558 return 0;
1561 /* Print "expr" as a subexpression of an "op" operation in C format.
1562 * If "left" is set, then "expr" is the left-most operand.
1564 static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p,
1565 enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
1567 int need_parens;
1569 need_parens = sub_expr_need_parens(op, expr, left);
1571 if (need_parens)
1572 p = isl_printer_print_str(p, "(");
1573 p = print_ast_expr_c(p, expr);
1574 if (need_parens)
1575 p = isl_printer_print_str(p, ")");
1576 return p;
1579 #define isl_ast_op_last isl_ast_op_address_of
1581 /* Data structure that holds the user-specified textual
1582 * representations for the operators in C format.
1583 * The entries are either NULL or copies of strings.
1584 * A NULL entry means that the default name should be used.
1586 struct isl_ast_op_names {
1587 char *op_str[isl_ast_op_last + 1];
1590 /* Create an empty struct isl_ast_op_names.
1592 static void *create_names(isl_ctx *ctx)
1594 return isl_calloc_type(ctx, struct isl_ast_op_names);
1597 /* Free a struct isl_ast_op_names along with all memory
1598 * owned by the struct.
1600 static void free_names(void *user)
1602 int i;
1603 struct isl_ast_op_names *names = user;
1605 if (!user)
1606 return;
1608 for (i = 0; i <= isl_ast_op_last; ++i)
1609 free(names->op_str[i]);
1610 free(user);
1613 /* Create an identifier that is used to store
1614 * an isl_ast_op_names note.
1616 static __isl_give isl_id *names_id(isl_ctx *ctx)
1618 return isl_id_alloc(ctx, "isl_ast_op_type_names", NULL);
1621 /* Ensure that "p" has a note identified by "id".
1622 * If there is no such note yet, then it is created by "note_create" and
1623 * scheduled do be freed by "note_free".
1625 static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p,
1626 __isl_keep isl_id *id, void *(*note_create)(isl_ctx *),
1627 void (*note_free)(void *))
1629 isl_ctx *ctx;
1630 isl_id *note_id;
1631 isl_bool has_note;
1632 void *note;
1634 has_note = isl_printer_has_note(p, id);
1635 if (has_note < 0)
1636 return isl_printer_free(p);
1637 if (has_note)
1638 return p;
1640 ctx = isl_printer_get_ctx(p);
1641 note = note_create(ctx);
1642 if (!note)
1643 return isl_printer_free(p);
1644 note_id = isl_id_alloc(ctx, NULL, note);
1645 if (!note_id)
1646 note_free(note);
1647 else
1648 note_id = isl_id_set_free_user(note_id, note_free);
1650 p = isl_printer_set_note(p, isl_id_copy(id), note_id);
1652 return p;
1655 /* Ensure that "p" has an isl_ast_op_names note identified by "id".
1657 static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p,
1658 __isl_keep isl_id *id)
1660 return alloc_note(p, id, &create_names, &free_names);
1663 /* Retrieve the note identified by "id" from "p".
1664 * The note is assumed to exist.
1666 static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id)
1668 void *note;
1670 id = isl_printer_get_note(p, isl_id_copy(id));
1671 note = isl_id_get_user(id);
1672 isl_id_free(id);
1674 return note;
1677 /* Use "name" to print operations of type "type" to "p".
1679 * Store the name in an isl_ast_op_names note attached to "p", such that
1680 * it can be retrieved by get_op_str.
1682 __isl_give isl_printer *isl_ast_op_type_set_print_name(
1683 __isl_take isl_printer *p, enum isl_ast_op_type type,
1684 __isl_keep const char *name)
1686 isl_id *id;
1687 struct isl_ast_op_names *names;
1689 if (!p)
1690 return NULL;
1691 if (type > isl_ast_op_last)
1692 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
1693 "invalid type", return isl_printer_free(p));
1695 id = names_id(isl_printer_get_ctx(p));
1696 p = alloc_names(p, id);
1697 names = get_note(p, id);
1698 isl_id_free(id);
1699 if (!names)
1700 return isl_printer_free(p);
1701 free(names->op_str[type]);
1702 names->op_str[type] = strdup(name);
1704 return p;
1707 /* Return the textual representation of "type" in C format.
1709 * If there is a user-specified name in an isl_ast_op_names note
1710 * associated to "p", then return that.
1711 * Otherwise, return the default name in op_str.
1713 static const char *get_op_str_c(__isl_keep isl_printer *p,
1714 enum isl_ast_op_type type)
1716 isl_id *id;
1717 isl_bool has_names;
1718 struct isl_ast_op_names *names = NULL;
1720 id = names_id(isl_printer_get_ctx(p));
1721 has_names = isl_printer_has_note(p, id);
1722 if (has_names >= 0 && has_names)
1723 names = get_note(p, id);
1724 isl_id_free(id);
1725 if (names && names->op_str[type])
1726 return names->op_str[type];
1727 return op_str_c[type];
1730 /* Print a min or max reduction "expr" in C format.
1732 static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p,
1733 __isl_keep isl_ast_expr *expr)
1735 int i = 0;
1737 for (i = 1; i < expr->u.op.n_arg; ++i) {
1738 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
1739 p = isl_printer_print_str(p, "(");
1741 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1742 for (i = 1; i < expr->u.op.n_arg; ++i) {
1743 p = isl_printer_print_str(p, ", ");
1744 p = print_ast_expr_c(p, expr->u.op.args[i]);
1745 p = isl_printer_print_str(p, ")");
1748 return p;
1751 /* Print a function call "expr" in C format.
1753 * The first argument represents the function to be called.
1755 static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p,
1756 __isl_keep isl_ast_expr *expr)
1758 int i = 0;
1760 p = print_ast_expr_c(p, expr->u.op.args[0]);
1761 p = isl_printer_print_str(p, "(");
1762 for (i = 1; i < expr->u.op.n_arg; ++i) {
1763 if (i != 1)
1764 p = isl_printer_print_str(p, ", ");
1765 p = print_ast_expr_c(p, expr->u.op.args[i]);
1767 p = isl_printer_print_str(p, ")");
1769 return p;
1772 /* Print an array access "expr" in C format.
1774 * The first argument represents the array being accessed.
1776 static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p,
1777 __isl_keep isl_ast_expr *expr)
1779 int i = 0;
1781 p = print_ast_expr_c(p, expr->u.op.args[0]);
1782 for (i = 1; i < expr->u.op.n_arg; ++i) {
1783 p = isl_printer_print_str(p, "[");
1784 p = print_ast_expr_c(p, expr->u.op.args[i]);
1785 p = isl_printer_print_str(p, "]");
1788 return p;
1791 /* Print "expr" to "p" in C format.
1793 static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
1794 __isl_keep isl_ast_expr *expr)
1796 if (!p)
1797 return NULL;
1798 if (!expr)
1799 return isl_printer_free(p);
1801 switch (expr->type) {
1802 case isl_ast_expr_op:
1803 if (expr->u.op.op == isl_ast_op_call) {
1804 p = print_call_c(p, expr);
1805 break;
1807 if (expr->u.op.op == isl_ast_op_access) {
1808 p = print_access_c(p, expr);
1809 break;
1811 if (expr->u.op.n_arg == 1) {
1812 p = isl_printer_print_str(p,
1813 get_op_str_c(p, expr->u.op.op));
1814 p = print_sub_expr_c(p, expr->u.op.op,
1815 expr->u.op.args[0], 0);
1816 break;
1818 if (expr->u.op.op == isl_ast_op_fdiv_q) {
1819 const char *name = get_op_str_c(p, isl_ast_op_fdiv_q);
1820 p = isl_printer_print_str(p, name);
1821 p = isl_printer_print_str(p, "(");
1822 p = print_ast_expr_c(p, expr->u.op.args[0]);
1823 p = isl_printer_print_str(p, ", ");
1824 p = print_ast_expr_c(p, expr->u.op.args[1]);
1825 p = isl_printer_print_str(p, ")");
1826 break;
1828 if (expr->u.op.op == isl_ast_op_max ||
1829 expr->u.op.op == isl_ast_op_min) {
1830 p = print_min_max_c(p, expr);
1831 break;
1833 if (expr->u.op.op == isl_ast_op_cond ||
1834 expr->u.op.op == isl_ast_op_select) {
1835 p = print_ast_expr_c(p, expr->u.op.args[0]);
1836 p = isl_printer_print_str(p, " ? ");
1837 p = print_ast_expr_c(p, expr->u.op.args[1]);
1838 p = isl_printer_print_str(p, " : ");
1839 p = print_ast_expr_c(p, expr->u.op.args[2]);
1840 break;
1842 if (expr->u.op.n_arg != 2)
1843 isl_die(isl_printer_get_ctx(p), isl_error_internal,
1844 "operation should have two arguments",
1845 return isl_printer_free(p));
1846 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[0], 1);
1847 if (expr->u.op.op != isl_ast_op_member)
1848 p = isl_printer_print_str(p, " ");
1849 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
1850 if (expr->u.op.op != isl_ast_op_member)
1851 p = isl_printer_print_str(p, " ");
1852 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[1], 0);
1853 break;
1854 case isl_ast_expr_id:
1855 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
1856 break;
1857 case isl_ast_expr_int:
1858 p = isl_printer_print_val(p, expr->u.v);
1859 break;
1860 case isl_ast_expr_error:
1861 break;
1864 return p;
1867 /* Textual representation of the isl_ast_op_type elements
1868 * for use in a YAML representation of an isl_ast_expr.
1870 static char *op_str[] = {
1871 [isl_ast_op_and] = "and",
1872 [isl_ast_op_and_then] = "and_then",
1873 [isl_ast_op_or] = "or",
1874 [isl_ast_op_or_else] = "or_else",
1875 [isl_ast_op_max] = "max",
1876 [isl_ast_op_min] = "min",
1877 [isl_ast_op_minus] = "minus",
1878 [isl_ast_op_add] = "add",
1879 [isl_ast_op_sub] = "sub",
1880 [isl_ast_op_mul] = "mul",
1881 [isl_ast_op_div] = "div",
1882 [isl_ast_op_fdiv_q] = "fdiv_q",
1883 [isl_ast_op_pdiv_q] = "pdiv_q",
1884 [isl_ast_op_pdiv_r] = "pdiv_r",
1885 [isl_ast_op_zdiv_r] = "zdiv_r",
1886 [isl_ast_op_cond] = "cond",
1887 [isl_ast_op_select] = "select",
1888 [isl_ast_op_eq] = "eq",
1889 [isl_ast_op_le] = "le",
1890 [isl_ast_op_lt] = "lt",
1891 [isl_ast_op_ge] = "ge",
1892 [isl_ast_op_gt] = "gt",
1893 [isl_ast_op_call] = "call",
1894 [isl_ast_op_access] = "access",
1895 [isl_ast_op_member] = "member",
1896 [isl_ast_op_address_of] = "address_of"
1899 static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
1900 __isl_keep isl_ast_expr *expr);
1902 /* Print the arguments of "expr" to "p" in isl format.
1904 * If there are no arguments, then nothing needs to be printed.
1905 * Otherwise add an "args" key to the current mapping with as value
1906 * the list of arguments of "expr".
1908 static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p,
1909 __isl_keep isl_ast_expr *expr)
1911 int i, n;
1913 n = isl_ast_expr_get_op_n_arg(expr);
1914 if (n < 0)
1915 return isl_printer_free(p);
1916 if (n == 0)
1917 return p;
1919 p = isl_printer_print_str(p, "args");
1920 p = isl_printer_yaml_next(p);
1921 p = isl_printer_yaml_start_sequence(p);
1922 for (i = 0; i < n; ++i) {
1923 isl_ast_expr *arg;
1925 arg = isl_ast_expr_get_op_arg(expr, i);
1926 p = print_ast_expr_isl(p, arg);
1927 isl_ast_expr_free(arg);
1928 p = isl_printer_yaml_next(p);
1930 p = isl_printer_yaml_end_sequence(p);
1932 return p;
1935 /* Print "expr" to "p" in isl format.
1937 * In particular, print the isl_ast_expr as a YAML document.
1939 static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
1940 __isl_keep isl_ast_expr *expr)
1942 enum isl_ast_expr_type type;
1943 enum isl_ast_op_type op;
1944 isl_id *id;
1945 isl_val *v;
1947 if (!expr)
1948 return isl_printer_free(p);
1950 p = isl_printer_yaml_start_mapping(p);
1951 type = isl_ast_expr_get_type(expr);
1952 switch (type) {
1953 case isl_ast_expr_error:
1954 return isl_printer_free(p);
1955 case isl_ast_expr_op:
1956 op = isl_ast_expr_get_op_type(expr);
1957 if (op == isl_ast_op_error)
1958 return isl_printer_free(p);
1959 p = isl_printer_print_str(p, "op");
1960 p = isl_printer_yaml_next(p);
1961 p = isl_printer_print_str(p, op_str[op]);
1962 p = isl_printer_yaml_next(p);
1963 p = print_arguments(p, expr);
1964 break;
1965 case isl_ast_expr_id:
1966 p = isl_printer_print_str(p, "id");
1967 p = isl_printer_yaml_next(p);
1968 id = isl_ast_expr_get_id(expr);
1969 p = isl_printer_print_id(p, id);
1970 isl_id_free(id);
1971 break;
1972 case isl_ast_expr_int:
1973 p = isl_printer_print_str(p, "val");
1974 p = isl_printer_yaml_next(p);
1975 v = isl_ast_expr_get_val(expr);
1976 p = isl_printer_print_val(p, v);
1977 isl_val_free(v);
1978 break;
1980 p = isl_printer_yaml_end_mapping(p);
1982 return p;
1985 /* Print "expr" to "p".
1987 * Only an isl and a C format are supported.
1989 __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
1990 __isl_keep isl_ast_expr *expr)
1992 int format;
1994 if (!p)
1995 return NULL;
1997 format = isl_printer_get_output_format(p);
1998 switch (format) {
1999 case ISL_FORMAT_ISL:
2000 p = print_ast_expr_isl(p, expr);
2001 break;
2002 case ISL_FORMAT_C:
2003 p = print_ast_expr_c(p, expr);
2004 break;
2005 default:
2006 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2007 "output format not supported for ast_expr",
2008 return isl_printer_free(p));
2011 return p;
2014 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2015 __isl_keep isl_ast_node *node);
2017 /* Print a YAML sequence containing the entries in "list" to "p".
2019 static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p,
2020 __isl_keep isl_ast_node_list *list)
2022 int i, n;
2024 n = isl_ast_node_list_n_ast_node(list);
2025 if (n < 0)
2026 return isl_printer_free(p);
2028 p = isl_printer_yaml_start_sequence(p);
2029 for (i = 0; i < n; ++i) {
2030 isl_ast_node *node;
2032 node = isl_ast_node_list_get_ast_node(list, i);
2033 p = print_ast_node_isl(p, node);
2034 isl_ast_node_free(node);
2035 p = isl_printer_yaml_next(p);
2037 p = isl_printer_yaml_end_sequence(p);
2039 return p;
2042 /* Print "node" to "p" in "isl format".
2044 * In particular, print the isl_ast_node as a YAML document.
2046 static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2047 __isl_keep isl_ast_node *node)
2049 switch (node->type) {
2050 case isl_ast_node_for:
2051 p = isl_printer_yaml_start_mapping(p);
2052 p = isl_printer_print_str(p, "iterator");
2053 p = isl_printer_yaml_next(p);
2054 p = isl_printer_print_ast_expr(p, node->u.f.iterator);
2055 p = isl_printer_yaml_next(p);
2056 if (node->u.f.degenerate) {
2057 p = isl_printer_print_str(p, "value");
2058 p = isl_printer_yaml_next(p);
2059 p = isl_printer_print_ast_expr(p, node->u.f.init);
2060 p = isl_printer_yaml_next(p);
2061 } else {
2062 p = isl_printer_print_str(p, "init");
2063 p = isl_printer_yaml_next(p);
2064 p = isl_printer_print_ast_expr(p, node->u.f.init);
2065 p = isl_printer_yaml_next(p);
2066 p = isl_printer_print_str(p, "cond");
2067 p = isl_printer_yaml_next(p);
2068 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2069 p = isl_printer_yaml_next(p);
2070 p = isl_printer_print_str(p, "inc");
2071 p = isl_printer_yaml_next(p);
2072 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2073 p = isl_printer_yaml_next(p);
2075 if (node->u.f.body) {
2076 p = isl_printer_print_str(p, "body");
2077 p = isl_printer_yaml_next(p);
2078 p = isl_printer_print_ast_node(p, node->u.f.body);
2079 p = isl_printer_yaml_next(p);
2081 p = isl_printer_yaml_end_mapping(p);
2082 break;
2083 case isl_ast_node_mark:
2084 p = isl_printer_yaml_start_mapping(p);
2085 p = isl_printer_print_str(p, "mark");
2086 p = isl_printer_yaml_next(p);
2087 p = isl_printer_print_id(p, node->u.m.mark);
2088 p = isl_printer_yaml_next(p);
2089 p = isl_printer_print_str(p, "node");
2090 p = isl_printer_yaml_next(p);
2091 p = isl_printer_print_ast_node(p, node->u.m.node);
2092 p = isl_printer_yaml_end_mapping(p);
2093 break;
2094 case isl_ast_node_user:
2095 p = isl_printer_yaml_start_mapping(p);
2096 p = isl_printer_print_str(p, "user");
2097 p = isl_printer_yaml_next(p);
2098 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2099 p = isl_printer_yaml_end_mapping(p);
2100 break;
2101 case isl_ast_node_if:
2102 p = isl_printer_yaml_start_mapping(p);
2103 p = isl_printer_print_str(p, "guard");
2104 p = isl_printer_yaml_next(p);
2105 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2106 p = isl_printer_yaml_next(p);
2107 if (node->u.i.then) {
2108 p = isl_printer_print_str(p, "then");
2109 p = isl_printer_yaml_next(p);
2110 p = isl_printer_print_ast_node(p, node->u.i.then);
2111 p = isl_printer_yaml_next(p);
2113 if (node->u.i.else_node) {
2114 p = isl_printer_print_str(p, "else");
2115 p = isl_printer_yaml_next(p);
2116 p = isl_printer_print_ast_node(p, node->u.i.else_node);
2118 p = isl_printer_yaml_end_mapping(p);
2119 break;
2120 case isl_ast_node_block:
2121 p = print_ast_node_list(p, node->u.b.children);
2122 break;
2123 case isl_ast_node_error:
2124 break;
2126 return p;
2129 /* Do we need to print a block around the body "node" of a for or if node?
2131 * If the node is a block, then we need to print a block.
2132 * Also if the node is a degenerate for then we will print it as
2133 * an assignment followed by the body of the for loop, so we need a block
2134 * as well.
2135 * If the node is an if node with an else, then we print a block
2136 * to avoid spurious dangling else warnings emitted by some compilers.
2137 * If the node is a mark, then in principle, we would have to check
2138 * the child of the mark node. However, even if the child would not
2139 * require us to print a block, for readability it is probably best
2140 * to print a block anyway.
2141 * If the ast_always_print_block option has been set, then we print a block.
2143 static int need_block(__isl_keep isl_ast_node *node)
2145 isl_ctx *ctx;
2147 if (node->type == isl_ast_node_block)
2148 return 1;
2149 if (node->type == isl_ast_node_for && node->u.f.degenerate)
2150 return 1;
2151 if (node->type == isl_ast_node_if && node->u.i.else_node)
2152 return 1;
2153 if (node->type == isl_ast_node_mark)
2154 return 1;
2156 ctx = isl_ast_node_get_ctx(node);
2157 return isl_options_get_ast_always_print_block(ctx);
2160 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2161 __isl_keep isl_ast_node *node,
2162 __isl_keep isl_ast_print_options *options, int in_block, int in_list);
2163 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2164 __isl_keep isl_ast_node *node,
2165 __isl_keep isl_ast_print_options *options, int new_line,
2166 int force_block);
2168 /* Print the body "node" of a for or if node.
2169 * If "else_node" is set, then it is printed as well.
2170 * If "force_block" is set, then print out the body as a block.
2172 * We first check if we need to print out a block.
2173 * We always print out a block if there is an else node to make
2174 * sure that the else node is matched to the correct if node.
2175 * For consistency, the corresponding else node is also printed as a block.
2177 * If the else node is itself an if, then we print it as
2179 * } else if (..) {
2182 * Otherwise the else node is printed as
2184 * } else {
2185 * node
2188 static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
2189 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
2190 __isl_keep isl_ast_print_options *options, int force_block)
2192 if (!node)
2193 return isl_printer_free(p);
2195 if (!force_block && !else_node && !need_block(node)) {
2196 p = isl_printer_end_line(p);
2197 p = isl_printer_indent(p, 2);
2198 p = isl_ast_node_print(node, p,
2199 isl_ast_print_options_copy(options));
2200 p = isl_printer_indent(p, -2);
2201 return p;
2204 p = isl_printer_print_str(p, " {");
2205 p = isl_printer_end_line(p);
2206 p = isl_printer_indent(p, 2);
2207 p = print_ast_node_c(p, node, options, 1, 0);
2208 p = isl_printer_indent(p, -2);
2209 p = isl_printer_start_line(p);
2210 p = isl_printer_print_str(p, "}");
2211 if (else_node) {
2212 if (else_node->type == isl_ast_node_if) {
2213 p = isl_printer_print_str(p, " else ");
2214 p = print_if_c(p, else_node, options, 0, 1);
2215 } else {
2216 p = isl_printer_print_str(p, " else");
2217 p = print_body_c(p, else_node, NULL, options, 1);
2219 } else
2220 p = isl_printer_end_line(p);
2222 return p;
2225 /* Print the start of a compound statement.
2227 static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
2229 p = isl_printer_start_line(p);
2230 p = isl_printer_print_str(p, "{");
2231 p = isl_printer_end_line(p);
2232 p = isl_printer_indent(p, 2);
2234 return p;
2237 /* Print the end of a compound statement.
2239 static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
2241 p = isl_printer_indent(p, -2);
2242 p = isl_printer_start_line(p);
2243 p = isl_printer_print_str(p, "}");
2244 p = isl_printer_end_line(p);
2246 return p;
2249 /* Print the for node "node".
2251 * If the for node is degenerate, it is printed as
2253 * type iterator = init;
2254 * body
2256 * Otherwise, it is printed as
2258 * for (type iterator = init; cond; iterator += inc)
2259 * body
2261 * "in_block" is set if we are currently inside a block.
2262 * "in_list" is set if the current node is not alone in the block.
2263 * If we are not in a block or if the current not is not alone in the block
2264 * then we print a block around a degenerate for loop such that the variable
2265 * declaration will not conflict with any potential other declaration
2266 * of the same variable.
2268 static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
2269 __isl_keep isl_ast_node *node,
2270 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2272 isl_id *id;
2273 const char *name;
2274 const char *type;
2276 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
2277 if (!node->u.f.degenerate) {
2278 id = isl_ast_expr_get_id(node->u.f.iterator);
2279 name = isl_id_get_name(id);
2280 isl_id_free(id);
2281 p = isl_printer_start_line(p);
2282 p = isl_printer_print_str(p, "for (");
2283 p = isl_printer_print_str(p, type);
2284 p = isl_printer_print_str(p, " ");
2285 p = isl_printer_print_str(p, name);
2286 p = isl_printer_print_str(p, " = ");
2287 p = isl_printer_print_ast_expr(p, node->u.f.init);
2288 p = isl_printer_print_str(p, "; ");
2289 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2290 p = isl_printer_print_str(p, "; ");
2291 p = isl_printer_print_str(p, name);
2292 p = isl_printer_print_str(p, " += ");
2293 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2294 p = isl_printer_print_str(p, ")");
2295 p = print_body_c(p, node->u.f.body, NULL, options, 0);
2296 } else {
2297 id = isl_ast_expr_get_id(node->u.f.iterator);
2298 name = isl_id_get_name(id);
2299 isl_id_free(id);
2300 if (!in_block || in_list)
2301 p = start_block(p);
2302 p = isl_printer_start_line(p);
2303 p = isl_printer_print_str(p, type);
2304 p = isl_printer_print_str(p, " ");
2305 p = isl_printer_print_str(p, name);
2306 p = isl_printer_print_str(p, " = ");
2307 p = isl_printer_print_ast_expr(p, node->u.f.init);
2308 p = isl_printer_print_str(p, ";");
2309 p = isl_printer_end_line(p);
2310 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
2311 if (!in_block || in_list)
2312 p = end_block(p);
2315 return p;
2318 /* Print the if node "node".
2319 * If "new_line" is set then the if node should be printed on a new line.
2320 * If "force_block" is set, then print out the body as a block.
2322 static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2323 __isl_keep isl_ast_node *node,
2324 __isl_keep isl_ast_print_options *options, int new_line,
2325 int force_block)
2327 if (new_line)
2328 p = isl_printer_start_line(p);
2329 p = isl_printer_print_str(p, "if (");
2330 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2331 p = isl_printer_print_str(p, ")");
2332 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options,
2333 force_block);
2335 return p;
2338 /* Print the "node" to "p".
2340 * "in_block" is set if we are currently inside a block.
2341 * If so, we do not print a block around the children of a block node.
2342 * We do this to avoid an extra block around the body of a degenerate
2343 * for node.
2345 * "in_list" is set if the current node is not alone in the block.
2347 static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2348 __isl_keep isl_ast_node *node,
2349 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2351 switch (node->type) {
2352 case isl_ast_node_for:
2353 if (options->print_for)
2354 return options->print_for(p,
2355 isl_ast_print_options_copy(options),
2356 node, options->print_for_user);
2357 p = print_for_c(p, node, options, in_block, in_list);
2358 break;
2359 case isl_ast_node_if:
2360 p = print_if_c(p, node, options, 1, 0);
2361 break;
2362 case isl_ast_node_block:
2363 if (!in_block)
2364 p = start_block(p);
2365 p = isl_ast_node_list_print(node->u.b.children, p, options);
2366 if (!in_block)
2367 p = end_block(p);
2368 break;
2369 case isl_ast_node_mark:
2370 p = isl_printer_start_line(p);
2371 p = isl_printer_print_str(p, "// ");
2372 p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark));
2373 p = isl_printer_end_line(p);
2374 p = print_ast_node_c(p, node->u.m.node, options, 0, in_list);
2375 break;
2376 case isl_ast_node_user:
2377 if (options->print_user)
2378 return options->print_user(p,
2379 isl_ast_print_options_copy(options),
2380 node, options->print_user_user);
2381 p = isl_printer_start_line(p);
2382 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2383 p = isl_printer_print_str(p, ";");
2384 p = isl_printer_end_line(p);
2385 break;
2386 case isl_ast_node_error:
2387 break;
2389 return p;
2392 /* Print the for node "node" to "p".
2394 __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
2395 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2397 if (!node || !options)
2398 goto error;
2399 if (node->type != isl_ast_node_for)
2400 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
2401 "not a for node", goto error);
2402 p = print_for_c(p, node, options, 0, 0);
2403 isl_ast_print_options_free(options);
2404 return p;
2405 error:
2406 isl_ast_print_options_free(options);
2407 isl_printer_free(p);
2408 return NULL;
2411 /* Print the if node "node" to "p".
2413 __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
2414 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2416 if (!node || !options)
2417 goto error;
2418 if (node->type != isl_ast_node_if)
2419 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
2420 "not an if node", goto error);
2421 p = print_if_c(p, node, options, 1, 0);
2422 isl_ast_print_options_free(options);
2423 return p;
2424 error:
2425 isl_ast_print_options_free(options);
2426 isl_printer_free(p);
2427 return NULL;
2430 /* Print "node" to "p".
2432 __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
2433 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2435 if (!options || !node)
2436 goto error;
2437 p = print_ast_node_c(p, node, options, 0, 0);
2438 isl_ast_print_options_free(options);
2439 return p;
2440 error:
2441 isl_ast_print_options_free(options);
2442 isl_printer_free(p);
2443 return NULL;
2446 /* Print "node" to "p".
2448 __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
2449 __isl_keep isl_ast_node *node)
2451 int format;
2452 isl_ast_print_options *options;
2454 if (!p)
2455 return NULL;
2457 format = isl_printer_get_output_format(p);
2458 switch (format) {
2459 case ISL_FORMAT_ISL:
2460 p = print_ast_node_isl(p, node);
2461 break;
2462 case ISL_FORMAT_C:
2463 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
2464 p = isl_ast_node_print(node, p, options);
2465 break;
2466 default:
2467 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2468 "output format not supported for ast_node",
2469 return isl_printer_free(p));
2472 return p;
2475 /* Print the list of nodes "list" to "p".
2477 __isl_give isl_printer *isl_ast_node_list_print(
2478 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
2479 __isl_keep isl_ast_print_options *options)
2481 int i;
2483 if (!p || !list || !options)
2484 return isl_printer_free(p);
2486 for (i = 0; i < list->n; ++i)
2487 p = print_ast_node_c(p, list->p[i], options, 1, 1);
2489 return p;
2492 #define ISL_AST_MACRO_FLOORD (1 << 0)
2493 #define ISL_AST_MACRO_MIN (1 << 1)
2494 #define ISL_AST_MACRO_MAX (1 << 2)
2495 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FLOORD | \
2496 ISL_AST_MACRO_MIN | \
2497 ISL_AST_MACRO_MAX)
2499 /* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2500 * then set the corresponding bit in "macros".
2502 static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
2504 int i;
2506 if (macros == ISL_AST_MACRO_ALL)
2507 return macros;
2509 if (expr->type != isl_ast_expr_op)
2510 return macros;
2512 if (expr->u.op.op == isl_ast_op_min)
2513 macros |= ISL_AST_MACRO_MIN;
2514 if (expr->u.op.op == isl_ast_op_max)
2515 macros |= ISL_AST_MACRO_MAX;
2516 if (expr->u.op.op == isl_ast_op_fdiv_q)
2517 macros |= ISL_AST_MACRO_FLOORD;
2519 for (i = 0; i < expr->u.op.n_arg; ++i)
2520 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
2522 return macros;
2525 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
2526 int macros);
2528 /* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2529 * then set the corresponding bit in "macros".
2531 static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
2533 if (macros == ISL_AST_MACRO_ALL)
2534 return macros;
2536 switch (node->type) {
2537 case isl_ast_node_for:
2538 macros = ast_expr_required_macros(node->u.f.init, macros);
2539 if (!node->u.f.degenerate) {
2540 macros = ast_expr_required_macros(node->u.f.cond,
2541 macros);
2542 macros = ast_expr_required_macros(node->u.f.inc,
2543 macros);
2545 macros = ast_node_required_macros(node->u.f.body, macros);
2546 break;
2547 case isl_ast_node_if:
2548 macros = ast_expr_required_macros(node->u.i.guard, macros);
2549 macros = ast_node_required_macros(node->u.i.then, macros);
2550 if (node->u.i.else_node)
2551 macros = ast_node_required_macros(node->u.i.else_node,
2552 macros);
2553 break;
2554 case isl_ast_node_block:
2555 macros = ast_node_list_required_macros(node->u.b.children,
2556 macros);
2557 break;
2558 case isl_ast_node_mark:
2559 macros = ast_node_required_macros(node->u.m.node, macros);
2560 break;
2561 case isl_ast_node_user:
2562 macros = ast_expr_required_macros(node->u.e.expr, macros);
2563 break;
2564 case isl_ast_node_error:
2565 break;
2568 return macros;
2571 /* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2572 * then set the corresponding bit in "macros".
2574 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
2575 int macros)
2577 int i;
2579 for (i = 0; i < list->n; ++i)
2580 macros = ast_node_required_macros(list->p[i], macros);
2582 return macros;
2585 /* Data structure for keeping track of whether a macro definition
2586 * for a given type has already been printed.
2587 * The value is zero if no definition has been printed and non-zero otherwise.
2589 struct isl_ast_op_printed {
2590 char printed[isl_ast_op_last + 1];
2593 /* Create an empty struct isl_ast_op_printed.
2595 static void *create_printed(isl_ctx *ctx)
2597 return isl_calloc_type(ctx, struct isl_ast_op_printed);
2600 /* Free a struct isl_ast_op_printed.
2602 static void free_printed(void *user)
2604 free(user);
2607 /* Ensure that "p" has an isl_ast_op_printed note identified by "id".
2609 static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p,
2610 __isl_keep isl_id *id)
2612 return alloc_note(p, id, &create_printed, &free_printed);
2615 /* Create an identifier that is used to store
2616 * an isl_ast_op_printed note.
2618 static __isl_give isl_id *printed_id(isl_ctx *ctx)
2620 return isl_id_alloc(ctx, "isl_ast_op_type_printed", NULL);
2623 /* Did the user specify that a macro definition should only be
2624 * printed once and has a macro definition for "type" already
2625 * been printed to "p"?
2626 * If definitions should only be printed once, but a definition
2627 * for "p" has not yet been printed, then mark it as having been
2628 * printed so that it will not printed again.
2629 * The actual printing is taken care of by the caller.
2631 static isl_bool already_printed_once(__isl_keep isl_printer *p,
2632 enum isl_ast_op_type type)
2634 isl_ctx *ctx;
2635 isl_id *id;
2636 struct isl_ast_op_printed *printed;
2638 if (!p)
2639 return isl_bool_error;
2641 ctx = isl_printer_get_ctx(p);
2642 if (!isl_options_get_ast_print_macro_once(ctx))
2643 return isl_bool_false;
2645 if (type > isl_ast_op_last)
2646 isl_die(isl_printer_get_ctx(p), isl_error_invalid,
2647 "invalid type", return isl_bool_error);
2649 id = printed_id(isl_printer_get_ctx(p));
2650 p = alloc_printed(p, id);
2651 printed = get_note(p, id);
2652 isl_id_free(id);
2653 if (!printed)
2654 return isl_bool_error;
2656 if (printed->printed[type])
2657 return isl_bool_true;
2659 printed->printed[type] = 1;
2660 return isl_bool_false;
2663 /* Print a macro definition for the operator "type".
2665 * If the user has specified that a macro definition should
2666 * only be printed once to any given printer and if the macro definition
2667 * has already been printed to "p", then do not print the definition.
2669 __isl_give isl_printer *isl_ast_op_type_print_macro(
2670 enum isl_ast_op_type type, __isl_take isl_printer *p)
2672 isl_bool skip;
2674 skip = already_printed_once(p, type);
2675 if (skip < 0)
2676 return isl_printer_free(p);
2677 if (skip)
2678 return p;
2680 switch (type) {
2681 case isl_ast_op_min:
2682 p = isl_printer_start_line(p);
2683 p = isl_printer_print_str(p, "#define ");
2684 p = isl_printer_print_str(p, get_op_str_c(p, type));
2685 p = isl_printer_print_str(p,
2686 "(x,y) ((x) < (y) ? (x) : (y))");
2687 p = isl_printer_end_line(p);
2688 break;
2689 case isl_ast_op_max:
2690 p = isl_printer_start_line(p);
2691 p = isl_printer_print_str(p, "#define ");
2692 p = isl_printer_print_str(p, get_op_str_c(p, type));
2693 p = isl_printer_print_str(p,
2694 "(x,y) ((x) > (y) ? (x) : (y))");
2695 p = isl_printer_end_line(p);
2696 break;
2697 case isl_ast_op_fdiv_q:
2698 p = isl_printer_start_line(p);
2699 p = isl_printer_print_str(p, "#define ");
2700 p = isl_printer_print_str(p, get_op_str_c(p, type));
2701 p = isl_printer_print_str(p,
2702 "(n,d) "
2703 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
2704 p = isl_printer_end_line(p);
2705 break;
2706 default:
2707 break;
2710 return p;
2713 /* Call "fn" for each type of operation represented in the "macros"
2714 * bit vector.
2716 static isl_stat foreach_ast_op_type(int macros,
2717 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2719 if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0)
2720 return isl_stat_error;
2721 if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0)
2722 return isl_stat_error;
2723 if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0)
2724 return isl_stat_error;
2726 return isl_stat_ok;
2729 /* Call "fn" for each type of operation that appears in "expr"
2730 * and that requires a macro definition.
2732 isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr,
2733 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2735 int macros;
2737 if (!expr)
2738 return isl_stat_error;
2740 macros = ast_expr_required_macros(expr, 0);
2741 return foreach_ast_op_type(macros, fn, user);
2744 /* Call "fn" for each type of operation that appears in "node"
2745 * and that requires a macro definition.
2747 isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
2748 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2750 int macros;
2752 if (!node)
2753 return isl_stat_error;
2755 macros = ast_node_required_macros(node, 0);
2756 return foreach_ast_op_type(macros, fn, user);
2759 static isl_stat ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
2761 isl_printer **p = user;
2763 *p = isl_ast_op_type_print_macro(type, *p);
2765 return isl_stat_ok;
2768 /* Print macro definitions for all the macros used in the result
2769 * of printing "expr".
2771 __isl_give isl_printer *isl_ast_expr_print_macros(
2772 __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
2774 if (isl_ast_expr_foreach_ast_op_type(expr,
2775 &ast_op_type_print_macro, &p) < 0)
2776 return isl_printer_free(p);
2777 return p;
2780 /* Print macro definitions for all the macros used in the result
2781 * of printing "node".
2783 __isl_give isl_printer *isl_ast_node_print_macros(
2784 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
2786 if (isl_ast_node_foreach_ast_op_type(node,
2787 &ast_op_type_print_macro, &p) < 0)
2788 return isl_printer_free(p);
2789 return p;
2792 /* Return a string containing C code representing this isl_ast_expr.
2794 __isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr)
2796 isl_printer *p;
2797 char *str;
2799 if (!expr)
2800 return NULL;
2802 p = isl_printer_to_str(isl_ast_expr_get_ctx(expr));
2803 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
2804 p = isl_printer_print_ast_expr(p, expr);
2806 str = isl_printer_get_str(p);
2808 isl_printer_free(p);
2810 return str;
2813 /* Return a string containing C code representing this isl_ast_node.
2815 __isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node)
2817 isl_printer *p;
2818 char *str;
2820 if (!node)
2821 return NULL;
2823 p = isl_printer_to_str(isl_ast_node_get_ctx(node));
2824 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
2825 p = isl_printer_print_ast_node(p, node);
2827 str = isl_printer_get_str(p);
2829 isl_printer_free(p);
2831 return str;