1 #include <isl/union_set.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
;
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
{
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
,
51 pet_function_summary
*summary
;
54 summary
= isl_calloc(ctx
, struct pet_function_summary
,
55 sizeof(struct pet_function_summary
) +
56 n_arg
* sizeof(struct pet_function_summary_arg
));
64 for (i
= 0; i
< n_arg
; ++i
)
65 summary
->arg
[i
].type
= pet_arg_other
;
70 /* Return an extra reference to "summary".
72 __isl_give pet_function_summary
*pet_function_summary_copy(
73 __isl_keep pet_function_summary
*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
)
90 if (arg
->type
!= pet_arg_array
)
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
)
105 if (--summary
->ref
> 0)
108 for (i
= 0; i
< summary
->n
; ++i
)
109 free_arg(&summary
->arg
[i
]);
111 isl_ctx_deref(summary
->ctx
);
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
)
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
)
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
;
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
)
168 enum pet_expr_access_type type
;
170 if (!summary
|| !may_read
|| !may_write
|| !must_write
)
173 if (pos
< 0 || pos
>= summary
->n
)
174 isl_die(summary
->ctx
, isl_error_invalid
,
175 "position out of bounds", goto error
);
178 for (i
= 0; i
< summary
->n
; ++i
)
179 if (pet_function_summary_arg_is_int(summary
, i
))
182 space
= isl_space_params_alloc(summary
->ctx
, n
);
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
) {
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
;
211 isl_space_free(space
);
213 if (type
< pet_expr_access_end
)
214 return pet_function_summary_free(summary
);
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
,
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
,
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
)
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
)
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
) {
288 fprintf(stderr
, "%*s", indent
, "");
289 fprintf(stderr
, "id:");
290 isl_id_dump(summary
->arg
[i
].id
);
293 fprintf(stderr
, "%*s", indent
, "");
294 fprintf(stderr
, "other\n");
297 fprintf(stderr
, "%*s", indent
, "");
298 fprintf(stderr
, "may_read: ");
300 summary
->arg
[i
].access
[pet_expr_access_may_read
]);
301 fprintf(stderr
, "%*s", indent
, "");
302 fprintf(stderr
, "may_write: ");
304 summary
->arg
[i
].access
[pet_expr_access_may_write
]);
305 fprintf(stderr
, "%*s", indent
, "");
306 fprintf(stderr
, "must_write: ");
308 summary
->arg
[i
].access
[pet_expr_access_must_write
]);
314 void pet_function_summary_dump(__isl_keep pet_function_summary
*summary
)
316 pet_function_summary_dump_with_indent(summary
, 0);