export pet_expr_new_cast
[pet.git] / summary.c
blobcc2b12a6547a736c545aeecc79611236b48d4d3b
1 #include "aff.h"
2 #include "summary.h"
4 /* A pet_function_summary objects represents an argument of a function.
6 * If "type" is pet_arg_int, then the argument has an integer type and
7 * can be used to describe the accesses performed by the pet_arg_array
8 * arguments. In this case, "id" refers to the formal argument.
10 * If "type" is pet_arg_array, then we keep track of the accesses
11 * through this argument in the access relations in "access".
12 * The domains of these access relations refer to the integer arguments
13 * of the function. That is, the input dimensions correspond
14 * to the arguments of type pet_arg_int.
16 * If "type" is pet_arg_other, then we do not keep track of any
17 * further information.
19 struct pet_function_summary_arg {
20 enum pet_arg_type type;
22 union {
23 isl_id *id;
24 isl_union_map *access[pet_expr_access_end];
28 /* A pet_function_summary object keeps track of the accesses performed
29 * by a function in terms of the function arguments.
31 * "n" is the number of arguments.
32 * "arg" contains a description of the "n" arguments.
34 struct pet_function_summary {
35 int ref;
36 isl_ctx *ctx;
38 unsigned n;
40 struct pet_function_summary_arg arg[];
43 /* Construct and return a new pet_function_summary object with
44 * "n_arg" arguments, initialized to pet_arg_other.
46 __isl_give pet_function_summary *pet_function_summary_alloc(isl_ctx *ctx,
47 unsigned n_arg)
49 pet_function_summary *summary;
50 int i;
52 summary = isl_calloc(ctx, struct pet_function_summary,
53 sizeof(struct pet_function_summary) +
54 n_arg * sizeof(struct pet_function_summary_arg));
55 if (!summary)
56 return summary;
58 summary->ctx = ctx;
59 isl_ctx_ref(ctx);
60 summary->ref = 1;
61 summary->n = n_arg;
62 for (i = 0; i < n_arg; ++i)
63 summary->arg[i].type = pet_arg_other;
65 return summary;
68 /* Return an extra reference to "summary".
70 __isl_give pet_function_summary *pet_function_summary_copy(
71 __isl_keep pet_function_summary *summary)
73 if (!summary)
74 return NULL;
76 summary->ref++;
77 return summary;
80 /* Free the data stored in "arg".
82 static void free_arg(struct pet_function_summary_arg *arg)
84 enum pet_expr_access_type type;
86 if (arg->type == pet_arg_int)
87 isl_id_free(arg->id);
88 if (arg->type != pet_arg_array)
89 return;
90 for (type = pet_expr_access_begin; type < pet_expr_access_end; ++type)
91 arg->access[type] = isl_union_map_free(arg->access[type]);
94 /* Free a reference to "summary".
96 __isl_null pet_function_summary *pet_function_summary_free(
97 __isl_take pet_function_summary *summary)
99 int i;
101 if (!summary)
102 return NULL;
103 if (--summary->ref > 0)
104 return NULL;
106 for (i = 0; i < summary->n; ++i)
107 free_arg(&summary->arg[i]);
109 isl_ctx_deref(summary->ctx);
110 free(summary);
111 return NULL;
114 /* Return the number of arguments of the function summarized by "summary".
116 int pet_function_summary_get_n_arg(__isl_keep pet_function_summary *summary)
118 if (!summary)
119 return -1;
121 return summary->n;
124 /* Mark the argument at position "pos" of "summary" as an integer argument
125 * with the given identifier.
127 __isl_give pet_function_summary *pet_function_summary_set_int(
128 __isl_take pet_function_summary *summary, int pos,
129 __isl_take isl_id *id)
131 if (!summary || !id)
132 goto error;
134 if (pos < 0 || pos >= summary->n)
135 isl_die(summary->ctx, isl_error_invalid,
136 "position out of bounds", goto error);
138 free_arg(&summary->arg[pos]);
140 summary->arg[pos].type = pet_arg_int;
141 summary->arg[pos].id = id;
143 return summary;
144 error:
145 isl_id_free(id);
146 return pet_function_summary_free(summary);
149 /* Mark the argument at position "pos" of "summary" as an array argument
150 * with the given sets of accessed elements.
151 * The integer arguments of "summary" may appear as parameters
152 * in these sets of accessed elements.
153 * These parameters are turned into input dimensions of
154 * the corresponding access relations, which are then associated
155 * to the array argument.
156 * The order of the input dimensions is the same as the order
157 * in which the integer arguments appear in the sequence of arguments.
159 __isl_give pet_function_summary *pet_function_summary_set_array(
160 __isl_take pet_function_summary *summary, int pos,
161 __isl_take isl_union_set *may_read, __isl_take isl_union_set *may_write,
162 __isl_take isl_union_set *must_write)
164 int i, n;
165 isl_space *space;
166 enum pet_expr_access_type type;
168 if (!summary || !may_read || !may_write || !must_write)
169 goto error;
171 if (pos < 0 || pos >= summary->n)
172 isl_die(summary->ctx, isl_error_invalid,
173 "position out of bounds", goto error);
175 n = 0;
176 for (i = 0; i < summary->n; ++i)
177 if (pet_function_summary_arg_is_int(summary, i))
178 n++;
180 space = isl_space_params_alloc(summary->ctx, n);
182 n = 0;
183 for (i = 0; i < summary->n; ++i)
184 if (pet_function_summary_arg_is_int(summary, i))
185 space = isl_space_set_dim_id(space, isl_dim_param, n++,
186 isl_id_copy(summary->arg[i].id));
188 free_arg(&summary->arg[pos]);
190 summary->arg[pos].type = pet_arg_array;
191 summary->arg[pos].access[pet_expr_access_may_read] =
192 isl_union_map_from_range(may_read);
193 summary->arg[pos].access[pet_expr_access_may_write] =
194 isl_union_map_from_range(may_write);
195 summary->arg[pos].access[pet_expr_access_must_write] =
196 isl_union_map_from_range(must_write);
198 for (type = pet_expr_access_begin; type < pet_expr_access_end; ++type) {
199 isl_union_map *umap;
200 umap = summary->arg[pos].access[type];
201 umap = isl_union_map_align_params(umap, isl_space_copy(space));
202 umap = pet_union_map_move_dims(umap, isl_dim_in, 0,
203 isl_dim_param, 0, n);
204 summary->arg[pos].access[type] = umap;
205 if (!umap)
206 break;
209 isl_space_free(space);
211 if (type < pet_expr_access_end)
212 return pet_function_summary_free(summary);
214 return summary;
215 error:
216 isl_union_set_free(may_read);
217 isl_union_set_free(may_write);
218 isl_union_set_free(must_write);
219 return pet_function_summary_free(summary);
222 /* Has the argument of "summary" at position "pos" been marked
223 * as an integer argument?
225 int pet_function_summary_arg_is_int(__isl_keep pet_function_summary *summary,
226 int pos)
228 if (!summary)
229 return -1;
231 if (pos < 0 || pos >= summary->n)
232 isl_die(summary->ctx, isl_error_invalid,
233 "position out of bounds", return -1);
235 return summary->arg[pos].type == pet_arg_int;
238 /* Has the argument of "summary" at position "pos" been marked
239 * as an array argument?
241 int pet_function_summary_arg_is_array(__isl_keep pet_function_summary *summary,
242 int pos)
244 if (!summary)
245 return -1;
247 if (pos < 0 || pos >= summary->n)
248 isl_die(summary->ctx, isl_error_invalid,
249 "position out of bounds", return -1);
251 return summary->arg[pos].type == pet_arg_array;
254 /* Return the access relation of type "type" associated to
255 * the argument of "summary" at position "pos", which is assumed
256 * to be an array argument.
258 __isl_give isl_union_map *pet_function_summary_arg_get_access(
259 __isl_keep pet_function_summary *summary, int pos,
260 enum pet_expr_access_type type)
262 if (!summary)
263 return NULL;
264 if (pos < 0 || pos >= summary->n)
265 isl_die(summary->ctx, isl_error_invalid,
266 "position out of bounds", return NULL);
267 if (summary->arg[pos].type != pet_arg_array)
268 isl_die(summary->ctx, isl_error_invalid,
269 "not an array argument", return NULL);
271 return isl_union_map_copy(summary->arg[pos].access[type]);
274 void pet_function_summary_dump_with_indent(
275 __isl_keep pet_function_summary *summary, int indent)
277 int i;
279 if (!summary)
280 return;
281 fprintf(stderr, "%*s", indent, "");
282 fprintf(stderr, "n: %d\n", summary->n);
283 for (i = 0; i < summary->n; ++i) {
284 switch (summary->arg[i].type) {
285 case pet_arg_int:
286 fprintf(stderr, "%*s", indent, "");
287 fprintf(stderr, "id:");
288 isl_id_dump(summary->arg[i].id);
289 break;
290 case pet_arg_other:
291 fprintf(stderr, "%*s", indent, "");
292 fprintf(stderr, "other\n");
293 break;
294 case pet_arg_array:
295 fprintf(stderr, "%*s", indent, "");
296 fprintf(stderr, "may_read: ");
297 isl_union_map_dump(
298 summary->arg[i].access[pet_expr_access_may_read]);
299 fprintf(stderr, "%*s", indent, "");
300 fprintf(stderr, "may_write: ");
301 isl_union_map_dump(
302 summary->arg[i].access[pet_expr_access_may_write]);
303 fprintf(stderr, "%*s", indent, "");
304 fprintf(stderr, "must_write: ");
305 isl_union_map_dump(
306 summary->arg[i].access[pet_expr_access_must_write]);
307 break;
312 void pet_function_summary_dump(__isl_keep pet_function_summary *summary)
314 pet_function_summary_dump_with_indent(summary, 0);