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
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",
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
)
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
)
72 for (i
= 0; i
< ARRAY_SIZE(type_str
); ++i
)
73 if (!strcmp(type_str
[i
], str
))
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
)
87 tree
= isl_calloc_type(ctx
, struct pet_tree
);
95 tree
->loc
= &pet_loc_dummy
;
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
)
110 ctx
= pet_expr_get_ctx(var
);
111 tree
= pet_tree_alloc(ctx
, pet_tree_decl
);
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
)
134 ctx
= pet_expr_get_ctx(var
);
135 tree
= pet_tree_alloc(ctx
, pet_tree_decl_init
);
140 tree
->u
.d
.init
= init
;
149 /* Return a new pet_tree representing the expression "expr".
151 __isl_give pet_tree
*pet_tree_new_expr(__isl_take pet_expr
*expr
)
158 ctx
= pet_expr_get_ctx(expr
);
159 tree
= pet_tree_alloc(ctx
, pet_tree_expr
);
163 tree
->u
.e
.expr
= expr
;
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
)
179 tree
= pet_tree_alloc(ctx
, pet_tree_block
);
182 tree
->u
.b
.block
= block
;
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
);
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
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
)
223 if (!iv
|| !init
|| !cond
|| !inc
|| !body
)
225 ctx
= pet_tree_get_ctx(body
);
226 tree
= pet_tree_alloc(ctx
, pet_tree_for
);
230 tree
->u
.l
.independent
= independent
;
231 tree
->u
.l
.declared
= declared
;
233 tree
->u
.l
.init
= init
;
234 tree
->u
.l
.cond
= cond
;
236 tree
->u
.l
.body
= body
;
237 tree
->loc
= pet_tree_get_loc(body
);
239 return pet_tree_free(tree
);
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
)
264 ctx
= pet_tree_get_ctx(body
);
265 tree
= pet_tree_alloc(ctx
, pet_tree_while
);
269 tree
->u
.l
.cond
= cond
;
270 tree
->u
.l
.body
= body
;
271 tree
->loc
= pet_tree_get_loc(body
);
273 return pet_tree_free(tree
);
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
)
294 ctx
= pet_tree_get_ctx(body
);
295 tree
= pet_tree_alloc(ctx
, pet_tree_infinite_loop
);
297 return pet_tree_free(body
);
299 tree
->u
.l
.body
= body
;
300 tree
->loc
= pet_tree_get_loc(body
);
302 return pet_tree_free(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
)
318 if (!cond
|| !then_body
)
320 ctx
= pet_tree_get_ctx(then_body
);
321 tree
= pet_tree_alloc(ctx
, pet_tree_if
);
325 tree
->u
.i
.cond
= cond
;
326 tree
->u
.i
.then_body
= then_body
;
327 tree
->loc
= pet_tree_get_loc(then_body
);
329 return pet_tree_free(tree
);
334 pet_tree_free(then_body
);
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
)
350 if (!cond
|| !then_body
|| !else_body
)
352 ctx
= pet_tree_get_ctx(then_body
);
353 tree
= pet_tree_alloc(ctx
, pet_tree_if_else
);
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
,
364 return pet_tree_free(tree
);
369 pet_tree_free(then_body
);
370 pet_tree_free(else_body
);
374 /* Return an independent duplicate of "tree".
376 static __isl_give pet_tree
*pet_tree_dup(__isl_keep pet_tree
*tree
)
384 switch (tree
->type
) {
388 dup
= pet_tree_new_block(tree
->ctx
, tree
->u
.b
.block
,
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
]));
395 dup
= pet_tree_new_break(tree
->ctx
);
397 case pet_tree_continue
:
398 dup
= pet_tree_new_continue(tree
->ctx
);
401 dup
= pet_tree_new_decl(pet_expr_copy(tree
->u
.d
.var
));
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
));
408 dup
= pet_tree_new_expr(pet_expr_copy(tree
->u
.e
.expr
));
411 dup
= pet_tree_new_for(tree
->u
.l
.independent
,
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
));
418 dup
= pet_tree_new_while(pet_expr_copy(tree
->u
.l
.cond
),
419 pet_tree_copy(tree
->u
.l
.body
));
421 case pet_tree_infinite_loop
:
422 dup
= pet_tree_new_infinite_loop(pet_tree_copy(tree
->u
.l
.body
));
425 dup
= pet_tree_new_if(pet_expr_copy(tree
->u
.i
.cond
),
426 pet_tree_copy(tree
->u
.i
.then_body
));
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
));
437 pet_loc_free(dup
->loc
);
438 dup
->loc
= pet_loc_copy(tree
->loc
);
440 return pet_tree_free(dup
);
442 dup
->label
= isl_id_copy(tree
->label
);
444 return pet_tree_free(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
)
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
)
474 /* Free a reference to "tree".
476 __isl_null pet_tree
*pet_tree_free(__isl_take pet_tree
*tree
)
485 pet_loc_free(tree
->loc
);
486 isl_id_free(tree
->label
);
488 switch (tree
->type
) {
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
);
497 case pet_tree_continue
:
499 case pet_tree_decl_init
:
500 pet_expr_free(tree
->u
.d
.init
);
502 pet_expr_free(tree
->u
.d
.var
);
505 pet_expr_free(tree
->u
.e
.expr
);
508 pet_expr_free(tree
->u
.l
.iv
);
509 pet_expr_free(tree
->u
.l
.init
);
510 pet_expr_free(tree
->u
.l
.inc
);
512 pet_expr_free(tree
->u
.l
.cond
);
513 case pet_tree_infinite_loop
:
514 pet_tree_free(tree
->u
.l
.body
);
516 case pet_tree_if_else
:
517 pet_tree_free(tree
->u
.i
.else_body
);
519 pet_expr_free(tree
->u
.i
.cond
);
520 pet_tree_free(tree
->u
.i
.then_body
);
524 isl_ctx_deref(tree
->ctx
);
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
)
548 return pet_tree_error
;
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
);
562 pet_loc_free(tree
->loc
);
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
);
581 isl_id_free(tree
->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
)
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
)
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);
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
)
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
;
637 return pet_tree_free(block
);
641 pet_tree_free(block
);
642 pet_tree_free(child
);
646 /* Does the block tree "tree" have its own scope?
648 int pet_tree_block_get_block(__isl_keep pet_tree
*tree
)
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
,
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
)
672 tree
= pet_tree_cow(tree
);
675 tree
->u
.b
.block
= is_block
;
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
,
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
)
703 switch (pet_tree_get_type(tree
)) {
705 case pet_tree_decl_init
:
712 /* Given a declaration tree "tree", return the variable that is being
715 __isl_give pet_expr
*pet_tree_decl_get_var(__isl_keep pet_tree
*tree
)
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
)
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
;
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
;
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
)
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
)
793 switch (pet_tree_get_type(tree
)) {
795 case pet_tree_infinite_loop
:
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
)
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
)
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
;
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
)
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
)
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
)
890 if (fn(tree
, user
) < 0)
893 switch (tree
->type
) {
897 for (i
= 0; i
< tree
->u
.b
.n
; ++i
)
898 if (pet_tree_foreach_sub_tree(tree
->u
.b
.child
[i
],
903 case pet_tree_continue
:
905 case pet_tree_decl_init
:
909 if (pet_tree_foreach_sub_tree(tree
->u
.i
.then_body
,
913 case pet_tree_if_else
:
914 if (pet_tree_foreach_sub_tree(tree
->u
.i
.then_body
,
917 if (pet_tree_foreach_sub_tree(tree
->u
.i
.else_body
,
923 case pet_tree_infinite_loop
:
924 if (pet_tree_foreach_sub_tree(tree
->u
.l
.body
, fn
, user
) < 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
);
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
;
956 switch (tree
->type
) {
961 case pet_tree_continue
:
962 case pet_tree_infinite_loop
:
965 if (data
->fn(tree
->u
.d
.var
, data
->user
) < 0)
968 case pet_tree_decl_init
:
969 if (data
->fn(tree
->u
.d
.var
, data
->user
) < 0)
971 if (data
->fn(tree
->u
.d
.init
, data
->user
) < 0)
975 if (data
->fn(tree
->u
.e
.expr
, data
->user
) < 0)
979 if (data
->fn(tree
->u
.i
.cond
, data
->user
) < 0)
982 case pet_tree_if_else
:
983 if (data
->fn(tree
->u
.i
.cond
, data
->user
) < 0)
987 if (data
->fn(tree
->u
.l
.cond
, data
->user
) < 0)
991 if (data
->fn(tree
->u
.l
.iv
, data
->user
) < 0)
993 if (data
->fn(tree
->u
.l
.init
, data
->user
) < 0)
995 if (data
->fn(tree
->u
.l
.cond
, data
->user
) < 0)
997 if (data
->fn(tree
->u
.l
.inc
, data
->user
) < 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
);
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
),
1070 tree
= pet_tree_cow(tree
);
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
);
1085 case pet_tree_break
:
1086 case pet_tree_continue
:
1089 tree
->u
.d
.var
= fn(tree
->u
.d
.var
, user
);
1091 return pet_tree_free(tree
);
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
);
1100 tree
->u
.e
.expr
= fn(tree
->u
.e
.expr
, user
);
1101 if (!tree
->u
.e
.expr
)
1102 return pet_tree_free(tree
);
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
);
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
);
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
);
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
);
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
);
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
);
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
,
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
),
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
),
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
,
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
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
);
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
)
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
,
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
{
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
)
1301 if (!tree1
|| !tree2
)
1307 if (tree1
->type
!= tree2
->type
)
1309 if (tree1
->label
!= tree2
->label
)
1312 switch (tree1
->type
) {
1313 case pet_tree_error
:
1315 case pet_tree_block
:
1316 if (tree1
->u
.b
.block
!= tree2
->u
.b
.block
)
1318 if (tree1
->u
.b
.n
!= tree2
->u
.b
.n
)
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
)
1327 case pet_tree_break
:
1328 case pet_tree_continue
:
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
)
1336 return pet_expr_is_equal(tree1
->u
.d
.init
, tree2
->u
.d
.init
);
1338 return pet_expr_is_equal(tree1
->u
.e
.expr
, tree2
->u
.e
.expr
);
1340 if (tree1
->u
.l
.declared
!= tree2
->u
.l
.declared
)
1342 equal
= pet_expr_is_equal(tree1
->u
.l
.iv
, tree2
->u
.l
.iv
);
1343 if (equal
< 0 || !equal
)
1345 equal
= pet_expr_is_equal(tree1
->u
.l
.init
, tree2
->u
.l
.init
);
1346 if (equal
< 0 || !equal
)
1348 equal
= pet_expr_is_equal(tree1
->u
.l
.cond
, tree2
->u
.l
.cond
);
1349 if (equal
< 0 || !equal
)
1351 equal
= pet_expr_is_equal(tree1
->u
.l
.inc
, tree2
->u
.l
.inc
);
1352 if (equal
< 0 || !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
)
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
);
1363 equal
= pet_expr_is_equal(tree1
->u
.i
.cond
, tree2
->u
.i
.cond
);
1364 if (equal
< 0 || !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
)
1372 equal
= pet_tree_is_equal(tree1
->u
.i
.then_body
,
1373 tree2
->u
.i
.then_body
);
1374 if (equal
< 0 || !equal
)
1376 return pet_tree_is_equal(tree1
->u
.i
.else_body
,
1377 tree2
->u
.i
.else_body
);
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
)
1390 if (tree
->type
!= pet_tree_expr
)
1392 if (pet_expr_get_type(tree
->u
.e
.expr
) != pet_expr_op
)
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
))
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
)
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
{
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
)
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
;
1474 if (pet_tree_foreach_expr(tree
, &check_write
, &data
) < 0 &&
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
);
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
)
1513 switch (tree
->type
) {
1514 case pet_tree_error
:
1516 case pet_tree_continue
:
1517 case pet_tree_break
:
1520 case pet_tree_decl_init
:
1523 case pet_tree_while
:
1524 case pet_tree_infinite_loop
:
1526 case pet_tree_block
:
1527 for (i
= 0; i
< tree
->u
.b
.n
; ++i
) {
1529 pet_tree_has_continue_or_break(tree
->u
.b
.child
[i
]);
1530 if (found
< 0 || found
)
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
)
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
)
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
));
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
],
1578 pet_expr_dump_with_indent(tree
->u
.e
.expr
, indent
);
1580 case pet_tree_break
:
1581 case pet_tree_continue
:
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
)
1590 print_indent(indent
);
1591 fprintf(stderr
, "init:\n");
1592 pet_expr_dump_with_indent(tree
->u
.d
.init
, indent
+ 2);
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
)
1604 print_indent(indent
);
1605 fprintf(stderr
, "else:\n");
1606 pet_tree_dump_with_indent(tree
->u
.i
.else_body
, indent
+ 2);
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);
1629 case pet_tree_error
:
1630 print_indent(indent
);
1631 fprintf(stderr
, "ERROR\n");
1636 void pet_tree_dump(__isl_keep pet_tree
*tree
)
1638 pet_tree_dump_with_indent(tree
, 0);