2 * Copyright 2014 Ecole Normale Superieure. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY ECOLE NORMALE SUPERIEURE ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECOLE NORMALE SUPERIEURE OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation
29 * are those of the authors and should not be interpreted as
30 * representing official policies, either expressed or implied, of
31 * Ecole Normale Superieure.
34 #include <isl/space.h>
35 #include <isl/union_set.h>
40 /* A pet_function_summary objects represents an argument of a function.
42 * If "type" is pet_arg_int, then the argument has an integer type and
43 * can be used to describe the accesses performed by the pet_arg_array
44 * arguments. In this case, "id" refers to the formal argument.
46 * If "type" is pet_arg_array, then we keep track of the accesses
47 * through this argument in the access relations in "access".
48 * The domains of these access relations refer to the integer arguments
49 * of the function. That is, the input dimensions correspond
50 * to the arguments of type pet_arg_int.
52 * If "type" is pet_arg_other, then we do not keep track of any
53 * further information.
55 struct pet_function_summary_arg
{
56 enum pet_arg_type type
;
60 isl_union_map
*access
[pet_expr_access_end
];
64 /* A pet_function_summary object keeps track of the accesses performed
65 * by a function in terms of the function arguments.
67 * "n" is the number of arguments.
68 * "arg" contains a description of the "n" arguments.
70 struct pet_function_summary
{
76 struct pet_function_summary_arg arg
[];
79 /* Construct and return a new pet_function_summary object with
80 * "n_arg" arguments, initialized to pet_arg_other.
82 __isl_give pet_function_summary
*pet_function_summary_alloc(isl_ctx
*ctx
,
85 pet_function_summary
*summary
;
88 summary
= isl_calloc(ctx
, struct pet_function_summary
,
89 sizeof(struct pet_function_summary
) +
90 n_arg
* sizeof(struct pet_function_summary_arg
));
98 for (i
= 0; i
< n_arg
; ++i
)
99 summary
->arg
[i
].type
= pet_arg_other
;
104 /* Return an extra reference to "summary".
106 __isl_give pet_function_summary
*pet_function_summary_copy(
107 __isl_keep pet_function_summary
*summary
)
116 /* Return the isl_ctx in which "summary" was created.
118 isl_ctx
*pet_function_summary_get_ctx(__isl_keep pet_function_summary
*summary
)
120 return summary
? summary
->ctx
: NULL
;
123 /* Free the data stored in "arg".
125 static void free_arg(struct pet_function_summary_arg
*arg
)
127 enum pet_expr_access_type type
;
129 if (arg
->type
== pet_arg_int
)
130 isl_id_free(arg
->id
);
131 if (arg
->type
!= pet_arg_array
)
133 for (type
= pet_expr_access_begin
; type
< pet_expr_access_end
; ++type
)
134 arg
->access
[type
] = isl_union_map_free(arg
->access
[type
]);
137 /* Free a reference to "summary".
139 __isl_null pet_function_summary
*pet_function_summary_free(
140 __isl_take pet_function_summary
*summary
)
146 if (--summary
->ref
> 0)
149 for (i
= 0; i
< summary
->n
; ++i
)
150 free_arg(&summary
->arg
[i
]);
152 isl_ctx_deref(summary
->ctx
);
157 /* Return the number of arguments of the function summarized by "summary".
159 int pet_function_summary_get_n_arg(__isl_keep pet_function_summary
*summary
)
167 /* Mark the argument at position "pos" of "summary" as an integer argument
168 * with the given identifier.
170 __isl_give pet_function_summary
*pet_function_summary_set_int(
171 __isl_take pet_function_summary
*summary
, int pos
,
172 __isl_take isl_id
*id
)
177 if (pos
< 0 || pos
>= summary
->n
)
178 isl_die(summary
->ctx
, isl_error_invalid
,
179 "position out of bounds", goto error
);
181 free_arg(&summary
->arg
[pos
]);
183 summary
->arg
[pos
].type
= pet_arg_int
;
184 summary
->arg
[pos
].id
= id
;
189 return pet_function_summary_free(summary
);
192 /* Mark the argument at position "pos" of "summary" as an array argument
193 * with the given sets of accessed elements.
194 * The integer arguments of "summary" may appear as parameters
195 * in these sets of accessed elements.
196 * These parameters are turned into input dimensions of
197 * the corresponding access relations, which are then associated
198 * to the array argument.
199 * The order of the input dimensions is the same as the order
200 * in which the integer arguments appear in the sequence of arguments.
202 __isl_give pet_function_summary
*pet_function_summary_set_array(
203 __isl_take pet_function_summary
*summary
, int pos
,
204 __isl_take isl_union_set
*may_read
, __isl_take isl_union_set
*may_write
,
205 __isl_take isl_union_set
*must_write
)
209 enum pet_expr_access_type type
;
211 if (!summary
|| !may_read
|| !may_write
|| !must_write
)
214 if (pos
< 0 || pos
>= summary
->n
)
215 isl_die(summary
->ctx
, isl_error_invalid
,
216 "position out of bounds", goto error
);
219 for (i
= 0; i
< summary
->n
; ++i
)
220 if (pet_function_summary_arg_is_int(summary
, i
))
223 space
= isl_space_params_alloc(summary
->ctx
, n
);
226 for (i
= 0; i
< summary
->n
; ++i
)
227 if (pet_function_summary_arg_is_int(summary
, i
))
228 space
= isl_space_set_dim_id(space
, isl_dim_param
, n
++,
229 isl_id_copy(summary
->arg
[i
].id
));
231 free_arg(&summary
->arg
[pos
]);
233 summary
->arg
[pos
].type
= pet_arg_array
;
234 summary
->arg
[pos
].access
[pet_expr_access_may_read
] =
235 isl_union_map_from_range(may_read
);
236 summary
->arg
[pos
].access
[pet_expr_access_may_write
] =
237 isl_union_map_from_range(may_write
);
238 summary
->arg
[pos
].access
[pet_expr_access_must_write
] =
239 isl_union_map_from_range(must_write
);
241 for (type
= pet_expr_access_begin
; type
< pet_expr_access_end
; ++type
) {
243 umap
= summary
->arg
[pos
].access
[type
];
244 umap
= isl_union_map_align_params(umap
, isl_space_copy(space
));
245 umap
= pet_union_map_move_dims(umap
, isl_dim_in
, 0,
246 isl_dim_param
, 0, n
);
247 summary
->arg
[pos
].access
[type
] = umap
;
252 isl_space_free(space
);
254 if (type
< pet_expr_access_end
)
255 return pet_function_summary_free(summary
);
259 isl_union_set_free(may_read
);
260 isl_union_set_free(may_write
);
261 isl_union_set_free(must_write
);
262 return pet_function_summary_free(summary
);
265 /* Has the argument of "summary" at position "pos" been marked
266 * as an integer argument?
268 int pet_function_summary_arg_is_int(__isl_keep pet_function_summary
*summary
,
274 if (pos
< 0 || pos
>= summary
->n
)
275 isl_die(summary
->ctx
, isl_error_invalid
,
276 "position out of bounds", return -1);
278 return summary
->arg
[pos
].type
== pet_arg_int
;
281 /* Has the argument of "summary" at position "pos" been marked
282 * as an array argument?
284 int pet_function_summary_arg_is_array(__isl_keep pet_function_summary
*summary
,
290 if (pos
< 0 || pos
>= summary
->n
)
291 isl_die(summary
->ctx
, isl_error_invalid
,
292 "position out of bounds", return -1);
294 return summary
->arg
[pos
].type
== pet_arg_array
;
297 /* Return the access relation of type "type" associated to
298 * the argument of "summary" at position "pos", which is assumed
299 * to be an array argument.
301 __isl_give isl_union_map
*pet_function_summary_arg_get_access(
302 __isl_keep pet_function_summary
*summary
, int pos
,
303 enum pet_expr_access_type type
)
307 if (pos
< 0 || pos
>= summary
->n
)
308 isl_die(summary
->ctx
, isl_error_invalid
,
309 "position out of bounds", return NULL
);
310 if (summary
->arg
[pos
].type
!= pet_arg_array
)
311 isl_die(summary
->ctx
, isl_error_invalid
,
312 "not an array argument", return NULL
);
314 return isl_union_map_copy(summary
->arg
[pos
].access
[type
]);
317 /* Print "summary" to "p" in YAML format.
319 __isl_give isl_printer
*pet_function_summary_print(
320 __isl_keep pet_function_summary
*summary
, __isl_take isl_printer
*p
)
325 return isl_printer_free(p
);
326 p
= isl_printer_yaml_start_sequence(p
);
327 for (i
= 0; i
< summary
->n
; ++i
) {
328 switch (summary
->arg
[i
].type
) {
330 p
= isl_printer_yaml_start_mapping(p
);
331 p
= isl_printer_print_str(p
, "id");
332 p
= isl_printer_yaml_next(p
);
333 p
= isl_printer_print_id(p
, summary
->arg
[i
].id
);
334 p
= isl_printer_yaml_next(p
);
335 p
= isl_printer_yaml_end_mapping(p
);
338 p
= isl_printer_print_str(p
, "other");
341 p
= isl_printer_yaml_start_mapping(p
);
342 p
= isl_printer_print_str(p
, "may_read");
343 p
= isl_printer_yaml_next(p
);
344 p
= isl_printer_print_union_map(p
,
345 summary
->arg
[i
].access
[pet_expr_access_may_read
]);
346 p
= isl_printer_yaml_next(p
);
347 p
= isl_printer_print_str(p
, "may_write");
348 p
= isl_printer_yaml_next(p
);
349 p
= isl_printer_print_union_map(p
,
350 summary
->arg
[i
].access
[pet_expr_access_may_write
]);
351 p
= isl_printer_yaml_next(p
);
352 p
= isl_printer_print_str(p
, "must_write");
353 p
= isl_printer_yaml_next(p
);
354 p
= isl_printer_print_union_map(p
,
355 summary
->arg
[i
].access
[pet_expr_access_must_write
]);
356 p
= isl_printer_yaml_next(p
);
357 p
= isl_printer_yaml_end_mapping(p
);
361 p
= isl_printer_yaml_end_sequence(p
);
366 /* Dump "summary" to stderr.
368 void pet_function_summary_dump(__isl_keep pet_function_summary
*summary
)
375 p
= isl_printer_to_file(pet_function_summary_get_ctx(summary
), stderr
);
376 p
= isl_printer_set_yaml_style(p
, ISL_YAML_STYLE_BLOCK
);
377 p
= pet_function_summary_print(summary
, p
);