2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2014 Ecole Normale Superieure. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
40 #include <isl/space.h>
47 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
49 static const char *type_str
[] = {
50 [pet_tree_block
] = "block",
51 [pet_tree_break
] = "break",
52 [pet_tree_continue
] = "continue",
53 [pet_tree_decl
] = "declaration",
54 [pet_tree_decl_init
] = "declaration-init",
55 [pet_tree_expr
] = "expression",
56 [pet_tree_for
] = "for",
57 [pet_tree_infinite_loop
] = "infinite-loop",
59 [pet_tree_if_else
] = "if-else",
60 [pet_tree_while
] = "while",
61 [pet_tree_return
] = "return",
64 /* Return a textual representation of the type "type".
66 const char *pet_tree_type_str(enum pet_tree_type type
)
70 return type_str
[type
];
73 /* Extract a type from its textual representation "str".
75 enum pet_tree_type
pet_tree_str_type(const char *str
)
79 for (i
= 0; i
< ARRAY_SIZE(type_str
); ++i
)
80 if (!strcmp(type_str
[i
], str
))
83 return pet_tree_error
;
86 /* Return a new pet_tree of the given type.
88 * The location is initializaed to pet_loc_dummy.
90 __isl_give pet_tree
*pet_tree_alloc(isl_ctx
*ctx
, enum pet_tree_type type
)
94 tree
= isl_calloc_type(ctx
, struct pet_tree
);
102 tree
->loc
= &pet_loc_dummy
;
107 /* Return a new pet_tree representing the declaration (without initialization)
108 * of the variable "var".
110 __isl_give pet_tree
*pet_tree_new_decl(__isl_take pet_expr
*var
)
117 ctx
= pet_expr_get_ctx(var
);
118 tree
= pet_tree_alloc(ctx
, pet_tree_decl
);
130 /* Return a new pet_tree representing the declaration of the variable "var"
131 * with initial value "init".
133 __isl_give pet_tree
*pet_tree_new_decl_init(__isl_take pet_expr
*var
,
134 __isl_take pet_expr
*init
)
141 ctx
= pet_expr_get_ctx(var
);
142 tree
= pet_tree_alloc(ctx
, pet_tree_decl_init
);
147 tree
->u
.d
.init
= init
;
156 /* Return a new pet_tree representing the expression "expr".
158 __isl_give pet_tree
*pet_tree_new_expr(__isl_take pet_expr
*expr
)
165 ctx
= pet_expr_get_ctx(expr
);
166 tree
= pet_tree_alloc(ctx
, pet_tree_expr
);
170 tree
->u
.e
.expr
= expr
;
178 /* Return a new pet_tree representing the return of expression "expr".
180 __isl_give pet_tree
*pet_tree_new_return(__isl_take pet_expr
*expr
)
187 ctx
= pet_expr_get_ctx(expr
);
188 tree
= pet_tree_alloc(ctx
, pet_tree_return
);
192 tree
->u
.e
.expr
= expr
;
200 /* Return a new pet_tree representing an initially empty sequence
201 * of trees with room for "n" trees.
202 * "block" indicates whether the sequence has its own scope.
204 __isl_give pet_tree
*pet_tree_new_block(isl_ctx
*ctx
, int block
, int n
)
208 tree
= pet_tree_alloc(ctx
, pet_tree_block
);
211 tree
->u
.b
.block
= block
;
214 tree
->u
.b
.child
= isl_calloc_array(ctx
, pet_tree
*, n
);
215 if (n
&& !tree
->u
.b
.child
)
216 return pet_tree_free(tree
);
221 /* Return a new pet_tree representing a break statement.
223 __isl_give pet_tree
*pet_tree_new_break(isl_ctx
*ctx
)
225 return pet_tree_alloc(ctx
, pet_tree_break
);
228 /* Return a new pet_tree representing a continue statement.
230 __isl_give pet_tree
*pet_tree_new_continue(isl_ctx
*ctx
)
232 return pet_tree_alloc(ctx
, pet_tree_continue
);
235 /* Return a new pet_tree representing a for loop
236 * with induction variable "iv", initial value for the induction
237 * variable "init", loop condition "cond", induction variable increment "inc"
238 * and loop body "body". "declared" indicates whether the induction variable
239 * is declared by the loop. "independent" is set if the for loop is marked
242 * The location of the loop is initialized to that of the body.
244 __isl_give pet_tree
*pet_tree_new_for(int independent
, int declared
,
245 __isl_take pet_expr
*iv
, __isl_take pet_expr
*init
,
246 __isl_take pet_expr
*cond
, __isl_take pet_expr
*inc
,
247 __isl_take pet_tree
*body
)
252 if (!iv
|| !init
|| !cond
|| !inc
|| !body
)
254 ctx
= pet_tree_get_ctx(body
);
255 tree
= pet_tree_alloc(ctx
, pet_tree_for
);
259 tree
->u
.l
.independent
= independent
;
260 tree
->u
.l
.declared
= declared
;
262 tree
->u
.l
.init
= init
;
263 tree
->u
.l
.cond
= cond
;
265 tree
->u
.l
.body
= body
;
266 tree
->loc
= pet_tree_get_loc(body
);
268 return pet_tree_free(tree
);
280 /* Return a new pet_tree representing a while loop
281 * with loop condition "cond" and loop body "body".
283 * The location of the loop is initialized to that of the body.
285 __isl_give pet_tree
*pet_tree_new_while(__isl_take pet_expr
*cond
,
286 __isl_take pet_tree
*body
)
293 ctx
= pet_tree_get_ctx(body
);
294 tree
= pet_tree_alloc(ctx
, pet_tree_while
);
298 tree
->u
.l
.cond
= cond
;
299 tree
->u
.l
.body
= body
;
300 tree
->loc
= pet_tree_get_loc(body
);
302 return pet_tree_free(tree
);
311 /* Return a new pet_tree representing an infinite loop
312 * with loop body "body".
314 * The location of the loop is initialized to that of the body.
316 __isl_give pet_tree
*pet_tree_new_infinite_loop(__isl_take pet_tree
*body
)
323 ctx
= pet_tree_get_ctx(body
);
324 tree
= pet_tree_alloc(ctx
, pet_tree_infinite_loop
);
326 return pet_tree_free(body
);
328 tree
->u
.l
.body
= body
;
329 tree
->loc
= pet_tree_get_loc(body
);
331 return pet_tree_free(tree
);
336 /* Return a new pet_tree representing an if statement
337 * with condition "cond" and then branch "then_body".
339 * The location of the if statement is initialized to that of the body.
341 __isl_give pet_tree
*pet_tree_new_if(__isl_take pet_expr
*cond
,
342 __isl_take pet_tree
*then_body
)
347 if (!cond
|| !then_body
)
349 ctx
= pet_tree_get_ctx(then_body
);
350 tree
= pet_tree_alloc(ctx
, pet_tree_if
);
354 tree
->u
.i
.cond
= cond
;
355 tree
->u
.i
.then_body
= then_body
;
356 tree
->loc
= pet_tree_get_loc(then_body
);
358 return pet_tree_free(tree
);
363 pet_tree_free(then_body
);
367 /* Return a new pet_tree representing an if statement
368 * with condition "cond", then branch "then_body" and else branch "else_body".
370 * The location of the if statement is initialized to cover
371 * those of the bodies.
373 __isl_give pet_tree
*pet_tree_new_if_else(__isl_take pet_expr
*cond
,
374 __isl_take pet_tree
*then_body
, __isl_take pet_tree
*else_body
)
379 if (!cond
|| !then_body
|| !else_body
)
381 ctx
= pet_tree_get_ctx(then_body
);
382 tree
= pet_tree_alloc(ctx
, pet_tree_if_else
);
386 tree
->u
.i
.cond
= cond
;
387 tree
->u
.i
.then_body
= then_body
;
388 tree
->u
.i
.else_body
= else_body
;
389 tree
->loc
= pet_tree_get_loc(then_body
);
390 tree
->loc
= pet_loc_update_start_end_from_loc(tree
->loc
,
393 return pet_tree_free(tree
);
398 pet_tree_free(then_body
);
399 pet_tree_free(else_body
);
403 /* Return an independent duplicate of "tree".
405 static __isl_give pet_tree
*pet_tree_dup(__isl_keep pet_tree
*tree
)
413 switch (tree
->type
) {
417 dup
= pet_tree_new_block(tree
->ctx
, tree
->u
.b
.block
,
419 for (i
= 0; i
< tree
->u
.b
.n
; ++i
)
420 dup
= pet_tree_block_add_child(dup
,
421 pet_tree_copy(tree
->u
.b
.child
[i
]));
424 dup
= pet_tree_new_break(tree
->ctx
);
426 case pet_tree_continue
:
427 dup
= pet_tree_new_continue(tree
->ctx
);
430 dup
= pet_tree_new_decl(pet_expr_copy(tree
->u
.d
.var
));
432 case pet_tree_decl_init
:
433 dup
= pet_tree_new_decl_init(pet_expr_copy(tree
->u
.d
.var
),
434 pet_expr_copy(tree
->u
.d
.init
));
437 dup
= pet_tree_new_expr(pet_expr_copy(tree
->u
.e
.expr
));
439 case pet_tree_return
:
440 dup
= pet_tree_new_return(pet_expr_copy(tree
->u
.e
.expr
));
443 dup
= pet_tree_new_for(tree
->u
.l
.independent
,
445 pet_expr_copy(tree
->u
.l
.iv
), pet_expr_copy(tree
->u
.l
.init
),
446 pet_expr_copy(tree
->u
.l
.cond
), pet_expr_copy(tree
->u
.l
.inc
),
447 pet_tree_copy(tree
->u
.l
.body
));
450 dup
= pet_tree_new_while(pet_expr_copy(tree
->u
.l
.cond
),
451 pet_tree_copy(tree
->u
.l
.body
));
453 case pet_tree_infinite_loop
:
454 dup
= pet_tree_new_infinite_loop(pet_tree_copy(tree
->u
.l
.body
));
457 dup
= pet_tree_new_if(pet_expr_copy(tree
->u
.i
.cond
),
458 pet_tree_copy(tree
->u
.i
.then_body
));
460 case pet_tree_if_else
:
461 dup
= pet_tree_new_if_else(pet_expr_copy(tree
->u
.i
.cond
),
462 pet_tree_copy(tree
->u
.i
.then_body
),
463 pet_tree_copy(tree
->u
.i
.else_body
));
469 pet_loc_free(dup
->loc
);
470 dup
->loc
= pet_loc_copy(tree
->loc
);
472 return pet_tree_free(dup
);
474 dup
->label
= isl_id_copy(tree
->label
);
476 return pet_tree_free(dup
);
482 /* Return a pet_tree that is equal to "tree" and that has only one reference.
484 __isl_give pet_tree
*pet_tree_cow(__isl_take pet_tree
*tree
)
492 return pet_tree_dup(tree
);
495 /* Return an extra reference to "tree".
497 __isl_give pet_tree
*pet_tree_copy(__isl_keep pet_tree
*tree
)
506 /* Free a reference to "tree".
508 __isl_null pet_tree
*pet_tree_free(__isl_take pet_tree
*tree
)
517 pet_loc_free(tree
->loc
);
518 isl_id_free(tree
->label
);
520 switch (tree
->type
) {
524 for (i
= 0; i
< tree
->u
.b
.n
; ++i
)
525 pet_tree_free(tree
->u
.b
.child
[i
]);
526 free(tree
->u
.b
.child
);
529 case pet_tree_continue
:
531 case pet_tree_decl_init
:
532 pet_expr_free(tree
->u
.d
.init
);
534 pet_expr_free(tree
->u
.d
.var
);
537 case pet_tree_return
:
538 pet_expr_free(tree
->u
.e
.expr
);
541 pet_expr_free(tree
->u
.l
.iv
);
542 pet_expr_free(tree
->u
.l
.init
);
543 pet_expr_free(tree
->u
.l
.inc
);
545 pet_expr_free(tree
->u
.l
.cond
);
546 case pet_tree_infinite_loop
:
547 pet_tree_free(tree
->u
.l
.body
);
549 case pet_tree_if_else
:
550 pet_tree_free(tree
->u
.i
.else_body
);
552 pet_expr_free(tree
->u
.i
.cond
);
553 pet_tree_free(tree
->u
.i
.then_body
);
557 isl_ctx_deref(tree
->ctx
);
562 /* Return the isl_ctx in which "tree" was created.
564 isl_ctx
*pet_tree_get_ctx(__isl_keep pet_tree
*tree
)
566 return tree
? tree
->ctx
: NULL
;
569 /* Return the location of "tree".
571 __isl_give pet_loc
*pet_tree_get_loc(__isl_keep pet_tree
*tree
)
573 return tree
? pet_loc_copy(tree
->loc
) : NULL
;
576 /* Return the type of "tree".
578 enum pet_tree_type
pet_tree_get_type(__isl_keep pet_tree
*tree
)
581 return pet_tree_error
;
586 /* Replace the location of "tree" by "loc".
588 __isl_give pet_tree
*pet_tree_set_loc(__isl_take pet_tree
*tree
,
589 __isl_take pet_loc
*loc
)
591 tree
= pet_tree_cow(tree
);
595 pet_loc_free(tree
->loc
);
605 /* Replace the label of "tree" by "label".
607 __isl_give pet_tree
*pet_tree_set_label(__isl_take pet_tree
*tree
,
608 __isl_take isl_id
*label
)
610 tree
= pet_tree_cow(tree
);
614 isl_id_free(tree
->label
);
620 return pet_tree_free(tree
);
623 /* Given an expression tree "tree", return the associated expression.
625 __isl_give pet_expr
*pet_tree_expr_get_expr(__isl_keep pet_tree
*tree
)
629 if (pet_tree_get_type(tree
) != pet_tree_expr
)
630 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
631 "not an expression tree", return NULL
);
633 return pet_expr_copy(tree
->u
.e
.expr
);
636 /* Given a return tree "tree", return the returned expression.
638 __isl_give pet_expr
*pet_tree_return_get_expr(__isl_keep pet_tree
*tree
)
642 if (pet_tree_get_type(tree
) != pet_tree_return
)
643 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
644 "not a return tree", return NULL
);
646 return pet_expr_copy(tree
->u
.e
.expr
);
649 /* Given a block tree "tree", return the number of children in the sequence.
651 int pet_tree_block_n_child(__isl_keep pet_tree
*tree
)
655 if (pet_tree_get_type(tree
) != pet_tree_block
)
656 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
657 "not a block tree", return -1);
662 /* Add "child" to the sequence of trees represented by "block".
664 * Update the location of "block" to include that of "child".
666 __isl_give pet_tree
*pet_tree_block_add_child(__isl_take pet_tree
*block
,
667 __isl_take pet_tree
*child
)
669 block
= pet_tree_cow(block
);
670 if (!block
|| !child
)
672 if (block
->type
!= pet_tree_block
)
673 isl_die(pet_tree_get_ctx(block
), isl_error_invalid
,
674 "not a block tree", goto error
);
675 if (block
->u
.b
.n
>= block
->u
.b
.max
)
676 isl_die(pet_tree_get_ctx(block
), isl_error_invalid
,
677 "out of space in block", goto error
);
679 block
->loc
= pet_loc_update_start_end_from_loc(block
->loc
, child
->loc
);
680 block
->u
.b
.child
[block
->u
.b
.n
++] = child
;
683 return pet_tree_free(block
);
687 pet_tree_free(block
);
688 pet_tree_free(child
);
692 /* Does the block tree "tree" have its own scope?
694 int pet_tree_block_get_block(__isl_keep pet_tree
*tree
)
698 if (pet_tree_get_type(tree
) != pet_tree_block
)
699 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
700 "not a block tree", return -1);
702 return tree
->u
.b
.block
;
705 /* Set the block property (whether or not the block tree has its own scope)
706 * of "tree" to "is_block".
708 __isl_give pet_tree
*pet_tree_block_set_block(__isl_take pet_tree
*tree
,
713 if (tree
->type
!= pet_tree_block
)
714 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
715 "not a block tree", return pet_tree_free(tree
));
716 if (tree
->u
.b
.block
== is_block
)
718 tree
= pet_tree_cow(tree
);
721 tree
->u
.b
.block
= is_block
;
725 /* Given a block tree "tree", return the child at position "pos".
727 __isl_give pet_tree
*pet_tree_block_get_child(__isl_keep pet_tree
*tree
,
732 if (pet_tree_get_type(tree
) != pet_tree_block
)
733 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
734 "not a block tree", return NULL
);
735 if (pos
< 0 || pos
>= tree
->u
.b
.n
)
736 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
737 "position out of bounds", return NULL
);
739 return pet_tree_copy(tree
->u
.b
.child
[pos
]);
742 /* Does "tree" represent a declaration (with or without initialization)?
744 int pet_tree_is_decl(__isl_keep pet_tree
*tree
)
749 switch (pet_tree_get_type(tree
)) {
751 case pet_tree_decl_init
:
758 /* Given a declaration tree "tree", return the variable that is being
761 __isl_give pet_expr
*pet_tree_decl_get_var(__isl_keep pet_tree
*tree
)
765 if (!pet_tree_is_decl(tree
))
766 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
767 "not a decl tree", return NULL
);
769 return pet_expr_copy(tree
->u
.d
.var
);
772 /* Given a declaration tree with initialization "tree",
773 * return the initial value of the declared variable.
775 __isl_give pet_expr
*pet_tree_decl_get_init(__isl_keep pet_tree
*tree
)
779 if (pet_tree_get_type(tree
) != pet_tree_decl_init
)
780 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
781 "not a decl_init tree", return NULL
);
783 return pet_expr_copy(tree
->u
.d
.init
);
786 /* Given an if tree "tree", return the if condition.
788 __isl_give pet_expr
*pet_tree_if_get_cond(__isl_keep pet_tree
*tree
)
790 enum pet_tree_type type
;
794 type
= pet_tree_get_type(tree
);
795 if (type
!= pet_tree_if
&& type
!= pet_tree_if_else
)
796 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
797 "not an if tree", return NULL
);
799 return pet_expr_copy(tree
->u
.i
.cond
);
802 /* Given an if tree "tree", return the body of the then branch.
804 __isl_give pet_tree
*pet_tree_if_get_then(__isl_keep pet_tree
*tree
)
806 enum pet_tree_type type
;
810 type
= pet_tree_get_type(tree
);
811 if (type
!= pet_tree_if
&& type
!= pet_tree_if_else
)
812 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
813 "not an if tree", return NULL
);
815 return pet_tree_copy(tree
->u
.i
.then_body
);
818 /* Given an if tree with an else branch "tree",
819 * return the body of that else branch.
821 __isl_give pet_tree
*pet_tree_if_get_else(__isl_keep pet_tree
*tree
)
825 if (pet_tree_get_type(tree
) != pet_tree_if_else
)
826 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
827 "not an if tree with an else branch", return NULL
);
829 return pet_tree_copy(tree
->u
.i
.else_body
);
832 /* Does "tree" represent some type of loop?
834 int pet_tree_is_loop(__isl_keep pet_tree
*tree
)
839 switch (pet_tree_get_type(tree
)) {
841 case pet_tree_infinite_loop
:
849 /* Given a for loop "tree", return the induction variable.
851 __isl_give pet_expr
*pet_tree_loop_get_var(__isl_keep pet_tree
*tree
)
855 if (pet_tree_get_type(tree
) != pet_tree_for
)
856 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
857 "not a for tree", return NULL
);
859 return pet_expr_copy(tree
->u
.l
.iv
);
862 /* Given a for loop "tree", return the initial value of the induction variable.
864 __isl_give pet_expr
*pet_tree_loop_get_init(__isl_keep pet_tree
*tree
)
868 if (pet_tree_get_type(tree
) != pet_tree_for
)
869 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
870 "not a for tree", return NULL
);
872 return pet_expr_copy(tree
->u
.l
.init
);
875 /* Given a loop "tree", return the loop condition.
877 * For an infinite loop, the loop condition always holds,
878 * so we simply return "1".
880 __isl_give pet_expr
*pet_tree_loop_get_cond(__isl_keep pet_tree
*tree
)
882 enum pet_tree_type type
;
886 type
= pet_tree_get_type(tree
);
887 if (type
== pet_tree_infinite_loop
)
888 return pet_expr_new_int(isl_val_one(pet_tree_get_ctx(tree
)));
889 if (type
!= pet_tree_for
&& type
!= pet_tree_while
)
890 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
891 "not a for or while tree", return NULL
);
893 return pet_expr_copy(tree
->u
.l
.cond
);
896 /* Given a for loop "tree", return the increment of the induction variable.
898 __isl_give pet_expr
*pet_tree_loop_get_inc(__isl_keep pet_tree
*tree
)
902 if (pet_tree_get_type(tree
) != pet_tree_for
)
903 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
904 "not a for tree", return NULL
);
906 return pet_expr_copy(tree
->u
.l
.inc
);
909 /* Given a loop tree "tree", return the body.
911 __isl_give pet_tree
*pet_tree_loop_get_body(__isl_keep pet_tree
*tree
)
916 if (!pet_tree_is_loop(tree
))
917 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
918 "not a loop tree", return NULL
);
920 return pet_tree_copy(tree
->u
.l
.body
);
923 /* Call "fn" on each node of "tree", including "tree" itself.
925 * Return 0 on success and -1 on error, where "fn" returning a negative
926 * value is treated as an error.
928 int pet_tree_foreach_sub_tree(__isl_keep pet_tree
*tree
,
929 int (*fn
)(__isl_keep pet_tree
*tree
, void *user
), void *user
)
936 if (fn(tree
, user
) < 0)
939 switch (tree
->type
) {
943 for (i
= 0; i
< tree
->u
.b
.n
; ++i
)
944 if (pet_tree_foreach_sub_tree(tree
->u
.b
.child
[i
],
949 case pet_tree_continue
:
951 case pet_tree_decl_init
:
953 case pet_tree_return
:
956 if (pet_tree_foreach_sub_tree(tree
->u
.i
.then_body
,
960 case pet_tree_if_else
:
961 if (pet_tree_foreach_sub_tree(tree
->u
.i
.then_body
,
964 if (pet_tree_foreach_sub_tree(tree
->u
.i
.else_body
,
970 case pet_tree_infinite_loop
:
971 if (pet_tree_foreach_sub_tree(tree
->u
.l
.body
, fn
, user
) < 0)
979 /* Intermediate data structure for foreach_expr.
981 * "fn" is the function that needs to be called on each expression.
982 * "user" is the user argument to be passed to "fn".
984 struct pet_tree_foreach_expr_data
{
985 int (*fn
)(__isl_keep pet_expr
*expr
, void *user
);
989 /* Call data->fn on each expression in the "tree" object.
990 * This function is used as a callback to pet_tree_foreach_sub_tree
991 * to implement pet_tree_foreach_expr.
993 * Return 0 on success and -1 on error, where data->fn returning a negative
994 * value is treated as an error.
996 static int foreach_expr(__isl_keep pet_tree
*tree
, void *user
)
998 struct pet_tree_foreach_expr_data
*data
= user
;
1003 switch (tree
->type
) {
1004 case pet_tree_error
:
1006 case pet_tree_block
:
1007 case pet_tree_break
:
1008 case pet_tree_continue
:
1009 case pet_tree_infinite_loop
:
1012 if (data
->fn(tree
->u
.d
.var
, data
->user
) < 0)
1015 case pet_tree_decl_init
:
1016 if (data
->fn(tree
->u
.d
.var
, data
->user
) < 0)
1018 if (data
->fn(tree
->u
.d
.init
, data
->user
) < 0)
1022 case pet_tree_return
:
1023 if (data
->fn(tree
->u
.e
.expr
, data
->user
) < 0)
1027 if (data
->fn(tree
->u
.i
.cond
, data
->user
) < 0)
1030 case pet_tree_if_else
:
1031 if (data
->fn(tree
->u
.i
.cond
, data
->user
) < 0)
1034 case pet_tree_while
:
1035 if (data
->fn(tree
->u
.l
.cond
, data
->user
) < 0)
1039 if (data
->fn(tree
->u
.l
.iv
, data
->user
) < 0)
1041 if (data
->fn(tree
->u
.l
.init
, data
->user
) < 0)
1043 if (data
->fn(tree
->u
.l
.cond
, data
->user
) < 0)
1045 if (data
->fn(tree
->u
.l
.inc
, data
->user
) < 0)
1053 /* Call "fn" on each top-level expression in the nodes of "tree"
1055 * Return 0 on success and -1 on error, where "fn" returning a negative
1056 * value is treated as an error.
1058 * We run over all nodes in "tree" and call "fn"
1059 * on each expression in those nodes.
1061 int pet_tree_foreach_expr(__isl_keep pet_tree
*tree
,
1062 int (*fn
)(__isl_keep pet_expr
*expr
, void *user
), void *user
)
1064 struct pet_tree_foreach_expr_data data
= { fn
, user
};
1066 return pet_tree_foreach_sub_tree(tree
, &foreach_expr
, &data
);
1069 /* Intermediate data structure for foreach_access_expr.
1071 * "fn" is the function that needs to be called on each access subexpression.
1072 * "user" is the user argument to be passed to "fn".
1074 struct pet_tree_foreach_access_expr_data
{
1075 int (*fn
)(__isl_keep pet_expr
*expr
, void *user
);
1079 /* Call data->fn on each access subexpression of "expr".
1080 * This function is used as a callback to pet_tree_foreach_expr
1081 * to implement pet_tree_foreach_access_expr.
1083 * Return 0 on success and -1 on error, where data->fn returning a negative
1084 * value is treated as an error.
1086 static int foreach_access_expr(__isl_keep pet_expr
*expr
, void *user
)
1088 struct pet_tree_foreach_access_expr_data
*data
= user
;
1090 return pet_expr_foreach_access_expr(expr
, data
->fn
, data
->user
);
1093 /* Call "fn" on each access subexpression in the nodes of "tree"
1095 * Return 0 on success and -1 on error, where "fn" returning a negative
1096 * value is treated as an error.
1098 * We run over all expressions in the nodes of "tree" and call "fn"
1099 * on each access subexpression of those expressions.
1101 int pet_tree_foreach_access_expr(__isl_keep pet_tree
*tree
,
1102 int (*fn
)(__isl_keep pet_expr
*expr
, void *user
), void *user
)
1104 struct pet_tree_foreach_access_expr_data data
= { fn
, user
};
1106 return pet_tree_foreach_expr(tree
, &foreach_access_expr
, &data
);
1109 /* Modify all top-level expressions in the nodes of "tree"
1110 * by calling "fn" on them.
1112 __isl_give pet_tree
*pet_tree_map_expr(__isl_take pet_tree
*tree
,
1113 __isl_give pet_expr
*(*fn
)(__isl_take pet_expr
*expr
, void *user
),
1118 tree
= pet_tree_cow(tree
);
1122 switch (tree
->type
) {
1123 case pet_tree_error
:
1124 return pet_tree_free(tree
);
1125 case pet_tree_block
:
1126 for (i
= 0; i
< tree
->u
.b
.n
; ++i
) {
1127 tree
->u
.b
.child
[i
] =
1128 pet_tree_map_expr(tree
->u
.b
.child
[i
], fn
, user
);
1129 if (!tree
->u
.b
.child
[i
])
1130 return pet_tree_free(tree
);
1133 case pet_tree_break
:
1134 case pet_tree_continue
:
1137 tree
->u
.d
.var
= fn(tree
->u
.d
.var
, user
);
1139 return pet_tree_free(tree
);
1141 case pet_tree_decl_init
:
1142 tree
->u
.d
.var
= fn(tree
->u
.d
.var
, user
);
1143 tree
->u
.d
.init
= fn(tree
->u
.d
.init
, user
);
1144 if (!tree
->u
.d
.var
|| !tree
->u
.d
.init
)
1145 return pet_tree_free(tree
);
1148 case pet_tree_return
:
1149 tree
->u
.e
.expr
= fn(tree
->u
.e
.expr
, user
);
1150 if (!tree
->u
.e
.expr
)
1151 return pet_tree_free(tree
);
1154 tree
->u
.i
.cond
= fn(tree
->u
.i
.cond
, user
);
1155 tree
->u
.i
.then_body
=
1156 pet_tree_map_expr(tree
->u
.i
.then_body
, fn
, user
);
1157 if (!tree
->u
.i
.cond
|| !tree
->u
.i
.then_body
)
1158 return pet_tree_free(tree
);
1160 case pet_tree_if_else
:
1161 tree
->u
.i
.cond
= fn(tree
->u
.i
.cond
, user
);
1162 tree
->u
.i
.then_body
=
1163 pet_tree_map_expr(tree
->u
.i
.then_body
, fn
, user
);
1164 tree
->u
.i
.else_body
=
1165 pet_tree_map_expr(tree
->u
.i
.else_body
, fn
, user
);
1166 if (!tree
->u
.i
.cond
||
1167 !tree
->u
.i
.then_body
|| !tree
->u
.i
.else_body
)
1168 return pet_tree_free(tree
);
1170 case pet_tree_while
:
1171 tree
->u
.l
.cond
= fn(tree
->u
.l
.cond
, user
);
1172 tree
->u
.l
.body
= pet_tree_map_expr(tree
->u
.l
.body
, fn
, user
);
1173 if (!tree
->u
.l
.cond
|| !tree
->u
.l
.body
)
1174 return pet_tree_free(tree
);
1177 tree
->u
.l
.iv
= fn(tree
->u
.l
.iv
, user
);
1178 tree
->u
.l
.init
= fn(tree
->u
.l
.init
, user
);
1179 tree
->u
.l
.cond
= fn(tree
->u
.l
.cond
, user
);
1180 tree
->u
.l
.inc
= fn(tree
->u
.l
.inc
, user
);
1181 tree
->u
.l
.body
= pet_tree_map_expr(tree
->u
.l
.body
, fn
, user
);
1182 if (!tree
->u
.l
.iv
|| !tree
->u
.l
.init
|| !tree
->u
.l
.cond
||
1183 !tree
->u
.l
.inc
|| !tree
->u
.l
.body
)
1184 return pet_tree_free(tree
);
1186 case pet_tree_infinite_loop
:
1187 tree
->u
.l
.body
= pet_tree_map_expr(tree
->u
.l
.body
, fn
, user
);
1188 if (!tree
->u
.l
.body
)
1189 return pet_tree_free(tree
);
1196 /* Intermediate data structure for map_expr.
1198 * "map" is a function that modifies subexpressions of a given type.
1199 * "fn" is the function that needs to be called on each of those subexpressions.
1200 * "user" is the user argument to be passed to "fn".
1202 struct pet_tree_map_expr_data
{
1203 __isl_give pet_expr
*(*map
)(__isl_take pet_expr
*expr
,
1204 __isl_give pet_expr
*(*fn
)(__isl_take pet_expr
*expr
,
1205 void *user
), void *user
);
1206 __isl_give pet_expr
*(*fn
)(__isl_take pet_expr
*expr
, void *user
);
1210 /* This function is called on each top-level expressions in the nodes
1211 * of a tree. Call data->map to modify subexpressions of the top-level
1212 * expression by calling data->fn on them.
1214 * This is a wrapper around data->map for use as a callback
1215 * to pet_tree_map_expr.
1217 static __isl_give pet_expr
*map_expr(__isl_take pet_expr
*expr
,
1220 struct pet_tree_map_expr_data
*data
= user
;
1222 return data
->map(expr
, data
->fn
, data
->user
);
1225 /* Modify all access subexpressions in the nodes of "tree"
1226 * by calling "fn" on them.
1228 * We run over all expressions in the nodes of "tree" and call "fn"
1229 * on each access subexpression of those expressions.
1231 __isl_give pet_tree
*pet_tree_map_access_expr(__isl_take pet_tree
*tree
,
1232 __isl_give pet_expr
*(*fn
)(__isl_take pet_expr
*expr
, void *user
),
1235 struct pet_tree_map_expr_data data
= { &pet_expr_map_access
, fn
, user
};
1237 return pet_tree_map_expr(tree
, &map_expr
, &data
);
1240 /* Modify all call subexpressions in the nodes of "tree"
1241 * by calling "fn" on them.
1243 * We run over all expressions in the nodes of "tree" and call "fn"
1244 * on each call subexpression of those expressions.
1246 __isl_give pet_tree
*pet_tree_map_call_expr(__isl_take pet_tree
*tree
,
1247 __isl_give pet_expr
*(*fn
)(__isl_take pet_expr
*expr
, void *user
),
1250 struct pet_tree_map_expr_data data
= { &pet_expr_map_call
, fn
, user
};
1252 return pet_tree_map_expr(tree
, &map_expr
, &data
);
1255 /* Wrapper around pet_expr_align_params
1256 * for use as a pet_tree_map_expr callback.
1258 static __isl_give pet_expr
*align_params(__isl_take pet_expr
*expr
,
1261 isl_space
*space
= user
;
1263 return pet_expr_align_params(expr
, isl_space_copy(space
));
1266 /* Add all parameters in "space" to all access relations and index expressions
1269 __isl_give pet_tree
*pet_tree_align_params(__isl_take pet_tree
*tree
,
1270 __isl_take isl_space
*space
)
1272 tree
= pet_tree_map_expr(tree
, &align_params
, space
);
1273 isl_space_free(space
);
1277 /* Wrapper around pet_expr_add_ref_ids
1278 * for use as a pet_tree_map_expr callback.
1280 static __isl_give pet_expr
*add_ref_ids(__isl_take pet_expr
*expr
, void *user
)
1284 return pet_expr_add_ref_ids(expr
, n_ref
);
1287 /* Add reference identifiers to all access expressions in "tree".
1288 * "n_ref" points to an integer that contains the sequence number
1289 * of the next reference.
1291 __isl_give pet_tree
*pet_tree_add_ref_ids(__isl_take pet_tree
*tree
,
1294 return pet_tree_map_expr(tree
, &add_ref_ids
, n_ref
);
1297 /* Wrapper around pet_expr_anonymize
1298 * for use as a pet_tree_map_expr callback.
1300 static __isl_give pet_expr
*anonymize(__isl_take pet_expr
*expr
, void *user
)
1302 return pet_expr_anonymize(expr
);
1305 /* Reset the user pointer on all parameter and tuple ids in "tree".
1307 __isl_give pet_tree
*pet_tree_anonymize(__isl_take pet_tree
*tree
)
1309 return pet_tree_map_expr(tree
, &anonymize
, NULL
);
1312 /* Arguments to be passed to pet_expr_gist from the gist wrapper.
1314 struct pet_tree_gist_data
{
1316 isl_union_map
*value_bounds
;
1319 /* Wrapper around pet_expr_gist for use as a pet_tree_map_expr callback.
1321 static __isl_give pet_expr
*gist(__isl_take pet_expr
*expr
, void *user
)
1323 struct pet_tree_gist_data
*data
= user
;
1325 return pet_expr_gist(expr
, data
->domain
, data
->value_bounds
);
1328 /* Compute the gist of all access relations and index expressions inside
1329 * "tree" based on the constraints on the parameters specified by "context"
1330 * and the constraints on the values of nested accesses specified
1331 * by "value_bounds".
1333 __isl_give pet_tree
*pet_tree_gist(__isl_take pet_tree
*tree
,
1334 __isl_keep isl_set
*context
, __isl_keep isl_union_map
*value_bounds
)
1336 struct pet_tree_gist_data data
= { context
, value_bounds
};
1338 return pet_tree_map_expr(tree
, &gist
, &data
);
1341 /* Return 1 if the two pet_tree objects are equivalent.
1343 * We ignore the locations of the trees.
1345 int pet_tree_is_equal(__isl_keep pet_tree
*tree1
, __isl_keep pet_tree
*tree2
)
1350 if (!tree1
|| !tree2
)
1356 if (tree1
->type
!= tree2
->type
)
1358 if (tree1
->label
!= tree2
->label
)
1361 switch (tree1
->type
) {
1362 case pet_tree_error
:
1364 case pet_tree_block
:
1365 if (tree1
->u
.b
.block
!= tree2
->u
.b
.block
)
1367 if (tree1
->u
.b
.n
!= tree2
->u
.b
.n
)
1369 for (i
= 0; i
< tree1
->u
.b
.n
; ++i
) {
1370 equal
= pet_tree_is_equal(tree1
->u
.b
.child
[i
],
1371 tree2
->u
.b
.child
[i
]);
1372 if (equal
< 0 || !equal
)
1376 case pet_tree_break
:
1377 case pet_tree_continue
:
1380 return pet_expr_is_equal(tree1
->u
.d
.var
, tree2
->u
.d
.var
);
1381 case pet_tree_decl_init
:
1382 equal
= pet_expr_is_equal(tree1
->u
.d
.var
, tree2
->u
.d
.var
);
1383 if (equal
< 0 || !equal
)
1385 return pet_expr_is_equal(tree1
->u
.d
.init
, tree2
->u
.d
.init
);
1387 case pet_tree_return
:
1388 return pet_expr_is_equal(tree1
->u
.e
.expr
, tree2
->u
.e
.expr
);
1390 if (tree1
->u
.l
.declared
!= tree2
->u
.l
.declared
)
1392 equal
= pet_expr_is_equal(tree1
->u
.l
.iv
, tree2
->u
.l
.iv
);
1393 if (equal
< 0 || !equal
)
1395 equal
= pet_expr_is_equal(tree1
->u
.l
.init
, tree2
->u
.l
.init
);
1396 if (equal
< 0 || !equal
)
1398 equal
= pet_expr_is_equal(tree1
->u
.l
.cond
, tree2
->u
.l
.cond
);
1399 if (equal
< 0 || !equal
)
1401 equal
= pet_expr_is_equal(tree1
->u
.l
.inc
, tree2
->u
.l
.inc
);
1402 if (equal
< 0 || !equal
)
1404 return pet_tree_is_equal(tree1
->u
.l
.body
, tree2
->u
.l
.body
);
1405 case pet_tree_while
:
1406 equal
= pet_expr_is_equal(tree1
->u
.l
.cond
, tree2
->u
.l
.cond
);
1407 if (equal
< 0 || !equal
)
1409 return pet_tree_is_equal(tree1
->u
.l
.body
, tree2
->u
.l
.body
);
1410 case pet_tree_infinite_loop
:
1411 return pet_tree_is_equal(tree1
->u
.l
.body
, tree2
->u
.l
.body
);
1413 equal
= pet_expr_is_equal(tree1
->u
.i
.cond
, tree2
->u
.i
.cond
);
1414 if (equal
< 0 || !equal
)
1416 return pet_tree_is_equal(tree1
->u
.i
.then_body
,
1417 tree2
->u
.i
.then_body
);
1418 case pet_tree_if_else
:
1419 equal
= pet_expr_is_equal(tree1
->u
.i
.cond
, tree2
->u
.i
.cond
);
1420 if (equal
< 0 || !equal
)
1422 equal
= pet_tree_is_equal(tree1
->u
.i
.then_body
,
1423 tree2
->u
.i
.then_body
);
1424 if (equal
< 0 || !equal
)
1426 return pet_tree_is_equal(tree1
->u
.i
.else_body
,
1427 tree2
->u
.i
.else_body
);
1433 /* Is "tree" an expression tree that performs the operation "type"?
1435 static int pet_tree_is_op_of_type(__isl_keep pet_tree
*tree
,
1436 enum pet_op_type type
)
1440 if (tree
->type
!= pet_tree_expr
)
1442 if (pet_expr_get_type(tree
->u
.e
.expr
) != pet_expr_op
)
1444 return pet_expr_op_get_type(tree
->u
.e
.expr
) == type
;
1447 /* Is "tree" an expression tree that performs a kill operation?
1449 int pet_tree_is_kill(__isl_keep pet_tree
*tree
)
1451 return pet_tree_is_op_of_type(tree
, pet_op_kill
);
1454 /* Is "tree" an expression tree that performs an assignment operation?
1456 int pet_tree_is_assign(__isl_keep pet_tree
*tree
)
1458 return pet_tree_is_op_of_type(tree
, pet_op_assign
);
1461 /* Is "tree" an expression tree that performs an assume operation?
1463 int pet_tree_is_assume(__isl_keep pet_tree
*tree
)
1465 return pet_tree_is_op_of_type(tree
, pet_op_assume
);
1468 /* Is "tree" an expression tree that performs an assume operation
1469 * such that the assumed expression is affine?
1471 isl_bool
pet_tree_is_affine_assume(__isl_keep pet_tree
*tree
)
1473 if (!pet_tree_is_assume(tree
))
1474 return isl_bool_false
;
1475 return pet_expr_is_affine(tree
->u
.e
.expr
->args
[0]);
1478 /* Given a tree that represent an assume operation expression
1479 * with an access as argument (possibly an affine expression),
1480 * return the index expression of that access.
1482 __isl_give isl_multi_pw_aff
*pet_tree_assume_get_index(
1483 __isl_keep pet_tree
*tree
)
1487 if (!pet_tree_is_assume(tree
))
1488 isl_die(pet_tree_get_ctx(tree
), isl_error_invalid
,
1489 "not an assume tree", return NULL
);
1490 return pet_expr_access_get_index(tree
->u
.e
.expr
->args
[0]);
1493 /* Internal data structure for pet_tree_writes.
1494 * "id" is the identifier that we are looking for.
1495 * "writes" is set if we have found the identifier being written to.
1497 struct pet_tree_writes_data
{
1502 /* Check if expr writes to data->id.
1503 * If so, set data->writes and abort the search.
1505 static int check_write(__isl_keep pet_expr
*expr
, void *user
)
1507 struct pet_tree_writes_data
*data
= user
;
1509 data
->writes
= pet_expr_writes(expr
, data
->id
);
1510 if (data
->writes
< 0 || data
->writes
)
1516 /* Is there any write access in "tree" that accesses "id"?
1518 int pet_tree_writes(__isl_keep pet_tree
*tree
, __isl_keep isl_id
*id
)
1520 struct pet_tree_writes_data data
;
1524 if (pet_tree_foreach_expr(tree
, &check_write
, &data
) < 0 &&
1531 /* Wrapper around pet_expr_update_domain
1532 * for use as a pet_tree_map_expr callback.
1534 static __isl_give pet_expr
*update_domain(__isl_take pet_expr
*expr
, void *user
)
1536 isl_multi_pw_aff
*update
= user
;
1538 return pet_expr_update_domain(expr
, isl_multi_pw_aff_copy(update
));
1541 /* Modify all access relations in "tree" by precomposing them with
1542 * the given iteration space transformation.
1544 __isl_give pet_tree
*pet_tree_update_domain(__isl_take pet_tree
*tree
,
1545 __isl_take isl_multi_pw_aff
*update
)
1547 tree
= pet_tree_map_expr(tree
, &update_domain
, update
);
1548 isl_multi_pw_aff_free(update
);
1552 /* Does "tree" contain a continue or break node (not contained in any loop
1553 * subtree of "tree")?
1555 int pet_tree_has_continue_or_break(__isl_keep pet_tree
*tree
)
1563 switch (tree
->type
) {
1564 case pet_tree_error
:
1566 case pet_tree_continue
:
1567 case pet_tree_break
:
1570 case pet_tree_decl_init
:
1572 case pet_tree_return
:
1574 case pet_tree_while
:
1575 case pet_tree_infinite_loop
:
1577 case pet_tree_block
:
1578 for (i
= 0; i
< tree
->u
.b
.n
; ++i
) {
1580 pet_tree_has_continue_or_break(tree
->u
.b
.child
[i
]);
1581 if (found
< 0 || found
)
1586 return pet_tree_has_continue_or_break(tree
->u
.i
.then_body
);
1587 case pet_tree_if_else
:
1588 found
= pet_tree_has_continue_or_break(tree
->u
.i
.then_body
);
1589 if (found
< 0 || found
)
1591 return pet_tree_has_continue_or_break(tree
->u
.i
.else_body
);
1595 static void print_indent(int indent
)
1597 fprintf(stderr
, "%*s", indent
, "");
1600 void pet_tree_dump_with_indent(__isl_keep pet_tree
*tree
, int indent
)
1607 print_indent(indent
);
1608 fprintf(stderr
, "%s\n", pet_tree_type_str(tree
->type
));
1609 print_indent(indent
);
1610 fprintf(stderr
, "line: %d\n", pet_loc_get_line(tree
->loc
));
1611 print_indent(indent
);
1612 fprintf(stderr
, "start: %d\n", pet_loc_get_start(tree
->loc
));
1613 print_indent(indent
);
1614 fprintf(stderr
, "end: %d\n", pet_loc_get_end(tree
->loc
));
1616 print_indent(indent
);
1617 fprintf(stderr
, "label: ");
1618 isl_id_dump(tree
->label
);
1620 switch (tree
->type
) {
1621 case pet_tree_block
:
1622 print_indent(indent
);
1623 fprintf(stderr
, "block: %d\n", tree
->u
.b
.block
);
1624 for (i
= 0; i
< tree
->u
.b
.n
; ++i
)
1625 pet_tree_dump_with_indent(tree
->u
.b
.child
[i
],
1629 pet_expr_dump_with_indent(tree
->u
.e
.expr
, indent
);
1631 case pet_tree_return
:
1632 print_indent(indent
);
1633 fprintf(stderr
, "return:\n");
1634 pet_expr_dump_with_indent(tree
->u
.e
.expr
, indent
);
1636 case pet_tree_break
:
1637 case pet_tree_continue
:
1640 case pet_tree_decl_init
:
1641 print_indent(indent
);
1642 fprintf(stderr
, "var:\n");
1643 pet_expr_dump_with_indent(tree
->u
.d
.var
, indent
+ 2);
1644 if (tree
->type
!= pet_tree_decl_init
)
1646 print_indent(indent
);
1647 fprintf(stderr
, "init:\n");
1648 pet_expr_dump_with_indent(tree
->u
.d
.init
, indent
+ 2);
1651 case pet_tree_if_else
:
1652 print_indent(indent
);
1653 fprintf(stderr
, "condition:\n");
1654 pet_expr_dump_with_indent(tree
->u
.i
.cond
, indent
+ 2);
1655 print_indent(indent
);
1656 fprintf(stderr
, "then:\n");
1657 pet_tree_dump_with_indent(tree
->u
.i
.then_body
, indent
+ 2);
1658 if (tree
->type
!= pet_tree_if_else
)
1660 print_indent(indent
);
1661 fprintf(stderr
, "else:\n");
1662 pet_tree_dump_with_indent(tree
->u
.i
.else_body
, indent
+ 2);
1665 print_indent(indent
);
1666 fprintf(stderr
, "declared: %d\n", tree
->u
.l
.declared
);
1667 print_indent(indent
);
1668 fprintf(stderr
, "var:\n");
1669 pet_expr_dump_with_indent(tree
->u
.l
.iv
, indent
+ 2);
1670 print_indent(indent
);
1671 fprintf(stderr
, "init:\n");
1672 pet_expr_dump_with_indent(tree
->u
.l
.init
, indent
+ 2);
1673 print_indent(indent
);
1674 fprintf(stderr
, "inc:\n");
1675 pet_expr_dump_with_indent(tree
->u
.l
.inc
, indent
+ 2);
1676 case pet_tree_while
:
1677 print_indent(indent
);
1678 fprintf(stderr
, "condition:\n");
1679 pet_expr_dump_with_indent(tree
->u
.l
.cond
, indent
+ 2);
1680 case pet_tree_infinite_loop
:
1681 print_indent(indent
);
1682 fprintf(stderr
, "body:\n");
1683 pet_tree_dump_with_indent(tree
->u
.l
.body
, indent
+ 2);
1685 case pet_tree_error
:
1686 print_indent(indent
);
1687 fprintf(stderr
, "ERROR\n");
1692 void pet_tree_dump(__isl_keep pet_tree
*tree
)
1694 pet_tree_dump_with_indent(tree
, 0);