PetScan::get_array_size: take isl_id representing array as input
[pet.git] / tree.c
blob00838afc20f68fddec9e8b008159f409cabb6337
1 /*
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
7 * are met:
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
32 * Leiden University.
35 #include <string.h>
37 #include "expr.h"
38 #include "loc.h"
39 #include "tree.h"
41 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
43 static const char *type_str[] = {
44 [pet_tree_block] = "block",
45 [pet_tree_break] = "break",
46 [pet_tree_continue] = "continue",
47 [pet_tree_decl] = "declaration",
48 [pet_tree_decl_init] = "declaration-init",
49 [pet_tree_expr] = "expression",
50 [pet_tree_for] = "for",
51 [pet_tree_infinite_loop] = "infinite-loop",
52 [pet_tree_if] = "if",
53 [pet_tree_if_else] = "if-else",
54 [pet_tree_while] = "while",
57 /* Return a textual representation of the type "type".
59 const char *pet_tree_type_str(enum pet_tree_type type)
61 if (type < 0)
62 return "error";
63 return type_str[type];
66 /* Extract a type from its textual representation "str".
68 enum pet_tree_type pet_tree_str_type(const char *str)
70 int i;
72 for (i = 0; i < ARRAY_SIZE(type_str); ++i)
73 if (!strcmp(type_str[i], str))
74 return i;
76 return pet_tree_error;
79 /* Return a new pet_tree of the given type.
81 * The location is initializaed to pet_loc_dummy.
83 __isl_give pet_tree *pet_tree_alloc(isl_ctx *ctx, enum pet_tree_type type)
85 pet_tree *tree;
87 tree = isl_calloc_type(ctx, struct pet_tree);
88 if (!tree)
89 return NULL;
91 tree->ctx = ctx;
92 isl_ctx_ref(ctx);
93 tree->ref = 1;
94 tree->type = type;
95 tree->loc = &pet_loc_dummy;
97 return tree;
100 /* Return a new pet_tree representing the declaration (without initialization)
101 * of the variable "var".
103 __isl_give pet_tree *pet_tree_new_decl(__isl_take pet_expr *var)
105 isl_ctx *ctx;
106 pet_tree *tree;
108 if (!var)
109 return NULL;
110 ctx = pet_expr_get_ctx(var);
111 tree = pet_tree_alloc(ctx, pet_tree_decl);
112 if (!tree)
113 goto error;
115 tree->u.d.var = var;
117 return tree;
118 error:
119 pet_expr_free(var);
120 return NULL;
123 /* Return a new pet_tree representing the declaration of the variable "var"
124 * with initial value "init".
126 __isl_give pet_tree *pet_tree_new_decl_init(__isl_take pet_expr *var,
127 __isl_take pet_expr *init)
129 isl_ctx *ctx;
130 pet_tree *tree;
132 if (!var || !init)
133 goto error;
134 ctx = pet_expr_get_ctx(var);
135 tree = pet_tree_alloc(ctx, pet_tree_decl_init);
136 if (!tree)
137 goto error;
139 tree->u.d.var = var;
140 tree->u.d.init = init;
142 return tree;
143 error:
144 pet_expr_free(var);
145 pet_expr_free(init);
146 return NULL;
149 /* Return a new pet_tree representing the expression "expr".
151 __isl_give pet_tree *pet_tree_new_expr(__isl_take pet_expr *expr)
153 isl_ctx *ctx;
154 pet_tree *tree;
156 if (!expr)
157 return NULL;
158 ctx = pet_expr_get_ctx(expr);
159 tree = pet_tree_alloc(ctx, pet_tree_expr);
160 if (!tree)
161 goto error;
163 tree->u.e.expr = expr;
165 return tree;
166 error:
167 pet_expr_free(expr);
168 return NULL;
171 /* Return a new pet_tree representing an intially empty sequence
172 * of trees with room for "n" trees.
173 * "block" indicates whether the sequence has its own scope.
175 __isl_give pet_tree *pet_tree_new_block(isl_ctx *ctx, int block, int n)
177 pet_tree *tree;
179 tree = pet_tree_alloc(ctx, pet_tree_block);
180 if (!tree)
181 return NULL;
182 tree->u.b.block = block;
183 tree->u.b.n = 0;
184 tree->u.b.max = n;
185 tree->u.b.child = isl_calloc_array(ctx, pet_tree *, n);
186 if (n && !tree->u.b.child)
187 return pet_tree_free(tree);
189 return tree;
192 /* Return a new pet_tree representing a break statement.
194 __isl_give pet_tree *pet_tree_new_break(isl_ctx *ctx)
196 return pet_tree_alloc(ctx, pet_tree_break);
199 /* Return a new pet_tree representing a continue statement.
201 __isl_give pet_tree *pet_tree_new_continue(isl_ctx *ctx)
203 return pet_tree_alloc(ctx, pet_tree_continue);
206 /* Return a new pet_tree representing a for loop
207 * with induction variable "iv", initial value for the induction
208 * variable "init", loop condition "cond", induction variable increment "inc"
209 * and loop body "body". "declared" indicates whether the induction variable
210 * is declared by the loop. "independent" is set if the for loop is marked
211 * independent.
213 * The location of the loop is initialized to that of the body.
215 __isl_give pet_tree *pet_tree_new_for(int independent, int declared,
216 __isl_take pet_expr *iv, __isl_take pet_expr *init,
217 __isl_take pet_expr *cond, __isl_take pet_expr *inc,
218 __isl_take pet_tree *body)
220 isl_ctx *ctx;
221 pet_tree *tree;
223 if (!iv || !init || !cond || !inc || !body)
224 goto error;
225 ctx = pet_tree_get_ctx(body);
226 tree = pet_tree_alloc(ctx, pet_tree_for);
227 if (!tree)
228 goto error;
230 tree->u.l.independent = independent;
231 tree->u.l.declared = declared;
232 tree->u.l.iv = iv;
233 tree->u.l.init = init;
234 tree->u.l.cond = cond;
235 tree->u.l.inc = inc;
236 tree->u.l.body = body;
237 tree->loc = pet_tree_get_loc(body);
238 if (!tree->loc)
239 return pet_tree_free(tree);
241 return tree;
242 error:
243 pet_expr_free(iv);
244 pet_expr_free(init);
245 pet_expr_free(cond);
246 pet_expr_free(inc);
247 pet_tree_free(body);
248 return NULL;
251 /* Return a new pet_tree representing a while loop
252 * with loop condition "cond" and loop body "body".
254 * The location of the loop is initialized to that of the body.
256 __isl_give pet_tree *pet_tree_new_while(__isl_take pet_expr *cond,
257 __isl_take pet_tree *body)
259 isl_ctx *ctx;
260 pet_tree *tree;
262 if (!cond || !body)
263 goto error;
264 ctx = pet_tree_get_ctx(body);
265 tree = pet_tree_alloc(ctx, pet_tree_while);
266 if (!tree)
267 goto error;
269 tree->u.l.cond = cond;
270 tree->u.l.body = body;
271 tree->loc = pet_tree_get_loc(body);
272 if (!tree->loc)
273 return pet_tree_free(tree);
275 return tree;
276 error:
277 pet_expr_free(cond);
278 pet_tree_free(body);
279 return NULL;
282 /* Return a new pet_tree representing an infinite loop
283 * with loop body "body".
285 * The location of the loop is initialized to that of the body.
287 __isl_give pet_tree *pet_tree_new_infinite_loop(__isl_take pet_tree *body)
289 isl_ctx *ctx;
290 pet_tree *tree;
292 if (!body)
293 return NULL;
294 ctx = pet_tree_get_ctx(body);
295 tree = pet_tree_alloc(ctx, pet_tree_infinite_loop);
296 if (!tree)
297 return pet_tree_free(body);
299 tree->u.l.body = body;
300 tree->loc = pet_tree_get_loc(body);
301 if (!tree->loc)
302 return pet_tree_free(tree);
304 return tree;
307 /* Return a new pet_tree representing an if statement
308 * with condition "cond" and then branch "then_body".
310 * The location of the if statement is initialized to that of the body.
312 __isl_give pet_tree *pet_tree_new_if(__isl_take pet_expr *cond,
313 __isl_take pet_tree *then_body)
315 isl_ctx *ctx;
316 pet_tree *tree;
318 if (!cond || !then_body)
319 goto error;
320 ctx = pet_tree_get_ctx(then_body);
321 tree = pet_tree_alloc(ctx, pet_tree_if);
322 if (!tree)
323 goto error;
325 tree->u.i.cond = cond;
326 tree->u.i.then_body = then_body;
327 tree->loc = pet_tree_get_loc(then_body);
328 if (!tree->loc)
329 return pet_tree_free(tree);
331 return tree;
332 error:
333 pet_expr_free(cond);
334 pet_tree_free(then_body);
335 return NULL;
338 /* Return a new pet_tree representing an if statement
339 * with condition "cond", then branch "then_body" and else branch "else_body".
341 * The location of the if statement is initialized to cover
342 * those of the bodies.
344 __isl_give pet_tree *pet_tree_new_if_else(__isl_take pet_expr *cond,
345 __isl_take pet_tree *then_body, __isl_take pet_tree *else_body)
347 isl_ctx *ctx;
348 pet_tree *tree;
350 if (!cond || !then_body || !else_body)
351 goto error;
352 ctx = pet_tree_get_ctx(then_body);
353 tree = pet_tree_alloc(ctx, pet_tree_if_else);
354 if (!tree)
355 goto error;
357 tree->u.i.cond = cond;
358 tree->u.i.then_body = then_body;
359 tree->u.i.else_body = else_body;
360 tree->loc = pet_tree_get_loc(then_body);
361 tree->loc = pet_loc_update_start_end_from_loc(tree->loc,
362 else_body->loc);
363 if (!tree->loc)
364 return pet_tree_free(tree);
366 return tree;
367 error:
368 pet_expr_free(cond);
369 pet_tree_free(then_body);
370 pet_tree_free(else_body);
371 return NULL;
374 /* Return an independent duplicate of "tree".
376 static __isl_give pet_tree *pet_tree_dup(__isl_keep pet_tree *tree)
378 int i;
379 pet_tree *dup;
381 if (!tree)
382 return NULL;
384 switch (tree->type) {
385 case pet_tree_error:
386 return NULL;
387 case pet_tree_block:
388 dup = pet_tree_new_block(tree->ctx, tree->u.b.block,
389 tree->u.b.n);
390 for (i = 0; i < tree->u.b.n; ++i)
391 dup = pet_tree_block_add_child(dup,
392 pet_tree_copy(tree->u.b.child[i]));
393 break;
394 case pet_tree_break:
395 dup = pet_tree_new_break(tree->ctx);
396 break;
397 case pet_tree_continue:
398 dup = pet_tree_new_continue(tree->ctx);
399 break;
400 case pet_tree_decl:
401 dup = pet_tree_new_decl(pet_expr_copy(tree->u.d.var));
402 break;
403 case pet_tree_decl_init:
404 dup = pet_tree_new_decl_init(pet_expr_copy(tree->u.d.var),
405 pet_expr_copy(tree->u.d.init));
406 break;
407 case pet_tree_expr:
408 dup = pet_tree_new_expr(pet_expr_copy(tree->u.e.expr));
409 break;
410 case pet_tree_for:
411 dup = pet_tree_new_for(tree->u.l.independent,
412 tree->u.l.declared,
413 pet_expr_copy(tree->u.l.iv), pet_expr_copy(tree->u.l.init),
414 pet_expr_copy(tree->u.l.cond), pet_expr_copy(tree->u.l.inc),
415 pet_tree_copy(tree->u.l.body));
416 break;
417 case pet_tree_while:
418 dup = pet_tree_new_while(pet_expr_copy(tree->u.l.cond),
419 pet_tree_copy(tree->u.l.body));
420 break;
421 case pet_tree_infinite_loop:
422 dup = pet_tree_new_infinite_loop(pet_tree_copy(tree->u.l.body));
423 break;
424 case pet_tree_if:
425 dup = pet_tree_new_if(pet_expr_copy(tree->u.i.cond),
426 pet_tree_copy(tree->u.i.then_body));
427 break;
428 case pet_tree_if_else:
429 dup = pet_tree_new_if_else(pet_expr_copy(tree->u.i.cond),
430 pet_tree_copy(tree->u.i.then_body),
431 pet_tree_copy(tree->u.i.else_body));
432 break;
435 if (!dup)
436 return NULL;
437 pet_loc_free(dup->loc);
438 dup->loc = pet_loc_copy(tree->loc);
439 if (!dup->loc)
440 return pet_tree_free(dup);
441 if (tree->label) {
442 dup->label = isl_id_copy(tree->label);
443 if (!dup->label)
444 return pet_tree_free(dup);
447 return dup;
450 /* Return a pet_tree that is equal to "tree" and that has only one reference.
452 __isl_give pet_tree *pet_tree_cow(__isl_take pet_tree *tree)
454 if (!tree)
455 return NULL;
457 if (tree->ref == 1)
458 return tree;
459 tree->ref--;
460 return pet_tree_dup(tree);
463 /* Return an extra reference to "tree".
465 __isl_give pet_tree *pet_tree_copy(__isl_keep pet_tree *tree)
467 if (!tree)
468 return NULL;
470 tree->ref++;
471 return tree;
474 /* Free a reference to "tree".
476 __isl_null pet_tree *pet_tree_free(__isl_take pet_tree *tree)
478 int i;
480 if (!tree)
481 return NULL;
482 if (--tree->ref > 0)
483 return NULL;
485 pet_loc_free(tree->loc);
486 isl_id_free(tree->label);
488 switch (tree->type) {
489 case pet_tree_error:
490 break;
491 case pet_tree_block:
492 for (i = 0; i < tree->u.b.n; ++i)
493 pet_tree_free(tree->u.b.child[i]);
494 free(tree->u.b.child);
495 break;
496 case pet_tree_break:
497 case pet_tree_continue:
498 break;
499 case pet_tree_decl_init:
500 pet_expr_free(tree->u.d.init);
501 case pet_tree_decl:
502 pet_expr_free(tree->u.d.var);
503 break;
504 case pet_tree_expr:
505 pet_expr_free(tree->u.e.expr);
506 break;
507 case pet_tree_for:
508 pet_expr_free(tree->u.l.iv);
509 pet_expr_free(tree->u.l.init);
510 pet_expr_free(tree->u.l.inc);
511 case pet_tree_while:
512 pet_expr_free(tree->u.l.cond);
513 case pet_tree_infinite_loop:
514 pet_tree_free(tree->u.l.body);
515 break;
516 case pet_tree_if_else:
517 pet_tree_free(tree->u.i.else_body);
518 case pet_tree_if:
519 pet_expr_free(tree->u.i.cond);
520 pet_tree_free(tree->u.i.then_body);
521 break;
524 isl_ctx_deref(tree->ctx);
525 free(tree);
526 return NULL;
529 /* Return the isl_ctx in which "tree" was created.
531 isl_ctx *pet_tree_get_ctx(__isl_keep pet_tree *tree)
533 return tree ? tree->ctx : NULL;
536 /* Return the location of "tree".
538 __isl_give pet_loc *pet_tree_get_loc(__isl_keep pet_tree *tree)
540 return tree ? pet_loc_copy(tree->loc) : NULL;
543 /* Return the type of "tree".
545 enum pet_tree_type pet_tree_get_type(__isl_keep pet_tree *tree)
547 if (!tree)
548 return pet_tree_error;
550 return tree->type;
553 /* Replace the location of "tree" by "loc".
555 __isl_give pet_tree *pet_tree_set_loc(__isl_take pet_tree *tree,
556 __isl_take pet_loc *loc)
558 tree = pet_tree_cow(tree);
559 if (!tree || !loc)
560 goto error;
562 pet_loc_free(tree->loc);
563 tree->loc = loc;
565 return tree;
566 error:
567 pet_loc_free(loc);
568 pet_tree_free(tree);
569 return NULL;
572 /* Replace the label of "tree" by "label".
574 __isl_give pet_tree *pet_tree_set_label(__isl_take pet_tree *tree,
575 __isl_take isl_id *label)
577 tree = pet_tree_cow(tree);
578 if (!tree || !label)
579 goto error;
581 isl_id_free(tree->label);
582 tree->label = label;
584 return tree;
585 error:
586 isl_id_free(label);
587 return pet_tree_free(tree);
590 /* Given an expression tree "tree", return the associated expression.
592 __isl_give pet_expr *pet_tree_expr_get_expr(__isl_keep pet_tree *tree)
594 if (!tree)
595 return NULL;
596 if (pet_tree_get_type(tree) != pet_tree_expr)
597 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
598 "not an expression tree", return NULL);
600 return pet_expr_copy(tree->u.e.expr);
603 /* Given a block tree "tree", return the number of children in the sequence.
605 int pet_tree_block_n_child(__isl_keep pet_tree *tree)
607 if (!tree)
608 return -1;
609 if (pet_tree_get_type(tree) != pet_tree_block)
610 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
611 "not a block tree", return -1);
613 return tree->u.b.n;
616 /* Add "child" to the sequence of trees represented by "block".
618 * Update the location of "block" to include that of "child".
620 __isl_give pet_tree *pet_tree_block_add_child(__isl_take pet_tree *block,
621 __isl_take pet_tree *child)
623 block = pet_tree_cow(block);
624 if (!block || !child)
625 goto error;
626 if (block->type != pet_tree_block)
627 isl_die(pet_tree_get_ctx(block), isl_error_invalid,
628 "not a block tree", goto error);
629 if (block->u.b.n >= block->u.b.max)
630 isl_die(pet_tree_get_ctx(block), isl_error_invalid,
631 "out of space in block", goto error);
633 block->loc = pet_loc_update_start_end_from_loc(block->loc, child->loc);
634 block->u.b.child[block->u.b.n++] = child;
636 if (!block->loc)
637 return pet_tree_free(block);
639 return block;
640 error:
641 pet_tree_free(block);
642 pet_tree_free(child);
643 return NULL;
646 /* Does the block tree "tree" have its own scope?
648 int pet_tree_block_get_block(__isl_keep pet_tree *tree)
650 if (!tree)
651 return -1;
652 if (pet_tree_get_type(tree) != pet_tree_block)
653 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
654 "not a block tree", return -1);
656 return tree->u.b.block;
659 /* Set the block property (whether or not the block tree has its own scope)
660 * of "tree" to "is_block".
662 __isl_give pet_tree *pet_tree_block_set_block(__isl_take pet_tree *tree,
663 int is_block)
665 if (!tree)
666 return NULL;
667 if (tree->type != pet_tree_block)
668 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
669 "not a block tree", return pet_tree_free(tree));
670 if (tree->u.b.block == is_block)
671 return tree;
672 tree = pet_tree_cow(tree);
673 if (!tree)
674 return NULL;
675 tree->u.b.block = is_block;
676 return tree;
679 /* Given a block tree "tree", return the child at position "pos".
681 __isl_give pet_tree *pet_tree_block_get_child(__isl_keep pet_tree *tree,
682 int pos)
684 if (!tree)
685 return NULL;
686 if (pet_tree_get_type(tree) != pet_tree_block)
687 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
688 "not a block tree", return NULL);
689 if (pos < 0 || pos >= tree->u.b.n)
690 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
691 "position out of bounds", return NULL);
693 return pet_tree_copy(tree->u.b.child[pos]);
696 /* Does "tree" represent a declaration (with or without initialization)?
698 int pet_tree_is_decl(__isl_keep pet_tree *tree)
700 if (!tree)
701 return -1;
703 switch (pet_tree_get_type(tree)) {
704 case pet_tree_decl:
705 case pet_tree_decl_init:
706 return 1;
707 default:
708 return 0;
712 /* Given a declaration tree "tree", return the variable that is being
713 * declared.
715 __isl_give pet_expr *pet_tree_decl_get_var(__isl_keep pet_tree *tree)
717 if (!tree)
718 return NULL;
719 if (!pet_tree_is_decl(tree))
720 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
721 "not a decl tree", return NULL);
723 return pet_expr_copy(tree->u.d.var);
726 /* Given a declaration tree with initialization "tree",
727 * return the initial value of the declared variable.
729 __isl_give pet_expr *pet_tree_decl_get_init(__isl_keep pet_tree *tree)
731 if (!tree)
732 return NULL;
733 if (pet_tree_get_type(tree) != pet_tree_decl_init)
734 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
735 "not a decl_init tree", return NULL);
737 return pet_expr_copy(tree->u.d.init);
740 /* Given an if tree "tree", return the if condition.
742 __isl_give pet_expr *pet_tree_if_get_cond(__isl_keep pet_tree *tree)
744 enum pet_tree_type type;
746 if (!tree)
747 return NULL;
748 type = pet_tree_get_type(tree);
749 if (type != pet_tree_if && type != pet_tree_if_else)
750 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
751 "not an if tree", return NULL);
753 return pet_expr_copy(tree->u.i.cond);
756 /* Given an if tree "tree", return the body of the then branch.
758 __isl_give pet_tree *pet_tree_if_get_then(__isl_keep pet_tree *tree)
760 enum pet_tree_type type;
762 if (!tree)
763 return NULL;
764 type = pet_tree_get_type(tree);
765 if (type != pet_tree_if && type != pet_tree_if_else)
766 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
767 "not an if tree", return NULL);
769 return pet_tree_copy(tree->u.i.then_body);
772 /* Given an if tree with an else branch "tree",
773 * return the body of that else branch.
775 __isl_give pet_tree *pet_tree_if_get_else(__isl_keep pet_tree *tree)
777 if (!tree)
778 return NULL;
779 if (pet_tree_get_type(tree) != pet_tree_if_else)
780 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
781 "not an if tree with an else branch", return NULL);
783 return pet_tree_copy(tree->u.i.else_body);
786 /* Does "tree" represent some type of loop?
788 int pet_tree_is_loop(__isl_keep pet_tree *tree)
790 if (!tree)
791 return -1;
793 switch (pet_tree_get_type(tree)) {
794 case pet_tree_for:
795 case pet_tree_infinite_loop:
796 case pet_tree_while:
797 return 1;
798 default:
799 return 0;
803 /* Given a for loop "tree", return the induction variable.
805 __isl_give pet_expr *pet_tree_loop_get_var(__isl_keep pet_tree *tree)
807 if (!tree)
808 return NULL;
809 if (pet_tree_get_type(tree) != pet_tree_for)
810 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
811 "not a for tree", return NULL);
813 return pet_expr_copy(tree->u.l.iv);
816 /* Given a for loop "tree", return the initial value of the induction variable.
818 __isl_give pet_expr *pet_tree_loop_get_init(__isl_keep pet_tree *tree)
820 if (!tree)
821 return NULL;
822 if (pet_tree_get_type(tree) != pet_tree_for)
823 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
824 "not a for tree", return NULL);
826 return pet_expr_copy(tree->u.l.init);
829 /* Given a loop "tree", return the loop condition.
831 * For an infinite loop, the loop condition always holds,
832 * so we simply return "1".
834 __isl_give pet_expr *pet_tree_loop_get_cond(__isl_keep pet_tree *tree)
836 enum pet_tree_type type;
838 if (!tree)
839 return NULL;
840 type = pet_tree_get_type(tree);
841 if (type == pet_tree_infinite_loop)
842 return pet_expr_new_int(isl_val_one(pet_tree_get_ctx(tree)));
843 if (type != pet_tree_for && type != pet_tree_while)
844 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
845 "not a for or while tree", return NULL);
847 return pet_expr_copy(tree->u.l.cond);
850 /* Given a for loop "tree", return the increment of the induction variable.
852 __isl_give pet_expr *pet_tree_loop_get_inc(__isl_keep pet_tree *tree)
854 if (!tree)
855 return NULL;
856 if (pet_tree_get_type(tree) != pet_tree_for)
857 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
858 "not a for tree", return NULL);
860 return pet_expr_copy(tree->u.l.inc);
863 /* Given a loop tree "tree", return the body.
865 __isl_give pet_tree *pet_tree_loop_get_body(__isl_keep pet_tree *tree)
867 if (!tree)
868 return NULL;
870 if (!pet_tree_is_loop(tree))
871 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
872 "not a loop tree", return NULL);
874 return pet_tree_copy(tree->u.l.body);
877 /* Call "fn" on each node of "tree", including "tree" itself.
879 * Return 0 on success and -1 on error, where "fn" returning a negative
880 * value is treated as an error.
882 int pet_tree_foreach_sub_tree(__isl_keep pet_tree *tree,
883 int (*fn)(__isl_keep pet_tree *tree, void *user), void *user)
885 int i;
887 if (!tree)
888 return -1;
890 if (fn(tree, user) < 0)
891 return -1;
893 switch (tree->type) {
894 case pet_tree_error:
895 return -1;
896 case pet_tree_block:
897 for (i = 0; i < tree->u.b.n; ++i)
898 if (pet_tree_foreach_sub_tree(tree->u.b.child[i],
899 fn, user) < 0)
900 return -1;
901 break;
902 case pet_tree_break:
903 case pet_tree_continue:
904 case pet_tree_decl:
905 case pet_tree_decl_init:
906 case pet_tree_expr:
907 break;
908 case pet_tree_if:
909 if (pet_tree_foreach_sub_tree(tree->u.i.then_body,
910 fn, user) < 0)
911 return -1;
912 break;
913 case pet_tree_if_else:
914 if (pet_tree_foreach_sub_tree(tree->u.i.then_body,
915 fn, user) < 0)
916 return -1;
917 if (pet_tree_foreach_sub_tree(tree->u.i.else_body,
918 fn, user) < 0)
919 return -1;
920 break;
921 case pet_tree_while:
922 case pet_tree_for:
923 case pet_tree_infinite_loop:
924 if (pet_tree_foreach_sub_tree(tree->u.l.body, fn, user) < 0)
925 return -1;
926 break;
929 return 0;
932 /* Intermediate data structure for foreach_expr.
934 * "fn" is the function that needs to be called on each expression.
935 * "user" is the user argument to be passed to "fn".
937 struct pet_tree_foreach_expr_data {
938 int (*fn)(__isl_keep pet_expr *expr, void *user);
939 void *user;
942 /* Call data->fn on each expression in the "tree" object.
943 * This function is used as a callback to pet_tree_foreach_sub_tree
944 * to implement pet_tree_foreach_expr.
946 * Return 0 on success and -1 on error, where data->fn returning a negative
947 * value is treated as an error.
949 static int foreach_expr(__isl_keep pet_tree *tree, void *user)
951 struct pet_tree_foreach_expr_data *data = user;
953 if (!tree)
954 return -1;
956 switch (tree->type) {
957 case pet_tree_error:
958 return -1;
959 case pet_tree_block:
960 case pet_tree_break:
961 case pet_tree_continue:
962 case pet_tree_infinite_loop:
963 break;
964 case pet_tree_decl:
965 if (data->fn(tree->u.d.var, data->user) < 0)
966 return -1;
967 break;
968 case pet_tree_decl_init:
969 if (data->fn(tree->u.d.var, data->user) < 0)
970 return -1;
971 if (data->fn(tree->u.d.init, data->user) < 0)
972 return -1;
973 break;
974 case pet_tree_expr:
975 if (data->fn(tree->u.e.expr, data->user) < 0)
976 return -1;
977 break;
978 case pet_tree_if:
979 if (data->fn(tree->u.i.cond, data->user) < 0)
980 return -1;
981 break;
982 case pet_tree_if_else:
983 if (data->fn(tree->u.i.cond, data->user) < 0)
984 return -1;
985 break;
986 case pet_tree_while:
987 if (data->fn(tree->u.l.cond, data->user) < 0)
988 return -1;
989 break;
990 case pet_tree_for:
991 if (data->fn(tree->u.l.iv, data->user) < 0)
992 return -1;
993 if (data->fn(tree->u.l.init, data->user) < 0)
994 return -1;
995 if (data->fn(tree->u.l.cond, data->user) < 0)
996 return -1;
997 if (data->fn(tree->u.l.inc, data->user) < 0)
998 return -1;
999 break;
1002 return 0;
1005 /* Call "fn" on each top-level expression in the nodes of "tree"
1007 * Return 0 on success and -1 on error, where "fn" returning a negative
1008 * value is treated as an error.
1010 * We run over all nodes in "tree" and call "fn"
1011 * on each expression in those nodes.
1013 int pet_tree_foreach_expr(__isl_keep pet_tree *tree,
1014 int (*fn)(__isl_keep pet_expr *expr, void *user), void *user)
1016 struct pet_tree_foreach_expr_data data = { fn, user };
1018 return pet_tree_foreach_sub_tree(tree, &foreach_expr, &data);
1021 /* Intermediate data structure for foreach_access_expr.
1023 * "fn" is the function that needs to be called on each access subexpression.
1024 * "user" is the user argument to be passed to "fn".
1026 struct pet_tree_foreach_access_expr_data {
1027 int (*fn)(__isl_keep pet_expr *expr, void *user);
1028 void *user;
1031 /* Call data->fn on each access subexpression of "expr".
1032 * This function is used as a callback to pet_tree_foreach_expr
1033 * to implement pet_tree_foreach_access_expr.
1035 * Return 0 on success and -1 on error, where data->fn returning a negative
1036 * value is treated as an error.
1038 static int foreach_access_expr(__isl_keep pet_expr *expr, void *user)
1040 struct pet_tree_foreach_access_expr_data *data = user;
1042 return pet_expr_foreach_access_expr(expr, data->fn, data->user);
1045 /* Call "fn" on each access subexpression in the nodes of "tree"
1047 * Return 0 on success and -1 on error, where "fn" returning a negative
1048 * value is treated as an error.
1050 * We run over all expressions in the nodes of "tree" and call "fn"
1051 * on each access subexpression of those expressions.
1053 int pet_tree_foreach_access_expr(__isl_keep pet_tree *tree,
1054 int (*fn)(__isl_keep pet_expr *expr, void *user), void *user)
1056 struct pet_tree_foreach_access_expr_data data = { fn, user };
1058 return pet_tree_foreach_expr(tree, &foreach_access_expr, &data);
1061 /* Modify all top-level expressions in the nodes of "tree"
1062 * by calling "fn" on them.
1064 __isl_give pet_tree *pet_tree_map_expr(__isl_take pet_tree *tree,
1065 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1066 void *user)
1068 int i;
1070 tree = pet_tree_cow(tree);
1071 if (!tree)
1072 return NULL;
1074 switch (tree->type) {
1075 case pet_tree_error:
1076 return pet_tree_free(tree);
1077 case pet_tree_block:
1078 for (i = 0; i < tree->u.b.n; ++i) {
1079 tree->u.b.child[i] =
1080 pet_tree_map_expr(tree->u.b.child[i], fn, user);
1081 if (!tree->u.b.child[i])
1082 return pet_tree_free(tree);
1084 break;
1085 case pet_tree_break:
1086 case pet_tree_continue:
1087 break;
1088 case pet_tree_decl:
1089 tree->u.d.var = fn(tree->u.d.var, user);
1090 if (!tree->u.d.var)
1091 return pet_tree_free(tree);
1092 break;
1093 case pet_tree_decl_init:
1094 tree->u.d.var = fn(tree->u.d.var, user);
1095 tree->u.d.init = fn(tree->u.d.init, user);
1096 if (!tree->u.d.var || !tree->u.d.init)
1097 return pet_tree_free(tree);
1098 break;
1099 case pet_tree_expr:
1100 tree->u.e.expr = fn(tree->u.e.expr, user);
1101 if (!tree->u.e.expr)
1102 return pet_tree_free(tree);
1103 break;
1104 case pet_tree_if:
1105 tree->u.i.cond = fn(tree->u.i.cond, user);
1106 tree->u.i.then_body =
1107 pet_tree_map_expr(tree->u.i.then_body, fn, user);
1108 if (!tree->u.i.cond || !tree->u.i.then_body)
1109 return pet_tree_free(tree);
1110 break;
1111 case pet_tree_if_else:
1112 tree->u.i.cond = fn(tree->u.i.cond, user);
1113 tree->u.i.then_body =
1114 pet_tree_map_expr(tree->u.i.then_body, fn, user);
1115 tree->u.i.else_body =
1116 pet_tree_map_expr(tree->u.i.else_body, fn, user);
1117 if (!tree->u.i.cond ||
1118 !tree->u.i.then_body || !tree->u.i.else_body)
1119 return pet_tree_free(tree);
1120 break;
1121 case pet_tree_while:
1122 tree->u.l.cond = fn(tree->u.l.cond, user);
1123 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1124 if (!tree->u.l.cond || !tree->u.l.body)
1125 return pet_tree_free(tree);
1126 break;
1127 case pet_tree_for:
1128 tree->u.l.iv = fn(tree->u.l.iv, user);
1129 tree->u.l.init = fn(tree->u.l.init, user);
1130 tree->u.l.cond = fn(tree->u.l.cond, user);
1131 tree->u.l.inc = fn(tree->u.l.inc, user);
1132 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1133 if (!tree->u.l.iv || !tree->u.l.init || !tree->u.l.cond ||
1134 !tree->u.l.inc || !tree->u.l.body)
1135 return pet_tree_free(tree);
1136 break;
1137 case pet_tree_infinite_loop:
1138 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1139 if (!tree->u.l.body)
1140 return pet_tree_free(tree);
1141 break;
1144 return tree;
1147 /* Intermediate data structure for map_expr.
1149 * "map" is a function that modifies subexpressions of a given type.
1150 * "fn" is the function that needs to be called on each of those subexpressions.
1151 * "user" is the user argument to be passed to "fn".
1153 struct pet_tree_map_expr_data {
1154 __isl_give pet_expr *(*map)(__isl_take pet_expr *expr,
1155 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr,
1156 void *user), void *user);
1157 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user);
1158 void *user;
1161 /* This function is called on each top-level expressions in the nodes
1162 * of a tree. Call data->map to modify subexpressions of the top-level
1163 * expression by calling data->fn on them.
1165 * This is a wrapper around data->map for use as a callback
1166 * to pet_tree_map_expr.
1168 static __isl_give pet_expr *map_expr(__isl_take pet_expr *expr,
1169 void *user)
1171 struct pet_tree_map_expr_data *data = user;
1173 return data->map(expr, data->fn, data->user);
1176 /* Modify all access subexpressions in the nodes of "tree"
1177 * by calling "fn" on them.
1179 * We run over all expressions in the nodes of "tree" and call "fn"
1180 * on each access subexpression of those expressions.
1182 __isl_give pet_tree *pet_tree_map_access_expr(__isl_take pet_tree *tree,
1183 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1184 void *user)
1186 struct pet_tree_map_expr_data data = { &pet_expr_map_access, fn, user };
1188 return pet_tree_map_expr(tree, &map_expr, &data);
1191 /* Modify all call subexpressions in the nodes of "tree"
1192 * by calling "fn" on them.
1194 * We run over all expressions in the nodes of "tree" and call "fn"
1195 * on each call subexpression of those expressions.
1197 __isl_give pet_tree *pet_tree_map_call_expr(__isl_take pet_tree *tree,
1198 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1199 void *user)
1201 struct pet_tree_map_expr_data data = { &pet_expr_map_call, fn, user };
1203 return pet_tree_map_expr(tree, &map_expr, &data);
1206 /* Wrapper around pet_expr_align_params
1207 * for use as a pet_tree_map_expr callback.
1209 static __isl_give pet_expr *align_params(__isl_take pet_expr *expr,
1210 void *user)
1212 isl_space *space = user;
1214 return pet_expr_align_params(expr, isl_space_copy(space));
1217 /* Add all parameters in "space" to all access relations and index expressions
1218 * in "tree".
1220 __isl_give pet_tree *pet_tree_align_params(__isl_take pet_tree *tree,
1221 __isl_take isl_space *space)
1223 tree = pet_tree_map_expr(tree, &align_params, space);
1224 isl_space_free(space);
1225 return tree;
1228 /* Wrapper around pet_expr_add_ref_ids
1229 * for use as a pet_tree_map_expr callback.
1231 static __isl_give pet_expr *add_ref_ids(__isl_take pet_expr *expr, void *user)
1233 int *n_ref = user;
1235 return pet_expr_add_ref_ids(expr, n_ref);
1238 /* Add reference identifiers to all access expressions in "tree".
1239 * "n_ref" points to an integer that contains the sequence number
1240 * of the next reference.
1242 __isl_give pet_tree *pet_tree_add_ref_ids(__isl_take pet_tree *tree,
1243 int *n_ref)
1245 return pet_tree_map_expr(tree, &add_ref_ids, n_ref);
1248 /* Wrapper around pet_expr_anonymize
1249 * for use as a pet_tree_map_expr callback.
1251 static __isl_give pet_expr *anonymize(__isl_take pet_expr *expr, void *user)
1253 return pet_expr_anonymize(expr);
1256 /* Reset the user pointer on all parameter and tuple ids in "tree".
1258 __isl_give pet_tree *pet_tree_anonymize(__isl_take pet_tree *tree)
1260 return pet_tree_map_expr(tree, &anonymize, NULL);
1263 /* Arguments to be passed to pet_expr_gist from the gist wrapper.
1265 struct pet_tree_gist_data {
1266 isl_set *domain;
1267 isl_union_map *value_bounds;
1270 /* Wrapper around pet_expr_gist for use as a pet_tree_map_expr callback.
1272 static __isl_give pet_expr *gist(__isl_take pet_expr *expr, void *user)
1274 struct pet_tree_gist_data *data = user;
1276 return pet_expr_gist(expr, data->domain, data->value_bounds);
1279 /* Compute the gist of all access relations and index expressions inside
1280 * "tree" based on the constraints on the parameters specified by "context"
1281 * and the constraints on the values of nested accesses specified
1282 * by "value_bounds".
1284 __isl_give pet_tree *pet_tree_gist(__isl_take pet_tree *tree,
1285 __isl_keep isl_set *context, __isl_keep isl_union_map *value_bounds)
1287 struct pet_tree_gist_data data = { context, value_bounds };
1289 return pet_tree_map_expr(tree, &gist, &data);
1292 /* Return 1 if the two pet_tree objects are equivalent.
1294 * We ignore the locations of the trees.
1296 int pet_tree_is_equal(__isl_keep pet_tree *tree1, __isl_keep pet_tree *tree2)
1298 int i;
1299 int equal;
1301 if (!tree1 || !tree2)
1302 return 0;
1304 if (tree1 == tree2)
1305 return 1;
1307 if (tree1->type != tree2->type)
1308 return 0;
1309 if (tree1->label != tree2->label)
1310 return 0;
1312 switch (tree1->type) {
1313 case pet_tree_error:
1314 return -1;
1315 case pet_tree_block:
1316 if (tree1->u.b.block != tree2->u.b.block)
1317 return 0;
1318 if (tree1->u.b.n != tree2->u.b.n)
1319 return 0;
1320 for (i = 0; i < tree1->u.b.n; ++i) {
1321 equal = pet_tree_is_equal(tree1->u.b.child[i],
1322 tree2->u.b.child[i]);
1323 if (equal < 0 || !equal)
1324 return equal;
1326 break;
1327 case pet_tree_break:
1328 case pet_tree_continue:
1329 break;
1330 case pet_tree_decl:
1331 return pet_expr_is_equal(tree1->u.d.var, tree2->u.d.var);
1332 case pet_tree_decl_init:
1333 equal = pet_expr_is_equal(tree1->u.d.var, tree2->u.d.var);
1334 if (equal < 0 || !equal)
1335 return equal;
1336 return pet_expr_is_equal(tree1->u.d.init, tree2->u.d.init);
1337 case pet_tree_expr:
1338 return pet_expr_is_equal(tree1->u.e.expr, tree2->u.e.expr);
1339 case pet_tree_for:
1340 if (tree1->u.l.declared != tree2->u.l.declared)
1341 return 0;
1342 equal = pet_expr_is_equal(tree1->u.l.iv, tree2->u.l.iv);
1343 if (equal < 0 || !equal)
1344 return equal;
1345 equal = pet_expr_is_equal(tree1->u.l.init, tree2->u.l.init);
1346 if (equal < 0 || !equal)
1347 return equal;
1348 equal = pet_expr_is_equal(tree1->u.l.cond, tree2->u.l.cond);
1349 if (equal < 0 || !equal)
1350 return equal;
1351 equal = pet_expr_is_equal(tree1->u.l.inc, tree2->u.l.inc);
1352 if (equal < 0 || !equal)
1353 return equal;
1354 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1355 case pet_tree_while:
1356 equal = pet_expr_is_equal(tree1->u.l.cond, tree2->u.l.cond);
1357 if (equal < 0 || !equal)
1358 return equal;
1359 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1360 case pet_tree_infinite_loop:
1361 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1362 case pet_tree_if:
1363 equal = pet_expr_is_equal(tree1->u.i.cond, tree2->u.i.cond);
1364 if (equal < 0 || !equal)
1365 return equal;
1366 return pet_tree_is_equal(tree1->u.i.then_body,
1367 tree2->u.i.then_body);
1368 case pet_tree_if_else:
1369 equal = pet_expr_is_equal(tree1->u.i.cond, tree2->u.i.cond);
1370 if (equal < 0 || !equal)
1371 return equal;
1372 equal = pet_tree_is_equal(tree1->u.i.then_body,
1373 tree2->u.i.then_body);
1374 if (equal < 0 || !equal)
1375 return equal;
1376 return pet_tree_is_equal(tree1->u.i.else_body,
1377 tree2->u.i.else_body);
1380 return 1;
1383 /* Is "tree" an expression tree that performs the operation "type"?
1385 static int pet_tree_is_op_of_type(__isl_keep pet_tree *tree,
1386 enum pet_op_type type)
1388 if (!tree)
1389 return 0;
1390 if (tree->type != pet_tree_expr)
1391 return 0;
1392 if (pet_expr_get_type(tree->u.e.expr) != pet_expr_op)
1393 return 0;
1394 return pet_expr_op_get_type(tree->u.e.expr) == type;
1397 /* Is "tree" an expression tree that performs a kill operation?
1399 int pet_tree_is_kill(__isl_keep pet_tree *tree)
1401 return pet_tree_is_op_of_type(tree, pet_op_kill);
1404 /* Is "tree" an expression tree that performs an assignment operation?
1406 int pet_tree_is_assign(__isl_keep pet_tree *tree)
1408 return pet_tree_is_op_of_type(tree, pet_op_assign);
1411 /* Is "tree" an expression tree that performs an assume operation?
1413 int pet_tree_is_assume(__isl_keep pet_tree *tree)
1415 return pet_tree_is_op_of_type(tree, pet_op_assume);
1418 /* Is "tree" an expression tree that performs an assume operation
1419 * such that the assumed expression is affine?
1421 int pet_tree_is_affine_assume(__isl_keep pet_tree *tree)
1423 if (!pet_tree_is_assume(tree))
1424 return 0;
1425 return pet_expr_is_affine(tree->u.e.expr->args[0]);
1428 /* Given a tree that represent an assume operation expression
1429 * with an access as argument (possibly an affine expression),
1430 * return the index expression of that access.
1432 __isl_give isl_multi_pw_aff *pet_tree_assume_get_index(
1433 __isl_keep pet_tree *tree)
1435 if (!tree)
1436 return NULL;
1437 if (!pet_tree_is_assume(tree))
1438 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
1439 "not an assume tree", return NULL);
1440 return pet_expr_access_get_index(tree->u.e.expr->args[0]);
1443 /* Internal data structure for pet_tree_writes.
1444 * "id" is the identifier that we are looking for.
1445 * "writes" is set if we have found the identifier being written to.
1447 struct pet_tree_writes_data {
1448 isl_id *id;
1449 int writes;
1452 /* Check if expr writes to data->id.
1453 * If so, set data->writes and abort the search.
1455 static int check_write(__isl_keep pet_expr *expr, void *user)
1457 struct pet_tree_writes_data *data = user;
1459 data->writes = pet_expr_writes(expr, data->id);
1460 if (data->writes < 0 || data->writes)
1461 return -1;
1463 return 0;
1466 /* Is there any write access in "tree" that accesses "id"?
1468 int pet_tree_writes(__isl_keep pet_tree *tree, __isl_keep isl_id *id)
1470 struct pet_tree_writes_data data;
1472 data.id = id;
1473 data.writes = 0;
1474 if (pet_tree_foreach_expr(tree, &check_write, &data) < 0 &&
1475 !data.writes)
1476 return -1;
1478 return data.writes;
1481 /* Wrapper around pet_expr_update_domain
1482 * for use as a pet_tree_map_expr callback.
1484 static __isl_give pet_expr *update_domain(__isl_take pet_expr *expr, void *user)
1486 isl_multi_pw_aff *update = user;
1488 return pet_expr_update_domain(expr, isl_multi_pw_aff_copy(update));
1491 /* Modify all access relations in "tree" by precomposing them with
1492 * the given iteration space transformation.
1494 __isl_give pet_tree *pet_tree_update_domain(__isl_take pet_tree *tree,
1495 __isl_take isl_multi_pw_aff *update)
1497 tree = pet_tree_map_expr(tree, &update_domain, update);
1498 isl_multi_pw_aff_free(update);
1499 return tree;
1502 /* Does "tree" contain a continue or break node (not contained in any loop
1503 * subtree of "tree")?
1505 int pet_tree_has_continue_or_break(__isl_keep pet_tree *tree)
1507 int i;
1508 int found;
1510 if (!tree)
1511 return -1;
1513 switch (tree->type) {
1514 case pet_tree_error:
1515 return -1;
1516 case pet_tree_continue:
1517 case pet_tree_break:
1518 return 1;
1519 case pet_tree_decl:
1520 case pet_tree_decl_init:
1521 case pet_tree_expr:
1522 case pet_tree_for:
1523 case pet_tree_while:
1524 case pet_tree_infinite_loop:
1525 return 0;
1526 case pet_tree_block:
1527 for (i = 0; i < tree->u.b.n; ++i) {
1528 found =
1529 pet_tree_has_continue_or_break(tree->u.b.child[i]);
1530 if (found < 0 || found)
1531 return found;
1533 return 0;
1534 case pet_tree_if:
1535 return pet_tree_has_continue_or_break(tree->u.i.then_body);
1536 case pet_tree_if_else:
1537 found = pet_tree_has_continue_or_break(tree->u.i.then_body);
1538 if (found < 0 || found)
1539 return found;
1540 return pet_tree_has_continue_or_break(tree->u.i.else_body);
1544 static void print_indent(int indent)
1546 fprintf(stderr, "%*s", indent, "");
1549 void pet_tree_dump_with_indent(__isl_keep pet_tree *tree, int indent)
1551 int i;
1553 if (!tree)
1554 return;
1556 print_indent(indent);
1557 fprintf(stderr, "%s\n", pet_tree_type_str(tree->type));
1558 print_indent(indent);
1559 fprintf(stderr, "line: %d\n", pet_loc_get_line(tree->loc));
1560 print_indent(indent);
1561 fprintf(stderr, "start: %d\n", pet_loc_get_start(tree->loc));
1562 print_indent(indent);
1563 fprintf(stderr, "end: %d\n", pet_loc_get_end(tree->loc));
1564 if (tree->label) {
1565 print_indent(indent);
1566 fprintf(stderr, "label: ");
1567 isl_id_dump(tree->label);
1569 switch (tree->type) {
1570 case pet_tree_block:
1571 print_indent(indent);
1572 fprintf(stderr, "block: %d\n", tree->u.b.block);
1573 for (i = 0; i < tree->u.b.n; ++i)
1574 pet_tree_dump_with_indent(tree->u.b.child[i],
1575 indent + 2);
1576 break;
1577 case pet_tree_expr:
1578 pet_expr_dump_with_indent(tree->u.e.expr, indent);
1579 break;
1580 case pet_tree_break:
1581 case pet_tree_continue:
1582 break;
1583 case pet_tree_decl:
1584 case pet_tree_decl_init:
1585 print_indent(indent);
1586 fprintf(stderr, "var:\n");
1587 pet_expr_dump_with_indent(tree->u.d.var, indent + 2);
1588 if (tree->type != pet_tree_decl_init)
1589 break;
1590 print_indent(indent);
1591 fprintf(stderr, "init:\n");
1592 pet_expr_dump_with_indent(tree->u.d.init, indent + 2);
1593 break;
1594 case pet_tree_if:
1595 case pet_tree_if_else:
1596 print_indent(indent);
1597 fprintf(stderr, "condition:\n");
1598 pet_expr_dump_with_indent(tree->u.i.cond, indent + 2);
1599 print_indent(indent);
1600 fprintf(stderr, "then:\n");
1601 pet_tree_dump_with_indent(tree->u.i.then_body, indent + 2);
1602 if (tree->type != pet_tree_if_else)
1603 break;
1604 print_indent(indent);
1605 fprintf(stderr, "else:\n");
1606 pet_tree_dump_with_indent(tree->u.i.else_body, indent + 2);
1607 break;
1608 case pet_tree_for:
1609 print_indent(indent);
1610 fprintf(stderr, "declared: %d\n", tree->u.l.declared);
1611 print_indent(indent);
1612 fprintf(stderr, "var:\n");
1613 pet_expr_dump_with_indent(tree->u.l.iv, indent + 2);
1614 print_indent(indent);
1615 fprintf(stderr, "init:\n");
1616 pet_expr_dump_with_indent(tree->u.l.init, indent + 2);
1617 print_indent(indent);
1618 fprintf(stderr, "inc:\n");
1619 pet_expr_dump_with_indent(tree->u.l.inc, indent + 2);
1620 case pet_tree_while:
1621 print_indent(indent);
1622 fprintf(stderr, "condition:\n");
1623 pet_expr_dump_with_indent(tree->u.l.cond, indent + 2);
1624 case pet_tree_infinite_loop:
1625 print_indent(indent);
1626 fprintf(stderr, "body:\n");
1627 pet_tree_dump_with_indent(tree->u.l.body, indent + 2);
1628 break;
1629 case pet_tree_error:
1630 print_indent(indent);
1631 fprintf(stderr, "ERROR\n");
1632 break;
1636 void pet_tree_dump(__isl_keep pet_tree *tree)
1638 pet_tree_dump_with_indent(tree, 0);