pet_scop_collect_arrays: only collect siblings of accessed fields
[pet.git] / tree.c
blob64b9e69a78aad6500f9472ba61aeb3e2c20b6a51
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 <isl/ctx.h>
38 #include <isl/id.h>
39 #include <isl/val.h>
40 #include <isl/space.h>
41 #include <isl/aff.h>
43 #include "expr.h"
44 #include "loc.h"
45 #include "tree.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",
58 [pet_tree_if] = "if",
59 [pet_tree_if_else] = "if-else",
60 [pet_tree_while] = "while",
63 /* Return a textual representation of the type "type".
65 const char *pet_tree_type_str(enum pet_tree_type type)
67 if (type < 0)
68 return "error";
69 return type_str[type];
72 /* Extract a type from its textual representation "str".
74 enum pet_tree_type pet_tree_str_type(const char *str)
76 int i;
78 for (i = 0; i < ARRAY_SIZE(type_str); ++i)
79 if (!strcmp(type_str[i], str))
80 return i;
82 return pet_tree_error;
85 /* Return a new pet_tree of the given type.
87 * The location is initializaed to pet_loc_dummy.
89 __isl_give pet_tree *pet_tree_alloc(isl_ctx *ctx, enum pet_tree_type type)
91 pet_tree *tree;
93 tree = isl_calloc_type(ctx, struct pet_tree);
94 if (!tree)
95 return NULL;
97 tree->ctx = ctx;
98 isl_ctx_ref(ctx);
99 tree->ref = 1;
100 tree->type = type;
101 tree->loc = &pet_loc_dummy;
103 return tree;
106 /* Return a new pet_tree representing the declaration (without initialization)
107 * of the variable "var".
109 __isl_give pet_tree *pet_tree_new_decl(__isl_take pet_expr *var)
111 isl_ctx *ctx;
112 pet_tree *tree;
114 if (!var)
115 return NULL;
116 ctx = pet_expr_get_ctx(var);
117 tree = pet_tree_alloc(ctx, pet_tree_decl);
118 if (!tree)
119 goto error;
121 tree->u.d.var = var;
123 return tree;
124 error:
125 pet_expr_free(var);
126 return NULL;
129 /* Return a new pet_tree representing the declaration of the variable "var"
130 * with initial value "init".
132 __isl_give pet_tree *pet_tree_new_decl_init(__isl_take pet_expr *var,
133 __isl_take pet_expr *init)
135 isl_ctx *ctx;
136 pet_tree *tree;
138 if (!var || !init)
139 goto error;
140 ctx = pet_expr_get_ctx(var);
141 tree = pet_tree_alloc(ctx, pet_tree_decl_init);
142 if (!tree)
143 goto error;
145 tree->u.d.var = var;
146 tree->u.d.init = init;
148 return tree;
149 error:
150 pet_expr_free(var);
151 pet_expr_free(init);
152 return NULL;
155 /* Return a new pet_tree representing the expression "expr".
157 __isl_give pet_tree *pet_tree_new_expr(__isl_take pet_expr *expr)
159 isl_ctx *ctx;
160 pet_tree *tree;
162 if (!expr)
163 return NULL;
164 ctx = pet_expr_get_ctx(expr);
165 tree = pet_tree_alloc(ctx, pet_tree_expr);
166 if (!tree)
167 goto error;
169 tree->u.e.expr = expr;
171 return tree;
172 error:
173 pet_expr_free(expr);
174 return NULL;
177 /* Return a new pet_tree representing an initially empty sequence
178 * of trees with room for "n" trees.
179 * "block" indicates whether the sequence has its own scope.
181 __isl_give pet_tree *pet_tree_new_block(isl_ctx *ctx, int block, int n)
183 pet_tree *tree;
185 tree = pet_tree_alloc(ctx, pet_tree_block);
186 if (!tree)
187 return NULL;
188 tree->u.b.block = block;
189 tree->u.b.n = 0;
190 tree->u.b.max = n;
191 tree->u.b.child = isl_calloc_array(ctx, pet_tree *, n);
192 if (n && !tree->u.b.child)
193 return pet_tree_free(tree);
195 return tree;
198 /* Return a new pet_tree representing a break statement.
200 __isl_give pet_tree *pet_tree_new_break(isl_ctx *ctx)
202 return pet_tree_alloc(ctx, pet_tree_break);
205 /* Return a new pet_tree representing a continue statement.
207 __isl_give pet_tree *pet_tree_new_continue(isl_ctx *ctx)
209 return pet_tree_alloc(ctx, pet_tree_continue);
212 /* Return a new pet_tree representing a for loop
213 * with induction variable "iv", initial value for the induction
214 * variable "init", loop condition "cond", induction variable increment "inc"
215 * and loop body "body". "declared" indicates whether the induction variable
216 * is declared by the loop. "independent" is set if the for loop is marked
217 * independent.
219 * The location of the loop is initialized to that of the body.
221 __isl_give pet_tree *pet_tree_new_for(int independent, int declared,
222 __isl_take pet_expr *iv, __isl_take pet_expr *init,
223 __isl_take pet_expr *cond, __isl_take pet_expr *inc,
224 __isl_take pet_tree *body)
226 isl_ctx *ctx;
227 pet_tree *tree;
229 if (!iv || !init || !cond || !inc || !body)
230 goto error;
231 ctx = pet_tree_get_ctx(body);
232 tree = pet_tree_alloc(ctx, pet_tree_for);
233 if (!tree)
234 goto error;
236 tree->u.l.independent = independent;
237 tree->u.l.declared = declared;
238 tree->u.l.iv = iv;
239 tree->u.l.init = init;
240 tree->u.l.cond = cond;
241 tree->u.l.inc = inc;
242 tree->u.l.body = body;
243 tree->loc = pet_tree_get_loc(body);
244 if (!tree->loc)
245 return pet_tree_free(tree);
247 return tree;
248 error:
249 pet_expr_free(iv);
250 pet_expr_free(init);
251 pet_expr_free(cond);
252 pet_expr_free(inc);
253 pet_tree_free(body);
254 return NULL;
257 /* Return a new pet_tree representing a while loop
258 * with loop condition "cond" and loop body "body".
260 * The location of the loop is initialized to that of the body.
262 __isl_give pet_tree *pet_tree_new_while(__isl_take pet_expr *cond,
263 __isl_take pet_tree *body)
265 isl_ctx *ctx;
266 pet_tree *tree;
268 if (!cond || !body)
269 goto error;
270 ctx = pet_tree_get_ctx(body);
271 tree = pet_tree_alloc(ctx, pet_tree_while);
272 if (!tree)
273 goto error;
275 tree->u.l.cond = cond;
276 tree->u.l.body = body;
277 tree->loc = pet_tree_get_loc(body);
278 if (!tree->loc)
279 return pet_tree_free(tree);
281 return tree;
282 error:
283 pet_expr_free(cond);
284 pet_tree_free(body);
285 return NULL;
288 /* Return a new pet_tree representing an infinite loop
289 * with loop body "body".
291 * The location of the loop is initialized to that of the body.
293 __isl_give pet_tree *pet_tree_new_infinite_loop(__isl_take pet_tree *body)
295 isl_ctx *ctx;
296 pet_tree *tree;
298 if (!body)
299 return NULL;
300 ctx = pet_tree_get_ctx(body);
301 tree = pet_tree_alloc(ctx, pet_tree_infinite_loop);
302 if (!tree)
303 return pet_tree_free(body);
305 tree->u.l.body = body;
306 tree->loc = pet_tree_get_loc(body);
307 if (!tree->loc)
308 return pet_tree_free(tree);
310 return tree;
313 /* Return a new pet_tree representing an if statement
314 * with condition "cond" and then branch "then_body".
316 * The location of the if statement is initialized to that of the body.
318 __isl_give pet_tree *pet_tree_new_if(__isl_take pet_expr *cond,
319 __isl_take pet_tree *then_body)
321 isl_ctx *ctx;
322 pet_tree *tree;
324 if (!cond || !then_body)
325 goto error;
326 ctx = pet_tree_get_ctx(then_body);
327 tree = pet_tree_alloc(ctx, pet_tree_if);
328 if (!tree)
329 goto error;
331 tree->u.i.cond = cond;
332 tree->u.i.then_body = then_body;
333 tree->loc = pet_tree_get_loc(then_body);
334 if (!tree->loc)
335 return pet_tree_free(tree);
337 return tree;
338 error:
339 pet_expr_free(cond);
340 pet_tree_free(then_body);
341 return NULL;
344 /* Return a new pet_tree representing an if statement
345 * with condition "cond", then branch "then_body" and else branch "else_body".
347 * The location of the if statement is initialized to cover
348 * those of the bodies.
350 __isl_give pet_tree *pet_tree_new_if_else(__isl_take pet_expr *cond,
351 __isl_take pet_tree *then_body, __isl_take pet_tree *else_body)
353 isl_ctx *ctx;
354 pet_tree *tree;
356 if (!cond || !then_body || !else_body)
357 goto error;
358 ctx = pet_tree_get_ctx(then_body);
359 tree = pet_tree_alloc(ctx, pet_tree_if_else);
360 if (!tree)
361 goto error;
363 tree->u.i.cond = cond;
364 tree->u.i.then_body = then_body;
365 tree->u.i.else_body = else_body;
366 tree->loc = pet_tree_get_loc(then_body);
367 tree->loc = pet_loc_update_start_end_from_loc(tree->loc,
368 else_body->loc);
369 if (!tree->loc)
370 return pet_tree_free(tree);
372 return tree;
373 error:
374 pet_expr_free(cond);
375 pet_tree_free(then_body);
376 pet_tree_free(else_body);
377 return NULL;
380 /* Return an independent duplicate of "tree".
382 static __isl_give pet_tree *pet_tree_dup(__isl_keep pet_tree *tree)
384 int i;
385 pet_tree *dup;
387 if (!tree)
388 return NULL;
390 switch (tree->type) {
391 case pet_tree_error:
392 return NULL;
393 case pet_tree_block:
394 dup = pet_tree_new_block(tree->ctx, tree->u.b.block,
395 tree->u.b.n);
396 for (i = 0; i < tree->u.b.n; ++i)
397 dup = pet_tree_block_add_child(dup,
398 pet_tree_copy(tree->u.b.child[i]));
399 break;
400 case pet_tree_break:
401 dup = pet_tree_new_break(tree->ctx);
402 break;
403 case pet_tree_continue:
404 dup = pet_tree_new_continue(tree->ctx);
405 break;
406 case pet_tree_decl:
407 dup = pet_tree_new_decl(pet_expr_copy(tree->u.d.var));
408 break;
409 case pet_tree_decl_init:
410 dup = pet_tree_new_decl_init(pet_expr_copy(tree->u.d.var),
411 pet_expr_copy(tree->u.d.init));
412 break;
413 case pet_tree_expr:
414 dup = pet_tree_new_expr(pet_expr_copy(tree->u.e.expr));
415 break;
416 case pet_tree_for:
417 dup = pet_tree_new_for(tree->u.l.independent,
418 tree->u.l.declared,
419 pet_expr_copy(tree->u.l.iv), pet_expr_copy(tree->u.l.init),
420 pet_expr_copy(tree->u.l.cond), pet_expr_copy(tree->u.l.inc),
421 pet_tree_copy(tree->u.l.body));
422 break;
423 case pet_tree_while:
424 dup = pet_tree_new_while(pet_expr_copy(tree->u.l.cond),
425 pet_tree_copy(tree->u.l.body));
426 break;
427 case pet_tree_infinite_loop:
428 dup = pet_tree_new_infinite_loop(pet_tree_copy(tree->u.l.body));
429 break;
430 case pet_tree_if:
431 dup = pet_tree_new_if(pet_expr_copy(tree->u.i.cond),
432 pet_tree_copy(tree->u.i.then_body));
433 break;
434 case pet_tree_if_else:
435 dup = pet_tree_new_if_else(pet_expr_copy(tree->u.i.cond),
436 pet_tree_copy(tree->u.i.then_body),
437 pet_tree_copy(tree->u.i.else_body));
438 break;
441 if (!dup)
442 return NULL;
443 pet_loc_free(dup->loc);
444 dup->loc = pet_loc_copy(tree->loc);
445 if (!dup->loc)
446 return pet_tree_free(dup);
447 if (tree->label) {
448 dup->label = isl_id_copy(tree->label);
449 if (!dup->label)
450 return pet_tree_free(dup);
453 return dup;
456 /* Return a pet_tree that is equal to "tree" and that has only one reference.
458 __isl_give pet_tree *pet_tree_cow(__isl_take pet_tree *tree)
460 if (!tree)
461 return NULL;
463 if (tree->ref == 1)
464 return tree;
465 tree->ref--;
466 return pet_tree_dup(tree);
469 /* Return an extra reference to "tree".
471 __isl_give pet_tree *pet_tree_copy(__isl_keep pet_tree *tree)
473 if (!tree)
474 return NULL;
476 tree->ref++;
477 return tree;
480 /* Free a reference to "tree".
482 __isl_null pet_tree *pet_tree_free(__isl_take pet_tree *tree)
484 int i;
486 if (!tree)
487 return NULL;
488 if (--tree->ref > 0)
489 return NULL;
491 pet_loc_free(tree->loc);
492 isl_id_free(tree->label);
494 switch (tree->type) {
495 case pet_tree_error:
496 break;
497 case pet_tree_block:
498 for (i = 0; i < tree->u.b.n; ++i)
499 pet_tree_free(tree->u.b.child[i]);
500 free(tree->u.b.child);
501 break;
502 case pet_tree_break:
503 case pet_tree_continue:
504 break;
505 case pet_tree_decl_init:
506 pet_expr_free(tree->u.d.init);
507 case pet_tree_decl:
508 pet_expr_free(tree->u.d.var);
509 break;
510 case pet_tree_expr:
511 pet_expr_free(tree->u.e.expr);
512 break;
513 case pet_tree_for:
514 pet_expr_free(tree->u.l.iv);
515 pet_expr_free(tree->u.l.init);
516 pet_expr_free(tree->u.l.inc);
517 case pet_tree_while:
518 pet_expr_free(tree->u.l.cond);
519 case pet_tree_infinite_loop:
520 pet_tree_free(tree->u.l.body);
521 break;
522 case pet_tree_if_else:
523 pet_tree_free(tree->u.i.else_body);
524 case pet_tree_if:
525 pet_expr_free(tree->u.i.cond);
526 pet_tree_free(tree->u.i.then_body);
527 break;
530 isl_ctx_deref(tree->ctx);
531 free(tree);
532 return NULL;
535 /* Return the isl_ctx in which "tree" was created.
537 isl_ctx *pet_tree_get_ctx(__isl_keep pet_tree *tree)
539 return tree ? tree->ctx : NULL;
542 /* Return the location of "tree".
544 __isl_give pet_loc *pet_tree_get_loc(__isl_keep pet_tree *tree)
546 return tree ? pet_loc_copy(tree->loc) : NULL;
549 /* Return the type of "tree".
551 enum pet_tree_type pet_tree_get_type(__isl_keep pet_tree *tree)
553 if (!tree)
554 return pet_tree_error;
556 return tree->type;
559 /* Replace the location of "tree" by "loc".
561 __isl_give pet_tree *pet_tree_set_loc(__isl_take pet_tree *tree,
562 __isl_take pet_loc *loc)
564 tree = pet_tree_cow(tree);
565 if (!tree || !loc)
566 goto error;
568 pet_loc_free(tree->loc);
569 tree->loc = loc;
571 return tree;
572 error:
573 pet_loc_free(loc);
574 pet_tree_free(tree);
575 return NULL;
578 /* Replace the label of "tree" by "label".
580 __isl_give pet_tree *pet_tree_set_label(__isl_take pet_tree *tree,
581 __isl_take isl_id *label)
583 tree = pet_tree_cow(tree);
584 if (!tree || !label)
585 goto error;
587 isl_id_free(tree->label);
588 tree->label = label;
590 return tree;
591 error:
592 isl_id_free(label);
593 return pet_tree_free(tree);
596 /* Given an expression tree "tree", return the associated expression.
598 __isl_give pet_expr *pet_tree_expr_get_expr(__isl_keep pet_tree *tree)
600 if (!tree)
601 return NULL;
602 if (pet_tree_get_type(tree) != pet_tree_expr)
603 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
604 "not an expression tree", return NULL);
606 return pet_expr_copy(tree->u.e.expr);
609 /* Given a block tree "tree", return the number of children in the sequence.
611 int pet_tree_block_n_child(__isl_keep pet_tree *tree)
613 if (!tree)
614 return -1;
615 if (pet_tree_get_type(tree) != pet_tree_block)
616 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
617 "not a block tree", return -1);
619 return tree->u.b.n;
622 /* Add "child" to the sequence of trees represented by "block".
624 * Update the location of "block" to include that of "child".
626 __isl_give pet_tree *pet_tree_block_add_child(__isl_take pet_tree *block,
627 __isl_take pet_tree *child)
629 block = pet_tree_cow(block);
630 if (!block || !child)
631 goto error;
632 if (block->type != pet_tree_block)
633 isl_die(pet_tree_get_ctx(block), isl_error_invalid,
634 "not a block tree", goto error);
635 if (block->u.b.n >= block->u.b.max)
636 isl_die(pet_tree_get_ctx(block), isl_error_invalid,
637 "out of space in block", goto error);
639 block->loc = pet_loc_update_start_end_from_loc(block->loc, child->loc);
640 block->u.b.child[block->u.b.n++] = child;
642 if (!block->loc)
643 return pet_tree_free(block);
645 return block;
646 error:
647 pet_tree_free(block);
648 pet_tree_free(child);
649 return NULL;
652 /* Does the block tree "tree" have its own scope?
654 int pet_tree_block_get_block(__isl_keep pet_tree *tree)
656 if (!tree)
657 return -1;
658 if (pet_tree_get_type(tree) != pet_tree_block)
659 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
660 "not a block tree", return -1);
662 return tree->u.b.block;
665 /* Set the block property (whether or not the block tree has its own scope)
666 * of "tree" to "is_block".
668 __isl_give pet_tree *pet_tree_block_set_block(__isl_take pet_tree *tree,
669 int is_block)
671 if (!tree)
672 return NULL;
673 if (tree->type != pet_tree_block)
674 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
675 "not a block tree", return pet_tree_free(tree));
676 if (tree->u.b.block == is_block)
677 return tree;
678 tree = pet_tree_cow(tree);
679 if (!tree)
680 return NULL;
681 tree->u.b.block = is_block;
682 return tree;
685 /* Given a block tree "tree", return the child at position "pos".
687 __isl_give pet_tree *pet_tree_block_get_child(__isl_keep pet_tree *tree,
688 int pos)
690 if (!tree)
691 return NULL;
692 if (pet_tree_get_type(tree) != pet_tree_block)
693 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
694 "not a block tree", return NULL);
695 if (pos < 0 || pos >= tree->u.b.n)
696 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
697 "position out of bounds", return NULL);
699 return pet_tree_copy(tree->u.b.child[pos]);
702 /* Does "tree" represent a declaration (with or without initialization)?
704 int pet_tree_is_decl(__isl_keep pet_tree *tree)
706 if (!tree)
707 return -1;
709 switch (pet_tree_get_type(tree)) {
710 case pet_tree_decl:
711 case pet_tree_decl_init:
712 return 1;
713 default:
714 return 0;
718 /* Given a declaration tree "tree", return the variable that is being
719 * declared.
721 __isl_give pet_expr *pet_tree_decl_get_var(__isl_keep pet_tree *tree)
723 if (!tree)
724 return NULL;
725 if (!pet_tree_is_decl(tree))
726 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
727 "not a decl tree", return NULL);
729 return pet_expr_copy(tree->u.d.var);
732 /* Given a declaration tree with initialization "tree",
733 * return the initial value of the declared variable.
735 __isl_give pet_expr *pet_tree_decl_get_init(__isl_keep pet_tree *tree)
737 if (!tree)
738 return NULL;
739 if (pet_tree_get_type(tree) != pet_tree_decl_init)
740 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
741 "not a decl_init tree", return NULL);
743 return pet_expr_copy(tree->u.d.init);
746 /* Given an if tree "tree", return the if condition.
748 __isl_give pet_expr *pet_tree_if_get_cond(__isl_keep pet_tree *tree)
750 enum pet_tree_type type;
752 if (!tree)
753 return NULL;
754 type = pet_tree_get_type(tree);
755 if (type != pet_tree_if && type != pet_tree_if_else)
756 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
757 "not an if tree", return NULL);
759 return pet_expr_copy(tree->u.i.cond);
762 /* Given an if tree "tree", return the body of the then branch.
764 __isl_give pet_tree *pet_tree_if_get_then(__isl_keep pet_tree *tree)
766 enum pet_tree_type type;
768 if (!tree)
769 return NULL;
770 type = pet_tree_get_type(tree);
771 if (type != pet_tree_if && type != pet_tree_if_else)
772 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
773 "not an if tree", return NULL);
775 return pet_tree_copy(tree->u.i.then_body);
778 /* Given an if tree with an else branch "tree",
779 * return the body of that else branch.
781 __isl_give pet_tree *pet_tree_if_get_else(__isl_keep pet_tree *tree)
783 if (!tree)
784 return NULL;
785 if (pet_tree_get_type(tree) != pet_tree_if_else)
786 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
787 "not an if tree with an else branch", return NULL);
789 return pet_tree_copy(tree->u.i.else_body);
792 /* Does "tree" represent some type of loop?
794 int pet_tree_is_loop(__isl_keep pet_tree *tree)
796 if (!tree)
797 return -1;
799 switch (pet_tree_get_type(tree)) {
800 case pet_tree_for:
801 case pet_tree_infinite_loop:
802 case pet_tree_while:
803 return 1;
804 default:
805 return 0;
809 /* Given a for loop "tree", return the induction variable.
811 __isl_give pet_expr *pet_tree_loop_get_var(__isl_keep pet_tree *tree)
813 if (!tree)
814 return NULL;
815 if (pet_tree_get_type(tree) != pet_tree_for)
816 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
817 "not a for tree", return NULL);
819 return pet_expr_copy(tree->u.l.iv);
822 /* Given a for loop "tree", return the initial value of the induction variable.
824 __isl_give pet_expr *pet_tree_loop_get_init(__isl_keep pet_tree *tree)
826 if (!tree)
827 return NULL;
828 if (pet_tree_get_type(tree) != pet_tree_for)
829 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
830 "not a for tree", return NULL);
832 return pet_expr_copy(tree->u.l.init);
835 /* Given a loop "tree", return the loop condition.
837 * For an infinite loop, the loop condition always holds,
838 * so we simply return "1".
840 __isl_give pet_expr *pet_tree_loop_get_cond(__isl_keep pet_tree *tree)
842 enum pet_tree_type type;
844 if (!tree)
845 return NULL;
846 type = pet_tree_get_type(tree);
847 if (type == pet_tree_infinite_loop)
848 return pet_expr_new_int(isl_val_one(pet_tree_get_ctx(tree)));
849 if (type != pet_tree_for && type != pet_tree_while)
850 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
851 "not a for or while tree", return NULL);
853 return pet_expr_copy(tree->u.l.cond);
856 /* Given a for loop "tree", return the increment of the induction variable.
858 __isl_give pet_expr *pet_tree_loop_get_inc(__isl_keep pet_tree *tree)
860 if (!tree)
861 return NULL;
862 if (pet_tree_get_type(tree) != pet_tree_for)
863 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
864 "not a for tree", return NULL);
866 return pet_expr_copy(tree->u.l.inc);
869 /* Given a loop tree "tree", return the body.
871 __isl_give pet_tree *pet_tree_loop_get_body(__isl_keep pet_tree *tree)
873 if (!tree)
874 return NULL;
876 if (!pet_tree_is_loop(tree))
877 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
878 "not a loop tree", return NULL);
880 return pet_tree_copy(tree->u.l.body);
883 /* Call "fn" on each node of "tree", including "tree" itself.
885 * Return 0 on success and -1 on error, where "fn" returning a negative
886 * value is treated as an error.
888 int pet_tree_foreach_sub_tree(__isl_keep pet_tree *tree,
889 int (*fn)(__isl_keep pet_tree *tree, void *user), void *user)
891 int i;
893 if (!tree)
894 return -1;
896 if (fn(tree, user) < 0)
897 return -1;
899 switch (tree->type) {
900 case pet_tree_error:
901 return -1;
902 case pet_tree_block:
903 for (i = 0; i < tree->u.b.n; ++i)
904 if (pet_tree_foreach_sub_tree(tree->u.b.child[i],
905 fn, user) < 0)
906 return -1;
907 break;
908 case pet_tree_break:
909 case pet_tree_continue:
910 case pet_tree_decl:
911 case pet_tree_decl_init:
912 case pet_tree_expr:
913 break;
914 case pet_tree_if:
915 if (pet_tree_foreach_sub_tree(tree->u.i.then_body,
916 fn, user) < 0)
917 return -1;
918 break;
919 case pet_tree_if_else:
920 if (pet_tree_foreach_sub_tree(tree->u.i.then_body,
921 fn, user) < 0)
922 return -1;
923 if (pet_tree_foreach_sub_tree(tree->u.i.else_body,
924 fn, user) < 0)
925 return -1;
926 break;
927 case pet_tree_while:
928 case pet_tree_for:
929 case pet_tree_infinite_loop:
930 if (pet_tree_foreach_sub_tree(tree->u.l.body, fn, user) < 0)
931 return -1;
932 break;
935 return 0;
938 /* Intermediate data structure for foreach_expr.
940 * "fn" is the function that needs to be called on each expression.
941 * "user" is the user argument to be passed to "fn".
943 struct pet_tree_foreach_expr_data {
944 int (*fn)(__isl_keep pet_expr *expr, void *user);
945 void *user;
948 /* Call data->fn on each expression in the "tree" object.
949 * This function is used as a callback to pet_tree_foreach_sub_tree
950 * to implement pet_tree_foreach_expr.
952 * Return 0 on success and -1 on error, where data->fn returning a negative
953 * value is treated as an error.
955 static int foreach_expr(__isl_keep pet_tree *tree, void *user)
957 struct pet_tree_foreach_expr_data *data = user;
959 if (!tree)
960 return -1;
962 switch (tree->type) {
963 case pet_tree_error:
964 return -1;
965 case pet_tree_block:
966 case pet_tree_break:
967 case pet_tree_continue:
968 case pet_tree_infinite_loop:
969 break;
970 case pet_tree_decl:
971 if (data->fn(tree->u.d.var, data->user) < 0)
972 return -1;
973 break;
974 case pet_tree_decl_init:
975 if (data->fn(tree->u.d.var, data->user) < 0)
976 return -1;
977 if (data->fn(tree->u.d.init, data->user) < 0)
978 return -1;
979 break;
980 case pet_tree_expr:
981 if (data->fn(tree->u.e.expr, data->user) < 0)
982 return -1;
983 break;
984 case pet_tree_if:
985 if (data->fn(tree->u.i.cond, data->user) < 0)
986 return -1;
987 break;
988 case pet_tree_if_else:
989 if (data->fn(tree->u.i.cond, data->user) < 0)
990 return -1;
991 break;
992 case pet_tree_while:
993 if (data->fn(tree->u.l.cond, data->user) < 0)
994 return -1;
995 break;
996 case pet_tree_for:
997 if (data->fn(tree->u.l.iv, data->user) < 0)
998 return -1;
999 if (data->fn(tree->u.l.init, data->user) < 0)
1000 return -1;
1001 if (data->fn(tree->u.l.cond, data->user) < 0)
1002 return -1;
1003 if (data->fn(tree->u.l.inc, data->user) < 0)
1004 return -1;
1005 break;
1008 return 0;
1011 /* Call "fn" on each top-level expression in the nodes of "tree"
1013 * Return 0 on success and -1 on error, where "fn" returning a negative
1014 * value is treated as an error.
1016 * We run over all nodes in "tree" and call "fn"
1017 * on each expression in those nodes.
1019 int pet_tree_foreach_expr(__isl_keep pet_tree *tree,
1020 int (*fn)(__isl_keep pet_expr *expr, void *user), void *user)
1022 struct pet_tree_foreach_expr_data data = { fn, user };
1024 return pet_tree_foreach_sub_tree(tree, &foreach_expr, &data);
1027 /* Intermediate data structure for foreach_access_expr.
1029 * "fn" is the function that needs to be called on each access subexpression.
1030 * "user" is the user argument to be passed to "fn".
1032 struct pet_tree_foreach_access_expr_data {
1033 int (*fn)(__isl_keep pet_expr *expr, void *user);
1034 void *user;
1037 /* Call data->fn on each access subexpression of "expr".
1038 * This function is used as a callback to pet_tree_foreach_expr
1039 * to implement pet_tree_foreach_access_expr.
1041 * Return 0 on success and -1 on error, where data->fn returning a negative
1042 * value is treated as an error.
1044 static int foreach_access_expr(__isl_keep pet_expr *expr, void *user)
1046 struct pet_tree_foreach_access_expr_data *data = user;
1048 return pet_expr_foreach_access_expr(expr, data->fn, data->user);
1051 /* Call "fn" on each access subexpression in the nodes of "tree"
1053 * Return 0 on success and -1 on error, where "fn" returning a negative
1054 * value is treated as an error.
1056 * We run over all expressions in the nodes of "tree" and call "fn"
1057 * on each access subexpression of those expressions.
1059 int pet_tree_foreach_access_expr(__isl_keep pet_tree *tree,
1060 int (*fn)(__isl_keep pet_expr *expr, void *user), void *user)
1062 struct pet_tree_foreach_access_expr_data data = { fn, user };
1064 return pet_tree_foreach_expr(tree, &foreach_access_expr, &data);
1067 /* Modify all top-level expressions in the nodes of "tree"
1068 * by calling "fn" on them.
1070 __isl_give pet_tree *pet_tree_map_expr(__isl_take pet_tree *tree,
1071 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1072 void *user)
1074 int i;
1076 tree = pet_tree_cow(tree);
1077 if (!tree)
1078 return NULL;
1080 switch (tree->type) {
1081 case pet_tree_error:
1082 return pet_tree_free(tree);
1083 case pet_tree_block:
1084 for (i = 0; i < tree->u.b.n; ++i) {
1085 tree->u.b.child[i] =
1086 pet_tree_map_expr(tree->u.b.child[i], fn, user);
1087 if (!tree->u.b.child[i])
1088 return pet_tree_free(tree);
1090 break;
1091 case pet_tree_break:
1092 case pet_tree_continue:
1093 break;
1094 case pet_tree_decl:
1095 tree->u.d.var = fn(tree->u.d.var, user);
1096 if (!tree->u.d.var)
1097 return pet_tree_free(tree);
1098 break;
1099 case pet_tree_decl_init:
1100 tree->u.d.var = fn(tree->u.d.var, user);
1101 tree->u.d.init = fn(tree->u.d.init, user);
1102 if (!tree->u.d.var || !tree->u.d.init)
1103 return pet_tree_free(tree);
1104 break;
1105 case pet_tree_expr:
1106 tree->u.e.expr = fn(tree->u.e.expr, user);
1107 if (!tree->u.e.expr)
1108 return pet_tree_free(tree);
1109 break;
1110 case pet_tree_if:
1111 tree->u.i.cond = fn(tree->u.i.cond, user);
1112 tree->u.i.then_body =
1113 pet_tree_map_expr(tree->u.i.then_body, fn, user);
1114 if (!tree->u.i.cond || !tree->u.i.then_body)
1115 return pet_tree_free(tree);
1116 break;
1117 case pet_tree_if_else:
1118 tree->u.i.cond = fn(tree->u.i.cond, user);
1119 tree->u.i.then_body =
1120 pet_tree_map_expr(tree->u.i.then_body, fn, user);
1121 tree->u.i.else_body =
1122 pet_tree_map_expr(tree->u.i.else_body, fn, user);
1123 if (!tree->u.i.cond ||
1124 !tree->u.i.then_body || !tree->u.i.else_body)
1125 return pet_tree_free(tree);
1126 break;
1127 case pet_tree_while:
1128 tree->u.l.cond = fn(tree->u.l.cond, user);
1129 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1130 if (!tree->u.l.cond || !tree->u.l.body)
1131 return pet_tree_free(tree);
1132 break;
1133 case pet_tree_for:
1134 tree->u.l.iv = fn(tree->u.l.iv, user);
1135 tree->u.l.init = fn(tree->u.l.init, user);
1136 tree->u.l.cond = fn(tree->u.l.cond, user);
1137 tree->u.l.inc = fn(tree->u.l.inc, user);
1138 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1139 if (!tree->u.l.iv || !tree->u.l.init || !tree->u.l.cond ||
1140 !tree->u.l.inc || !tree->u.l.body)
1141 return pet_tree_free(tree);
1142 break;
1143 case pet_tree_infinite_loop:
1144 tree->u.l.body = pet_tree_map_expr(tree->u.l.body, fn, user);
1145 if (!tree->u.l.body)
1146 return pet_tree_free(tree);
1147 break;
1150 return tree;
1153 /* Intermediate data structure for map_expr.
1155 * "map" is a function that modifies subexpressions of a given type.
1156 * "fn" is the function that needs to be called on each of those subexpressions.
1157 * "user" is the user argument to be passed to "fn".
1159 struct pet_tree_map_expr_data {
1160 __isl_give pet_expr *(*map)(__isl_take pet_expr *expr,
1161 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr,
1162 void *user), void *user);
1163 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user);
1164 void *user;
1167 /* This function is called on each top-level expressions in the nodes
1168 * of a tree. Call data->map to modify subexpressions of the top-level
1169 * expression by calling data->fn on them.
1171 * This is a wrapper around data->map for use as a callback
1172 * to pet_tree_map_expr.
1174 static __isl_give pet_expr *map_expr(__isl_take pet_expr *expr,
1175 void *user)
1177 struct pet_tree_map_expr_data *data = user;
1179 return data->map(expr, data->fn, data->user);
1182 /* Modify all access subexpressions in the nodes of "tree"
1183 * by calling "fn" on them.
1185 * We run over all expressions in the nodes of "tree" and call "fn"
1186 * on each access subexpression of those expressions.
1188 __isl_give pet_tree *pet_tree_map_access_expr(__isl_take pet_tree *tree,
1189 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1190 void *user)
1192 struct pet_tree_map_expr_data data = { &pet_expr_map_access, fn, user };
1194 return pet_tree_map_expr(tree, &map_expr, &data);
1197 /* Modify all call subexpressions in the nodes of "tree"
1198 * by calling "fn" on them.
1200 * We run over all expressions in the nodes of "tree" and call "fn"
1201 * on each call subexpression of those expressions.
1203 __isl_give pet_tree *pet_tree_map_call_expr(__isl_take pet_tree *tree,
1204 __isl_give pet_expr *(*fn)(__isl_take pet_expr *expr, void *user),
1205 void *user)
1207 struct pet_tree_map_expr_data data = { &pet_expr_map_call, fn, user };
1209 return pet_tree_map_expr(tree, &map_expr, &data);
1212 /* Wrapper around pet_expr_align_params
1213 * for use as a pet_tree_map_expr callback.
1215 static __isl_give pet_expr *align_params(__isl_take pet_expr *expr,
1216 void *user)
1218 isl_space *space = user;
1220 return pet_expr_align_params(expr, isl_space_copy(space));
1223 /* Add all parameters in "space" to all access relations and index expressions
1224 * in "tree".
1226 __isl_give pet_tree *pet_tree_align_params(__isl_take pet_tree *tree,
1227 __isl_take isl_space *space)
1229 tree = pet_tree_map_expr(tree, &align_params, space);
1230 isl_space_free(space);
1231 return tree;
1234 /* Wrapper around pet_expr_add_ref_ids
1235 * for use as a pet_tree_map_expr callback.
1237 static __isl_give pet_expr *add_ref_ids(__isl_take pet_expr *expr, void *user)
1239 int *n_ref = user;
1241 return pet_expr_add_ref_ids(expr, n_ref);
1244 /* Add reference identifiers to all access expressions in "tree".
1245 * "n_ref" points to an integer that contains the sequence number
1246 * of the next reference.
1248 __isl_give pet_tree *pet_tree_add_ref_ids(__isl_take pet_tree *tree,
1249 int *n_ref)
1251 return pet_tree_map_expr(tree, &add_ref_ids, n_ref);
1254 /* Wrapper around pet_expr_anonymize
1255 * for use as a pet_tree_map_expr callback.
1257 static __isl_give pet_expr *anonymize(__isl_take pet_expr *expr, void *user)
1259 return pet_expr_anonymize(expr);
1262 /* Reset the user pointer on all parameter and tuple ids in "tree".
1264 __isl_give pet_tree *pet_tree_anonymize(__isl_take pet_tree *tree)
1266 return pet_tree_map_expr(tree, &anonymize, NULL);
1269 /* Arguments to be passed to pet_expr_gist from the gist wrapper.
1271 struct pet_tree_gist_data {
1272 isl_set *domain;
1273 isl_union_map *value_bounds;
1276 /* Wrapper around pet_expr_gist for use as a pet_tree_map_expr callback.
1278 static __isl_give pet_expr *gist(__isl_take pet_expr *expr, void *user)
1280 struct pet_tree_gist_data *data = user;
1282 return pet_expr_gist(expr, data->domain, data->value_bounds);
1285 /* Compute the gist of all access relations and index expressions inside
1286 * "tree" based on the constraints on the parameters specified by "context"
1287 * and the constraints on the values of nested accesses specified
1288 * by "value_bounds".
1290 __isl_give pet_tree *pet_tree_gist(__isl_take pet_tree *tree,
1291 __isl_keep isl_set *context, __isl_keep isl_union_map *value_bounds)
1293 struct pet_tree_gist_data data = { context, value_bounds };
1295 return pet_tree_map_expr(tree, &gist, &data);
1298 /* Return 1 if the two pet_tree objects are equivalent.
1300 * We ignore the locations of the trees.
1302 int pet_tree_is_equal(__isl_keep pet_tree *tree1, __isl_keep pet_tree *tree2)
1304 int i;
1305 int equal;
1307 if (!tree1 || !tree2)
1308 return 0;
1310 if (tree1 == tree2)
1311 return 1;
1313 if (tree1->type != tree2->type)
1314 return 0;
1315 if (tree1->label != tree2->label)
1316 return 0;
1318 switch (tree1->type) {
1319 case pet_tree_error:
1320 return -1;
1321 case pet_tree_block:
1322 if (tree1->u.b.block != tree2->u.b.block)
1323 return 0;
1324 if (tree1->u.b.n != tree2->u.b.n)
1325 return 0;
1326 for (i = 0; i < tree1->u.b.n; ++i) {
1327 equal = pet_tree_is_equal(tree1->u.b.child[i],
1328 tree2->u.b.child[i]);
1329 if (equal < 0 || !equal)
1330 return equal;
1332 break;
1333 case pet_tree_break:
1334 case pet_tree_continue:
1335 break;
1336 case pet_tree_decl:
1337 return pet_expr_is_equal(tree1->u.d.var, tree2->u.d.var);
1338 case pet_tree_decl_init:
1339 equal = pet_expr_is_equal(tree1->u.d.var, tree2->u.d.var);
1340 if (equal < 0 || !equal)
1341 return equal;
1342 return pet_expr_is_equal(tree1->u.d.init, tree2->u.d.init);
1343 case pet_tree_expr:
1344 return pet_expr_is_equal(tree1->u.e.expr, tree2->u.e.expr);
1345 case pet_tree_for:
1346 if (tree1->u.l.declared != tree2->u.l.declared)
1347 return 0;
1348 equal = pet_expr_is_equal(tree1->u.l.iv, tree2->u.l.iv);
1349 if (equal < 0 || !equal)
1350 return equal;
1351 equal = pet_expr_is_equal(tree1->u.l.init, tree2->u.l.init);
1352 if (equal < 0 || !equal)
1353 return equal;
1354 equal = pet_expr_is_equal(tree1->u.l.cond, tree2->u.l.cond);
1355 if (equal < 0 || !equal)
1356 return equal;
1357 equal = pet_expr_is_equal(tree1->u.l.inc, tree2->u.l.inc);
1358 if (equal < 0 || !equal)
1359 return equal;
1360 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1361 case pet_tree_while:
1362 equal = pet_expr_is_equal(tree1->u.l.cond, tree2->u.l.cond);
1363 if (equal < 0 || !equal)
1364 return equal;
1365 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1366 case pet_tree_infinite_loop:
1367 return pet_tree_is_equal(tree1->u.l.body, tree2->u.l.body);
1368 case pet_tree_if:
1369 equal = pet_expr_is_equal(tree1->u.i.cond, tree2->u.i.cond);
1370 if (equal < 0 || !equal)
1371 return equal;
1372 return pet_tree_is_equal(tree1->u.i.then_body,
1373 tree2->u.i.then_body);
1374 case pet_tree_if_else:
1375 equal = pet_expr_is_equal(tree1->u.i.cond, tree2->u.i.cond);
1376 if (equal < 0 || !equal)
1377 return equal;
1378 equal = pet_tree_is_equal(tree1->u.i.then_body,
1379 tree2->u.i.then_body);
1380 if (equal < 0 || !equal)
1381 return equal;
1382 return pet_tree_is_equal(tree1->u.i.else_body,
1383 tree2->u.i.else_body);
1386 return 1;
1389 /* Is "tree" an expression tree that performs the operation "type"?
1391 static int pet_tree_is_op_of_type(__isl_keep pet_tree *tree,
1392 enum pet_op_type type)
1394 if (!tree)
1395 return 0;
1396 if (tree->type != pet_tree_expr)
1397 return 0;
1398 if (pet_expr_get_type(tree->u.e.expr) != pet_expr_op)
1399 return 0;
1400 return pet_expr_op_get_type(tree->u.e.expr) == type;
1403 /* Is "tree" an expression tree that performs a kill operation?
1405 int pet_tree_is_kill(__isl_keep pet_tree *tree)
1407 return pet_tree_is_op_of_type(tree, pet_op_kill);
1410 /* Is "tree" an expression tree that performs an assignment operation?
1412 int pet_tree_is_assign(__isl_keep pet_tree *tree)
1414 return pet_tree_is_op_of_type(tree, pet_op_assign);
1417 /* Is "tree" an expression tree that performs an assume operation?
1419 int pet_tree_is_assume(__isl_keep pet_tree *tree)
1421 return pet_tree_is_op_of_type(tree, pet_op_assume);
1424 /* Is "tree" an expression tree that performs an assume operation
1425 * such that the assumed expression is affine?
1427 isl_bool pet_tree_is_affine_assume(__isl_keep pet_tree *tree)
1429 if (!pet_tree_is_assume(tree))
1430 return isl_bool_false;
1431 return pet_expr_is_affine(tree->u.e.expr->args[0]);
1434 /* Given a tree that represent an assume operation expression
1435 * with an access as argument (possibly an affine expression),
1436 * return the index expression of that access.
1438 __isl_give isl_multi_pw_aff *pet_tree_assume_get_index(
1439 __isl_keep pet_tree *tree)
1441 if (!tree)
1442 return NULL;
1443 if (!pet_tree_is_assume(tree))
1444 isl_die(pet_tree_get_ctx(tree), isl_error_invalid,
1445 "not an assume tree", return NULL);
1446 return pet_expr_access_get_index(tree->u.e.expr->args[0]);
1449 /* Internal data structure for pet_tree_writes.
1450 * "id" is the identifier that we are looking for.
1451 * "writes" is set if we have found the identifier being written to.
1453 struct pet_tree_writes_data {
1454 isl_id *id;
1455 int writes;
1458 /* Check if expr writes to data->id.
1459 * If so, set data->writes and abort the search.
1461 static int check_write(__isl_keep pet_expr *expr, void *user)
1463 struct pet_tree_writes_data *data = user;
1465 data->writes = pet_expr_writes(expr, data->id);
1466 if (data->writes < 0 || data->writes)
1467 return -1;
1469 return 0;
1472 /* Is there any write access in "tree" that accesses "id"?
1474 int pet_tree_writes(__isl_keep pet_tree *tree, __isl_keep isl_id *id)
1476 struct pet_tree_writes_data data;
1478 data.id = id;
1479 data.writes = 0;
1480 if (pet_tree_foreach_expr(tree, &check_write, &data) < 0 &&
1481 !data.writes)
1482 return -1;
1484 return data.writes;
1487 /* Wrapper around pet_expr_update_domain
1488 * for use as a pet_tree_map_expr callback.
1490 static __isl_give pet_expr *update_domain(__isl_take pet_expr *expr, void *user)
1492 isl_multi_pw_aff *update = user;
1494 return pet_expr_update_domain(expr, isl_multi_pw_aff_copy(update));
1497 /* Modify all access relations in "tree" by precomposing them with
1498 * the given iteration space transformation.
1500 __isl_give pet_tree *pet_tree_update_domain(__isl_take pet_tree *tree,
1501 __isl_take isl_multi_pw_aff *update)
1503 tree = pet_tree_map_expr(tree, &update_domain, update);
1504 isl_multi_pw_aff_free(update);
1505 return tree;
1508 /* Does "tree" contain a continue or break node (not contained in any loop
1509 * subtree of "tree")?
1511 int pet_tree_has_continue_or_break(__isl_keep pet_tree *tree)
1513 int i;
1514 int found;
1516 if (!tree)
1517 return -1;
1519 switch (tree->type) {
1520 case pet_tree_error:
1521 return -1;
1522 case pet_tree_continue:
1523 case pet_tree_break:
1524 return 1;
1525 case pet_tree_decl:
1526 case pet_tree_decl_init:
1527 case pet_tree_expr:
1528 case pet_tree_for:
1529 case pet_tree_while:
1530 case pet_tree_infinite_loop:
1531 return 0;
1532 case pet_tree_block:
1533 for (i = 0; i < tree->u.b.n; ++i) {
1534 found =
1535 pet_tree_has_continue_or_break(tree->u.b.child[i]);
1536 if (found < 0 || found)
1537 return found;
1539 return 0;
1540 case pet_tree_if:
1541 return pet_tree_has_continue_or_break(tree->u.i.then_body);
1542 case pet_tree_if_else:
1543 found = pet_tree_has_continue_or_break(tree->u.i.then_body);
1544 if (found < 0 || found)
1545 return found;
1546 return pet_tree_has_continue_or_break(tree->u.i.else_body);
1550 static void print_indent(int indent)
1552 fprintf(stderr, "%*s", indent, "");
1555 void pet_tree_dump_with_indent(__isl_keep pet_tree *tree, int indent)
1557 int i;
1559 if (!tree)
1560 return;
1562 print_indent(indent);
1563 fprintf(stderr, "%s\n", pet_tree_type_str(tree->type));
1564 print_indent(indent);
1565 fprintf(stderr, "line: %d\n", pet_loc_get_line(tree->loc));
1566 print_indent(indent);
1567 fprintf(stderr, "start: %d\n", pet_loc_get_start(tree->loc));
1568 print_indent(indent);
1569 fprintf(stderr, "end: %d\n", pet_loc_get_end(tree->loc));
1570 if (tree->label) {
1571 print_indent(indent);
1572 fprintf(stderr, "label: ");
1573 isl_id_dump(tree->label);
1575 switch (tree->type) {
1576 case pet_tree_block:
1577 print_indent(indent);
1578 fprintf(stderr, "block: %d\n", tree->u.b.block);
1579 for (i = 0; i < tree->u.b.n; ++i)
1580 pet_tree_dump_with_indent(tree->u.b.child[i],
1581 indent + 2);
1582 break;
1583 case pet_tree_expr:
1584 pet_expr_dump_with_indent(tree->u.e.expr, indent);
1585 break;
1586 case pet_tree_break:
1587 case pet_tree_continue:
1588 break;
1589 case pet_tree_decl:
1590 case pet_tree_decl_init:
1591 print_indent(indent);
1592 fprintf(stderr, "var:\n");
1593 pet_expr_dump_with_indent(tree->u.d.var, indent + 2);
1594 if (tree->type != pet_tree_decl_init)
1595 break;
1596 print_indent(indent);
1597 fprintf(stderr, "init:\n");
1598 pet_expr_dump_with_indent(tree->u.d.init, indent + 2);
1599 break;
1600 case pet_tree_if:
1601 case pet_tree_if_else:
1602 print_indent(indent);
1603 fprintf(stderr, "condition:\n");
1604 pet_expr_dump_with_indent(tree->u.i.cond, indent + 2);
1605 print_indent(indent);
1606 fprintf(stderr, "then:\n");
1607 pet_tree_dump_with_indent(tree->u.i.then_body, indent + 2);
1608 if (tree->type != pet_tree_if_else)
1609 break;
1610 print_indent(indent);
1611 fprintf(stderr, "else:\n");
1612 pet_tree_dump_with_indent(tree->u.i.else_body, indent + 2);
1613 break;
1614 case pet_tree_for:
1615 print_indent(indent);
1616 fprintf(stderr, "declared: %d\n", tree->u.l.declared);
1617 print_indent(indent);
1618 fprintf(stderr, "var:\n");
1619 pet_expr_dump_with_indent(tree->u.l.iv, indent + 2);
1620 print_indent(indent);
1621 fprintf(stderr, "init:\n");
1622 pet_expr_dump_with_indent(tree->u.l.init, indent + 2);
1623 print_indent(indent);
1624 fprintf(stderr, "inc:\n");
1625 pet_expr_dump_with_indent(tree->u.l.inc, indent + 2);
1626 case pet_tree_while:
1627 print_indent(indent);
1628 fprintf(stderr, "condition:\n");
1629 pet_expr_dump_with_indent(tree->u.l.cond, indent + 2);
1630 case pet_tree_infinite_loop:
1631 print_indent(indent);
1632 fprintf(stderr, "body:\n");
1633 pet_tree_dump_with_indent(tree->u.l.body, indent + 2);
1634 break;
1635 case pet_tree_error:
1636 print_indent(indent);
1637 fprintf(stderr, "ERROR\n");
1638 break;
1642 void pet_tree_dump(__isl_keep pet_tree *tree)
1644 pet_tree_dump_with_indent(tree, 0);