PetScan::extract_affine(Expr *): stop taking into account nesting_enabled
[pet.git] / nest.c
blob7263a616da4a8077be5291ad6a7426027884b3e2
1 /*
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
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
35 #include <string.h>
37 #include "expr.h"
38 #include "nest.h"
39 #include "scop.h"
41 /* A wrapper around pet_expr_free to be used as an isl_id free user function.
43 static void pet_expr_free_wrap(void *user)
45 pet_expr_free((pet_expr *) user);
48 /* Create an isl_id that refers to the nested access "expr".
50 __isl_give isl_id *pet_nested_pet_expr(__isl_take pet_expr *expr)
52 isl_id *id;
54 id = isl_id_alloc(pet_expr_get_ctx(expr), "__pet_expr", expr);
55 id = isl_id_set_free_user(id, &pet_expr_free_wrap);
57 return id;
60 /* Extract a pet_expr from an isl_id created by pet_nested_pet_expr.
61 * Such an isl_id has name "__pet_expr" and
62 * the user pointer points to a pet_expr object.
64 __isl_give pet_expr *pet_nested_extract_expr(__isl_keep isl_id *id)
66 return pet_expr_copy((pet_expr *) isl_id_get_user(id));
69 /* Does "id" refer to a nested access created by pet_nested_pet_expr?
71 int pet_nested_in_id(__isl_keep isl_id *id)
73 const char *name;
75 if (!id)
76 return 0;
77 if (!isl_id_get_user(id))
78 return 0;
80 name = isl_id_get_name(id);
81 return !strcmp(name, "__pet_expr");
84 /* Does parameter "pos" of "space" refer to a nested access?
86 static int pet_nested_in_space(__isl_keep isl_space *space, int pos)
88 int nested;
89 isl_id *id;
91 id = isl_space_get_dim_id(space, isl_dim_param, pos);
92 nested = pet_nested_in_id(id);
93 isl_id_free(id);
95 return nested;
98 /* Does parameter "pos" of "set" refer to a nested access?
100 int pet_nested_in_set(__isl_keep isl_set *set, int pos)
102 int nested;
103 isl_id *id;
105 id = isl_set_get_dim_id(set, isl_dim_param, pos);
106 nested = pet_nested_in_id(id);
107 isl_id_free(id);
109 return nested;
112 /* Does parameter "pos" of "map" refer to a nested access?
114 int pet_nested_in_map(__isl_keep isl_map *map, int pos)
116 int nested;
117 isl_id *id;
119 id = isl_map_get_dim_id(map, isl_dim_param, pos);
120 nested = pet_nested_in_id(id);
121 isl_id_free(id);
123 return nested;
126 /* Does "space" involve any parameters that refer to nested accesses?
128 int pet_nested_any_in_space(__isl_keep isl_space *space)
130 int i;
131 int nparam;
133 nparam = isl_space_dim(space, isl_dim_param);
134 for (i = 0; i < nparam; ++i)
135 if (pet_nested_in_space(space, i))
136 return 1;
138 return 0;
141 /* Does "pa" involve any parameters that refer to nested accesses?
143 int pet_nested_any_in_pw_aff(__isl_keep isl_pw_aff *pa)
145 isl_space *space;
146 int nested;
148 space = isl_pw_aff_get_space(pa);
149 nested = pet_nested_any_in_space(space);
150 isl_space_free(space);
152 return nested;
155 /* How many parameters of "space" refer to nested accesses?
157 int pet_nested_n_in_space(__isl_keep isl_space *space)
159 int i, n = 0;
160 int nparam;
162 nparam = isl_space_dim(space, isl_dim_param);
163 for (i = 0; i < nparam; ++i)
164 if (pet_nested_in_space(space, i))
165 ++n;
167 return n;
170 /* How many parameters of "map" refer to nested accesses?
172 int pet_nested_n_in_map(__isl_keep isl_map *map)
174 isl_space *space;
175 int n;
177 space = isl_map_get_space(map);
178 n = pet_nested_n_in_space(space);
179 isl_space_free(space);
181 return n;
184 /* How many parameters of "set" refer to nested accesses?
186 int pet_nested_n_in_set(__isl_keep isl_set *set)
188 isl_space *space;
189 int n;
191 space = isl_set_get_space(set);
192 n = pet_nested_n_in_space(space);
193 isl_space_free(space);
195 return n;
198 /* Remove all parameters from "set" that refer to nested accesses.
200 __isl_give isl_set *pet_nested_remove_from_set(__isl_take isl_set *set)
202 int i;
203 int nparam;
205 nparam = isl_set_dim(set, isl_dim_param);
206 for (i = nparam - 1; i >= 0; --i)
207 if (pet_nested_in_set(set, i))
208 set = isl_set_project_out(set, isl_dim_param, i, 1);
210 return set;
213 /* Remove all parameters from "map" that refer to nested accesses.
215 static __isl_give isl_map *pet_nested_remove_from_map(__isl_take isl_map *map)
217 int i;
218 int nparam;
220 nparam = isl_map_dim(map, isl_dim_param);
221 for (i = nparam - 1; i >= 0; --i)
222 if (pet_nested_in_map(map, i))
223 map = isl_map_project_out(map, isl_dim_param, i, 1);
225 return map;
228 /* Remove all parameters from "mpa" that refer to nested accesses.
230 static __isl_give isl_multi_pw_aff *pet_nested_remove_from_multi_pw_aff(
231 __isl_take isl_multi_pw_aff *mpa)
233 int i;
234 int nparam;
235 isl_space *space;
237 space = isl_multi_pw_aff_get_space(mpa);
238 nparam = isl_space_dim(space, isl_dim_param);
239 for (i = nparam - 1; i >= 0; --i) {
240 if (!pet_nested_in_space(space, i))
241 continue;
242 mpa = isl_multi_pw_aff_drop_dims(mpa, isl_dim_param, i, 1);
244 isl_space_free(space);
246 return mpa;
249 /* Remove all parameters from the index expression and access relation of "expr"
250 * that refer to nested accesses.
252 static __isl_give pet_expr *expr_remove_nested_parameters(
253 __isl_take pet_expr *expr, void *user)
255 expr = pet_expr_cow(expr);
256 if (!expr)
257 return NULL;
259 expr->acc.access = pet_nested_remove_from_map(expr->acc.access);
260 expr->acc.index = pet_nested_remove_from_multi_pw_aff(expr->acc.index);
261 if (!expr->acc.access || !expr->acc.index)
262 return pet_expr_free(expr);
264 return expr;
267 /* Remove all nested access parameters from the schedule and all
268 * accesses of "stmt".
269 * There is no need to remove them from the domain as these parameters
270 * have already been removed from the domain when this function is called.
272 struct pet_stmt *pet_stmt_remove_nested_parameters(struct pet_stmt *stmt)
274 int i;
276 if (!stmt)
277 return NULL;
278 stmt->schedule = pet_nested_remove_from_map(stmt->schedule);
279 stmt->body = pet_expr_map_access(stmt->body,
280 &expr_remove_nested_parameters, NULL);
281 if (!stmt->schedule || !stmt->body)
282 goto error;
283 for (i = 0; i < stmt->n_arg; ++i) {
284 stmt->args[i] = pet_expr_map_access(stmt->args[i],
285 &expr_remove_nested_parameters, NULL);
286 if (!stmt->args[i])
287 goto error;
290 return stmt;
291 error:
292 pet_stmt_free(stmt);
293 return NULL;