2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2012-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
42 /* A wrapper around pet_expr_free to be used as an isl_id free user function.
44 static void pet_expr_free_wrap(void *user
)
46 pet_expr_free((pet_expr
*) user
);
49 /* Create an isl_id that refers to the nested access "expr".
51 __isl_give isl_id
*pet_nested_pet_expr(__isl_take pet_expr
*expr
)
55 id
= isl_id_alloc(pet_expr_get_ctx(expr
), "__pet_expr", expr
);
56 id
= isl_id_set_free_user(id
, &pet_expr_free_wrap
);
61 /* Extract a pet_expr from an isl_id created by pet_nested_pet_expr.
62 * Such an isl_id has name "__pet_expr" and
63 * the user pointer points to a pet_expr object.
65 __isl_give pet_expr
*pet_nested_extract_expr(__isl_keep isl_id
*id
)
67 return pet_expr_copy((pet_expr
*) isl_id_get_user(id
));
70 /* Does "id" refer to a nested access created by pet_nested_pet_expr?
72 int pet_nested_in_id(__isl_keep isl_id
*id
)
78 if (!isl_id_get_user(id
))
81 name
= isl_id_get_name(id
);
82 return !strcmp(name
, "__pet_expr");
85 /* Does parameter "pos" of "space" refer to a nested access?
87 static int pet_nested_in_space(__isl_keep isl_space
*space
, int pos
)
92 id
= isl_space_get_dim_id(space
, isl_dim_param
, pos
);
93 nested
= pet_nested_in_id(id
);
99 /* Does parameter "pos" of "set" refer to a nested access?
101 int pet_nested_in_set(__isl_keep isl_set
*set
, int pos
)
106 id
= isl_set_get_dim_id(set
, isl_dim_param
, pos
);
107 nested
= pet_nested_in_id(id
);
113 /* Does parameter "pos" of "map" refer to a nested access?
115 int pet_nested_in_map(__isl_keep isl_map
*map
, int pos
)
120 id
= isl_map_get_dim_id(map
, isl_dim_param
, pos
);
121 nested
= pet_nested_in_id(id
);
127 /* Does "space" involve any parameters that refer to nested accesses?
129 int pet_nested_any_in_space(__isl_keep isl_space
*space
)
134 nparam
= isl_space_dim(space
, isl_dim_param
);
135 for (i
= 0; i
< nparam
; ++i
)
136 if (pet_nested_in_space(space
, i
))
142 /* Does "pa" involve any parameters that refer to nested accesses?
144 int pet_nested_any_in_pw_aff(__isl_keep isl_pw_aff
*pa
)
149 space
= isl_pw_aff_get_space(pa
);
150 nested
= pet_nested_any_in_space(space
);
151 isl_space_free(space
);
156 /* How many parameters of "space" refer to nested accesses?
158 int pet_nested_n_in_space(__isl_keep isl_space
*space
)
163 nparam
= isl_space_dim(space
, isl_dim_param
);
164 for (i
= 0; i
< nparam
; ++i
)
165 if (pet_nested_in_space(space
, i
))
171 /* How many parameters of "map" refer to nested accesses?
173 int pet_nested_n_in_map(__isl_keep isl_map
*map
)
178 space
= isl_map_get_space(map
);
179 n
= pet_nested_n_in_space(space
);
180 isl_space_free(space
);
185 /* How many parameters of "set" refer to nested accesses?
187 int pet_nested_n_in_set(__isl_keep isl_set
*set
)
192 space
= isl_set_get_space(set
);
193 n
= pet_nested_n_in_space(space
);
194 isl_space_free(space
);
199 /* Remove all parameters from "space" that refer to nested accesses.
201 __isl_give isl_space
*pet_nested_remove_from_space(__isl_take isl_space
*space
)
206 nparam
= isl_space_dim(space
, isl_dim_param
);
207 for (i
= nparam
- 1; i
>= 0; --i
)
208 if (pet_nested_in_space(space
, i
))
209 space
= isl_space_drop_dims(space
, isl_dim_param
, i
, 1);
214 /* Remove all parameters from "set" that refer to nested accesses.
216 __isl_give isl_set
*pet_nested_remove_from_set(__isl_take isl_set
*set
)
221 nparam
= isl_set_dim(set
, isl_dim_param
);
222 for (i
= nparam
- 1; i
>= 0; --i
)
223 if (pet_nested_in_set(set
, i
))
224 set
= isl_set_project_out(set
, isl_dim_param
, i
, 1);
229 /* Remove all parameters from "map" that refer to nested accesses.
231 static __isl_give isl_map
*pet_nested_remove_from_map(__isl_take isl_map
*map
)
236 nparam
= isl_map_dim(map
, isl_dim_param
);
237 for (i
= nparam
- 1; i
>= 0; --i
)
238 if (pet_nested_in_map(map
, i
))
239 map
= isl_map_project_out(map
, isl_dim_param
, i
, 1);
244 /* Remove all parameters from "mpa" that refer to nested accesses.
246 static __isl_give isl_multi_pw_aff
*pet_nested_remove_from_multi_pw_aff(
247 __isl_take isl_multi_pw_aff
*mpa
)
253 space
= isl_multi_pw_aff_get_space(mpa
);
254 nparam
= isl_space_dim(space
, isl_dim_param
);
255 for (i
= nparam
- 1; i
>= 0; --i
) {
256 if (!pet_nested_in_space(space
, i
))
258 mpa
= isl_multi_pw_aff_drop_dims(mpa
, isl_dim_param
, i
, 1);
260 isl_space_free(space
);
265 /* Remove all parameters from the index expression and access relation of "expr"
266 * that refer to nested accesses.
268 static __isl_give pet_expr
*expr_remove_nested_parameters(
269 __isl_take pet_expr
*expr
, void *user
)
271 expr
= pet_expr_cow(expr
);
275 expr
->acc
.access
= pet_nested_remove_from_map(expr
->acc
.access
);
276 expr
->acc
.index
= pet_nested_remove_from_multi_pw_aff(expr
->acc
.index
);
277 if (!expr
->acc
.access
|| !expr
->acc
.index
)
278 return pet_expr_free(expr
);
283 /* Remove all nested access parameters from the schedule and all
284 * accesses of "stmt".
285 * There is no need to remove them from the domain as these parameters
286 * have already been removed from the domain when this function is called.
288 struct pet_stmt
*pet_stmt_remove_nested_parameters(struct pet_stmt
*stmt
)
294 stmt
->schedule
= pet_nested_remove_from_map(stmt
->schedule
);
295 stmt
->body
= pet_expr_map_access(stmt
->body
,
296 &expr_remove_nested_parameters
, NULL
);
297 if (!stmt
->schedule
|| !stmt
->body
)
299 for (i
= 0; i
< stmt
->n_arg
; ++i
) {
300 stmt
->args
[i
] = pet_expr_map_access(stmt
->args
[i
],
301 &expr_remove_nested_parameters
, NULL
);
312 /* For each nested access parameter in "space",
313 * construct a corresponding pet_expr, place it in args and
314 * record its position in "param2pos".
315 * "n_arg" is the number of elements that are already in args.
316 * The position recorded in "param2pos" takes this number into account.
317 * If the pet_expr corresponding to a parameter is identical to
318 * the pet_expr corresponding to an earlier parameter, then these two
319 * parameters are made to refer to the same element in args.
321 * Return the final number of elements in args or -1 if an error has occurred.
323 int pet_extract_nested_from_space(__isl_keep isl_space
*space
,
324 int n_arg
, __isl_give pet_expr
**args
, int *param2pos
)
328 nparam
= isl_space_dim(space
, isl_dim_param
);
329 for (i
= 0; i
< nparam
; ++i
) {
331 isl_id
*id
= isl_space_get_dim_id(space
, isl_dim_param
, i
);
333 if (!pet_nested_in_id(id
)) {
338 args
[n_arg
] = pet_nested_extract_expr(id
);
343 for (j
= 0; j
< n_arg
; ++j
)
344 if (pet_expr_is_equal(args
[j
], args
[n_arg
]))
348 pet_expr_free(args
[n_arg
]);
352 param2pos
[i
] = n_arg
++;
358 /* For each nested access parameter in the access relations in "expr",
359 * construct a corresponding pet_expr, append it to the arguments of "expr"
360 * and record its position in "param2pos" (relative to the initial
361 * number of arguments).
362 * n is the number of nested access parameters.
364 __isl_give pet_expr
*pet_expr_extract_nested(__isl_take pet_expr
*expr
, int n
,
372 ctx
= pet_expr_get_ctx(expr
);
373 args
= isl_calloc_array(ctx
, pet_expr
*, n
);
375 return pet_expr_free(expr
);
377 n_arg
= pet_expr_get_n_arg(expr
);
378 space
= pet_expr_access_get_parameter_space(expr
);
379 n
= pet_extract_nested_from_space(space
, 0, args
, param2pos
);
380 isl_space_free(space
);
383 expr
= pet_expr_free(expr
);
385 expr
= pet_expr_set_n_arg(expr
, n_arg
+ n
);
387 for (i
= 0; i
< n
; ++i
)
388 expr
= pet_expr_set_arg(expr
, n_arg
+ i
, args
[i
]);
394 /* Are "expr1" and "expr2" both array accesses such that
395 * the access relation of "expr1" is a subset of that of "expr2"?
396 * Only take into account the first "n_arg" arguments.
398 static int is_sub_access(__isl_keep pet_expr
*expr1
, __isl_keep pet_expr
*expr2
,
402 isl_map
*access1
, *access2
;
406 if (!expr1
|| !expr2
)
408 if (pet_expr_get_type(expr1
) != pet_expr_access
)
410 if (pet_expr_get_type(expr2
) != pet_expr_access
)
412 if (pet_expr_is_affine(expr1
))
414 if (pet_expr_is_affine(expr2
))
416 n1
= pet_expr_get_n_arg(expr1
);
419 n2
= pet_expr_get_n_arg(expr2
);
424 for (i
= 0; i
< n1
; ++i
) {
425 pet_expr
*arg1
, *arg2
;
427 arg1
= pet_expr_get_arg(expr1
, i
);
428 arg2
= pet_expr_get_arg(expr2
, i
);
429 equal
= pet_expr_is_equal(arg1
, arg2
);
432 if (equal
< 0 || !equal
)
435 id1
= pet_expr_access_get_id(expr1
);
436 id2
= pet_expr_access_get_id(expr2
);
444 access1
= pet_expr_access_get_access(expr1
);
445 access2
= pet_expr_access_get_access(expr2
);
446 is_subset
= isl_map_is_subset(access1
, access2
);
447 isl_map_free(access1
);
448 isl_map_free(access2
);
453 /* Mark self dependences among the arguments of "expr" starting at "first".
454 * These arguments have already been added to the list of arguments
455 * but are not yet referenced directly from the index expression.
456 * Instead, they are still referenced through parameters encoding
459 * In particular, if "expr" is a read access, then check the arguments
460 * starting at "first" to see if "expr" accesses a subset of
461 * the elements accessed by the argument, or under more restrictive conditions.
462 * If so, then this nested access can be removed from the constraints
463 * governing the outer access. There is no point in restricting
464 * accesses to an array if in order to evaluate the restriction,
465 * we have to access the same elements (or more).
467 * Rather than removing the argument at this point (which would
468 * complicate the resolution of the other nested accesses), we simply
469 * mark it here by replacing it by a NaN pet_expr.
470 * These NaNs are then later removed in remove_marked_self_dependences.
472 static __isl_give pet_expr
*mark_self_dependences(__isl_take pet_expr
*expr
,
477 if (pet_expr_access_is_write(expr
))
480 n
= pet_expr_get_n_arg(expr
);
481 for (i
= first
; i
< n
; ++i
) {
485 arg
= pet_expr_get_arg(expr
, i
);
486 mark
= is_sub_access(expr
, arg
, first
);
489 return pet_expr_free(expr
);
493 arg
= pet_expr_new_int(isl_val_nan(pet_expr_get_ctx(expr
)));
494 expr
= pet_expr_set_arg(expr
, i
, arg
);
500 /* Is "expr" a NaN integer expression?
502 static int expr_is_nan(__isl_keep pet_expr
*expr
)
507 if (pet_expr_get_type(expr
) != pet_expr_int
)
510 v
= pet_expr_int_get_val(expr
);
511 is_nan
= isl_val_is_nan(v
);
517 /* Check if we have marked any self dependences (as NaNs)
518 * in mark_self_dependences and remove them here.
519 * It is safe to project them out since these arguments
520 * can at most be referenced from the condition of the access relation,
521 * but do not appear in the index expression.
522 * "dim" is the dimension of the iteration domain.
524 static __isl_give pet_expr
*remove_marked_self_dependences(
525 __isl_take pet_expr
*expr
, int dim
, int first
)
529 n
= pet_expr_get_n_arg(expr
);
530 for (i
= n
- 1; i
>= first
; --i
) {
534 arg
= pet_expr_get_arg(expr
, i
);
535 is_nan
= expr_is_nan(arg
);
539 expr
= pet_expr_access_project_out_arg(expr
, dim
, i
);
545 /* Look for parameters in any access relation in "expr" that
546 * refer to nested accesses. In particular, these are
547 * parameters with name "__pet_expr".
549 * If there are any such parameters, then the domain of the index
550 * expression and the access relation, which is either [] or
551 * [[] -> [a_1,...,a_m]] at this point, is replaced by [[] -> [t_1,...,t_n]] or
552 * [[] -> [a_1,...,a_m,t_1,...,t_n]], with m the original number of arguments
553 * (n_arg) and n the number of these parameters
554 * (after identifying identical nested accesses).
556 * This transformation is performed in several steps.
557 * We first extract the arguments in pet_expr_extract_nested.
558 * param2pos maps the original parameter position to the position
559 * of the argument beyond the initial (n_arg) number of arguments.
560 * Then we move these parameters to input dimensions.
561 * t2pos maps the positions of these temporary input dimensions
562 * to the positions of the corresponding arguments.
563 * Finally, we express these temporary dimensions in terms of the domain
564 * [[] -> [a_1,...,a_m,t_1,...,t_n]] and precompose index expression and access
565 * relations with this function.
567 __isl_give pet_expr
*pet_expr_resolve_nested(__isl_take pet_expr
*expr
)
582 n_arg
= pet_expr_get_n_arg(expr
);
583 for (i
= 0; i
< n_arg
; ++i
) {
585 arg
= pet_expr_get_arg(expr
, i
);
586 arg
= pet_expr_resolve_nested(arg
);
587 expr
= pet_expr_set_arg(expr
, i
, arg
);
590 if (pet_expr_get_type(expr
) != pet_expr_access
)
593 space
= pet_expr_access_get_parameter_space(expr
);
594 n
= pet_nested_n_in_space(space
);
595 isl_space_free(space
);
599 expr
= pet_expr_access_align_params(expr
);
603 space
= pet_expr_access_get_parameter_space(expr
);
604 nparam
= isl_space_dim(space
, isl_dim_param
);
605 isl_space_free(space
);
607 ctx
= pet_expr_get_ctx(expr
);
609 param2pos
= isl_alloc_array(ctx
, int, nparam
);
610 t2pos
= isl_alloc_array(ctx
, int, n
);
613 expr
= pet_expr_extract_nested(expr
, n
, param2pos
);
614 expr
= mark_self_dependences(expr
, n_arg
);
619 space
= pet_expr_access_get_parameter_space(expr
);
620 nparam
= isl_space_dim(space
, isl_dim_param
);
621 for (i
= nparam
- 1; i
>= 0; --i
) {
622 isl_id
*id
= isl_space_get_dim_id(space
, isl_dim_param
, i
);
623 if (!pet_nested_in_id(id
)) {
628 expr
= pet_expr_access_move_dims(expr
,
629 isl_dim_in
, n_arg
+ n
, isl_dim_param
, i
, 1);
630 t2pos
[n
] = n_arg
+ param2pos
[i
];
635 isl_space_free(space
);
637 space
= pet_expr_access_get_parameter_space(expr
);
638 space
= isl_space_set_from_params(space
);
639 space
= isl_space_add_dims(space
, isl_dim_set
,
640 pet_expr_get_n_arg(expr
));
641 space
= isl_space_wrap(isl_space_from_range(space
));
642 ls
= isl_local_space_from_space(isl_space_copy(space
));
643 space
= isl_space_from_domain(space
);
644 space
= isl_space_add_dims(space
, isl_dim_out
, n_arg
+ n
);
645 ma
= isl_multi_aff_zero(space
);
647 for (i
= 0; i
< n_arg
; ++i
) {
648 aff
= isl_aff_var_on_domain(isl_local_space_copy(ls
),
650 ma
= isl_multi_aff_set_aff(ma
, i
, aff
);
652 for (i
= 0; i
< n
; ++i
) {
653 aff
= isl_aff_var_on_domain(isl_local_space_copy(ls
),
654 isl_dim_set
, t2pos
[i
]);
655 ma
= isl_multi_aff_set_aff(ma
, n_arg
+ i
, aff
);
657 isl_local_space_free(ls
);
659 expr
= pet_expr_access_pullback_multi_aff(expr
, ma
);
661 expr
= remove_marked_self_dependences(expr
, 0, n_arg
);
669 return pet_expr_free(expr
);
672 /* Precompose the access relation and the index expression associated
673 * to "expr" with the function pointed to by "user",
674 * thereby embedding the access relation in the domain of this function.
675 * The initial domain of the access relation and the index expression
676 * is the zero-dimensional domain.
678 static __isl_give pet_expr
*embed_access(__isl_take pet_expr
*expr
, void *user
)
680 isl_multi_aff
*ma
= (isl_multi_aff
*) user
;
682 return pet_expr_access_pullback_multi_aff(expr
, isl_multi_aff_copy(ma
));
685 /* Precompose all access relations in "expr" with "ma", thereby
686 * embedding them in the domain of "ma".
688 static __isl_give pet_expr
*embed(__isl_take pet_expr
*expr
,
689 __isl_keep isl_multi_aff
*ma
)
691 return pet_expr_map_access(expr
, &embed_access
, ma
);
694 /* For each nested access parameter in the domain of "stmt",
695 * construct a corresponding pet_expr, place it before the original
696 * elements in stmt->args and record its position in "param2pos".
697 * n is the number of nested access parameters.
699 struct pet_stmt
*pet_stmt_extract_nested(struct pet_stmt
*stmt
, int n
,
708 ctx
= isl_set_get_ctx(stmt
->domain
);
711 args
= isl_calloc_array(ctx
, pet_expr
*, n
+ n_arg
);
715 space
= isl_set_get_space(stmt
->domain
);
716 n_arg
= pet_extract_nested_from_space(space
, 0, args
, param2pos
);
717 isl_space_free(space
);
722 for (i
= 0; i
< stmt
->n_arg
; ++i
)
723 args
[n_arg
+ i
] = stmt
->args
[i
];
726 stmt
->n_arg
+= n_arg
;
731 for (i
= 0; i
< n
; ++i
)
732 pet_expr_free(args
[i
]);
739 /* Check whether any of the arguments i of "stmt" starting at position "n"
740 * is equal to one of the first "n" arguments j.
741 * If so, combine the constraints on arguments i and j and remove
744 static struct pet_stmt
*remove_duplicate_arguments(struct pet_stmt
*stmt
, int n
)
753 if (n
== stmt
->n_arg
)
756 map
= isl_set_unwrap(stmt
->domain
);
758 for (i
= stmt
->n_arg
- 1; i
>= n
; --i
) {
759 for (j
= 0; j
< n
; ++j
)
760 if (pet_expr_is_equal(stmt
->args
[i
], stmt
->args
[j
]))
765 map
= isl_map_equate(map
, isl_dim_out
, i
, isl_dim_out
, j
);
766 map
= isl_map_project_out(map
, isl_dim_out
, i
, 1);
768 pet_expr_free(stmt
->args
[i
]);
769 for (j
= i
; j
+ 1 < stmt
->n_arg
; ++j
)
770 stmt
->args
[j
] = stmt
->args
[j
+ 1];
774 stmt
->domain
= isl_map_wrap(map
);
783 /* Look for parameters in the iteration domain of "stmt" that
784 * refer to nested accesses. In particular, these are
785 * parameters with name "__pet_expr".
787 * If there are any such parameters, then as many extra variables
788 * (after identifying identical nested accesses) are inserted in the
789 * range of the map wrapped inside the domain, before the original variables.
790 * If the original domain is not a wrapped map, then a new wrapped
791 * map is created with zero output dimensions.
792 * The parameters are then equated to the corresponding output dimensions
793 * and subsequently projected out, from the iteration domain,
794 * the schedule and the access relations.
795 * For each of the output dimensions, a corresponding argument
796 * expression is inserted. Initially they are created with
797 * a zero-dimensional domain, so they have to be embedded
798 * in the current iteration domain.
799 * param2pos maps the position of the parameter to the position
800 * of the corresponding output dimension in the wrapped map.
802 struct pet_stmt
*pet_stmt_resolve_nested(struct pet_stmt
*stmt
)
817 n
= pet_nested_n_in_set(stmt
->domain
);
821 ctx
= isl_set_get_ctx(stmt
->domain
);
824 nparam
= isl_set_dim(stmt
->domain
, isl_dim_param
);
825 param2pos
= isl_alloc_array(ctx
, int, nparam
);
826 stmt
= pet_stmt_extract_nested(stmt
, n
, param2pos
);
832 n
= stmt
->n_arg
- n_arg
;
833 if (isl_set_is_wrapping(stmt
->domain
))
834 map
= isl_set_unwrap(stmt
->domain
);
836 map
= isl_map_from_domain(stmt
->domain
);
837 map
= isl_map_insert_dims(map
, isl_dim_out
, 0, n
);
839 for (i
= nparam
- 1; i
>= 0; --i
) {
842 if (!pet_nested_in_map(map
, i
))
845 id
= pet_expr_access_get_id(stmt
->args
[param2pos
[i
]]);
846 map
= isl_map_set_dim_id(map
, isl_dim_out
, param2pos
[i
], id
);
847 map
= isl_map_equate(map
, isl_dim_param
, i
, isl_dim_out
,
849 map
= isl_map_project_out(map
, isl_dim_param
, i
, 1);
852 stmt
->domain
= isl_map_wrap(map
);
854 space
= isl_space_unwrap(isl_set_get_space(stmt
->domain
));
855 space
= isl_space_from_domain(isl_space_domain(space
));
856 ma
= isl_multi_aff_zero(space
);
857 for (pos
= 0; pos
< n
; ++pos
)
858 stmt
->args
[pos
] = embed(stmt
->args
[pos
], ma
);
859 isl_multi_aff_free(ma
);
861 stmt
= pet_stmt_remove_nested_parameters(stmt
);
862 stmt
= remove_duplicate_arguments(stmt
, n
);
868 /* For each statement in "scop", move the parameters that correspond
869 * to nested access into the ranges of the domains and create
870 * corresponding argument expressions.
872 struct pet_scop
*pet_scop_resolve_nested(struct pet_scop
*scop
)
879 for (i
= 0; i
< scop
->n_stmt
; ++i
) {
880 scop
->stmts
[i
] = pet_stmt_resolve_nested(scop
->stmts
[i
]);
882 return pet_scop_free(scop
);