2 * Copyright 2012-2013 Ecole Normale Superieure
3 * Copyright 2022 Cerebras Systems
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege,
8 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
9 * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
15 #include <isl/stream.h>
17 #include <isl_ast_private.h>
20 #define EL_BASE ast_expr
22 #include <isl_list_templ.c>
25 #define EL_BASE ast_node
27 #include <isl_list_templ.c>
29 isl_ctx
*isl_ast_print_options_get_ctx(
30 __isl_keep isl_ast_print_options
*options
)
32 return options
? options
->ctx
: NULL
;
35 __isl_give isl_ast_print_options
*isl_ast_print_options_alloc(isl_ctx
*ctx
)
37 isl_ast_print_options
*options
;
39 options
= isl_calloc_type(ctx
, isl_ast_print_options
);
50 __isl_give isl_ast_print_options
*isl_ast_print_options_dup(
51 __isl_keep isl_ast_print_options
*options
)
54 isl_ast_print_options
*dup
;
59 ctx
= isl_ast_print_options_get_ctx(options
);
60 dup
= isl_ast_print_options_alloc(ctx
);
64 dup
->print_for
= options
->print_for
;
65 dup
->print_for_user
= options
->print_for_user
;
66 dup
->print_user
= options
->print_user
;
67 dup
->print_user_user
= options
->print_user_user
;
72 __isl_give isl_ast_print_options
*isl_ast_print_options_cow(
73 __isl_take isl_ast_print_options
*options
)
78 if (options
->ref
== 1)
81 return isl_ast_print_options_dup(options
);
84 __isl_give isl_ast_print_options
*isl_ast_print_options_copy(
85 __isl_keep isl_ast_print_options
*options
)
94 __isl_null isl_ast_print_options
*isl_ast_print_options_free(
95 __isl_take isl_ast_print_options
*options
)
100 if (--options
->ref
> 0)
103 isl_ctx_deref(options
->ctx
);
109 /* Set the print_user callback of "options" to "print_user".
111 * If this callback is set, then it is used to print user nodes in the AST.
112 * Otherwise, the expression associated to the user node is printed.
114 __isl_give isl_ast_print_options
*isl_ast_print_options_set_print_user(
115 __isl_take isl_ast_print_options
*options
,
116 __isl_give isl_printer
*(*print_user
)(__isl_take isl_printer
*p
,
117 __isl_take isl_ast_print_options
*options
,
118 __isl_keep isl_ast_node
*node
, void *user
),
121 options
= isl_ast_print_options_cow(options
);
125 options
->print_user
= print_user
;
126 options
->print_user_user
= user
;
131 /* Set the print_for callback of "options" to "print_for".
133 * If this callback is set, then it used to print for nodes in the AST.
135 __isl_give isl_ast_print_options
*isl_ast_print_options_set_print_for(
136 __isl_take isl_ast_print_options
*options
,
137 __isl_give isl_printer
*(*print_for
)(__isl_take isl_printer
*p
,
138 __isl_take isl_ast_print_options
*options
,
139 __isl_keep isl_ast_node
*node
, void *user
),
142 options
= isl_ast_print_options_cow(options
);
146 options
->print_for
= print_for
;
147 options
->print_for_user
= user
;
152 /* Create a new operation expression of operation type "op",
153 * with arguments "args".
155 static __isl_give isl_ast_expr
*alloc_op(enum isl_ast_expr_op_type op
,
156 __isl_take isl_ast_expr_list
*args
)
164 ctx
= isl_ast_expr_list_get_ctx(args
);
165 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
172 expr
->type
= isl_ast_expr_op
;
174 expr
->u
.op
.args
= args
;
178 isl_ast_expr_list_free(args
);
182 /* Create a new operation expression of operation type "op",
183 * which will end up having "n_arg" arguments.
184 * The caller still needs to add those arguments.
186 __isl_give isl_ast_expr
*isl_ast_expr_alloc_op(isl_ctx
*ctx
,
187 enum isl_ast_expr_op_type op
, int n_arg
)
189 isl_ast_expr_list
*args
;
191 args
= isl_ast_expr_list_alloc(ctx
, n_arg
);
192 return alloc_op(op
, args
);
195 __isl_give isl_ast_expr
*isl_ast_expr_copy(__isl_keep isl_ast_expr
*expr
)
204 __isl_give isl_ast_expr
*isl_ast_expr_dup(__isl_keep isl_ast_expr
*expr
)
211 switch (expr
->type
) {
212 case isl_ast_expr_int
:
213 dup
= isl_ast_expr_from_val(isl_val_copy(expr
->u
.v
));
215 case isl_ast_expr_id
:
216 dup
= isl_ast_expr_from_id(isl_id_copy(expr
->u
.id
));
218 case isl_ast_expr_op
:
219 dup
= alloc_op(expr
->u
.op
.op
,
220 isl_ast_expr_list_copy(expr
->u
.op
.args
));
222 case isl_ast_expr_error
:
232 __isl_give isl_ast_expr
*isl_ast_expr_cow(__isl_take isl_ast_expr
*expr
)
240 return isl_ast_expr_dup(expr
);
243 __isl_null isl_ast_expr
*isl_ast_expr_free(__isl_take isl_ast_expr
*expr
)
251 isl_ctx_deref(expr
->ctx
);
253 switch (expr
->type
) {
254 case isl_ast_expr_int
:
255 isl_val_free(expr
->u
.v
);
257 case isl_ast_expr_id
:
258 isl_id_free(expr
->u
.id
);
260 case isl_ast_expr_op
:
261 isl_ast_expr_list_free(expr
->u
.op
.args
);
263 case isl_ast_expr_error
:
271 isl_ctx
*isl_ast_expr_get_ctx(__isl_keep isl_ast_expr
*expr
)
273 return expr
? expr
->ctx
: NULL
;
276 enum isl_ast_expr_type
isl_ast_expr_get_type(__isl_keep isl_ast_expr
*expr
)
278 return expr
? expr
->type
: isl_ast_expr_error
;
281 /* Return the integer value represented by "expr".
283 __isl_give isl_val
*isl_ast_expr_int_get_val(__isl_keep isl_ast_expr
*expr
)
287 if (expr
->type
!= isl_ast_expr_int
)
288 isl_die(isl_ast_expr_get_ctx(expr
), isl_error_invalid
,
289 "expression not an int", return NULL
);
290 return isl_val_copy(expr
->u
.v
);
293 /* This is an alternative name for the function above.
295 __isl_give isl_val
*isl_ast_expr_get_val(__isl_keep isl_ast_expr
*expr
)
297 return isl_ast_expr_int_get_val(expr
);
300 __isl_give isl_id
*isl_ast_expr_id_get_id(__isl_keep isl_ast_expr
*expr
)
304 if (expr
->type
!= isl_ast_expr_id
)
305 isl_die(isl_ast_expr_get_ctx(expr
), isl_error_invalid
,
306 "expression not an identifier", return NULL
);
308 return isl_id_copy(expr
->u
.id
);
311 /* This is an alternative name for the function above.
313 __isl_give isl_id
*isl_ast_expr_get_id(__isl_keep isl_ast_expr
*expr
)
315 return isl_ast_expr_id_get_id(expr
);
318 /* Check that "expr" is of type isl_ast_expr_op.
320 static isl_stat
isl_ast_expr_check_op(__isl_keep isl_ast_expr
*expr
)
323 return isl_stat_error
;
324 if (expr
->type
!= isl_ast_expr_op
)
325 isl_die(isl_ast_expr_get_ctx(expr
), isl_error_invalid
,
326 "expression not an operation", return isl_stat_error
);
330 /* Return the type of operation represented by "expr".
332 enum isl_ast_expr_op_type
isl_ast_expr_op_get_type(
333 __isl_keep isl_ast_expr
*expr
)
335 if (isl_ast_expr_check_op(expr
) < 0)
336 return isl_ast_expr_op_error
;
337 return expr
->u
.op
.op
;
340 /* This is an alternative name for the function above.
342 enum isl_ast_expr_op_type
isl_ast_expr_get_op_type(
343 __isl_keep isl_ast_expr
*expr
)
345 return isl_ast_expr_op_get_type(expr
);
348 /* Return the number of arguments of the operation represented by "expr".
350 isl_size
isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr
*expr
)
352 if (isl_ast_expr_check_op(expr
) < 0)
353 return isl_size_error
;
354 return isl_ast_expr_list_size(expr
->u
.op
.args
);
357 /* This is an alternative name for the function above.
359 isl_size
isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr
*expr
)
361 return isl_ast_expr_op_get_n_arg(expr
);
364 /* Return the argument at position "pos" of the operation represented by "expr".
366 __isl_give isl_ast_expr
*isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr
*expr
,
369 if (isl_ast_expr_check_op(expr
) < 0)
372 return isl_ast_expr_list_get_at(expr
->u
.op
.args
, pos
);
375 /* This is an alternative name for the function above.
377 __isl_give isl_ast_expr
*isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr
*expr
,
380 return isl_ast_expr_op_get_arg(expr
, pos
);
383 /* Return a copy of the arguments of the operation represented by "expr".
385 static __isl_give isl_ast_expr_list
*isl_ast_expr_op_get_args(
386 __isl_keep isl_ast_expr
*expr
)
388 if (isl_ast_expr_check_op(expr
) < 0)
390 return isl_ast_expr_list_copy(expr
->u
.op
.args
);
393 /* Return the arguments of the operation expression "expr".
394 * This may be either a copy or the arguments themselves
395 * if there is only one reference to "expr".
396 * This allows the arguments to be modified inplace
397 * if both "expr" and its arguments have only a single reference.
398 * The caller is not allowed to modify "expr" between this call and
399 * the subsequent call to isl_ast_expr_op_restore_args.
400 * The only exception is that isl_ast_expr_free can be called instead.
402 static __isl_give isl_ast_expr_list
*isl_ast_expr_op_take_args(
403 __isl_keep isl_ast_expr
*expr
)
405 isl_ast_expr_list
*args
;
407 if (isl_ast_expr_check_op(expr
) < 0)
410 return isl_ast_expr_op_get_args(expr
);
411 args
= expr
->u
.op
.args
;
412 expr
->u
.op
.args
= NULL
;
416 /* Set the arguments of the operation expression "expr" to "args",
417 * where the arguments of "args" may be missing
418 * due to a preceding call to isl_ast_expr_op_take_args.
419 * However, in this case, "expr" only has a single reference and
420 * then the call to isl_ast_expr_cow has no effect.
422 static __isl_give isl_ast_expr
*isl_ast_expr_op_restore_args(
423 __isl_take isl_ast_expr
*expr
, __isl_take isl_ast_expr_list
*args
)
425 if (isl_ast_expr_check_op(expr
) < 0 || !args
)
427 if (expr
->u
.op
.args
== args
) {
428 isl_ast_expr_list_free(args
);
432 expr
= isl_ast_expr_cow(expr
);
436 isl_ast_expr_list_free(expr
->u
.op
.args
);
437 expr
->u
.op
.args
= args
;
441 isl_ast_expr_free(expr
);
442 isl_ast_expr_list_free(args
);
446 /* Add "arg" to the arguments of the operation expression "expr".
448 __isl_give isl_ast_expr
*isl_ast_expr_op_add_arg(__isl_take isl_ast_expr
*expr
,
449 __isl_take isl_ast_expr
*arg
)
451 isl_ast_expr_list
*args
;
453 args
= isl_ast_expr_op_take_args(expr
);
454 args
= isl_ast_expr_list_add(args
, arg
);
455 expr
= isl_ast_expr_op_restore_args(expr
, args
);
460 /* Replace the argument at position "pos" of "expr" by "arg".
462 __isl_give isl_ast_expr
*isl_ast_expr_set_op_arg(__isl_take isl_ast_expr
*expr
,
463 int pos
, __isl_take isl_ast_expr
*arg
)
465 isl_ast_expr_list
*args
;
467 args
= isl_ast_expr_op_take_args(expr
);
468 args
= isl_ast_expr_list_set_at(args
, pos
, arg
);
469 expr
= isl_ast_expr_op_restore_args(expr
, args
);
474 /* Are the lists of AST expressions "list1" and "list2" the same?
476 static isl_bool
isl_ast_expr_list_is_equal(__isl_keep isl_ast_expr_list
*list1
,
477 __isl_keep isl_ast_expr_list
*list2
)
482 if (!list1
|| !list2
)
483 return isl_bool_error
;
485 return isl_bool_true
;
487 n1
= isl_ast_expr_list_size(list1
);
488 n2
= isl_ast_expr_list_size(list2
);
489 if (n1
< 0 || n2
< 0)
490 return isl_bool_error
;
492 return isl_bool_false
;
493 for (i
= 0; i
< n1
; ++i
) {
494 isl_ast_expr
*expr1
, *expr2
;
497 expr1
= isl_ast_expr_list_get_at(list1
, i
);
498 expr2
= isl_ast_expr_list_get_at(list2
, i
);
499 equal
= isl_ast_expr_is_equal(expr1
, expr2
);
500 isl_ast_expr_free(expr1
);
501 isl_ast_expr_free(expr2
);
502 if (equal
< 0 || !equal
)
506 return isl_bool_true
;
509 /* Is "expr1" equal to "expr2"?
511 isl_bool
isl_ast_expr_is_equal(__isl_keep isl_ast_expr
*expr1
,
512 __isl_keep isl_ast_expr
*expr2
)
514 if (!expr1
|| !expr2
)
515 return isl_bool_error
;
518 return isl_bool_true
;
519 if (expr1
->type
!= expr2
->type
)
520 return isl_bool_false
;
521 switch (expr1
->type
) {
522 case isl_ast_expr_int
:
523 return isl_val_eq(expr1
->u
.v
, expr2
->u
.v
);
524 case isl_ast_expr_id
:
525 return isl_bool_ok(expr1
->u
.id
== expr2
->u
.id
);
526 case isl_ast_expr_op
:
527 if (expr1
->u
.op
.op
!= expr2
->u
.op
.op
)
528 return isl_bool_false
;
529 return isl_ast_expr_list_is_equal(expr1
->u
.op
.args
,
531 case isl_ast_expr_error
:
532 return isl_bool_error
;
535 isl_die(isl_ast_expr_get_ctx(expr1
), isl_error_internal
,
536 "unhandled case", return isl_bool_error
);
539 /* Create a new id expression representing "id".
541 __isl_give isl_ast_expr
*isl_ast_expr_from_id(__isl_take isl_id
*id
)
549 ctx
= isl_id_get_ctx(id
);
550 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
557 expr
->type
= isl_ast_expr_id
;
566 /* Create a new integer expression representing "i".
568 __isl_give isl_ast_expr
*isl_ast_expr_alloc_int_si(isl_ctx
*ctx
, int i
)
572 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
579 expr
->type
= isl_ast_expr_int
;
580 expr
->u
.v
= isl_val_int_from_si(ctx
, i
);
582 return isl_ast_expr_free(expr
);
587 /* Create a new integer expression representing "v".
589 __isl_give isl_ast_expr
*isl_ast_expr_from_val(__isl_take isl_val
*v
)
596 if (!isl_val_is_int(v
))
597 isl_die(isl_val_get_ctx(v
), isl_error_invalid
,
598 "expecting integer value", goto error
);
600 ctx
= isl_val_get_ctx(v
);
601 expr
= isl_calloc_type(ctx
, isl_ast_expr
);
608 expr
->type
= isl_ast_expr_int
;
617 /* Create an expression representing the unary operation "type" applied to
620 __isl_give isl_ast_expr
*isl_ast_expr_alloc_unary(
621 enum isl_ast_expr_op_type type
, __isl_take isl_ast_expr
*arg
)
624 isl_ast_expr
*expr
= NULL
;
625 isl_ast_expr_list
*args
;
630 ctx
= isl_ast_expr_get_ctx(arg
);
631 expr
= isl_ast_expr_alloc_op(ctx
, type
, 1);
633 args
= isl_ast_expr_op_take_args(expr
);
634 args
= isl_ast_expr_list_add(args
, arg
);
635 expr
= isl_ast_expr_op_restore_args(expr
, args
);
640 /* Create an expression representing the negation of "arg".
642 __isl_give isl_ast_expr
*isl_ast_expr_neg(__isl_take isl_ast_expr
*arg
)
644 return isl_ast_expr_alloc_unary(isl_ast_expr_op_minus
, arg
);
647 /* Create an expression representing the address of "expr".
649 __isl_give isl_ast_expr
*isl_ast_expr_address_of(__isl_take isl_ast_expr
*expr
)
654 if (isl_ast_expr_get_type(expr
) != isl_ast_expr_op
||
655 isl_ast_expr_get_op_type(expr
) != isl_ast_expr_op_access
)
656 isl_die(isl_ast_expr_get_ctx(expr
), isl_error_invalid
,
657 "can only take address of access expressions",
658 return isl_ast_expr_free(expr
));
660 return isl_ast_expr_alloc_unary(isl_ast_expr_op_address_of
, expr
);
663 /* Create an expression representing the binary operation "type"
664 * applied to "expr1" and "expr2".
666 __isl_give isl_ast_expr
*isl_ast_expr_alloc_binary(
667 enum isl_ast_expr_op_type type
,
668 __isl_take isl_ast_expr
*expr1
, __isl_take isl_ast_expr
*expr2
)
671 isl_ast_expr
*expr
= NULL
;
672 isl_ast_expr_list
*args
;
674 if (!expr1
|| !expr2
)
677 ctx
= isl_ast_expr_get_ctx(expr1
);
678 expr
= isl_ast_expr_alloc_op(ctx
, type
, 2);
680 args
= isl_ast_expr_op_take_args(expr
);
681 args
= isl_ast_expr_list_add(args
, expr1
);
682 args
= isl_ast_expr_list_add(args
, expr2
);
683 expr
= isl_ast_expr_op_restore_args(expr
, args
);
687 isl_ast_expr_free(expr1
);
688 isl_ast_expr_free(expr2
);
692 /* Create an expression representing the sum of "expr1" and "expr2".
694 __isl_give isl_ast_expr
*isl_ast_expr_add(__isl_take isl_ast_expr
*expr1
,
695 __isl_take isl_ast_expr
*expr2
)
697 return isl_ast_expr_alloc_binary(isl_ast_expr_op_add
, expr1
, expr2
);
700 /* Create an expression representing the difference of "expr1" and "expr2".
702 __isl_give isl_ast_expr
*isl_ast_expr_sub(__isl_take isl_ast_expr
*expr1
,
703 __isl_take isl_ast_expr
*expr2
)
705 return isl_ast_expr_alloc_binary(isl_ast_expr_op_sub
, expr1
, expr2
);
708 /* Create an expression representing the product of "expr1" and "expr2".
710 __isl_give isl_ast_expr
*isl_ast_expr_mul(__isl_take isl_ast_expr
*expr1
,
711 __isl_take isl_ast_expr
*expr2
)
713 return isl_ast_expr_alloc_binary(isl_ast_expr_op_mul
, expr1
, expr2
);
716 /* Create an expression representing the quotient of "expr1" and "expr2".
718 __isl_give isl_ast_expr
*isl_ast_expr_div(__isl_take isl_ast_expr
*expr1
,
719 __isl_take isl_ast_expr
*expr2
)
721 return isl_ast_expr_alloc_binary(isl_ast_expr_op_div
, expr1
, expr2
);
724 /* Create an expression representing the quotient of the integer
725 * division of "expr1" by "expr2", where "expr1" is known to be
728 __isl_give isl_ast_expr
*isl_ast_expr_pdiv_q(__isl_take isl_ast_expr
*expr1
,
729 __isl_take isl_ast_expr
*expr2
)
731 return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_q
, expr1
, expr2
);
734 /* Create an expression representing the remainder of the integer
735 * division of "expr1" by "expr2", where "expr1" is known to be
738 __isl_give isl_ast_expr
*isl_ast_expr_pdiv_r(__isl_take isl_ast_expr
*expr1
,
739 __isl_take isl_ast_expr
*expr2
)
741 return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_r
, expr1
, expr2
);
744 /* Create an expression representing the conjunction of "expr1" and "expr2".
746 __isl_give isl_ast_expr
*isl_ast_expr_and(__isl_take isl_ast_expr
*expr1
,
747 __isl_take isl_ast_expr
*expr2
)
749 return isl_ast_expr_alloc_binary(isl_ast_expr_op_and
, expr1
, expr2
);
752 /* Create an expression representing the conjunction of "expr1" and "expr2",
753 * where "expr2" is evaluated only if "expr1" is evaluated to true.
755 __isl_give isl_ast_expr
*isl_ast_expr_and_then(__isl_take isl_ast_expr
*expr1
,
756 __isl_take isl_ast_expr
*expr2
)
758 return isl_ast_expr_alloc_binary(isl_ast_expr_op_and_then
, expr1
, expr2
);
761 /* Create an expression representing the disjunction of "expr1" and "expr2".
763 __isl_give isl_ast_expr
*isl_ast_expr_or(__isl_take isl_ast_expr
*expr1
,
764 __isl_take isl_ast_expr
*expr2
)
766 return isl_ast_expr_alloc_binary(isl_ast_expr_op_or
, expr1
, expr2
);
769 /* Create an expression representing the disjunction of "expr1" and "expr2",
770 * where "expr2" is evaluated only if "expr1" is evaluated to false.
772 __isl_give isl_ast_expr
*isl_ast_expr_or_else(__isl_take isl_ast_expr
*expr1
,
773 __isl_take isl_ast_expr
*expr2
)
775 return isl_ast_expr_alloc_binary(isl_ast_expr_op_or_else
, expr1
, expr2
);
778 /* Create an expression representing "expr1" less than or equal to "expr2".
780 __isl_give isl_ast_expr
*isl_ast_expr_le(__isl_take isl_ast_expr
*expr1
,
781 __isl_take isl_ast_expr
*expr2
)
783 return isl_ast_expr_alloc_binary(isl_ast_expr_op_le
, expr1
, expr2
);
786 /* Create an expression representing "expr1" less than "expr2".
788 __isl_give isl_ast_expr
*isl_ast_expr_lt(__isl_take isl_ast_expr
*expr1
,
789 __isl_take isl_ast_expr
*expr2
)
791 return isl_ast_expr_alloc_binary(isl_ast_expr_op_lt
, expr1
, expr2
);
794 /* Create an expression representing "expr1" greater than or equal to "expr2".
796 __isl_give isl_ast_expr
*isl_ast_expr_ge(__isl_take isl_ast_expr
*expr1
,
797 __isl_take isl_ast_expr
*expr2
)
799 return isl_ast_expr_alloc_binary(isl_ast_expr_op_ge
, expr1
, expr2
);
802 /* Create an expression representing "expr1" greater than "expr2".
804 __isl_give isl_ast_expr
*isl_ast_expr_gt(__isl_take isl_ast_expr
*expr1
,
805 __isl_take isl_ast_expr
*expr2
)
807 return isl_ast_expr_alloc_binary(isl_ast_expr_op_gt
, expr1
, expr2
);
810 /* Create an expression representing "expr1" equal to "expr2".
812 __isl_give isl_ast_expr
*isl_ast_expr_eq(__isl_take isl_ast_expr
*expr1
,
813 __isl_take isl_ast_expr
*expr2
)
815 return isl_ast_expr_alloc_binary(isl_ast_expr_op_eq
, expr1
, expr2
);
818 /* Create an expression of type "type" with as arguments "arg0" followed
821 static __isl_give isl_ast_expr
*ast_expr_with_arguments(
822 enum isl_ast_expr_op_type type
, __isl_take isl_ast_expr
*arg0
,
823 __isl_take isl_ast_expr_list
*arguments
)
825 arguments
= isl_ast_expr_list_insert(arguments
, 0, arg0
);
826 return alloc_op(type
, arguments
);
829 /* Create an expression representing an access to "array" with index
830 * expressions "indices".
832 __isl_give isl_ast_expr
*isl_ast_expr_access(__isl_take isl_ast_expr
*array
,
833 __isl_take isl_ast_expr_list
*indices
)
835 return ast_expr_with_arguments(isl_ast_expr_op_access
, array
, indices
);
838 /* Create an expression representing a call to "function" with argument
839 * expressions "arguments".
841 __isl_give isl_ast_expr
*isl_ast_expr_call(__isl_take isl_ast_expr
*function
,
842 __isl_take isl_ast_expr_list
*arguments
)
844 return ast_expr_with_arguments(isl_ast_expr_op_call
, function
, arguments
);
847 /* Wrapper around isl_ast_expr_substitute_ids for use
848 * as an isl_ast_expr_list_map callback.
850 static __isl_give isl_ast_expr
*substitute_ids(__isl_take isl_ast_expr
*expr
,
853 isl_id_to_ast_expr
*id2expr
= user
;
855 return isl_ast_expr_substitute_ids(expr
,
856 isl_id_to_ast_expr_copy(id2expr
));
859 /* For each subexpression of "expr" of type isl_ast_expr_id,
860 * if it appears in "id2expr", then replace it by the corresponding
863 __isl_give isl_ast_expr
*isl_ast_expr_substitute_ids(
864 __isl_take isl_ast_expr
*expr
, __isl_take isl_id_to_ast_expr
*id2expr
)
866 isl_maybe_isl_ast_expr m
;
867 isl_ast_expr_list
*args
;
869 if (!expr
|| !id2expr
)
872 switch (expr
->type
) {
873 case isl_ast_expr_int
:
875 case isl_ast_expr_id
:
876 m
= isl_id_to_ast_expr_try_get(id2expr
, expr
->u
.id
);
881 isl_ast_expr_free(expr
);
884 case isl_ast_expr_op
:
885 args
= isl_ast_expr_op_take_args(expr
);
886 args
= isl_ast_expr_list_map(args
, &substitute_ids
, id2expr
);
887 expr
= isl_ast_expr_op_restore_args(expr
, args
);
889 case isl_ast_expr_error
:
890 expr
= isl_ast_expr_free(expr
);
894 isl_id_to_ast_expr_free(id2expr
);
897 isl_ast_expr_free(expr
);
898 isl_id_to_ast_expr_free(id2expr
);
902 isl_ctx
*isl_ast_node_get_ctx(__isl_keep isl_ast_node
*node
)
904 return node
? node
->ctx
: NULL
;
907 enum isl_ast_node_type
isl_ast_node_get_type(__isl_keep isl_ast_node
*node
)
909 return node
? node
->type
: isl_ast_node_error
;
912 __isl_give isl_ast_node
*isl_ast_node_alloc(isl_ctx
*ctx
,
913 enum isl_ast_node_type type
)
917 node
= isl_calloc_type(ctx
, isl_ast_node
);
929 /* Create an if node with the given guard.
931 * The then body needs to be filled in later.
933 __isl_give isl_ast_node
*isl_ast_node_alloc_if(__isl_take isl_ast_expr
*guard
)
940 node
= isl_ast_node_alloc(isl_ast_expr_get_ctx(guard
), isl_ast_node_if
);
943 node
->u
.i
.guard
= guard
;
947 isl_ast_expr_free(guard
);
951 /* Create a for node with the given iterator.
953 * The remaining fields need to be filled in later.
955 __isl_give isl_ast_node
*isl_ast_node_alloc_for(__isl_take isl_id
*id
)
963 ctx
= isl_id_get_ctx(id
);
964 node
= isl_ast_node_alloc(ctx
, isl_ast_node_for
);
968 node
->u
.f
.iterator
= isl_ast_expr_from_id(id
);
969 if (!node
->u
.f
.iterator
)
970 return isl_ast_node_free(node
);
978 /* Create a mark node, marking "node" with "id".
980 __isl_give isl_ast_node
*isl_ast_node_alloc_mark(__isl_take isl_id
*id
,
981 __isl_take isl_ast_node
*node
)
989 ctx
= isl_id_get_ctx(id
);
990 mark
= isl_ast_node_alloc(ctx
, isl_ast_node_mark
);
995 mark
->u
.m
.node
= node
;
1000 isl_ast_node_free(node
);
1004 /* Create a user node evaluating "expr".
1006 __isl_give isl_ast_node
*isl_ast_node_user_from_expr(
1007 __isl_take isl_ast_expr
*expr
)
1015 ctx
= isl_ast_expr_get_ctx(expr
);
1016 node
= isl_ast_node_alloc(ctx
, isl_ast_node_user
);
1020 node
->u
.e
.expr
= expr
;
1024 isl_ast_expr_free(expr
);
1028 /* This is an alternative name for the function above.
1030 __isl_give isl_ast_node
*isl_ast_node_alloc_user(__isl_take isl_ast_expr
*expr
)
1032 return isl_ast_node_user_from_expr(expr
);
1035 /* Create a block node with the given children.
1037 __isl_give isl_ast_node
*isl_ast_node_block_from_children(
1038 __isl_take isl_ast_node_list
*list
)
1046 ctx
= isl_ast_node_list_get_ctx(list
);
1047 node
= isl_ast_node_alloc(ctx
, isl_ast_node_block
);
1051 node
->u
.b
.children
= list
;
1055 isl_ast_node_list_free(list
);
1059 /* This is an alternative name for the function above.
1061 __isl_give isl_ast_node
*isl_ast_node_alloc_block(
1062 __isl_take isl_ast_node_list
*list
)
1064 return isl_ast_node_block_from_children(list
);
1067 /* Represent the given list of nodes as a single node, either by
1068 * extract the node from a single element list or by creating
1069 * a block node with the list of nodes as children.
1071 __isl_give isl_ast_node
*isl_ast_node_from_ast_node_list(
1072 __isl_take isl_ast_node_list
*list
)
1077 n
= isl_ast_node_list_n_ast_node(list
);
1081 return isl_ast_node_alloc_block(list
);
1083 node
= isl_ast_node_list_get_ast_node(list
, 0);
1084 isl_ast_node_list_free(list
);
1088 isl_ast_node_list_free(list
);
1092 __isl_give isl_ast_node
*isl_ast_node_copy(__isl_keep isl_ast_node
*node
)
1101 /* Return a fresh copy of "node".
1103 * In the case of a degenerate for node, take into account
1104 * that "cond" and "inc" are NULL.
1106 __isl_give isl_ast_node
*isl_ast_node_dup(__isl_keep isl_ast_node
*node
)
1113 dup
= isl_ast_node_alloc(isl_ast_node_get_ctx(node
), node
->type
);
1117 switch (node
->type
) {
1118 case isl_ast_node_if
:
1119 dup
->u
.i
.guard
= isl_ast_expr_copy(node
->u
.i
.guard
);
1120 dup
->u
.i
.then
= isl_ast_node_copy(node
->u
.i
.then
);
1121 dup
->u
.i
.else_node
= isl_ast_node_copy(node
->u
.i
.else_node
);
1122 if (!dup
->u
.i
.guard
|| !dup
->u
.i
.then
||
1123 (node
->u
.i
.else_node
&& !dup
->u
.i
.else_node
))
1124 return isl_ast_node_free(dup
);
1126 case isl_ast_node_for
:
1127 dup
->u
.f
.degenerate
= node
->u
.f
.degenerate
;
1128 dup
->u
.f
.iterator
= isl_ast_expr_copy(node
->u
.f
.iterator
);
1129 dup
->u
.f
.init
= isl_ast_expr_copy(node
->u
.f
.init
);
1130 dup
->u
.f
.body
= isl_ast_node_copy(node
->u
.f
.body
);
1131 if (!dup
->u
.f
.iterator
|| !dup
->u
.f
.init
|| !dup
->u
.f
.body
)
1132 return isl_ast_node_free(dup
);
1133 if (node
->u
.f
.degenerate
)
1135 dup
->u
.f
.cond
= isl_ast_expr_copy(node
->u
.f
.cond
);
1136 dup
->u
.f
.inc
= isl_ast_expr_copy(node
->u
.f
.inc
);
1137 if (!dup
->u
.f
.cond
|| !dup
->u
.f
.inc
)
1138 return isl_ast_node_free(dup
);
1140 case isl_ast_node_block
:
1141 dup
->u
.b
.children
= isl_ast_node_list_copy(node
->u
.b
.children
);
1142 if (!dup
->u
.b
.children
)
1143 return isl_ast_node_free(dup
);
1145 case isl_ast_node_mark
:
1146 dup
->u
.m
.mark
= isl_id_copy(node
->u
.m
.mark
);
1147 dup
->u
.m
.node
= isl_ast_node_copy(node
->u
.m
.node
);
1148 if (!dup
->u
.m
.mark
|| !dup
->u
.m
.node
)
1149 return isl_ast_node_free(dup
);
1151 case isl_ast_node_user
:
1152 dup
->u
.e
.expr
= isl_ast_expr_copy(node
->u
.e
.expr
);
1154 return isl_ast_node_free(dup
);
1156 case isl_ast_node_error
:
1160 if (!node
->annotation
)
1162 dup
->annotation
= isl_id_copy(node
->annotation
);
1163 if (!dup
->annotation
)
1164 return isl_ast_node_free(dup
);
1169 __isl_give isl_ast_node
*isl_ast_node_cow(__isl_take isl_ast_node
*node
)
1177 return isl_ast_node_dup(node
);
1180 __isl_null isl_ast_node
*isl_ast_node_free(__isl_take isl_ast_node
*node
)
1185 if (--node
->ref
> 0)
1188 switch (node
->type
) {
1189 case isl_ast_node_if
:
1190 isl_ast_expr_free(node
->u
.i
.guard
);
1191 isl_ast_node_free(node
->u
.i
.then
);
1192 isl_ast_node_free(node
->u
.i
.else_node
);
1194 case isl_ast_node_for
:
1195 isl_ast_expr_free(node
->u
.f
.iterator
);
1196 isl_ast_expr_free(node
->u
.f
.init
);
1197 isl_ast_expr_free(node
->u
.f
.cond
);
1198 isl_ast_expr_free(node
->u
.f
.inc
);
1199 isl_ast_node_free(node
->u
.f
.body
);
1201 case isl_ast_node_block
:
1202 isl_ast_node_list_free(node
->u
.b
.children
);
1204 case isl_ast_node_mark
:
1205 isl_id_free(node
->u
.m
.mark
);
1206 isl_ast_node_free(node
->u
.m
.node
);
1208 case isl_ast_node_user
:
1209 isl_ast_expr_free(node
->u
.e
.expr
);
1211 case isl_ast_node_error
:
1215 isl_id_free(node
->annotation
);
1216 isl_ctx_deref(node
->ctx
);
1222 /* Check that "node" is of type "type", printing "msg" if not.
1224 static isl_stat
isl_ast_node_check_type(__isl_keep isl_ast_node
*node
,
1225 enum isl_ast_node_type type
, const char *msg
)
1228 return isl_stat_error
;
1229 if (node
->type
!= type
)
1230 isl_die(isl_ast_node_get_ctx(node
), isl_error_invalid
, msg
,
1231 return isl_stat_error
);
1235 /* Check that "node" is of type isl_ast_node_block.
1237 static isl_stat
isl_ast_node_check_block(__isl_keep isl_ast_node
*node
)
1239 return isl_ast_node_check_type(node
, isl_ast_node_block
,
1240 "not a block node");
1243 /* Check that "node" is of type isl_ast_node_if.
1245 static isl_stat
isl_ast_node_check_if(__isl_keep isl_ast_node
*node
)
1247 return isl_ast_node_check_type(node
, isl_ast_node_if
, "not an if node");
1250 /* Check that "node" is of type isl_ast_node_for.
1252 static isl_stat
isl_ast_node_check_for(__isl_keep isl_ast_node
*node
)
1254 return isl_ast_node_check_type(node
, isl_ast_node_for
,
1258 /* Check that "node" is of type isl_ast_node_mark.
1260 static isl_stat
isl_ast_node_check_mark(__isl_keep isl_ast_node
*node
)
1262 return isl_ast_node_check_type(node
, isl_ast_node_mark
,
1266 /* Check that "node" is of type isl_ast_node_user.
1268 static isl_stat
isl_ast_node_check_user(__isl_keep isl_ast_node
*node
)
1270 return isl_ast_node_check_type(node
, isl_ast_node_user
,
1275 #define NODE_TYPE for
1277 #define FIELD_NAME init
1279 #define FIELD_TYPE isl_ast_expr
1281 #define FIELD u.f.init
1282 #include "isl_ast_node_set_field_templ.c"
1285 #define NODE_TYPE for
1287 #define FIELD_NAME cond
1289 #define FIELD_TYPE isl_ast_expr
1291 #define FIELD u.f.cond
1292 #include "isl_ast_node_set_field_templ.c"
1295 #define NODE_TYPE for
1297 #define FIELD_NAME inc
1299 #define FIELD_TYPE isl_ast_expr
1301 #define FIELD u.f.inc
1302 #include "isl_ast_node_set_field_templ.c"
1305 #define NODE_TYPE for
1307 #define FIELD_NAME body
1309 #define FIELD_TYPE isl_ast_node
1311 #define FIELD u.f.body
1312 #include "isl_ast_node_set_field_templ.c"
1314 /* Return the body of the for-node "node",
1315 * This may be either a copy or the body itself
1316 * if there is only one reference to "node".
1317 * This allows the body to be modified inplace
1318 * if both "node" and its body have only a single reference.
1319 * The caller is not allowed to modify "node" between this call and
1320 * the subsequent call to isl_ast_node_for_restore_body.
1321 * The only exception is that isl_ast_node_free can be called instead.
1323 static __isl_give isl_ast_node
*isl_ast_node_for_take_body(
1324 __isl_keep isl_ast_node
*node
)
1328 if (isl_ast_node_check_for(node
) < 0)
1331 return isl_ast_node_for_get_body(node
);
1332 body
= node
->u
.f
.body
;
1333 node
->u
.f
.body
= NULL
;
1337 /* Set the body of the for-node "node" to "body",
1338 * where the body of "node" may be missing
1339 * due to a preceding call to isl_ast_node_for_take_body.
1340 * However, in this case, "node" only has a single reference.
1342 static __isl_give isl_ast_node
*isl_ast_node_for_restore_body(
1343 __isl_take isl_ast_node
*node
, __isl_take isl_ast_node
*body
)
1345 return isl_ast_node_for_set_body(node
, body
);
1348 __isl_give isl_ast_node
*isl_ast_node_for_get_body(
1349 __isl_keep isl_ast_node
*node
)
1351 if (isl_ast_node_check_for(node
) < 0)
1353 return isl_ast_node_copy(node
->u
.f
.body
);
1356 /* Mark the given for node as being degenerate.
1358 __isl_give isl_ast_node
*isl_ast_node_for_mark_degenerate(
1359 __isl_take isl_ast_node
*node
)
1361 node
= isl_ast_node_cow(node
);
1364 node
->u
.f
.degenerate
= 1;
1368 isl_bool
isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node
*node
)
1370 if (isl_ast_node_check_for(node
) < 0)
1371 return isl_bool_error
;
1372 return isl_bool_ok(node
->u
.f
.degenerate
);
1375 __isl_give isl_ast_expr
*isl_ast_node_for_get_iterator(
1376 __isl_keep isl_ast_node
*node
)
1378 if (isl_ast_node_check_for(node
) < 0)
1380 return isl_ast_expr_copy(node
->u
.f
.iterator
);
1383 __isl_give isl_ast_expr
*isl_ast_node_for_get_init(
1384 __isl_keep isl_ast_node
*node
)
1386 if (isl_ast_node_check_for(node
) < 0)
1388 return isl_ast_expr_copy(node
->u
.f
.init
);
1391 /* Return the condition expression of the given for node.
1393 * If the for node is degenerate, then the condition is not explicitly
1394 * stored in the node. Instead, it is constructed as
1398 __isl_give isl_ast_expr
*isl_ast_node_for_get_cond(
1399 __isl_keep isl_ast_node
*node
)
1401 if (isl_ast_node_check_for(node
) < 0)
1403 if (!node
->u
.f
.degenerate
)
1404 return isl_ast_expr_copy(node
->u
.f
.cond
);
1406 return isl_ast_expr_alloc_binary(isl_ast_expr_op_le
,
1407 isl_ast_expr_copy(node
->u
.f
.iterator
),
1408 isl_ast_expr_copy(node
->u
.f
.init
));
1411 /* Return the increment of the given for node.
1413 * If the for node is degenerate, then the increment is not explicitly
1414 * stored in the node. We simply return "1".
1416 __isl_give isl_ast_expr
*isl_ast_node_for_get_inc(
1417 __isl_keep isl_ast_node
*node
)
1419 if (isl_ast_node_check_for(node
) < 0)
1421 if (!node
->u
.f
.degenerate
)
1422 return isl_ast_expr_copy(node
->u
.f
.inc
);
1423 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node
), 1);
1427 #define NODE_TYPE if
1429 #define FIELD_NAME then
1431 #define FIELD_TYPE isl_ast_node
1433 #define FIELD u.i.then
1434 #include "isl_ast_node_set_field_templ.c"
1436 /* Return the then-branch of the if-node "node",
1437 * This may be either a copy or the branch itself
1438 * if there is only one reference to "node".
1439 * This allows the branch to be modified inplace
1440 * if both "node" and its then-branch have only a single reference.
1441 * The caller is not allowed to modify "node" between this call and
1442 * the subsequent call to isl_ast_node_if_restore_then_node.
1443 * The only exception is that isl_ast_node_free can be called instead.
1445 static __isl_give isl_ast_node
*isl_ast_node_if_take_then_node(
1446 __isl_keep isl_ast_node
*node
)
1448 isl_ast_node
*then_node
;
1450 if (isl_ast_node_check_if(node
) < 0)
1453 return isl_ast_node_if_get_then_node(node
);
1454 then_node
= node
->u
.i
.then
;
1455 node
->u
.i
.then
= NULL
;
1459 /* Set the then-branch of the if-node "node" to "child",
1460 * where the then-branch of "node" may be missing
1461 * due to a preceding call to isl_ast_node_if_take_then_node.
1462 * However, in this case, "node" only has a single reference.
1464 static __isl_give isl_ast_node
*isl_ast_node_if_restore_then_node(
1465 __isl_take isl_ast_node
*node
, __isl_take isl_ast_node
*child
)
1467 return isl_ast_node_if_set_then(node
, child
);
1470 /* Return the then-node of the given if-node.
1472 __isl_give isl_ast_node
*isl_ast_node_if_get_then_node(
1473 __isl_keep isl_ast_node
*node
)
1475 if (isl_ast_node_check_if(node
) < 0)
1477 return isl_ast_node_copy(node
->u
.i
.then
);
1480 /* This is an alternative name for the function above.
1482 __isl_give isl_ast_node
*isl_ast_node_if_get_then(
1483 __isl_keep isl_ast_node
*node
)
1485 return isl_ast_node_if_get_then_node(node
);
1488 /* Does the given if-node have an else-node?
1490 isl_bool
isl_ast_node_if_has_else_node(__isl_keep isl_ast_node
*node
)
1492 if (isl_ast_node_check_if(node
) < 0)
1493 return isl_bool_error
;
1494 return isl_bool_ok(node
->u
.i
.else_node
!= NULL
);
1497 /* This is an alternative name for the function above.
1499 isl_bool
isl_ast_node_if_has_else(__isl_keep isl_ast_node
*node
)
1501 return isl_ast_node_if_has_else_node(node
);
1504 /* Return the else-node of the given if-node,
1505 * assuming there is one.
1507 __isl_give isl_ast_node
*isl_ast_node_if_get_else_node(
1508 __isl_keep isl_ast_node
*node
)
1510 if (isl_ast_node_check_if(node
) < 0)
1512 return isl_ast_node_copy(node
->u
.i
.else_node
);
1515 /* This is an alternative name for the function above.
1517 __isl_give isl_ast_node
*isl_ast_node_if_get_else(
1518 __isl_keep isl_ast_node
*node
)
1520 return isl_ast_node_if_get_else_node(node
);
1524 #define NODE_TYPE if
1526 #define FIELD_NAME else_node
1528 #define FIELD_TYPE isl_ast_node
1530 #define FIELD u.i.else_node
1532 #include "isl_ast_node_set_field_templ.c"
1534 /* Return the else-branch of the if-node "node",
1535 * This may be either a copy or the branch itself
1536 * if there is only one reference to "node".
1537 * This allows the branch to be modified inplace
1538 * if both "node" and its else-branch have only a single reference.
1539 * The caller is not allowed to modify "node" between this call and
1540 * the subsequent call to isl_ast_node_if_restore_else_node.
1541 * The only exception is that isl_ast_node_free can be called instead.
1543 static __isl_give isl_ast_node
*isl_ast_node_if_take_else_node(
1544 __isl_keep isl_ast_node
*node
)
1546 isl_ast_node
*else_node
;
1548 if (isl_ast_node_check_if(node
) < 0)
1551 return isl_ast_node_if_get_else_node(node
);
1552 else_node
= node
->u
.i
.else_node
;
1553 node
->u
.i
.else_node
= NULL
;
1557 /* Set the else-branch of the if-node "node" to "child",
1558 * where the else-branch of "node" may be missing
1559 * due to a preceding call to isl_ast_node_if_take_else_node.
1560 * However, in this case, "node" only has a single reference.
1562 static __isl_give isl_ast_node
*isl_ast_node_if_restore_else_node(
1563 __isl_take isl_ast_node
*node
, __isl_take isl_ast_node
*child
)
1565 return isl_ast_node_if_set_else_node(node
, child
);
1568 __isl_give isl_ast_expr
*isl_ast_node_if_get_cond(
1569 __isl_keep isl_ast_node
*node
)
1571 if (isl_ast_node_check_if(node
) < 0)
1573 return isl_ast_expr_copy(node
->u
.i
.guard
);
1576 __isl_give isl_ast_node_list
*isl_ast_node_block_get_children(
1577 __isl_keep isl_ast_node
*node
)
1579 if (isl_ast_node_check_block(node
) < 0)
1581 return isl_ast_node_list_copy(node
->u
.b
.children
);
1585 #define NODE_TYPE block
1587 #define FIELD_NAME children
1589 #define FIELD_TYPE isl_ast_node_list
1591 #define FIELD u.b.children
1593 #include "isl_ast_node_set_field_templ.c"
1595 /* Return the children of the block-node "node",
1596 * This may be either a copy or the children themselves
1597 * if there is only one reference to "node".
1598 * This allows the children to be modified inplace
1599 * if both "node" and its children have only a single reference.
1600 * The caller is not allowed to modify "node" between this call and
1601 * the subsequent call to isl_ast_node_block_restore_children.
1602 * The only exception is that isl_ast_node_free can be called instead.
1604 static __isl_give isl_ast_node_list
*isl_ast_node_block_take_children(
1605 __isl_keep isl_ast_node
*node
)
1607 isl_ast_node_list
*children
;
1609 if (isl_ast_node_check_block(node
) < 0)
1612 return isl_ast_node_block_get_children(node
);
1613 children
= node
->u
.b
.children
;
1614 node
->u
.b
.children
= NULL
;
1618 /* Set the children of the block-node "node" to "children",
1619 * where the children of "node" may be missing
1620 * due to a preceding call to isl_ast_node_block_take_children.
1621 * However, in this case, "node" only has a single reference.
1623 static __isl_give isl_ast_node
*isl_ast_node_block_restore_children(
1624 __isl_take isl_ast_node
*node
, __isl_take isl_ast_node_list
*children
)
1626 return isl_ast_node_block_set_children(node
, children
);
1629 __isl_give isl_ast_expr
*isl_ast_node_user_get_expr(
1630 __isl_keep isl_ast_node
*node
)
1632 if (isl_ast_node_check_user(node
) < 0)
1635 return isl_ast_expr_copy(node
->u
.e
.expr
);
1638 /* Return the mark identifier of the mark node "node".
1640 __isl_give isl_id
*isl_ast_node_mark_get_id(__isl_keep isl_ast_node
*node
)
1642 if (isl_ast_node_check_mark(node
) < 0)
1645 return isl_id_copy(node
->u
.m
.mark
);
1648 /* Return the node marked by mark node "node".
1650 __isl_give isl_ast_node
*isl_ast_node_mark_get_node(
1651 __isl_keep isl_ast_node
*node
)
1653 if (isl_ast_node_check_mark(node
) < 0)
1656 return isl_ast_node_copy(node
->u
.m
.node
);
1660 #define NODE_TYPE mark
1662 #define FIELD_NAME node
1664 #define FIELD_TYPE isl_ast_node
1666 #define FIELD u.m.node
1668 #include "isl_ast_node_set_field_templ.c"
1670 /* Return the child of the mark-node "node",
1671 * This may be either a copy or the child itself
1672 * if there is only one reference to "node".
1673 * This allows the child to be modified inplace
1674 * if both "node" and its child have only a single reference.
1675 * The caller is not allowed to modify "node" between this call and
1676 * the subsequent call to isl_ast_node_mark_restore_node.
1677 * The only exception is that isl_ast_node_free can be called instead.
1679 static __isl_give isl_ast_node
*isl_ast_node_mark_take_node(
1680 __isl_keep isl_ast_node
*node
)
1682 isl_ast_node
*child
;
1684 if (isl_ast_node_check_mark(node
) < 0)
1687 return isl_ast_node_mark_get_node(node
);
1688 child
= node
->u
.m
.node
;
1689 node
->u
.m
.node
= NULL
;
1693 /* Set the child of the mark-node "node" to "child",
1694 * where the child of "node" may be missing
1695 * due to a preceding call to isl_ast_node_mark_take_node.
1696 * However, in this case, "node" only has a single reference.
1698 static __isl_give isl_ast_node
*isl_ast_node_mark_restore_node(
1699 __isl_take isl_ast_node
*node
, __isl_take isl_ast_node
*child
)
1701 return isl_ast_node_mark_set_node(node
, child
);
1704 __isl_give isl_id
*isl_ast_node_get_annotation(__isl_keep isl_ast_node
*node
)
1706 return node
? isl_id_copy(node
->annotation
) : NULL
;
1709 /* Check that "node" is of any type.
1710 * That is, simply check that it is a valid node.
1712 static isl_stat
isl_ast_node_check_any(__isl_keep isl_ast_node
*node
)
1714 return isl_stat_non_null(node
);
1718 #define NODE_TYPE any
1720 #define FIELD_NAME annotation
1722 #define FIELD_TYPE isl_id
1724 #define FIELD annotation
1726 #include "isl_ast_node_set_field_templ.c"
1728 /* Replace node->annotation by "annotation".
1730 __isl_give isl_ast_node
*isl_ast_node_set_annotation(
1731 __isl_take isl_ast_node
*node
, __isl_take isl_id
*annotation
)
1733 return isl_ast_node_any_set_annotation(node
, annotation
);
1736 static __isl_give isl_ast_node
*traverse(__isl_take isl_ast_node
*node
,
1737 __isl_give isl_ast_node
*(*enter
)(__isl_take isl_ast_node
*node
,
1738 int *more
, void *user
),
1739 __isl_give isl_ast_node
*(*leave
)(__isl_take isl_ast_node
*node
,
1743 /* Traverse the elements of "list" and all their descendants
1744 * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1745 * whenever a node is left.
1747 * Return the updated node.
1749 static __isl_give isl_ast_node_list
*traverse_list(
1750 __isl_take isl_ast_node_list
*list
,
1751 __isl_give isl_ast_node
*(*enter
)(__isl_take isl_ast_node
*node
,
1752 int *more
, void *user
),
1753 __isl_give isl_ast_node
*(*leave
)(__isl_take isl_ast_node
*node
,
1760 n
= isl_ast_node_list_size(list
);
1762 return isl_ast_node_list_free(list
);
1764 for (i
= 0; i
< n
; ++i
) {
1767 node
= isl_ast_node_list_get_at(list
, i
);
1768 node
= traverse(node
, enter
, leave
, user
);
1769 list
= isl_ast_node_list_set_at(list
, i
, node
);
1775 /* Traverse the descendants of "node" (including the node itself)
1776 * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1777 * whenever a node is left.
1779 * If "enter" sets the "more" argument to zero, then the subtree rooted
1780 * at the given node is skipped.
1782 * Return the updated node.
1784 static __isl_give isl_ast_node
*traverse(__isl_take isl_ast_node
*node
,
1785 __isl_give isl_ast_node
*(*enter
)(__isl_take isl_ast_node
*node
,
1786 int *more
, void *user
),
1787 __isl_give isl_ast_node
*(*leave
)(__isl_take isl_ast_node
*node
,
1793 isl_ast_node
*child
;
1794 isl_ast_node_list
*children
;
1796 node
= enter(node
, &more
, user
);
1802 switch (node
->type
) {
1803 case isl_ast_node_for
:
1804 child
= isl_ast_node_for_take_body(node
);
1805 child
= traverse(child
, enter
, leave
, user
);
1806 node
= isl_ast_node_for_restore_body(node
, child
);
1807 return leave(node
, user
);
1808 case isl_ast_node_if
:
1809 child
= isl_ast_node_if_take_then_node(node
);
1810 child
= traverse(child
, enter
, leave
, user
);
1811 node
= isl_ast_node_if_restore_then_node(node
, child
);
1812 has_else
= isl_ast_node_if_has_else_node(node
);
1814 return isl_ast_node_free(node
);
1816 return leave(node
, user
);
1817 child
= isl_ast_node_if_take_else_node(node
);
1818 child
= traverse(child
, enter
, leave
, user
);
1819 node
= isl_ast_node_if_restore_else_node(node
, child
);
1820 return leave(node
, user
);
1821 case isl_ast_node_block
:
1822 children
= isl_ast_node_block_take_children(node
);
1823 children
= traverse_list(children
, enter
, leave
, user
);
1824 node
= isl_ast_node_block_restore_children(node
, children
);
1825 return leave(node
, user
);
1826 case isl_ast_node_mark
:
1827 child
= isl_ast_node_mark_take_node(node
);
1828 child
= traverse(child
, enter
, leave
, user
);
1829 node
= isl_ast_node_mark_restore_node(node
, child
);
1830 return leave(node
, user
);
1831 case isl_ast_node_user
:
1832 return leave(node
, user
);
1833 case isl_ast_node_error
:
1834 return isl_ast_node_free(node
);
1840 /* Internal data structure storing the arguments of
1841 * isl_ast_node_foreach_descendant_top_down.
1843 struct isl_ast_node_preorder_data
{
1844 isl_bool (*fn
)(__isl_keep isl_ast_node
*node
, void *user
);
1848 /* Enter "node" and set *more to continue traversing its descendants.
1850 * In the case of a depth first preorder traversal, call data->fn and
1851 * let it decide whether to continue.
1853 static __isl_give isl_ast_node
*preorder_enter(__isl_take isl_ast_node
*node
,
1854 int *more
, void *user
)
1856 struct isl_ast_node_preorder_data
*data
= user
;
1861 m
= data
->fn(node
, data
->user
);
1863 return isl_ast_node_free(node
);
1870 * In the case of a depth first preorder traversal, nothing needs to be done.
1872 static __isl_give isl_ast_node
*preorder_leave(__isl_take isl_ast_node
*node
,
1878 /* Traverse the descendants of "node" (including the node itself)
1879 * in depth first preorder.
1881 * If "fn" returns isl_bool_error on any of the nodes, then the traversal
1883 * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
1884 * at that node is skipped.
1886 * Return isl_stat_ok on success and isl_stat_error on failure.
1888 isl_stat
isl_ast_node_foreach_descendant_top_down(
1889 __isl_keep isl_ast_node
*node
,
1890 isl_bool (*fn
)(__isl_keep isl_ast_node
*node
, void *user
), void *user
)
1892 struct isl_ast_node_preorder_data data
= { fn
, user
};
1894 node
= isl_ast_node_copy(node
);
1895 node
= traverse(node
, &preorder_enter
, &preorder_leave
, &data
);
1896 isl_ast_node_free(node
);
1898 return isl_stat_non_null(node
);
1901 /* Internal data structure storing the arguments of
1902 * isl_ast_node_map_descendant_bottom_up.
1904 struct isl_ast_node_postorder_data
{
1905 __isl_give isl_ast_node
*(*fn
)(__isl_take isl_ast_node
*node
,
1910 /* Enter "node" and set *more to continue traversing its descendants.
1912 * In the case of a depth-first post-order traversal,
1913 * nothing needs to be done and traversal always continues.
1915 static __isl_give isl_ast_node
*postorder_enter(__isl_take isl_ast_node
*node
,
1916 int *more
, void *user
)
1924 * In the case of a depth-first post-order traversal, call data->fn.
1926 static __isl_give isl_ast_node
*postorder_leave(__isl_take isl_ast_node
*node
,
1929 struct isl_ast_node_postorder_data
*data
= user
;
1934 node
= data
->fn(node
, data
->user
);
1938 /* Traverse the descendants of "node" (including the node itself)
1939 * in depth-first post-order, where the user callback is allowed to modify the
1942 * Return the updated node.
1944 __isl_give isl_ast_node
*isl_ast_node_map_descendant_bottom_up(
1945 __isl_take isl_ast_node
*node
,
1946 __isl_give isl_ast_node
*(*fn
)(__isl_take isl_ast_node
*node
,
1947 void *user
), void *user
)
1949 struct isl_ast_node_postorder_data data
= { fn
, user
};
1951 return traverse(node
, &postorder_enter
, &postorder_leave
, &data
);
1954 /* Textual C representation of the various operators.
1956 static char *op_str_c
[] = {
1957 [isl_ast_expr_op_and
] = "&&",
1958 [isl_ast_expr_op_and_then
] = "&&",
1959 [isl_ast_expr_op_or
] = "||",
1960 [isl_ast_expr_op_or_else
] = "||",
1961 [isl_ast_expr_op_max
] = "max",
1962 [isl_ast_expr_op_min
] = "min",
1963 [isl_ast_expr_op_minus
] = "-",
1964 [isl_ast_expr_op_add
] = "+",
1965 [isl_ast_expr_op_sub
] = "-",
1966 [isl_ast_expr_op_mul
] = "*",
1967 [isl_ast_expr_op_fdiv_q
] = "floord",
1968 [isl_ast_expr_op_pdiv_q
] = "/",
1969 [isl_ast_expr_op_pdiv_r
] = "%",
1970 [isl_ast_expr_op_zdiv_r
] = "%",
1971 [isl_ast_expr_op_div
] = "/",
1972 [isl_ast_expr_op_eq
] = "==",
1973 [isl_ast_expr_op_le
] = "<=",
1974 [isl_ast_expr_op_ge
] = ">=",
1975 [isl_ast_expr_op_lt
] = "<",
1976 [isl_ast_expr_op_gt
] = ">",
1977 [isl_ast_expr_op_member
] = ".",
1978 [isl_ast_expr_op_address_of
] = "&"
1981 /* Precedence in C of the various operators.
1982 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1983 * Lowest value means highest precedence.
1985 static int op_prec
[] = {
1986 [isl_ast_expr_op_and
] = 13,
1987 [isl_ast_expr_op_and_then
] = 13,
1988 [isl_ast_expr_op_or
] = 14,
1989 [isl_ast_expr_op_or_else
] = 14,
1990 [isl_ast_expr_op_max
] = 2,
1991 [isl_ast_expr_op_min
] = 2,
1992 [isl_ast_expr_op_minus
] = 3,
1993 [isl_ast_expr_op_add
] = 6,
1994 [isl_ast_expr_op_sub
] = 6,
1995 [isl_ast_expr_op_mul
] = 5,
1996 [isl_ast_expr_op_div
] = 5,
1997 [isl_ast_expr_op_fdiv_q
] = 2,
1998 [isl_ast_expr_op_pdiv_q
] = 5,
1999 [isl_ast_expr_op_pdiv_r
] = 5,
2000 [isl_ast_expr_op_zdiv_r
] = 5,
2001 [isl_ast_expr_op_cond
] = 15,
2002 [isl_ast_expr_op_select
] = 15,
2003 [isl_ast_expr_op_eq
] = 9,
2004 [isl_ast_expr_op_le
] = 8,
2005 [isl_ast_expr_op_ge
] = 8,
2006 [isl_ast_expr_op_lt
] = 8,
2007 [isl_ast_expr_op_gt
] = 8,
2008 [isl_ast_expr_op_call
] = 2,
2009 [isl_ast_expr_op_access
] = 2,
2010 [isl_ast_expr_op_member
] = 2,
2011 [isl_ast_expr_op_address_of
] = 3
2014 /* Is the operator left-to-right associative?
2016 static int op_left
[] = {
2017 [isl_ast_expr_op_and
] = 1,
2018 [isl_ast_expr_op_and_then
] = 1,
2019 [isl_ast_expr_op_or
] = 1,
2020 [isl_ast_expr_op_or_else
] = 1,
2021 [isl_ast_expr_op_max
] = 1,
2022 [isl_ast_expr_op_min
] = 1,
2023 [isl_ast_expr_op_minus
] = 0,
2024 [isl_ast_expr_op_add
] = 1,
2025 [isl_ast_expr_op_sub
] = 1,
2026 [isl_ast_expr_op_mul
] = 1,
2027 [isl_ast_expr_op_div
] = 1,
2028 [isl_ast_expr_op_fdiv_q
] = 1,
2029 [isl_ast_expr_op_pdiv_q
] = 1,
2030 [isl_ast_expr_op_pdiv_r
] = 1,
2031 [isl_ast_expr_op_zdiv_r
] = 1,
2032 [isl_ast_expr_op_cond
] = 0,
2033 [isl_ast_expr_op_select
] = 0,
2034 [isl_ast_expr_op_eq
] = 1,
2035 [isl_ast_expr_op_le
] = 1,
2036 [isl_ast_expr_op_ge
] = 1,
2037 [isl_ast_expr_op_lt
] = 1,
2038 [isl_ast_expr_op_gt
] = 1,
2039 [isl_ast_expr_op_call
] = 1,
2040 [isl_ast_expr_op_access
] = 1,
2041 [isl_ast_expr_op_member
] = 1,
2042 [isl_ast_expr_op_address_of
] = 0
2045 static int is_and(enum isl_ast_expr_op_type op
)
2047 return op
== isl_ast_expr_op_and
|| op
== isl_ast_expr_op_and_then
;
2050 static int is_or(enum isl_ast_expr_op_type op
)
2052 return op
== isl_ast_expr_op_or
|| op
== isl_ast_expr_op_or_else
;
2055 static int is_add_sub(enum isl_ast_expr_op_type op
)
2057 return op
== isl_ast_expr_op_add
|| op
== isl_ast_expr_op_sub
;
2060 static int is_div_mod(enum isl_ast_expr_op_type op
)
2062 return op
== isl_ast_expr_op_div
||
2063 op
== isl_ast_expr_op_pdiv_r
||
2064 op
== isl_ast_expr_op_zdiv_r
;
2067 static __isl_give isl_printer
*print_ast_expr_c(__isl_take isl_printer
*p
,
2068 __isl_keep isl_ast_expr
*expr
);
2070 /* Do we need/want parentheses around "expr" as a subexpression of
2071 * an "op" operation? If "left" is set, then "expr" is the left-most
2074 * We only need parentheses if "expr" represents an operation.
2076 * If op has a higher precedence than expr->u.op.op, then we need
2078 * If op and expr->u.op.op have the same precedence, but the operations
2079 * are performed in an order that is different from the associativity,
2080 * then we need parentheses.
2082 * An and inside an or technically does not require parentheses,
2083 * but some compilers complain about that, so we add them anyway.
2085 * Computations such as "a / b * c" and "a % b + c" can be somewhat
2086 * difficult to read, so we add parentheses for those as well.
2088 static int sub_expr_need_parens(enum isl_ast_expr_op_type op
,
2089 __isl_keep isl_ast_expr
*expr
, int left
)
2091 if (expr
->type
!= isl_ast_expr_op
)
2094 if (op_prec
[expr
->u
.op
.op
] > op_prec
[op
])
2096 if (op_prec
[expr
->u
.op
.op
] == op_prec
[op
] && left
!= op_left
[op
])
2099 if (is_or(op
) && is_and(expr
->u
.op
.op
))
2101 if (op
== isl_ast_expr_op_mul
&& expr
->u
.op
.op
!= isl_ast_expr_op_mul
&&
2102 op_prec
[expr
->u
.op
.op
] == op_prec
[op
])
2104 if (is_add_sub(op
) && is_div_mod(expr
->u
.op
.op
))
2110 /* Print the subexpression at position "pos" of operation expression "expr"
2112 * If "left" is set, then "expr" is the left-most operand.
2114 static __isl_give isl_printer
*print_sub_expr_c(__isl_take isl_printer
*p
,
2115 __isl_keep isl_ast_expr
*expr
, int pos
, int left
)
2121 return isl_printer_free(p
);
2123 arg
= isl_ast_expr_list_get_at(expr
->u
.op
.args
, pos
);
2124 need_parens
= sub_expr_need_parens(expr
->u
.op
.op
, arg
, left
);
2127 p
= isl_printer_print_str(p
, "(");
2128 p
= print_ast_expr_c(p
, arg
);
2130 p
= isl_printer_print_str(p
, ")");
2132 isl_ast_expr_free(arg
);
2137 #define isl_ast_expr_op_last isl_ast_expr_op_address_of
2139 /* Data structure that holds the user-specified textual
2140 * representations for the operators in C format.
2141 * The entries are either NULL or copies of strings.
2142 * A NULL entry means that the default name should be used.
2144 struct isl_ast_expr_op_names
{
2145 char *op_str
[isl_ast_expr_op_last
+ 1];
2148 /* Create an empty struct isl_ast_expr_op_names.
2150 static void *create_names(isl_ctx
*ctx
)
2152 return isl_calloc_type(ctx
, struct isl_ast_expr_op_names
);
2155 /* Free a struct isl_ast_expr_op_names along with all memory
2156 * owned by the struct.
2158 static void free_names(void *user
)
2161 struct isl_ast_expr_op_names
*names
= user
;
2166 for (i
= 0; i
<= isl_ast_expr_op_last
; ++i
)
2167 free(names
->op_str
[i
]);
2171 /* Create an identifier that is used to store
2172 * an isl_ast_expr_op_names note.
2174 static __isl_give isl_id
*names_id(isl_ctx
*ctx
)
2176 return isl_id_alloc(ctx
, "isl_ast_expr_op_type_names", NULL
);
2179 /* Ensure that "p" has a note identified by "id".
2180 * If there is no such note yet, then it is created by "note_create" and
2181 * scheduled do be freed by "note_free".
2183 static __isl_give isl_printer
*alloc_note(__isl_take isl_printer
*p
,
2184 __isl_keep isl_id
*id
, void *(*note_create
)(isl_ctx
*),
2185 void (*note_free
)(void *))
2192 has_note
= isl_printer_has_note(p
, id
);
2194 return isl_printer_free(p
);
2198 ctx
= isl_printer_get_ctx(p
);
2199 note
= note_create(ctx
);
2201 return isl_printer_free(p
);
2202 note_id
= isl_id_alloc(ctx
, NULL
, note
);
2206 note_id
= isl_id_set_free_user(note_id
, note_free
);
2208 p
= isl_printer_set_note(p
, isl_id_copy(id
), note_id
);
2213 /* Ensure that "p" has an isl_ast_expr_op_names note identified by "id".
2215 static __isl_give isl_printer
*alloc_names(__isl_take isl_printer
*p
,
2216 __isl_keep isl_id
*id
)
2218 return alloc_note(p
, id
, &create_names
, &free_names
);
2221 /* Retrieve the note identified by "id" from "p".
2222 * The note is assumed to exist.
2224 static void *get_note(__isl_keep isl_printer
*p
, __isl_keep isl_id
*id
)
2228 id
= isl_printer_get_note(p
, isl_id_copy(id
));
2229 note
= isl_id_get_user(id
);
2235 /* Use "name" to print operations of type "type" to "p".
2237 * Store the name in an isl_ast_expr_op_names note attached to "p", such that
2238 * it can be retrieved by get_op_str.
2240 __isl_give isl_printer
*isl_ast_expr_op_type_set_print_name(
2241 __isl_take isl_printer
*p
, enum isl_ast_expr_op_type type
,
2242 __isl_keep
const char *name
)
2245 struct isl_ast_expr_op_names
*names
;
2249 if (type
> isl_ast_expr_op_last
)
2250 isl_die(isl_printer_get_ctx(p
), isl_error_invalid
,
2251 "invalid type", return isl_printer_free(p
));
2253 id
= names_id(isl_printer_get_ctx(p
));
2254 p
= alloc_names(p
, id
);
2255 names
= get_note(p
, id
);
2258 return isl_printer_free(p
);
2259 free(names
->op_str
[type
]);
2260 names
->op_str
[type
] = strdup(name
);
2265 /* This is an alternative name for the function above.
2267 __isl_give isl_printer
*isl_ast_op_type_set_print_name(
2268 __isl_take isl_printer
*p
, enum isl_ast_expr_op_type type
,
2269 __isl_keep
const char *name
)
2271 return isl_ast_expr_op_type_set_print_name(p
, type
, name
);
2274 /* Return the textual representation of "type" in C format.
2276 * If there is a user-specified name in an isl_ast_expr_op_names note
2277 * associated to "p", then return that.
2278 * Otherwise, return the default name in op_str_c.
2280 static const char *get_op_str_c(__isl_keep isl_printer
*p
,
2281 enum isl_ast_expr_op_type type
)
2285 struct isl_ast_expr_op_names
*names
= NULL
;
2287 id
= names_id(isl_printer_get_ctx(p
));
2288 has_names
= isl_printer_has_note(p
, id
);
2289 if (has_names
>= 0 && has_names
)
2290 names
= get_note(p
, id
);
2292 if (names
&& names
->op_str
[type
])
2293 return names
->op_str
[type
];
2294 return op_str_c
[type
];
2297 /* Print the expression at position "pos" in "list" in C format.
2299 static __isl_give isl_printer
*print_at_c(__isl_take isl_printer
*p
,
2300 __isl_keep isl_ast_expr_list
*list
, int pos
)
2304 expr
= isl_ast_expr_list_get_at(list
, pos
);
2305 p
= print_ast_expr_c(p
, expr
);
2306 isl_ast_expr_free(expr
);
2311 /* Print a min or max reduction "expr" in C format.
2313 static __isl_give isl_printer
*print_min_max_c(__isl_take isl_printer
*p
,
2314 __isl_keep isl_ast_expr
*expr
)
2319 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
2321 return isl_printer_free(p
);
2323 for (i
= 1; i
< n
; ++i
) {
2324 p
= isl_printer_print_str(p
, get_op_str_c(p
, expr
->u
.op
.op
));
2325 p
= isl_printer_print_str(p
, "(");
2327 p
= print_at_c(p
, expr
->u
.op
.args
, 0);
2328 for (i
= 1; i
< n
; ++i
) {
2329 p
= isl_printer_print_str(p
, ", ");
2330 p
= print_at_c(p
, expr
->u
.op
.args
, i
);
2331 p
= isl_printer_print_str(p
, ")");
2337 /* Print a function call "expr" in C format.
2339 * The first argument represents the function to be called.
2341 static __isl_give isl_printer
*print_call_c(__isl_take isl_printer
*p
,
2342 __isl_keep isl_ast_expr
*expr
)
2347 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
2349 return isl_printer_free(p
);
2351 p
= print_at_c(p
, expr
->u
.op
.args
, 0);
2352 p
= isl_printer_print_str(p
, "(");
2353 for (i
= 1; i
< n
; ++i
) {
2355 p
= isl_printer_print_str(p
, ", ");
2356 p
= print_at_c(p
, expr
->u
.op
.args
, i
);
2358 p
= isl_printer_print_str(p
, ")");
2363 /* Print an array access "expr" in C format.
2365 * The first argument represents the array being accessed.
2367 static __isl_give isl_printer
*print_access_c(__isl_take isl_printer
*p
,
2368 __isl_keep isl_ast_expr
*expr
)
2373 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
2375 return isl_printer_free(p
);
2377 p
= print_at_c(p
, expr
->u
.op
.args
, 0);
2378 for (i
= 1; i
< n
; ++i
) {
2379 p
= isl_printer_print_str(p
, "[");
2380 p
= print_at_c(p
, expr
->u
.op
.args
, i
);
2381 p
= isl_printer_print_str(p
, "]");
2387 /* Print "expr" to "p" in C format.
2389 static __isl_give isl_printer
*print_ast_expr_c(__isl_take isl_printer
*p
,
2390 __isl_keep isl_ast_expr
*expr
)
2397 return isl_printer_free(p
);
2399 switch (expr
->type
) {
2400 case isl_ast_expr_op
:
2401 if (expr
->u
.op
.op
== isl_ast_expr_op_call
) {
2402 p
= print_call_c(p
, expr
);
2405 if (expr
->u
.op
.op
== isl_ast_expr_op_access
) {
2406 p
= print_access_c(p
, expr
);
2409 n
= isl_ast_expr_list_size(expr
->u
.op
.args
);
2411 return isl_printer_free(p
);
2413 p
= isl_printer_print_str(p
,
2414 get_op_str_c(p
, expr
->u
.op
.op
));
2415 p
= print_sub_expr_c(p
, expr
, 0, 0);
2418 if (expr
->u
.op
.op
== isl_ast_expr_op_fdiv_q
) {
2421 name
= get_op_str_c(p
, isl_ast_expr_op_fdiv_q
);
2422 p
= isl_printer_print_str(p
, name
);
2423 p
= isl_printer_print_str(p
, "(");
2424 p
= print_at_c(p
, expr
->u
.op
.args
, 0);
2425 p
= isl_printer_print_str(p
, ", ");
2426 p
= print_at_c(p
, expr
->u
.op
.args
, 1);
2427 p
= isl_printer_print_str(p
, ")");
2430 if (expr
->u
.op
.op
== isl_ast_expr_op_max
||
2431 expr
->u
.op
.op
== isl_ast_expr_op_min
) {
2432 p
= print_min_max_c(p
, expr
);
2435 if (expr
->u
.op
.op
== isl_ast_expr_op_cond
||
2436 expr
->u
.op
.op
== isl_ast_expr_op_select
) {
2437 p
= print_at_c(p
, expr
->u
.op
.args
, 0);
2438 p
= isl_printer_print_str(p
, " ? ");
2439 p
= print_at_c(p
, expr
->u
.op
.args
, 1);
2440 p
= isl_printer_print_str(p
, " : ");
2441 p
= print_at_c(p
, expr
->u
.op
.args
, 2);
2445 isl_die(isl_printer_get_ctx(p
), isl_error_internal
,
2446 "operation should have two arguments",
2447 return isl_printer_free(p
));
2448 p
= print_sub_expr_c(p
, expr
, 0, 1);
2449 if (expr
->u
.op
.op
!= isl_ast_expr_op_member
)
2450 p
= isl_printer_print_str(p
, " ");
2451 p
= isl_printer_print_str(p
, get_op_str_c(p
, expr
->u
.op
.op
));
2452 if (expr
->u
.op
.op
!= isl_ast_expr_op_member
)
2453 p
= isl_printer_print_str(p
, " ");
2454 p
= print_sub_expr_c(p
, expr
, 1, 0);
2456 case isl_ast_expr_id
:
2457 p
= isl_printer_print_str(p
, isl_id_get_name(expr
->u
.id
));
2459 case isl_ast_expr_int
:
2460 p
= isl_printer_print_val(p
, expr
->u
.v
);
2462 case isl_ast_expr_error
:
2469 /* Textual representation of the isl_ast_expr_op_type elements
2470 * for use in a YAML representation of an isl_ast_expr.
2472 static char *op_str
[] = {
2473 [isl_ast_expr_op_and
] = "and",
2474 [isl_ast_expr_op_and_then
] = "and_then",
2475 [isl_ast_expr_op_or
] = "or",
2476 [isl_ast_expr_op_or_else
] = "or_else",
2477 [isl_ast_expr_op_max
] = "max",
2478 [isl_ast_expr_op_min
] = "min",
2479 [isl_ast_expr_op_minus
] = "minus",
2480 [isl_ast_expr_op_add
] = "add",
2481 [isl_ast_expr_op_sub
] = "sub",
2482 [isl_ast_expr_op_mul
] = "mul",
2483 [isl_ast_expr_op_div
] = "div",
2484 [isl_ast_expr_op_fdiv_q
] = "fdiv_q",
2485 [isl_ast_expr_op_pdiv_q
] = "pdiv_q",
2486 [isl_ast_expr_op_pdiv_r
] = "pdiv_r",
2487 [isl_ast_expr_op_zdiv_r
] = "zdiv_r",
2488 [isl_ast_expr_op_cond
] = "cond",
2489 [isl_ast_expr_op_select
] = "select",
2490 [isl_ast_expr_op_eq
] = "eq",
2491 [isl_ast_expr_op_le
] = "le",
2492 [isl_ast_expr_op_lt
] = "lt",
2493 [isl_ast_expr_op_ge
] = "ge",
2494 [isl_ast_expr_op_gt
] = "gt",
2495 [isl_ast_expr_op_call
] = "call",
2496 [isl_ast_expr_op_access
] = "access",
2497 [isl_ast_expr_op_member
] = "member",
2498 [isl_ast_expr_op_address_of
] = "address_of"
2501 static __isl_give isl_printer
*print_ast_expr_isl(__isl_take isl_printer
*p
,
2502 __isl_keep isl_ast_expr
*expr
);
2504 /* Print the arguments of "expr" to "p" in isl format.
2506 * If there are no arguments, then nothing needs to be printed.
2507 * Otherwise add an "args" key to the current mapping with as value
2508 * the list of arguments of "expr".
2510 static __isl_give isl_printer
*print_arguments(__isl_take isl_printer
*p
,
2511 __isl_keep isl_ast_expr
*expr
)
2516 n
= isl_ast_expr_get_op_n_arg(expr
);
2518 return isl_printer_free(p
);
2522 p
= isl_printer_print_str(p
, "args");
2523 p
= isl_printer_yaml_next(p
);
2524 p
= isl_printer_yaml_start_sequence(p
);
2525 for (i
= 0; i
< n
; ++i
) {
2528 arg
= isl_ast_expr_get_op_arg(expr
, i
);
2529 p
= print_ast_expr_isl(p
, arg
);
2530 isl_ast_expr_free(arg
);
2531 p
= isl_printer_yaml_next(p
);
2533 p
= isl_printer_yaml_end_sequence(p
);
2538 /* Textual representations of the YAML keys for an isl_ast_expr object.
2540 static char *expr_str
[] = {
2541 [isl_ast_expr_op
] = "op",
2542 [isl_ast_expr_id
] = "id",
2543 [isl_ast_expr_int
] = "val",
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
, expr_str
[type
]);
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
, expr_str
[type
]);
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
, expr_str
[type
]);
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
));
2626 #define KEY enum isl_ast_expr_op_type
2628 #define KEY_ERROR isl_ast_expr_op_error
2630 #define KEY_END (isl_ast_expr_op_address_of + 1)
2632 #define KEY_STR op_str
2634 #define KEY_EXTRACT extract_op_type
2636 #define KEY_GET get_op_type
2637 #include "extract_key.c"
2639 /* Return the next token, which is assumed to be a key in a YAML mapping,
2640 * from "s" as a string.
2642 static __isl_give
char *next_key(__isl_keep isl_stream
*s
)
2644 struct isl_token
*tok
;
2650 tok
= isl_stream_next_token(s
);
2652 isl_stream_error(s
, NULL
, "unexpected EOF");
2655 ctx
= isl_stream_get_ctx(s
);
2656 str
= isl_token_get_str(ctx
, tok
);
2657 isl_token_free(tok
);
2661 /* Remove the next token, which is assumed to be the key "expected"
2662 * in a YAML mapping, from "s" and move to the corresponding value.
2664 static isl_stat
eat_key(__isl_keep isl_stream
*s
, const char *expected
)
2671 return isl_stat_error
;
2672 ok
= !strcmp(str
, expected
);
2676 isl_stream_error(s
, NULL
, "expecting different key");
2677 return isl_stat_error
;
2680 if (isl_stream_yaml_next(s
) < 0)
2681 return isl_stat_error
;
2687 #define EL_BASE ast_expr
2689 #include <isl_list_read_yaml_templ.c>
2691 /* Read an isl_ast_expr object of type isl_ast_expr_op from "s",
2692 * where the "op" key has already been read by the caller.
2694 * Read the operation type and the arguments and
2695 * return the corresponding isl_ast_expr object.
2697 static __isl_give isl_ast_expr
*read_op(__isl_keep isl_stream
*s
)
2699 enum isl_ast_expr_op_type op
;
2700 isl_ast_expr_list
*list
;
2702 op
= get_op_type(s
);
2705 if (isl_stream_yaml_next(s
) < 0)
2707 if (eat_key(s
, "args") < 0)
2710 list
= isl_stream_yaml_read_ast_expr_list(s
);
2712 return alloc_op(op
, list
);
2715 /* Read an isl_ast_expr object of type isl_ast_expr_id from "s",
2716 * where the "id" key has already been read by the caller.
2718 static __isl_give isl_ast_expr
*read_id(__isl_keep isl_stream
*s
)
2720 return isl_ast_expr_from_id(isl_stream_read_id(s
));
2723 /* Read an isl_ast_expr object of type isl_ast_expr_int from "s",
2724 * where the "val" key has already been read by the caller.
2726 static __isl_give isl_ast_expr
*read_int(__isl_keep isl_stream
*s
)
2728 return isl_ast_expr_from_val(isl_stream_read_val(s
));
2732 #define KEY enum isl_ast_expr_type
2734 #define KEY_ERROR isl_ast_expr_error
2736 #define KEY_END (isl_ast_expr_int + 1)
2738 #define KEY_STR expr_str
2740 #define KEY_EXTRACT extract_expr_type
2742 #define KEY_GET get_expr_type
2743 #include "extract_key.c"
2745 /* Read an isl_ast_expr object from "s".
2747 * The keys in the YAML mapping are assumed to appear
2748 * in the same order as the one in which they are printed
2749 * by print_ast_expr_isl.
2750 * In particular, the isl_ast_expr_op type, which is the only one
2751 * with more than one element, is identified by the "op" key and
2752 * not by the "args" key.
2754 __isl_give isl_ast_expr
*isl_stream_read_ast_expr(__isl_keep isl_stream
*s
)
2756 enum isl_ast_expr_type type
;
2760 if (isl_stream_yaml_read_start_mapping(s
))
2762 more
= isl_stream_yaml_next(s
);
2766 isl_stream_error(s
, NULL
, "missing key");
2770 type
= get_expr_type(s
);
2773 if (isl_stream_yaml_next(s
) < 0)
2776 case isl_ast_expr_op
:
2779 case isl_ast_expr_id
:
2782 case isl_ast_expr_int
:
2785 case isl_ast_expr_error
:
2789 if (isl_stream_yaml_read_end_mapping(s
) < 0)
2790 return isl_ast_expr_free(expr
);
2795 static __isl_give isl_printer
*print_ast_node_isl(__isl_take isl_printer
*p
,
2796 __isl_keep isl_ast_node
*node
);
2798 /* Print a YAML sequence containing the entries in "list" to "p".
2800 static __isl_give isl_printer
*print_ast_node_list(__isl_take isl_printer
*p
,
2801 __isl_keep isl_ast_node_list
*list
)
2806 n
= isl_ast_node_list_n_ast_node(list
);
2808 return isl_printer_free(p
);
2810 p
= isl_printer_yaml_start_sequence(p
);
2811 for (i
= 0; i
< n
; ++i
) {
2814 node
= isl_ast_node_list_get_ast_node(list
, i
);
2815 p
= print_ast_node_isl(p
, node
);
2816 isl_ast_node_free(node
);
2817 p
= isl_printer_yaml_next(p
);
2819 p
= isl_printer_yaml_end_sequence(p
);
2824 /* Print "node" to "p" in "isl format".
2826 * In particular, print the isl_ast_node as a YAML document.
2828 static __isl_give isl_printer
*print_ast_node_isl(__isl_take isl_printer
*p
,
2829 __isl_keep isl_ast_node
*node
)
2831 switch (node
->type
) {
2832 case isl_ast_node_for
:
2833 p
= isl_printer_yaml_start_mapping(p
);
2834 p
= isl_printer_print_str(p
, "iterator");
2835 p
= isl_printer_yaml_next(p
);
2836 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.iterator
);
2837 p
= isl_printer_yaml_next(p
);
2838 if (node
->u
.f
.degenerate
) {
2839 p
= isl_printer_print_str(p
, "value");
2840 p
= isl_printer_yaml_next(p
);
2841 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.init
);
2842 p
= isl_printer_yaml_next(p
);
2844 p
= isl_printer_print_str(p
, "init");
2845 p
= isl_printer_yaml_next(p
);
2846 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.init
);
2847 p
= isl_printer_yaml_next(p
);
2848 p
= isl_printer_print_str(p
, "cond");
2849 p
= isl_printer_yaml_next(p
);
2850 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.cond
);
2851 p
= isl_printer_yaml_next(p
);
2852 p
= isl_printer_print_str(p
, "inc");
2853 p
= isl_printer_yaml_next(p
);
2854 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.inc
);
2855 p
= isl_printer_yaml_next(p
);
2857 if (node
->u
.f
.body
) {
2858 p
= isl_printer_print_str(p
, "body");
2859 p
= isl_printer_yaml_next(p
);
2860 p
= isl_printer_print_ast_node(p
, node
->u
.f
.body
);
2861 p
= isl_printer_yaml_next(p
);
2863 p
= isl_printer_yaml_end_mapping(p
);
2865 case isl_ast_node_mark
:
2866 p
= isl_printer_yaml_start_mapping(p
);
2867 p
= isl_printer_print_str(p
, "mark");
2868 p
= isl_printer_yaml_next(p
);
2869 p
= isl_printer_print_id(p
, node
->u
.m
.mark
);
2870 p
= isl_printer_yaml_next(p
);
2871 p
= isl_printer_print_str(p
, "node");
2872 p
= isl_printer_yaml_next(p
);
2873 p
= isl_printer_print_ast_node(p
, node
->u
.m
.node
);
2874 p
= isl_printer_yaml_end_mapping(p
);
2876 case isl_ast_node_user
:
2877 p
= isl_printer_yaml_start_mapping(p
);
2878 p
= isl_printer_print_str(p
, "user");
2879 p
= isl_printer_yaml_next(p
);
2880 p
= isl_printer_print_ast_expr(p
, node
->u
.e
.expr
);
2881 p
= isl_printer_yaml_end_mapping(p
);
2883 case isl_ast_node_if
:
2884 p
= isl_printer_yaml_start_mapping(p
);
2885 p
= isl_printer_print_str(p
, "guard");
2886 p
= isl_printer_yaml_next(p
);
2887 p
= isl_printer_print_ast_expr(p
, node
->u
.i
.guard
);
2888 p
= isl_printer_yaml_next(p
);
2889 if (node
->u
.i
.then
) {
2890 p
= isl_printer_print_str(p
, "then");
2891 p
= isl_printer_yaml_next(p
);
2892 p
= isl_printer_print_ast_node(p
, node
->u
.i
.then
);
2893 p
= isl_printer_yaml_next(p
);
2895 if (node
->u
.i
.else_node
) {
2896 p
= isl_printer_print_str(p
, "else");
2897 p
= isl_printer_yaml_next(p
);
2898 p
= isl_printer_print_ast_node(p
, node
->u
.i
.else_node
);
2900 p
= isl_printer_yaml_end_mapping(p
);
2902 case isl_ast_node_block
:
2903 p
= print_ast_node_list(p
, node
->u
.b
.children
);
2905 case isl_ast_node_error
:
2911 /* Do we need to print a block around the body "node" of a for or if node?
2913 * If the node is a block, then we need to print a block.
2914 * Also if the node is a degenerate for then we will print it as
2915 * an assignment followed by the body of the for loop, so we need a block
2917 * If the node is an if node with an else, then we print a block
2918 * to avoid spurious dangling else warnings emitted by some compilers.
2919 * If the node is a mark, then in principle, we would have to check
2920 * the child of the mark node. However, even if the child would not
2921 * require us to print a block, for readability it is probably best
2922 * to print a block anyway.
2923 * If the ast_always_print_block option has been set, then we print a block.
2925 static int need_block(__isl_keep isl_ast_node
*node
)
2929 if (node
->type
== isl_ast_node_block
)
2931 if (node
->type
== isl_ast_node_for
&& node
->u
.f
.degenerate
)
2933 if (node
->type
== isl_ast_node_if
&& node
->u
.i
.else_node
)
2935 if (node
->type
== isl_ast_node_mark
)
2938 ctx
= isl_ast_node_get_ctx(node
);
2939 return isl_options_get_ast_always_print_block(ctx
);
2942 static __isl_give isl_printer
*print_ast_node_c(__isl_take isl_printer
*p
,
2943 __isl_keep isl_ast_node
*node
,
2944 __isl_keep isl_ast_print_options
*options
, int in_block
, int in_list
);
2945 static __isl_give isl_printer
*print_if_c(__isl_take isl_printer
*p
,
2946 __isl_keep isl_ast_node
*node
,
2947 __isl_keep isl_ast_print_options
*options
, int new_line
,
2950 /* Print the body "node" of a for or if node.
2951 * If "else_node" is set, then it is printed as well.
2952 * If "force_block" is set, then print out the body as a block.
2954 * We first check if we need to print out a block.
2955 * We always print out a block if there is an else node to make
2956 * sure that the else node is matched to the correct if node.
2957 * For consistency, the corresponding else node is also printed as a block.
2959 * If the else node is itself an if, then we print it as
2964 * Otherwise the else node is printed as
2970 static __isl_give isl_printer
*print_body_c(__isl_take isl_printer
*p
,
2971 __isl_keep isl_ast_node
*node
, __isl_keep isl_ast_node
*else_node
,
2972 __isl_keep isl_ast_print_options
*options
, int force_block
)
2975 return isl_printer_free(p
);
2977 if (!force_block
&& !else_node
&& !need_block(node
)) {
2978 p
= isl_printer_end_line(p
);
2979 p
= isl_printer_indent(p
, 2);
2980 p
= isl_ast_node_print(node
, p
,
2981 isl_ast_print_options_copy(options
));
2982 p
= isl_printer_indent(p
, -2);
2986 p
= isl_printer_print_str(p
, " {");
2987 p
= isl_printer_end_line(p
);
2988 p
= isl_printer_indent(p
, 2);
2989 p
= print_ast_node_c(p
, node
, options
, 1, 0);
2990 p
= isl_printer_indent(p
, -2);
2991 p
= isl_printer_start_line(p
);
2992 p
= isl_printer_print_str(p
, "}");
2994 if (else_node
->type
== isl_ast_node_if
) {
2995 p
= isl_printer_print_str(p
, " else ");
2996 p
= print_if_c(p
, else_node
, options
, 0, 1);
2998 p
= isl_printer_print_str(p
, " else");
2999 p
= print_body_c(p
, else_node
, NULL
, options
, 1);
3002 p
= isl_printer_end_line(p
);
3007 /* Print the start of a compound statement.
3009 static __isl_give isl_printer
*start_block(__isl_take isl_printer
*p
)
3011 p
= isl_printer_start_line(p
);
3012 p
= isl_printer_print_str(p
, "{");
3013 p
= isl_printer_end_line(p
);
3014 p
= isl_printer_indent(p
, 2);
3019 /* Print the end of a compound statement.
3021 static __isl_give isl_printer
*end_block(__isl_take isl_printer
*p
)
3023 p
= isl_printer_indent(p
, -2);
3024 p
= isl_printer_start_line(p
);
3025 p
= isl_printer_print_str(p
, "}");
3026 p
= isl_printer_end_line(p
);
3031 /* Print the for node "node".
3033 * If the for node is degenerate, it is printed as
3035 * type iterator = init;
3038 * Otherwise, it is printed as
3040 * for (type iterator = init; cond; iterator += inc)
3043 * "in_block" is set if we are currently inside a block.
3044 * "in_list" is set if the current node is not alone in the block.
3045 * If we are not in a block or if the current not is not alone in the block
3046 * then we print a block around a degenerate for loop such that the variable
3047 * declaration will not conflict with any potential other declaration
3048 * of the same variable.
3050 static __isl_give isl_printer
*print_for_c(__isl_take isl_printer
*p
,
3051 __isl_keep isl_ast_node
*node
,
3052 __isl_keep isl_ast_print_options
*options
, int in_block
, int in_list
)
3058 type
= isl_options_get_ast_iterator_type(isl_printer_get_ctx(p
));
3059 if (!node
->u
.f
.degenerate
) {
3060 id
= isl_ast_expr_get_id(node
->u
.f
.iterator
);
3061 name
= isl_id_get_name(id
);
3063 p
= isl_printer_start_line(p
);
3064 p
= isl_printer_print_str(p
, "for (");
3065 p
= isl_printer_print_str(p
, type
);
3066 p
= isl_printer_print_str(p
, " ");
3067 p
= isl_printer_print_str(p
, name
);
3068 p
= isl_printer_print_str(p
, " = ");
3069 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.init
);
3070 p
= isl_printer_print_str(p
, "; ");
3071 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.cond
);
3072 p
= isl_printer_print_str(p
, "; ");
3073 p
= isl_printer_print_str(p
, name
);
3074 p
= isl_printer_print_str(p
, " += ");
3075 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.inc
);
3076 p
= isl_printer_print_str(p
, ")");
3077 p
= print_body_c(p
, node
->u
.f
.body
, NULL
, options
, 0);
3079 id
= isl_ast_expr_get_id(node
->u
.f
.iterator
);
3080 name
= isl_id_get_name(id
);
3082 if (!in_block
|| in_list
)
3084 p
= isl_printer_start_line(p
);
3085 p
= isl_printer_print_str(p
, type
);
3086 p
= isl_printer_print_str(p
, " ");
3087 p
= isl_printer_print_str(p
, name
);
3088 p
= isl_printer_print_str(p
, " = ");
3089 p
= isl_printer_print_ast_expr(p
, node
->u
.f
.init
);
3090 p
= isl_printer_print_str(p
, ";");
3091 p
= isl_printer_end_line(p
);
3092 p
= print_ast_node_c(p
, node
->u
.f
.body
, options
, 1, 0);
3093 if (!in_block
|| in_list
)
3100 /* Print the if node "node".
3101 * If "new_line" is set then the if node should be printed on a new line.
3102 * If "force_block" is set, then print out the body as a block.
3104 static __isl_give isl_printer
*print_if_c(__isl_take isl_printer
*p
,
3105 __isl_keep isl_ast_node
*node
,
3106 __isl_keep isl_ast_print_options
*options
, int new_line
,
3110 p
= isl_printer_start_line(p
);
3111 p
= isl_printer_print_str(p
, "if (");
3112 p
= isl_printer_print_ast_expr(p
, node
->u
.i
.guard
);
3113 p
= isl_printer_print_str(p
, ")");
3114 p
= print_body_c(p
, node
->u
.i
.then
, node
->u
.i
.else_node
, options
,
3120 /* Print the "node" to "p".
3122 * "in_block" is set if we are currently inside a block.
3123 * If so, we do not print a block around the children of a block node.
3124 * We do this to avoid an extra block around the body of a degenerate
3127 * "in_list" is set if the current node is not alone in the block.
3129 static __isl_give isl_printer
*print_ast_node_c(__isl_take isl_printer
*p
,
3130 __isl_keep isl_ast_node
*node
,
3131 __isl_keep isl_ast_print_options
*options
, int in_block
, int in_list
)
3133 switch (node
->type
) {
3134 case isl_ast_node_for
:
3135 if (options
->print_for
)
3136 return options
->print_for(p
,
3137 isl_ast_print_options_copy(options
),
3138 node
, options
->print_for_user
);
3139 p
= print_for_c(p
, node
, options
, in_block
, in_list
);
3141 case isl_ast_node_if
:
3142 p
= print_if_c(p
, node
, options
, 1, 0);
3144 case isl_ast_node_block
:
3147 p
= isl_ast_node_list_print(node
->u
.b
.children
, p
, options
);
3151 case isl_ast_node_mark
:
3152 p
= isl_printer_start_line(p
);
3153 p
= isl_printer_print_str(p
, "// ");
3154 p
= isl_printer_print_str(p
, isl_id_get_name(node
->u
.m
.mark
));
3155 p
= isl_printer_end_line(p
);
3156 p
= print_ast_node_c(p
, node
->u
.m
.node
, options
, 0, in_list
);
3158 case isl_ast_node_user
:
3159 if (options
->print_user
)
3160 return options
->print_user(p
,
3161 isl_ast_print_options_copy(options
),
3162 node
, options
->print_user_user
);
3163 p
= isl_printer_start_line(p
);
3164 p
= isl_printer_print_ast_expr(p
, node
->u
.e
.expr
);
3165 p
= isl_printer_print_str(p
, ";");
3166 p
= isl_printer_end_line(p
);
3168 case isl_ast_node_error
:
3174 /* Print the for node "node" to "p".
3176 __isl_give isl_printer
*isl_ast_node_for_print(__isl_keep isl_ast_node
*node
,
3177 __isl_take isl_printer
*p
, __isl_take isl_ast_print_options
*options
)
3179 if (isl_ast_node_check_for(node
) < 0 || !options
)
3181 p
= print_for_c(p
, node
, options
, 0, 0);
3182 isl_ast_print_options_free(options
);
3185 isl_ast_print_options_free(options
);
3186 isl_printer_free(p
);
3190 /* Print the if node "node" to "p".
3192 __isl_give isl_printer
*isl_ast_node_if_print(__isl_keep isl_ast_node
*node
,
3193 __isl_take isl_printer
*p
, __isl_take isl_ast_print_options
*options
)
3195 if (isl_ast_node_check_if(node
) < 0 || !options
)
3197 p
= print_if_c(p
, node
, options
, 1, 0);
3198 isl_ast_print_options_free(options
);
3201 isl_ast_print_options_free(options
);
3202 isl_printer_free(p
);
3206 /* Print "node" to "p".
3208 * "node" is assumed to be either the outermost node in an AST or
3209 * a node that is known not to be a block.
3210 * If "node" is a block (and is therefore outermost) and
3211 * if the ast_print_outermost_block options is not set,
3212 * then act as if the printing occurs inside a block, such
3213 * that no "extra" block will get printed.
3215 __isl_give isl_printer
*isl_ast_node_print(__isl_keep isl_ast_node
*node
,
3216 __isl_take isl_printer
*p
, __isl_take isl_ast_print_options
*options
)
3220 if (!options
|| !node
)
3222 if (node
->type
== isl_ast_node_block
) {
3225 ctx
= isl_ast_node_get_ctx(node
);
3226 in_block
= !isl_options_get_ast_print_outermost_block(ctx
);
3228 p
= print_ast_node_c(p
, node
, options
, in_block
, 0);
3229 isl_ast_print_options_free(options
);
3232 isl_ast_print_options_free(options
);
3233 isl_printer_free(p
);
3237 /* Print "node" to "p".
3239 __isl_give isl_printer
*isl_printer_print_ast_node(__isl_take isl_printer
*p
,
3240 __isl_keep isl_ast_node
*node
)
3243 isl_ast_print_options
*options
;
3248 format
= isl_printer_get_output_format(p
);
3250 case ISL_FORMAT_ISL
:
3251 p
= print_ast_node_isl(p
, node
);
3254 options
= isl_ast_print_options_alloc(isl_printer_get_ctx(p
));
3255 p
= isl_ast_node_print(node
, p
, options
);
3258 isl_die(isl_printer_get_ctx(p
), isl_error_unsupported
,
3259 "output format not supported for ast_node",
3260 return isl_printer_free(p
));
3266 /* Print the list of nodes "list" to "p".
3268 __isl_give isl_printer
*isl_ast_node_list_print(
3269 __isl_keep isl_ast_node_list
*list
, __isl_take isl_printer
*p
,
3270 __isl_keep isl_ast_print_options
*options
)
3274 if (!p
|| !list
|| !options
)
3275 return isl_printer_free(p
);
3277 for (i
= 0; i
< list
->n
; ++i
)
3278 p
= print_ast_node_c(p
, list
->p
[i
], options
, 1, 1);
3283 /* Is the next token on "s" the start of a YAML sequence
3284 * (rather than a YAML mapping)?
3286 * A YAML sequence starts with either a '[' or a '-', depending on the format.
3288 static isl_bool
next_is_sequence(__isl_keep isl_stream
*s
)
3290 struct isl_token
*tok
;
3294 tok
= isl_stream_next_token(s
);
3296 return isl_bool_error
;
3297 type
= isl_token_get_type(tok
);
3298 seq
= type
== '[' || type
== '-';
3299 isl_stream_push_token(s
, tok
);
3301 return isl_bool_ok(seq
);
3305 #define EL_BASE ast_node
3307 #include <isl_list_read_yaml_templ.c>
3309 /* Read an isl_ast_node object of type isl_ast_node_block from "s".
3311 static __isl_give isl_ast_node
*read_block(__isl_keep isl_stream
*s
)
3313 isl_ast_node_list
*children
;
3315 children
= isl_stream_yaml_read_ast_node_list(s
);
3316 return isl_ast_node_block_from_children(children
);
3319 /* Textual representation of the first YAML key used
3320 * while printing an isl_ast_node of a given type.
3322 * An isl_ast_node of type isl_ast_node_block is not printed
3323 * as a YAML mapping and is therefore assigned a dummy key.
3325 static char *node_first_str
[] = {
3326 [isl_ast_node_for
] = "iterator",
3327 [isl_ast_node_mark
] = "mark",
3328 [isl_ast_node_user
] = "user",
3329 [isl_ast_node_if
] = "guard",
3330 [isl_ast_node_block
] = "",
3334 #define KEY enum isl_ast_node_type
3336 #define KEY_ERROR isl_ast_node_error
3338 #define KEY_END (isl_ast_node_user + 1)
3340 #define KEY_STR node_first_str
3342 #define KEY_EXTRACT extract_node_type
3344 #define KEY_GET get_node_type
3345 #include "extract_key.c"
3347 static __isl_give isl_ast_node
*read_body(__isl_keep isl_stream
*s
,
3348 __isl_take isl_ast_node
*node
)
3350 if (eat_key(s
, "body") < 0)
3351 return isl_ast_node_free(node
);
3352 node
= isl_ast_node_for_set_body(node
, isl_stream_read_ast_node(s
));
3353 if (isl_stream_yaml_next(s
) < 0)
3354 return isl_ast_node_free(node
);
3358 /* Read an isl_ast_node object of type isl_ast_node_for from "s",
3359 * where the initial "iterator" key has already been read by the caller.
3361 * If the initial value is printed as the value of the key "value",
3362 * then the for-loop is degenerate and can at most have
3363 * a further "body" element.
3364 * Otherwise, the for-loop also has "cond" and "inc" elements.
3366 static __isl_give isl_ast_node
*read_for(__isl_keep isl_stream
*s
)
3373 int is_value
, is_init
;
3375 expr
= isl_stream_read_ast_expr(s
);
3376 id
= isl_ast_expr_id_get_id(expr
);
3377 isl_ast_expr_free(expr
);
3380 if (isl_stream_yaml_next(s
) < 0)
3381 id
= isl_id_free(id
);
3383 node
= isl_ast_node_alloc_for(id
);
3387 return isl_ast_node_free(node
);
3388 is_value
= !strcmp(key
, "value");
3389 is_init
= !strcmp(key
, "init");
3391 if (!is_value
&& !is_init
)
3392 isl_die(isl_stream_get_ctx(s
), isl_error_invalid
,
3393 "unexpected key", return isl_ast_node_free(node
));
3394 if (isl_stream_yaml_next(s
) < 0)
3395 return isl_ast_node_free(node
);
3396 node
= isl_ast_node_for_set_init(node
, isl_stream_read_ast_expr(s
));
3397 if ((more
= isl_stream_yaml_next(s
)) < 0)
3398 return isl_ast_node_free(node
);
3400 node
= isl_ast_node_for_mark_degenerate(node
);
3402 node
= read_body(s
, node
);
3406 if (eat_key(s
, "cond") < 0)
3407 return isl_ast_node_free(node
);
3408 node
= isl_ast_node_for_set_cond(node
, isl_stream_read_ast_expr(s
));
3409 if (isl_stream_yaml_next(s
) < 0)
3410 return isl_ast_node_free(node
);
3411 if (eat_key(s
, "inc") < 0)
3412 return isl_ast_node_free(node
);
3413 node
= isl_ast_node_for_set_inc(node
, isl_stream_read_ast_expr(s
));
3414 if ((more
= isl_stream_yaml_next(s
)) < 0)
3415 return isl_ast_node_free(node
);
3418 node
= read_body(s
, node
);
3423 /* Read an isl_ast_node object of type isl_ast_node_mark from "s",
3424 * where the initial "mark" key has already been read by the caller.
3426 static __isl_give isl_ast_node
*read_mark(__isl_keep isl_stream
*s
)
3431 id
= isl_stream_read_id(s
);
3434 if (isl_stream_yaml_next(s
) < 0)
3436 if (eat_key(s
, "node") < 0)
3438 node
= isl_stream_read_ast_node(s
);
3439 node
= isl_ast_node_alloc_mark(id
, node
);
3440 if (isl_stream_yaml_next(s
) < 0)
3441 return isl_ast_node_free(node
);
3448 /* Read an isl_ast_node object of type isl_ast_node_user from "s",
3449 * where the "user" key has already been read by the caller.
3451 static __isl_give isl_ast_node
*read_user(__isl_keep isl_stream
*s
)
3455 node
= isl_ast_node_alloc_user(isl_stream_read_ast_expr(s
));
3456 if (isl_stream_yaml_next(s
) < 0)
3457 return isl_ast_node_free(node
);
3461 /* Read an isl_ast_node object of type isl_ast_node_if from "s",
3462 * where the initial "guard" key has already been read by the caller.
3464 static __isl_give isl_ast_node
*read_if(__isl_keep isl_stream
*s
)
3469 node
= isl_ast_node_alloc_if(isl_stream_read_ast_expr(s
));
3470 if ((more
= isl_stream_yaml_next(s
)) < 0)
3471 return isl_ast_node_free(node
);
3475 if (eat_key(s
, "then") < 0)
3476 return isl_ast_node_free(node
);
3477 node
= isl_ast_node_if_set_then(node
, isl_stream_read_ast_node(s
));
3478 if ((more
= isl_stream_yaml_next(s
)) < 0)
3479 return isl_ast_node_free(node
);
3483 if (eat_key(s
, "else") < 0)
3484 return isl_ast_node_free(node
);
3485 node
= isl_ast_node_if_set_else_node(node
, isl_stream_read_ast_node(s
));
3486 if (isl_stream_yaml_next(s
) < 0)
3487 return isl_ast_node_free(node
);
3492 /* Read an isl_ast_node object from "s".
3494 * A block node is printed as a YAML sequence by print_ast_node_isl.
3495 * Every other node type is printed as a YAML mapping.
3497 * First check if the next element is a sequence and if so,
3498 * read a block node.
3499 * Otherwise, read a node based on the first mapping key
3500 * that is used to print a node type.
3501 * Note that the keys in the YAML mapping are assumed to appear
3502 * in the same order as the one in which they are printed
3503 * by print_ast_node_isl.
3505 __isl_give isl_ast_node
*isl_stream_read_ast_node(__isl_keep isl_stream
*s
)
3507 enum isl_ast_node_type type
;
3512 seq
= next_is_sequence(s
);
3516 return read_block(s
);
3518 if (isl_stream_yaml_read_start_mapping(s
))
3520 more
= isl_stream_yaml_next(s
);
3524 isl_stream_error(s
, NULL
, "missing key");
3528 type
= get_node_type(s
);
3531 if (isl_stream_yaml_next(s
) < 0)
3535 case isl_ast_node_block
:
3536 isl_die(isl_stream_get_ctx(s
), isl_error_internal
,
3537 "block cannot be detected as mapping",
3539 case isl_ast_node_for
:
3542 case isl_ast_node_mark
:
3543 node
= read_mark(s
);
3545 case isl_ast_node_user
:
3546 node
= read_user(s
);
3548 case isl_ast_node_if
:
3551 case isl_ast_node_error
:
3555 if (isl_stream_yaml_read_end_mapping(s
) < 0)
3556 return isl_ast_node_free(node
);
3561 #define ISL_AST_MACRO_FDIV_Q (1 << 0)
3562 #define ISL_AST_MACRO_MIN (1 << 1)
3563 #define ISL_AST_MACRO_MAX (1 << 2)
3564 #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FDIV_Q | \
3565 ISL_AST_MACRO_MIN | \
3568 static int ast_expr_required_macros(__isl_keep isl_ast_expr
*expr
, int macros
);
3570 /* Wrapper around ast_expr_required_macros for use
3571 * as an isl_ast_expr_list_foreach callback.
3573 static isl_stat
entry_required_macros(__isl_take isl_ast_expr
*expr
, void *user
)
3577 *macros
= ast_expr_required_macros(expr
, *macros
);
3578 isl_ast_expr_free(expr
);
3583 /* If "expr" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3584 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3586 static int ast_expr_required_macros(__isl_keep isl_ast_expr
*expr
, int macros
)
3588 if (macros
== ISL_AST_MACRO_ALL
)
3591 if (expr
->type
!= isl_ast_expr_op
)
3594 if (expr
->u
.op
.op
== isl_ast_expr_op_min
)
3595 macros
|= ISL_AST_MACRO_MIN
;
3596 if (expr
->u
.op
.op
== isl_ast_expr_op_max
)
3597 macros
|= ISL_AST_MACRO_MAX
;
3598 if (expr
->u
.op
.op
== isl_ast_expr_op_fdiv_q
)
3599 macros
|= ISL_AST_MACRO_FDIV_Q
;
3601 isl_ast_expr_list_foreach(expr
->u
.op
.args
,
3602 &entry_required_macros
, ¯os
);
3607 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list
*list
,
3610 /* If "node" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3611 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3613 static int ast_node_required_macros(__isl_keep isl_ast_node
*node
, int macros
)
3615 if (macros
== ISL_AST_MACRO_ALL
)
3618 switch (node
->type
) {
3619 case isl_ast_node_for
:
3620 macros
= ast_expr_required_macros(node
->u
.f
.init
, macros
);
3621 if (!node
->u
.f
.degenerate
) {
3622 macros
= ast_expr_required_macros(node
->u
.f
.cond
,
3624 macros
= ast_expr_required_macros(node
->u
.f
.inc
,
3627 macros
= ast_node_required_macros(node
->u
.f
.body
, macros
);
3629 case isl_ast_node_if
:
3630 macros
= ast_expr_required_macros(node
->u
.i
.guard
, macros
);
3631 macros
= ast_node_required_macros(node
->u
.i
.then
, macros
);
3632 if (node
->u
.i
.else_node
)
3633 macros
= ast_node_required_macros(node
->u
.i
.else_node
,
3636 case isl_ast_node_block
:
3637 macros
= ast_node_list_required_macros(node
->u
.b
.children
,
3640 case isl_ast_node_mark
:
3641 macros
= ast_node_required_macros(node
->u
.m
.node
, macros
);
3643 case isl_ast_node_user
:
3644 macros
= ast_expr_required_macros(node
->u
.e
.expr
, macros
);
3646 case isl_ast_node_error
:
3653 /* If "list" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3654 * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3656 static int ast_node_list_required_macros(__isl_keep isl_ast_node_list
*list
,
3661 for (i
= 0; i
< list
->n
; ++i
)
3662 macros
= ast_node_required_macros(list
->p
[i
], macros
);
3667 /* Data structure for keeping track of whether a macro definition
3668 * for a given type has already been printed.
3669 * The value is zero if no definition has been printed and non-zero otherwise.
3671 struct isl_ast_expr_op_printed
{
3672 char printed
[isl_ast_expr_op_last
+ 1];
3675 /* Create an empty struct isl_ast_expr_op_printed.
3677 static void *create_printed(isl_ctx
*ctx
)
3679 return isl_calloc_type(ctx
, struct isl_ast_expr_op_printed
);
3682 /* Free a struct isl_ast_expr_op_printed.
3684 static void free_printed(void *user
)
3689 /* Ensure that "p" has an isl_ast_expr_op_printed note identified by "id".
3691 static __isl_give isl_printer
*alloc_printed(__isl_take isl_printer
*p
,
3692 __isl_keep isl_id
*id
)
3694 return alloc_note(p
, id
, &create_printed
, &free_printed
);
3697 /* Create an identifier that is used to store
3698 * an isl_ast_expr_op_printed note.
3700 static __isl_give isl_id
*printed_id(isl_ctx
*ctx
)
3702 return isl_id_alloc(ctx
, "isl_ast_expr_op_type_printed", NULL
);
3705 /* Did the user specify that a macro definition should only be
3706 * printed once and has a macro definition for "type" already
3707 * been printed to "p"?
3708 * If definitions should only be printed once, but a definition
3709 * for "p" has not yet been printed, then mark it as having been
3710 * printed so that it will not printed again.
3711 * The actual printing is taken care of by the caller.
3713 static isl_bool
already_printed_once(__isl_keep isl_printer
*p
,
3714 enum isl_ast_expr_op_type type
)
3718 struct isl_ast_expr_op_printed
*printed
;
3721 return isl_bool_error
;
3723 ctx
= isl_printer_get_ctx(p
);
3724 if (!isl_options_get_ast_print_macro_once(ctx
))
3725 return isl_bool_false
;
3727 if (type
> isl_ast_expr_op_last
)
3728 isl_die(isl_printer_get_ctx(p
), isl_error_invalid
,
3729 "invalid type", return isl_bool_error
);
3731 id
= printed_id(isl_printer_get_ctx(p
));
3732 p
= alloc_printed(p
, id
);
3733 printed
= get_note(p
, id
);
3736 return isl_bool_error
;
3738 if (printed
->printed
[type
])
3739 return isl_bool_true
;
3741 printed
->printed
[type
] = 1;
3742 return isl_bool_false
;
3745 /* Print a macro definition for the operator "type".
3747 * If the user has specified that a macro definition should
3748 * only be printed once to any given printer and if the macro definition
3749 * has already been printed to "p", then do not print the definition.
3751 __isl_give isl_printer
*isl_ast_expr_op_type_print_macro(
3752 enum isl_ast_expr_op_type type
, __isl_take isl_printer
*p
)
3756 skip
= already_printed_once(p
, type
);
3758 return isl_printer_free(p
);
3763 case isl_ast_expr_op_min
:
3764 p
= isl_printer_start_line(p
);
3765 p
= isl_printer_print_str(p
, "#define ");
3766 p
= isl_printer_print_str(p
, get_op_str_c(p
, type
));
3767 p
= isl_printer_print_str(p
,
3768 "(x,y) ((x) < (y) ? (x) : (y))");
3769 p
= isl_printer_end_line(p
);
3771 case isl_ast_expr_op_max
:
3772 p
= isl_printer_start_line(p
);
3773 p
= isl_printer_print_str(p
, "#define ");
3774 p
= isl_printer_print_str(p
, get_op_str_c(p
, type
));
3775 p
= isl_printer_print_str(p
,
3776 "(x,y) ((x) > (y) ? (x) : (y))");
3777 p
= isl_printer_end_line(p
);
3779 case isl_ast_expr_op_fdiv_q
:
3780 p
= isl_printer_start_line(p
);
3781 p
= isl_printer_print_str(p
, "#define ");
3782 p
= isl_printer_print_str(p
, get_op_str_c(p
, type
));
3783 p
= isl_printer_print_str(p
,
3785 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
3786 p
= isl_printer_end_line(p
);
3795 /* This is an alternative name for the function above.
3797 __isl_give isl_printer
*isl_ast_op_type_print_macro(
3798 enum isl_ast_expr_op_type type
, __isl_take isl_printer
*p
)
3800 return isl_ast_expr_op_type_print_macro(type
, p
);
3803 /* Call "fn" for each type of operation represented in the "macros"
3806 static isl_stat
foreach_ast_expr_op_type(int macros
,
3807 isl_stat (*fn
)(enum isl_ast_expr_op_type type
, void *user
), void *user
)
3809 if (macros
& ISL_AST_MACRO_MIN
&& fn(isl_ast_expr_op_min
, user
) < 0)
3810 return isl_stat_error
;
3811 if (macros
& ISL_AST_MACRO_MAX
&& fn(isl_ast_expr_op_max
, user
) < 0)
3812 return isl_stat_error
;
3813 if (macros
& ISL_AST_MACRO_FDIV_Q
&&
3814 fn(isl_ast_expr_op_fdiv_q
, user
) < 0)
3815 return isl_stat_error
;
3820 /* Call "fn" for each type of operation that appears in "expr"
3821 * and that requires a macro definition.
3823 isl_stat
isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr
*expr
,
3824 isl_stat (*fn
)(enum isl_ast_expr_op_type type
, void *user
), void *user
)
3829 return isl_stat_error
;
3831 macros
= ast_expr_required_macros(expr
, 0);
3832 return foreach_ast_expr_op_type(macros
, fn
, user
);
3835 /* This is an alternative name for the function above.
3837 isl_stat
isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr
*expr
,
3838 isl_stat (*fn
)(enum isl_ast_expr_op_type type
, void *user
), void *user
)
3840 return isl_ast_expr_foreach_ast_expr_op_type(expr
, fn
, user
);
3843 /* Call "fn" for each type of operation that appears in "node"
3844 * and that requires a macro definition.
3846 isl_stat
isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node
*node
,
3847 isl_stat (*fn
)(enum isl_ast_expr_op_type type
, void *user
), void *user
)
3852 return isl_stat_error
;
3854 macros
= ast_node_required_macros(node
, 0);
3855 return foreach_ast_expr_op_type(macros
, fn
, user
);
3858 /* This is an alternative name for the function above.
3860 isl_stat
isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node
*node
,
3861 isl_stat (*fn
)(enum isl_ast_expr_op_type type
, void *user
), void *user
)
3863 return isl_ast_node_foreach_ast_expr_op_type(node
, fn
, user
);
3866 static isl_stat
ast_op_type_print_macro(enum isl_ast_expr_op_type type
,
3869 isl_printer
**p
= user
;
3871 *p
= isl_ast_expr_op_type_print_macro(type
, *p
);
3876 /* Print macro definitions for all the macros used in the result
3877 * of printing "expr".
3879 __isl_give isl_printer
*isl_ast_expr_print_macros(
3880 __isl_keep isl_ast_expr
*expr
, __isl_take isl_printer
*p
)
3882 if (isl_ast_expr_foreach_ast_expr_op_type(expr
,
3883 &ast_op_type_print_macro
, &p
) < 0)
3884 return isl_printer_free(p
);
3888 /* Print macro definitions for all the macros used in the result
3889 * of printing "node".
3891 __isl_give isl_printer
*isl_ast_node_print_macros(
3892 __isl_keep isl_ast_node
*node
, __isl_take isl_printer
*p
)
3894 if (isl_ast_node_foreach_ast_expr_op_type(node
,
3895 &ast_op_type_print_macro
, &p
) < 0)
3896 return isl_printer_free(p
);
3900 /* Return a string containing C code representing this isl_ast_expr.
3902 __isl_give
char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr
*expr
)
3910 p
= isl_printer_to_str(isl_ast_expr_get_ctx(expr
));
3911 p
= isl_printer_set_output_format(p
, ISL_FORMAT_C
);
3912 p
= isl_printer_print_ast_expr(p
, expr
);
3914 str
= isl_printer_get_str(p
);
3916 isl_printer_free(p
);
3921 /* Return a string containing C code representing this isl_ast_node.
3923 __isl_give
char *isl_ast_node_to_C_str(__isl_keep isl_ast_node
*node
)
3931 p
= isl_printer_to_str(isl_ast_node_get_ctx(node
));
3932 p
= isl_printer_set_output_format(p
, ISL_FORMAT_C
);
3933 p
= isl_printer_print_ast_node(p
, node
);
3935 str
= isl_printer_get_str(p
);
3937 isl_printer_free(p
);