add pet_inliner
[pet.git] / summary.c
blobe4970456fded7a0477fd8bc9741319d08198e889
1 #include <isl/union_set.h>
3 #include "aff.h"
4 #include "summary.h"
6 /* A pet_function_summary objects represents an argument of a function.
8 * If "type" is pet_arg_int, then the argument has an integer type and
9 * can be used to describe the accesses performed by the pet_arg_array
10 * arguments. In this case, "id" refers to the formal argument.
12 * If "type" is pet_arg_array, then we keep track of the accesses
13 * through this argument in the access relations in "access".
14 * The domains of these access relations refer to the integer arguments
15 * of the function. That is, the input dimensions correspond
16 * to the arguments of type pet_arg_int.
18 * If "type" is pet_arg_other, then we do not keep track of any
19 * further information.
21 struct pet_function_summary_arg {
22 enum pet_arg_type type;
24 union {
25 isl_id *id;
26 isl_union_map *access[pet_expr_access_end];
30 /* A pet_function_summary object keeps track of the accesses performed
31 * by a function in terms of the function arguments.
33 * "n" is the number of arguments.
34 * "arg" contains a description of the "n" arguments.
36 struct pet_function_summary {
37 int ref;
38 isl_ctx *ctx;
40 unsigned n;
42 struct pet_function_summary_arg arg[];
45 /* Construct and return a new pet_function_summary object with
46 * "n_arg" arguments, initialized to pet_arg_other.
48 __isl_give pet_function_summary *pet_function_summary_alloc(isl_ctx *ctx,
49 unsigned n_arg)
51 pet_function_summary *summary;
52 int i;
54 summary = isl_calloc(ctx, struct pet_function_summary,
55 sizeof(struct pet_function_summary) +
56 n_arg * sizeof(struct pet_function_summary_arg));
57 if (!summary)
58 return summary;
60 summary->ctx = ctx;
61 isl_ctx_ref(ctx);
62 summary->ref = 1;
63 summary->n = n_arg;
64 for (i = 0; i < n_arg; ++i)
65 summary->arg[i].type = pet_arg_other;
67 return summary;
70 /* Return an extra reference to "summary".
72 __isl_give pet_function_summary *pet_function_summary_copy(
73 __isl_keep pet_function_summary *summary)
75 if (!summary)
76 return NULL;
78 summary->ref++;
79 return summary;
82 /* Free the data stored in "arg".
84 static void free_arg(struct pet_function_summary_arg *arg)
86 enum pet_expr_access_type type;
88 if (arg->type == pet_arg_int)
89 isl_id_free(arg->id);
90 if (arg->type != pet_arg_array)
91 return;
92 for (type = pet_expr_access_begin; type < pet_expr_access_end; ++type)
93 arg->access[type] = isl_union_map_free(arg->access[type]);
96 /* Free a reference to "summary".
98 __isl_null pet_function_summary *pet_function_summary_free(
99 __isl_take pet_function_summary *summary)
101 int i;
103 if (!summary)
104 return NULL;
105 if (--summary->ref > 0)
106 return NULL;
108 for (i = 0; i < summary->n; ++i)
109 free_arg(&summary->arg[i]);
111 isl_ctx_deref(summary->ctx);
112 free(summary);
113 return NULL;
116 /* Return the number of arguments of the function summarized by "summary".
118 int pet_function_summary_get_n_arg(__isl_keep pet_function_summary *summary)
120 if (!summary)
121 return -1;
123 return summary->n;
126 /* Mark the argument at position "pos" of "summary" as an integer argument
127 * with the given identifier.
129 __isl_give pet_function_summary *pet_function_summary_set_int(
130 __isl_take pet_function_summary *summary, int pos,
131 __isl_take isl_id *id)
133 if (!summary || !id)
134 goto error;
136 if (pos < 0 || pos >= summary->n)
137 isl_die(summary->ctx, isl_error_invalid,
138 "position out of bounds", goto error);
140 free_arg(&summary->arg[pos]);
142 summary->arg[pos].type = pet_arg_int;
143 summary->arg[pos].id = id;
145 return summary;
146 error:
147 isl_id_free(id);
148 return pet_function_summary_free(summary);
151 /* Mark the argument at position "pos" of "summary" as an array argument
152 * with the given sets of accessed elements.
153 * The integer arguments of "summary" may appear as parameters
154 * in these sets of accessed elements.
155 * These parameters are turned into input dimensions of
156 * the corresponding access relations, which are then associated
157 * to the array argument.
158 * The order of the input dimensions is the same as the order
159 * in which the integer arguments appear in the sequence of arguments.
161 __isl_give pet_function_summary *pet_function_summary_set_array(
162 __isl_take pet_function_summary *summary, int pos,
163 __isl_take isl_union_set *may_read, __isl_take isl_union_set *may_write,
164 __isl_take isl_union_set *must_write)
166 int i, n;
167 isl_space *space;
168 enum pet_expr_access_type type;
170 if (!summary || !may_read || !may_write || !must_write)
171 goto error;
173 if (pos < 0 || pos >= summary->n)
174 isl_die(summary->ctx, isl_error_invalid,
175 "position out of bounds", goto error);
177 n = 0;
178 for (i = 0; i < summary->n; ++i)
179 if (pet_function_summary_arg_is_int(summary, i))
180 n++;
182 space = isl_space_params_alloc(summary->ctx, n);
184 n = 0;
185 for (i = 0; i < summary->n; ++i)
186 if (pet_function_summary_arg_is_int(summary, i))
187 space = isl_space_set_dim_id(space, isl_dim_param, n++,
188 isl_id_copy(summary->arg[i].id));
190 free_arg(&summary->arg[pos]);
192 summary->arg[pos].type = pet_arg_array;
193 summary->arg[pos].access[pet_expr_access_may_read] =
194 isl_union_map_from_range(may_read);
195 summary->arg[pos].access[pet_expr_access_may_write] =
196 isl_union_map_from_range(may_write);
197 summary->arg[pos].access[pet_expr_access_must_write] =
198 isl_union_map_from_range(must_write);
200 for (type = pet_expr_access_begin; type < pet_expr_access_end; ++type) {
201 isl_union_map *umap;
202 umap = summary->arg[pos].access[type];
203 umap = isl_union_map_align_params(umap, isl_space_copy(space));
204 umap = pet_union_map_move_dims(umap, isl_dim_in, 0,
205 isl_dim_param, 0, n);
206 summary->arg[pos].access[type] = umap;
207 if (!umap)
208 break;
211 isl_space_free(space);
213 if (type < pet_expr_access_end)
214 return pet_function_summary_free(summary);
216 return summary;
217 error:
218 isl_union_set_free(may_read);
219 isl_union_set_free(may_write);
220 isl_union_set_free(must_write);
221 return pet_function_summary_free(summary);
224 /* Has the argument of "summary" at position "pos" been marked
225 * as an integer argument?
227 int pet_function_summary_arg_is_int(__isl_keep pet_function_summary *summary,
228 int pos)
230 if (!summary)
231 return -1;
233 if (pos < 0 || pos >= summary->n)
234 isl_die(summary->ctx, isl_error_invalid,
235 "position out of bounds", return -1);
237 return summary->arg[pos].type == pet_arg_int;
240 /* Has the argument of "summary" at position "pos" been marked
241 * as an array argument?
243 int pet_function_summary_arg_is_array(__isl_keep pet_function_summary *summary,
244 int pos)
246 if (!summary)
247 return -1;
249 if (pos < 0 || pos >= summary->n)
250 isl_die(summary->ctx, isl_error_invalid,
251 "position out of bounds", return -1);
253 return summary->arg[pos].type == pet_arg_array;
256 /* Return the access relation of type "type" associated to
257 * the argument of "summary" at position "pos", which is assumed
258 * to be an array argument.
260 __isl_give isl_union_map *pet_function_summary_arg_get_access(
261 __isl_keep pet_function_summary *summary, int pos,
262 enum pet_expr_access_type type)
264 if (!summary)
265 return NULL;
266 if (pos < 0 || pos >= summary->n)
267 isl_die(summary->ctx, isl_error_invalid,
268 "position out of bounds", return NULL);
269 if (summary->arg[pos].type != pet_arg_array)
270 isl_die(summary->ctx, isl_error_invalid,
271 "not an array argument", return NULL);
273 return isl_union_map_copy(summary->arg[pos].access[type]);
276 void pet_function_summary_dump_with_indent(
277 __isl_keep pet_function_summary *summary, int indent)
279 int i;
281 if (!summary)
282 return;
283 fprintf(stderr, "%*s", indent, "");
284 fprintf(stderr, "n: %d\n", summary->n);
285 for (i = 0; i < summary->n; ++i) {
286 switch (summary->arg[i].type) {
287 case pet_arg_int:
288 fprintf(stderr, "%*s", indent, "");
289 fprintf(stderr, "id:");
290 isl_id_dump(summary->arg[i].id);
291 break;
292 case pet_arg_other:
293 fprintf(stderr, "%*s", indent, "");
294 fprintf(stderr, "other\n");
295 break;
296 case pet_arg_array:
297 fprintf(stderr, "%*s", indent, "");
298 fprintf(stderr, "may_read: ");
299 isl_union_map_dump(
300 summary->arg[i].access[pet_expr_access_may_read]);
301 fprintf(stderr, "%*s", indent, "");
302 fprintf(stderr, "may_write: ");
303 isl_union_map_dump(
304 summary->arg[i].access[pet_expr_access_may_write]);
305 fprintf(stderr, "%*s", indent, "");
306 fprintf(stderr, "must_write: ");
307 isl_union_map_dump(
308 summary->arg[i].access[pet_expr_access_must_write]);
309 break;
314 void pet_function_summary_dump(__isl_keep pet_function_summary *summary)
316 pet_function_summary_dump_with_indent(summary, 0);