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
14 #include <isl_ast_private.h>
17 #define EL_BASE ast_expr
19 #include <isl_list_templ.c>
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
);
47 __isl_give isl_ast_print_options
*isl_ast_print_options_dup(
48 __isl_keep isl_ast_print_options
*options
)
51 isl_ast_print_options
*dup
;
56 ctx
= isl_ast_print_options_get_ctx(options
);
57 dup
= isl_ast_print_options_alloc(ctx
);
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
;
69 __isl_give isl_ast_print_options
*isl_ast_print_options_cow(
70 __isl_take isl_ast_print_options
*options
)
75 if (options
->ref
== 1)
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
)
91 __isl_null isl_ast_print_options
*isl_ast_print_options_free(
92 __isl_take isl_ast_print_options
*options
)
97 if (--options
->ref
> 0)
100 isl_ctx_deref(options
->ctx
);
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
),
118 options
= isl_ast_print_options_cow(options
);
122 options
->print_user
= print_user
;
123 options
->print_user_user
= user
;
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
),
139 options
= isl_ast_print_options_cow(options
);
143 options
->print_for
= print_for
;
144 options
->print_for_user
= user
;
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
)
161 ctx
= isl_ast_expr_list_get_ctx(args
);
162 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
169 expr
->type
= isl_ast_expr_op
;
171 expr
->u
.op
.args
= args
;
175 isl_ast_expr_list_free(args
);
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
)
201 __isl_give isl_ast_expr
*isl_ast_expr_dup(__isl_keep isl_ast_expr
*expr
)
208 switch (expr
->type
) {
209 case isl_ast_expr_int
:
210 dup
= isl_ast_expr_from_val(isl_val_copy(expr
->u
.v
));
212 case isl_ast_expr_id
:
213 dup
= isl_ast_expr_from_id(isl_id_copy(expr
->u
.id
));
215 case isl_ast_expr_op
:
216 dup
= alloc_op(expr
->u
.op
.op
,
217 isl_ast_expr_list_copy(expr
->u
.op
.args
));
219 case isl_ast_expr_error
:
229 __isl_give isl_ast_expr
*isl_ast_expr_cow(__isl_take isl_ast_expr
*expr
)
237 return isl_ast_expr_dup(expr
);
240 __isl_null isl_ast_expr
*isl_ast_expr_free(__isl_take isl_ast_expr
*expr
)
248 isl_ctx_deref(expr
->ctx
);
250 switch (expr
->type
) {
251 case isl_ast_expr_int
:
252 isl_val_free(expr
->u
.v
);
254 case isl_ast_expr_id
:
255 isl_id_free(expr
->u
.id
);
257 case isl_ast_expr_op
:
258 isl_ast_expr_list_free(expr
->u
.op
.args
);
260 case isl_ast_expr_error
:
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
)
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
)
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
)
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
);
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
,
366 if (isl_ast_expr_check_op(expr
) < 0)
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
,
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)
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)
407 return isl_ast_expr_op_get_args(expr
);
408 args
= expr
->u
.op
.args
;
409 expr
->u
.op
.args
= NULL
;
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
)
424 if (expr
->u
.op
.args
== args
) {
425 isl_ast_expr_list_free(args
);
429 expr
= isl_ast_expr_cow(expr
);
433 isl_ast_expr_list_free(expr
->u
.op
.args
);
434 expr
->u
.op
.args
= args
;
438 isl_ast_expr_free(expr
);
439 isl_ast_expr_list_free(args
);
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
);
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
);
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
)
479 if (!list1
|| !list2
)
480 return isl_bool_error
;
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
;
489 return isl_bool_false
;
490 for (i
= 0; i
< n1
; ++i
) {
491 isl_ast_expr
*expr1
, *expr2
;
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
)
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
;
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
,
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
)
546 ctx
= isl_id_get_ctx(id
);
547 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
554 expr
->type
= isl_ast_expr_id
;
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
)
569 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
576 expr
->type
= isl_ast_expr_int
;
577 expr
->u
.v
= isl_val_int_from_si(ctx
, i
);
579 return isl_ast_expr_free(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
)
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
);
605 expr
->type
= isl_ast_expr_int
;
614 /* Create an expression representing the unary operation "type" applied to
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
)
621 isl_ast_expr
*expr
= NULL
;
622 isl_ast_expr_list
*args
;
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
);
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
)
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
)
668 isl_ast_expr
*expr
= NULL
;
669 isl_ast_expr_list
*args
;
671 if (!expr1
|| !expr2
)
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
);
684 isl_ast_expr_free(expr1
);
685 isl_ast_expr_free(expr2
);
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
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
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
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
,
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
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
)
869 switch (expr
->type
) {
870 case isl_ast_expr_int
:
872 case isl_ast_expr_id
:
873 m
= isl_id_to_ast_expr_try_get(id2expr
, expr
->u
.id
);
878 isl_ast_expr_free(expr
);
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
);
886 case isl_ast_expr_error
:
887 expr
= isl_ast_expr_free(expr
);
891 isl_id_to_ast_expr_free(id2expr
);
894 isl_ast_expr_free(expr
);
895 isl_id_to_ast_expr_free(id2expr
);
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
)
914 node
= isl_calloc_type(ctx
, isl_ast_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
)
937 node
= isl_ast_node_alloc(isl_ast_expr_get_ctx(guard
), isl_ast_node_if
);
940 node
->u
.i
.guard
= guard
;
944 isl_ast_expr_free(guard
);
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
)
960 ctx
= isl_id_get_ctx(id
);
961 node
= isl_ast_node_alloc(ctx
, isl_ast_node_for
);
965 node
->u
.f
.iterator
= isl_ast_expr_from_id(id
);
966 if (!node
->u
.f
.iterator
)
967 return isl_ast_node_free(node
);
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
)
986 ctx
= isl_id_get_ctx(id
);
987 mark
= isl_ast_node_alloc(ctx
, isl_ast_node_mark
);
992 mark
->u
.m
.node
= node
;
997 isl_ast_node_free(node
);
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
)
1012 ctx
= isl_ast_expr_get_ctx(expr
);
1013 node
= isl_ast_node_alloc(ctx
, isl_ast_node_user
);
1017 node
->u
.e
.expr
= expr
;
1021 isl_ast_expr_free(expr
);
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
)
1043 ctx
= isl_ast_node_list_get_ctx(list
);
1044 node
= isl_ast_node_alloc(ctx
, isl_ast_node_block
);
1048 node
->u
.b
.children
= list
;
1052 isl_ast_node_list_free(list
);
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
)
1066 n
= isl_ast_node_list_n_ast_node(list
);
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
);
1077 isl_ast_node_list_free(list
);
1081 __isl_give isl_ast_node
*isl_ast_node_copy(__isl_keep isl_ast_node
*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
)
1102 dup
= isl_ast_node_alloc(isl_ast_node_get_ctx(node
), node
->type
);
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
);
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
)
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
);
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
);
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
);
1140 case isl_ast_node_user
:
1141 dup
->u
.e
.expr
= isl_ast_expr_copy(node
->u
.e
.expr
);
1143 return isl_ast_node_free(dup
);
1145 case isl_ast_node_error
:
1149 if (!node
->annotation
)
1151 dup
->annotation
= isl_id_copy(node
->annotation
);
1152 if (!dup
->annotation
)
1153 return isl_ast_node_free(dup
);
1158 __isl_give isl_ast_node
*isl_ast_node_cow(__isl_take isl_ast_node
*node
)
1166 return isl_ast_node_dup(node
);
1169 __isl_null isl_ast_node
*isl_ast_node_free(__isl_take isl_ast_node
*node
)
1174 if (--node
->ref
> 0)
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
);
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
);
1190 case isl_ast_node_block
:
1191 isl_ast_node_list_free(node
->u
.b
.children
);
1193 case isl_ast_node_mark
:
1194 isl_id_free(node
->u
.m
.mark
);
1195 isl_ast_node_free(node
->u
.m
.node
);
1197 case isl_ast_node_user
:
1198 isl_ast_expr_free(node
->u
.e
.expr
);
1200 case isl_ast_node_error
:
1204 isl_id_free(node
->annotation
);
1205 isl_ctx_deref(node
->ctx
);
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
)
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
);
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
,
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
,
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
,
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
)
1277 if (isl_ast_node_check_for(node
) < 0)
1280 return isl_ast_node_for_get_body(node
);
1281 body
= node
->u
.f
.body
;
1282 node
->u
.f
.body
= NULL
;
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
)
1297 if (node
->u
.f
.body
== body
) {
1298 isl_ast_node_free(body
);
1302 node
= isl_ast_node_cow(node
);
1306 isl_ast_node_free(node
->u
.f
.body
);
1307 node
->u
.f
.body
= body
;
1311 isl_ast_node_free(node
);
1312 isl_ast_node_free(body
);
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)
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
);
1340 node
->u
.f
.degenerate
= 1;
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)
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)
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
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)
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)
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)
1419 return isl_ast_node_if_get_then_node(node
);
1420 then_node
= node
->u
.i
.then
;
1421 node
->u
.i
.then
= NULL
;
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
)
1436 if (node
->u
.i
.then
== child
) {
1437 isl_ast_node_free(child
);
1441 node
= isl_ast_node_cow(node
);
1445 isl_ast_node_free(node
->u
.i
.then
);
1446 node
->u
.i
.then
= child
;
1450 isl_ast_node_free(node
);
1451 isl_ast_node_free(child
);
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)
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)
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)
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
;
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
)
1550 if (node
->u
.i
.else_node
== child
) {
1551 isl_ast_node_free(child
);
1555 node
= isl_ast_node_cow(node
);
1559 isl_ast_node_free(node
->u
.i
.else_node
);
1560 node
->u
.i
.else_node
= child
;
1564 isl_ast_node_free(node
);
1565 isl_ast_node_free(child
);
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)
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)
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)
1602 return isl_ast_node_block_get_children(node
);
1603 children
= node
->u
.b
.children
;
1604 node
->u
.b
.children
= NULL
;
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
)
1619 if (node
->u
.b
.children
== children
) {
1620 isl_ast_node_list_free(children
);
1624 node
= isl_ast_node_cow(node
);
1628 isl_ast_node_list_free(node
->u
.b
.children
);
1629 node
->u
.b
.children
= children
;
1633 isl_ast_node_free(node
);
1634 isl_ast_node_list_free(children
);
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)
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)
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)
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)
1685 return isl_ast_node_mark_get_node(node
);
1686 child
= node
->u
.m
.node
;
1687 node
->u
.m
.node
= NULL
;
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
)
1702 if (node
->u
.m
.node
== child
) {
1703 isl_ast_node_free(child
);
1707 node
= isl_ast_node_cow(node
);
1711 isl_ast_node_free(node
->u
.m
.node
);
1712 node
->u
.m
.node
= child
;
1716 isl_ast_node_free(node
);
1717 isl_ast_node_free(child
);
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
)
1735 isl_id_free(node
->annotation
);
1736 node
->annotation
= annotation
;
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
,
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
,
1768 n
= isl_ast_node_list_size(list
);
1770 return isl_ast_node_list_free(list
);
1772 for (i
= 0; i
< n
; ++i
) {
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
);
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
,
1801 isl_ast_node
*child
;
1802 isl_ast_node_list
*children
;
1804 node
= enter(node
, &more
, user
);
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
);
1822 return isl_ast_node_free(node
);
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
);
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
);
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
;
1869 m
= data
->fn(node
, data
->user
);
1871 return isl_ast_node_free(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
,
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
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
,
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
)
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
,
1937 struct isl_ast_node_postorder_data
*data
= user
;
1942 node
= data
->fn(node
, data
->user
);
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
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
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
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
)
2102 if (op_prec
[expr
->u
.op
.op
] > op_prec
[op
])
2104 if (op_prec
[expr
->u
.op
.op
] == op_prec
[op
] && left
!= op_left
[op
])
2107 if (is_or(op
) && is_and(expr
->u
.op
.op
))
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
])
2112 if (is_add_sub(op
) && is_div_mod(expr
->u
.op
.op
))
2118 /* Print the subexpression at position "pos" of operation expression "expr"
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
)
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
);
2135 p
= isl_printer_print_str(p
, "(");
2136 p
= print_ast_expr_c(p
, arg
);
2138 p
= isl_printer_print_str(p
, ")");
2140 isl_ast_expr_free(arg
);
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
)
2169 struct isl_ast_expr_op_names
*names
= user
;
2174 for (i
= 0; i
<= isl_ast_expr_op_last
; ++i
)
2175 free(names
->op_str
[i
]);
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 *))
2200 has_note
= isl_printer_has_note(p
, id
);
2202 return isl_printer_free(p
);
2206 ctx
= isl_printer_get_ctx(p
);
2207 note
= note_create(ctx
);
2209 return isl_printer_free(p
);
2210 note_id
= isl_id_alloc(ctx
, NULL
, note
);
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
);
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
)
2236 id
= isl_printer_get_note(p
, isl_id_copy(id
));
2237 note
= isl_id_get_user(id
);
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
)
2253 struct isl_ast_expr_op_names
*names
;
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
);
2266 return isl_printer_free(p
);
2267 free(names
->op_str
[type
]);
2268 names
->op_str
[type
] = strdup(name
);
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
)
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
);
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
)
2312 expr
= isl_ast_expr_list_get_at(list
, pos
);
2313 p
= print_ast_expr_c(p
, expr
);
2314 isl_ast_expr_free(expr
);
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
)
2327 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
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
, ")");
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
)
2355 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
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
) {
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
, ")");
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
)
2381 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
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
, "]");
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
)
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
);
2413 if (expr
->u
.op
.op
== isl_ast_expr_op_access
) {
2414 p
= print_access_c(p
, expr
);
2417 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
2419 return isl_printer_free(p
);
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);
2426 if (expr
->u
.op
.op
== isl_ast_expr_op_fdiv_q
) {
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
, ")");
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
);
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);
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);
2464 case isl_ast_expr_id
:
2465 p
= isl_printer_print_str(p
, isl_id_get_name(expr
->u
.id
));
2467 case isl_ast_expr_int
:
2468 p
= isl_printer_print_val(p
, expr
->u
.v
);
2470 case isl_ast_expr_error
:
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
)
2524 n
= isl_ast_expr_get_op_n_arg(expr
);
2526 return isl_printer_free(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
) {
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
);
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
;
2559 return isl_printer_free(p
);
2561 p
= isl_printer_yaml_start_mapping(p
);
2562 type
= isl_ast_expr_get_type(expr
);
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
);
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
);
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
);
2591 p
= isl_printer_yaml_end_mapping(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
)
2608 format
= isl_printer_get_output_format(p
);
2610 case ISL_FORMAT_ISL
:
2611 p
= print_ast_expr_isl(p
, expr
);
2614 p
= print_ast_expr_c(p
, expr
);
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
));
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
)
2636 n
= isl_ast_node_list_n_ast_node(list
);
2638 return isl_printer_free(p
);
2640 p
= isl_printer_yaml_start_sequence(p
);
2641 for (i
= 0; i
< n
; ++i
) {
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
);
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
);
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
);
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
);
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
);
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
);
2732 case isl_ast_node_block
:
2733 p
= print_ast_node_list(p
, node
->u
.b
.children
);
2735 case isl_ast_node_error
:
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
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
)
2759 if (node
->type
== isl_ast_node_block
)
2761 if (node
->type
== isl_ast_node_for
&& node
->u
.f
.degenerate
)
2763 if (node
->type
== isl_ast_node_if
&& node
->u
.i
.else_node
)
2765 if (node
->type
== isl_ast_node_mark
)
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
,
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
2794 * Otherwise the else node is printed as
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
)
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);
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
, "}");
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);
2828 p
= isl_printer_print_str(p
, " else");
2829 p
= print_body_c(p
, else_node
, NULL
, options
, 1);
2832 p
= isl_printer_end_line(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);
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
);
2861 /* Print the for node "node".
2863 * If the for node is degenerate, it is printed as
2865 * type iterator = init;
2868 * Otherwise, it is printed as
2870 * for (type iterator = init; cond; iterator += inc)
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
)
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
);
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);
2909 id
= isl_ast_expr_get_id(node
->u
.f
.iterator
);
2910 name
= isl_id_get_name(id
);
2912 if (!in_block
|| in_list
)
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
)
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
,
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
,
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
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
);
2971 case isl_ast_node_if
:
2972 p
= print_if_c(p
, node
, options
, 1, 0);
2974 case isl_ast_node_block
:
2977 p
= isl_ast_node_list_print(node
->u
.b
.children
, p
, options
);
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
);
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
);
2998 case isl_ast_node_error
:
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
)
3011 p
= print_for_c(p
, node
, options
, 0, 0);
3012 isl_ast_print_options_free(options
);
3015 isl_ast_print_options_free(options
);
3016 isl_printer_free(p
);
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
)
3027 p
= print_if_c(p
, node
, options
, 1, 0);
3028 isl_ast_print_options_free(options
);
3031 isl_ast_print_options_free(options
);
3032 isl_printer_free(p
);
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
)
3050 if (!options
|| !node
)
3052 if (node
->type
== isl_ast_node_block
) {
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
);
3062 isl_ast_print_options_free(options
);
3063 isl_printer_free(p
);
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
)
3073 isl_ast_print_options
*options
;
3078 format
= isl_printer_get_output_format(p
);
3080 case ISL_FORMAT_ISL
:
3081 p
= print_ast_node_isl(p
, node
);
3084 options
= isl_ast_print_options_alloc(isl_printer_get_ctx(p
));
3085 p
= isl_ast_node_print(node
, p
, options
);
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
));
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
)
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);
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 | \
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
)
3129 *macros
= ast_expr_required_macros(expr
, *macros
);
3130 isl_ast_expr_free(expr
);
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
)
3143 if (expr
->type
!= isl_ast_expr_op
)
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
, ¯os
);
3159 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list
*list
,
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
)
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
,
3176 macros
= ast_expr_required_macros(node
->u
.f
.inc
,
3179 macros
= ast_node_required_macros(node
->u
.f
.body
, macros
);
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
,
3188 case isl_ast_node_block
:
3189 macros
= ast_node_list_required_macros(node
->u
.b
.children
,
3192 case isl_ast_node_mark
:
3193 macros
= ast_node_required_macros(node
->u
.m
.node
, macros
);
3195 case isl_ast_node_user
:
3196 macros
= ast_expr_required_macros(node
->u
.e
.expr
, macros
);
3198 case isl_ast_node_error
:
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
,
3213 for (i
= 0; i
< list
->n
; ++i
)
3214 macros
= ast_node_required_macros(list
->p
[i
], 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
)
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
)
3270 struct isl_ast_expr_op_printed
*printed
;
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
);
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
)
3308 skip
= already_printed_once(p
, type
);
3310 return isl_printer_free(p
);
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
);
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
);
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
,
3337 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
3338 p
= isl_printer_end_line(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"
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
;
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
)
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
)
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
,
3421 isl_printer
**p
= user
;
3423 *p
= isl_ast_expr_op_type_print_macro(type
, *p
);
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
);
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
);
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
)
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
);
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
)
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
);