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
;
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
{
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
,
49 pet_function_summary
*summary
;
52 summary
= isl_calloc(ctx
, struct pet_function_summary
,
53 sizeof(struct pet_function_summary
) +
54 n_arg
* sizeof(struct pet_function_summary_arg
));
62 for (i
= 0; i
< n_arg
; ++i
)
63 summary
->arg
[i
].type
= pet_arg_other
;
68 /* Return an extra reference to "summary".
70 __isl_give pet_function_summary
*pet_function_summary_copy(
71 __isl_keep pet_function_summary
*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
)
88 if (arg
->type
!= pet_arg_array
)
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
)
103 if (--summary
->ref
> 0)
106 for (i
= 0; i
< summary
->n
; ++i
)
107 free_arg(&summary
->arg
[i
]);
109 isl_ctx_deref(summary
->ctx
);
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
)
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
)
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
;
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
)
166 enum pet_expr_access_type type
;
168 if (!summary
|| !may_read
|| !may_write
|| !must_write
)
171 if (pos
< 0 || pos
>= summary
->n
)
172 isl_die(summary
->ctx
, isl_error_invalid
,
173 "position out of bounds", goto error
);
176 for (i
= 0; i
< summary
->n
; ++i
)
177 if (pet_function_summary_arg_is_int(summary
, i
))
180 space
= isl_space_params_alloc(summary
->ctx
, n
);
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
) {
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
;
209 isl_space_free(space
);
211 if (type
< pet_expr_access_end
)
212 return pet_function_summary_free(summary
);
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
,
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
,
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
)
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
)
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
) {
286 fprintf(stderr
, "%*s", indent
, "");
287 fprintf(stderr
, "id:");
288 isl_id_dump(summary
->arg
[i
].id
);
291 fprintf(stderr
, "%*s", indent
, "");
292 fprintf(stderr
, "other\n");
295 fprintf(stderr
, "%*s", indent
, "");
296 fprintf(stderr
, "may_read: ");
298 summary
->arg
[i
].access
[pet_expr_access_may_read
]);
299 fprintf(stderr
, "%*s", indent
, "");
300 fprintf(stderr
, "may_write: ");
302 summary
->arg
[i
].access
[pet_expr_access_may_write
]);
303 fprintf(stderr
, "%*s", indent
, "");
304 fprintf(stderr
, "must_write: ");
306 summary
->arg
[i
].access
[pet_expr_access_must_write
]);
312 void pet_function_summary_dump(__isl_keep pet_function_summary
*summary
)
314 pet_function_summary_dump_with_indent(summary
, 0);