isl_ast.c revision 1.1 1 1.1 mrg /*
2 1.1 mrg * Copyright 2012-2013 Ecole Normale Superieure
3 1.1 mrg * Copyright 2022 Cerebras Systems
4 1.1 mrg *
5 1.1 mrg * Use of this software is governed by the MIT license
6 1.1 mrg *
7 1.1 mrg * Written by Sven Verdoolaege,
8 1.1 mrg * Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France
9 1.1 mrg * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
10 1.1 mrg */
11 1.1 mrg
12 1.1 mrg #include <string.h>
13 1.1 mrg
14 1.1 mrg #include <isl/id.h>
15 1.1 mrg #include <isl/stream.h>
16 1.1 mrg #include <isl/val.h>
17 1.1 mrg #include <isl_ast_private.h>
18 1.1 mrg
19 1.1 mrg #undef EL_BASE
20 1.1 mrg #define EL_BASE ast_expr
21 1.1 mrg
22 1.1 mrg #include <isl_list_templ.c>
23 1.1 mrg
24 1.1 mrg #undef EL_BASE
25 1.1 mrg #define EL_BASE ast_node
26 1.1 mrg
27 1.1 mrg #include <isl_list_templ.c>
28 1.1 mrg
29 1.1 mrg isl_ctx *isl_ast_print_options_get_ctx(
30 1.1 mrg __isl_keep isl_ast_print_options *options)
31 1.1 mrg {
32 1.1 mrg return options ? options->ctx : NULL;
33 1.1 mrg }
34 1.1 mrg
35 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
36 1.1 mrg {
37 1.1 mrg isl_ast_print_options *options;
38 1.1 mrg
39 1.1 mrg options = isl_calloc_type(ctx, isl_ast_print_options);
40 1.1 mrg if (!options)
41 1.1 mrg return NULL;
42 1.1 mrg
43 1.1 mrg options->ctx = ctx;
44 1.1 mrg isl_ctx_ref(ctx);
45 1.1 mrg options->ref = 1;
46 1.1 mrg
47 1.1 mrg return options;
48 1.1 mrg }
49 1.1 mrg
50 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_dup(
51 1.1 mrg __isl_keep isl_ast_print_options *options)
52 1.1 mrg {
53 1.1 mrg isl_ctx *ctx;
54 1.1 mrg isl_ast_print_options *dup;
55 1.1 mrg
56 1.1 mrg if (!options)
57 1.1 mrg return NULL;
58 1.1 mrg
59 1.1 mrg ctx = isl_ast_print_options_get_ctx(options);
60 1.1 mrg dup = isl_ast_print_options_alloc(ctx);
61 1.1 mrg if (!dup)
62 1.1 mrg return NULL;
63 1.1 mrg
64 1.1 mrg dup->print_for = options->print_for;
65 1.1 mrg dup->print_for_user = options->print_for_user;
66 1.1 mrg dup->print_user = options->print_user;
67 1.1 mrg dup->print_user_user = options->print_user_user;
68 1.1 mrg
69 1.1 mrg return dup;
70 1.1 mrg }
71 1.1 mrg
72 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_cow(
73 1.1 mrg __isl_take isl_ast_print_options *options)
74 1.1 mrg {
75 1.1 mrg if (!options)
76 1.1 mrg return NULL;
77 1.1 mrg
78 1.1 mrg if (options->ref == 1)
79 1.1 mrg return options;
80 1.1 mrg options->ref--;
81 1.1 mrg return isl_ast_print_options_dup(options);
82 1.1 mrg }
83 1.1 mrg
84 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_copy(
85 1.1 mrg __isl_keep isl_ast_print_options *options)
86 1.1 mrg {
87 1.1 mrg if (!options)
88 1.1 mrg return NULL;
89 1.1 mrg
90 1.1 mrg options->ref++;
91 1.1 mrg return options;
92 1.1 mrg }
93 1.1 mrg
94 1.1 mrg __isl_null isl_ast_print_options *isl_ast_print_options_free(
95 1.1 mrg __isl_take isl_ast_print_options *options)
96 1.1 mrg {
97 1.1 mrg if (!options)
98 1.1 mrg return NULL;
99 1.1 mrg
100 1.1 mrg if (--options->ref > 0)
101 1.1 mrg return NULL;
102 1.1 mrg
103 1.1 mrg isl_ctx_deref(options->ctx);
104 1.1 mrg
105 1.1 mrg free(options);
106 1.1 mrg return NULL;
107 1.1 mrg }
108 1.1 mrg
109 1.1 mrg /* Set the print_user callback of "options" to "print_user".
110 1.1 mrg *
111 1.1 mrg * If this callback is set, then it is used to print user nodes in the AST.
112 1.1 mrg * Otherwise, the expression associated to the user node is printed.
113 1.1 mrg */
114 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
115 1.1 mrg __isl_take isl_ast_print_options *options,
116 1.1 mrg __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
117 1.1 mrg __isl_take isl_ast_print_options *options,
118 1.1 mrg __isl_keep isl_ast_node *node, void *user),
119 1.1 mrg void *user)
120 1.1 mrg {
121 1.1 mrg options = isl_ast_print_options_cow(options);
122 1.1 mrg if (!options)
123 1.1 mrg return NULL;
124 1.1 mrg
125 1.1 mrg options->print_user = print_user;
126 1.1 mrg options->print_user_user = user;
127 1.1 mrg
128 1.1 mrg return options;
129 1.1 mrg }
130 1.1 mrg
131 1.1 mrg /* Set the print_for callback of "options" to "print_for".
132 1.1 mrg *
133 1.1 mrg * If this callback is set, then it used to print for nodes in the AST.
134 1.1 mrg */
135 1.1 mrg __isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
136 1.1 mrg __isl_take isl_ast_print_options *options,
137 1.1 mrg __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
138 1.1 mrg __isl_take isl_ast_print_options *options,
139 1.1 mrg __isl_keep isl_ast_node *node, void *user),
140 1.1 mrg void *user)
141 1.1 mrg {
142 1.1 mrg options = isl_ast_print_options_cow(options);
143 1.1 mrg if (!options)
144 1.1 mrg return NULL;
145 1.1 mrg
146 1.1 mrg options->print_for = print_for;
147 1.1 mrg options->print_for_user = user;
148 1.1 mrg
149 1.1 mrg return options;
150 1.1 mrg }
151 1.1 mrg
152 1.1 mrg /* Create a new operation expression of operation type "op",
153 1.1 mrg * with arguments "args".
154 1.1 mrg */
155 1.1 mrg static __isl_give isl_ast_expr *alloc_op(enum isl_ast_expr_op_type op,
156 1.1 mrg __isl_take isl_ast_expr_list *args)
157 1.1 mrg {
158 1.1 mrg isl_ctx *ctx;
159 1.1 mrg isl_ast_expr *expr;
160 1.1 mrg
161 1.1 mrg if (!args)
162 1.1 mrg return NULL;
163 1.1 mrg
164 1.1 mrg ctx = isl_ast_expr_list_get_ctx(args);
165 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr);
166 1.1 mrg if (!expr)
167 1.1 mrg goto error;
168 1.1 mrg
169 1.1 mrg expr->ctx = ctx;
170 1.1 mrg isl_ctx_ref(ctx);
171 1.1 mrg expr->ref = 1;
172 1.1 mrg expr->type = isl_ast_expr_op;
173 1.1 mrg expr->u.op.op = op;
174 1.1 mrg expr->u.op.args = args;
175 1.1 mrg
176 1.1 mrg return expr;
177 1.1 mrg error:
178 1.1 mrg isl_ast_expr_list_free(args);
179 1.1 mrg return NULL;
180 1.1 mrg }
181 1.1 mrg
182 1.1 mrg /* Create a new operation expression of operation type "op",
183 1.1 mrg * which will end up having "n_arg" arguments.
184 1.1 mrg * The caller still needs to add those arguments.
185 1.1 mrg */
186 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
187 1.1 mrg enum isl_ast_expr_op_type op, int n_arg)
188 1.1 mrg {
189 1.1 mrg isl_ast_expr_list *args;
190 1.1 mrg
191 1.1 mrg args = isl_ast_expr_list_alloc(ctx, n_arg);
192 1.1 mrg return alloc_op(op, args);
193 1.1 mrg }
194 1.1 mrg
195 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
196 1.1 mrg {
197 1.1 mrg if (!expr)
198 1.1 mrg return NULL;
199 1.1 mrg
200 1.1 mrg expr->ref++;
201 1.1 mrg return expr;
202 1.1 mrg }
203 1.1 mrg
204 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
205 1.1 mrg {
206 1.1 mrg isl_ast_expr *dup;
207 1.1 mrg
208 1.1 mrg if (!expr)
209 1.1 mrg return NULL;
210 1.1 mrg
211 1.1 mrg switch (expr->type) {
212 1.1 mrg case isl_ast_expr_int:
213 1.1 mrg dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
214 1.1 mrg break;
215 1.1 mrg case isl_ast_expr_id:
216 1.1 mrg dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
217 1.1 mrg break;
218 1.1 mrg case isl_ast_expr_op:
219 1.1 mrg dup = alloc_op(expr->u.op.op,
220 1.1 mrg isl_ast_expr_list_copy(expr->u.op.args));
221 1.1 mrg break;
222 1.1 mrg case isl_ast_expr_error:
223 1.1 mrg dup = NULL;
224 1.1 mrg }
225 1.1 mrg
226 1.1 mrg if (!dup)
227 1.1 mrg return NULL;
228 1.1 mrg
229 1.1 mrg return dup;
230 1.1 mrg }
231 1.1 mrg
232 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
233 1.1 mrg {
234 1.1 mrg if (!expr)
235 1.1 mrg return NULL;
236 1.1 mrg
237 1.1 mrg if (expr->ref == 1)
238 1.1 mrg return expr;
239 1.1 mrg expr->ref--;
240 1.1 mrg return isl_ast_expr_dup(expr);
241 1.1 mrg }
242 1.1 mrg
243 1.1 mrg __isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
244 1.1 mrg {
245 1.1 mrg if (!expr)
246 1.1 mrg return NULL;
247 1.1 mrg
248 1.1 mrg if (--expr->ref > 0)
249 1.1 mrg return NULL;
250 1.1 mrg
251 1.1 mrg isl_ctx_deref(expr->ctx);
252 1.1 mrg
253 1.1 mrg switch (expr->type) {
254 1.1 mrg case isl_ast_expr_int:
255 1.1 mrg isl_val_free(expr->u.v);
256 1.1 mrg break;
257 1.1 mrg case isl_ast_expr_id:
258 1.1 mrg isl_id_free(expr->u.id);
259 1.1 mrg break;
260 1.1 mrg case isl_ast_expr_op:
261 1.1 mrg isl_ast_expr_list_free(expr->u.op.args);
262 1.1 mrg break;
263 1.1 mrg case isl_ast_expr_error:
264 1.1 mrg break;
265 1.1 mrg }
266 1.1 mrg
267 1.1 mrg free(expr);
268 1.1 mrg return NULL;
269 1.1 mrg }
270 1.1 mrg
271 1.1 mrg isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
272 1.1 mrg {
273 1.1 mrg return expr ? expr->ctx : NULL;
274 1.1 mrg }
275 1.1 mrg
276 1.1 mrg enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
277 1.1 mrg {
278 1.1 mrg return expr ? expr->type : isl_ast_expr_error;
279 1.1 mrg }
280 1.1 mrg
281 1.1 mrg /* Return the integer value represented by "expr".
282 1.1 mrg */
283 1.1 mrg __isl_give isl_val *isl_ast_expr_int_get_val(__isl_keep isl_ast_expr *expr)
284 1.1 mrg {
285 1.1 mrg if (!expr)
286 1.1 mrg return NULL;
287 1.1 mrg if (expr->type != isl_ast_expr_int)
288 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
289 1.1 mrg "expression not an int", return NULL);
290 1.1 mrg return isl_val_copy(expr->u.v);
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg /* This is an alternative name for the function above.
294 1.1 mrg */
295 1.1 mrg __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
296 1.1 mrg {
297 1.1 mrg return isl_ast_expr_int_get_val(expr);
298 1.1 mrg }
299 1.1 mrg
300 1.1 mrg __isl_give isl_id *isl_ast_expr_id_get_id(__isl_keep isl_ast_expr *expr)
301 1.1 mrg {
302 1.1 mrg if (!expr)
303 1.1 mrg return NULL;
304 1.1 mrg if (expr->type != isl_ast_expr_id)
305 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
306 1.1 mrg "expression not an identifier", return NULL);
307 1.1 mrg
308 1.1 mrg return isl_id_copy(expr->u.id);
309 1.1 mrg }
310 1.1 mrg
311 1.1 mrg /* This is an alternative name for the function above.
312 1.1 mrg */
313 1.1 mrg __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
314 1.1 mrg {
315 1.1 mrg return isl_ast_expr_id_get_id(expr);
316 1.1 mrg }
317 1.1 mrg
318 1.1 mrg /* Check that "expr" is of type isl_ast_expr_op.
319 1.1 mrg */
320 1.1 mrg static isl_stat isl_ast_expr_check_op(__isl_keep isl_ast_expr *expr)
321 1.1 mrg {
322 1.1 mrg if (!expr)
323 1.1 mrg return isl_stat_error;
324 1.1 mrg if (expr->type != isl_ast_expr_op)
325 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
326 1.1 mrg "expression not an operation", return isl_stat_error);
327 1.1 mrg return isl_stat_ok;
328 1.1 mrg }
329 1.1 mrg
330 1.1 mrg /* Return the type of operation represented by "expr".
331 1.1 mrg */
332 1.1 mrg enum isl_ast_expr_op_type isl_ast_expr_op_get_type(
333 1.1 mrg __isl_keep isl_ast_expr *expr)
334 1.1 mrg {
335 1.1 mrg if (isl_ast_expr_check_op(expr) < 0)
336 1.1 mrg return isl_ast_expr_op_error;
337 1.1 mrg return expr->u.op.op;
338 1.1 mrg }
339 1.1 mrg
340 1.1 mrg /* This is an alternative name for the function above.
341 1.1 mrg */
342 1.1 mrg enum isl_ast_expr_op_type isl_ast_expr_get_op_type(
343 1.1 mrg __isl_keep isl_ast_expr *expr)
344 1.1 mrg {
345 1.1 mrg return isl_ast_expr_op_get_type(expr);
346 1.1 mrg }
347 1.1 mrg
348 1.1 mrg /* Return the number of arguments of the operation represented by "expr".
349 1.1 mrg */
350 1.1 mrg isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr)
351 1.1 mrg {
352 1.1 mrg if (isl_ast_expr_check_op(expr) < 0)
353 1.1 mrg return isl_size_error;
354 1.1 mrg return isl_ast_expr_list_size(expr->u.op.args);
355 1.1 mrg }
356 1.1 mrg
357 1.1 mrg /* This is an alternative name for the function above.
358 1.1 mrg */
359 1.1 mrg isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
360 1.1 mrg {
361 1.1 mrg return isl_ast_expr_op_get_n_arg(expr);
362 1.1 mrg }
363 1.1 mrg
364 1.1 mrg /* Return the argument at position "pos" of the operation represented by "expr".
365 1.1 mrg */
366 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr *expr,
367 1.1 mrg int pos)
368 1.1 mrg {
369 1.1 mrg if (isl_ast_expr_check_op(expr) < 0)
370 1.1 mrg return NULL;
371 1.1 mrg
372 1.1 mrg return isl_ast_expr_list_get_at(expr->u.op.args, pos);
373 1.1 mrg }
374 1.1 mrg
375 1.1 mrg /* This is an alternative name for the function above.
376 1.1 mrg */
377 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
378 1.1 mrg int pos)
379 1.1 mrg {
380 1.1 mrg return isl_ast_expr_op_get_arg(expr, pos);
381 1.1 mrg }
382 1.1 mrg
383 1.1 mrg /* Return a copy of the arguments of the operation represented by "expr".
384 1.1 mrg */
385 1.1 mrg static __isl_give isl_ast_expr_list *isl_ast_expr_op_get_args(
386 1.1 mrg __isl_keep isl_ast_expr *expr)
387 1.1 mrg {
388 1.1 mrg if (isl_ast_expr_check_op(expr) < 0)
389 1.1 mrg return NULL;
390 1.1 mrg return isl_ast_expr_list_copy(expr->u.op.args);
391 1.1 mrg }
392 1.1 mrg
393 1.1 mrg /* Return the arguments of the operation expression "expr".
394 1.1 mrg * This may be either a copy or the arguments themselves
395 1.1 mrg * if there is only one reference to "expr".
396 1.1 mrg * This allows the arguments to be modified inplace
397 1.1 mrg * if both "expr" and its arguments have only a single reference.
398 1.1 mrg * The caller is not allowed to modify "expr" between this call and
399 1.1 mrg * the subsequent call to isl_ast_expr_op_restore_args.
400 1.1 mrg * The only exception is that isl_ast_expr_free can be called instead.
401 1.1 mrg */
402 1.1 mrg static __isl_give isl_ast_expr_list *isl_ast_expr_op_take_args(
403 1.1 mrg __isl_keep isl_ast_expr *expr)
404 1.1 mrg {
405 1.1 mrg isl_ast_expr_list *args;
406 1.1 mrg
407 1.1 mrg if (isl_ast_expr_check_op(expr) < 0)
408 1.1 mrg return NULL;
409 1.1 mrg if (expr->ref != 1)
410 1.1 mrg return isl_ast_expr_op_get_args(expr);
411 1.1 mrg args = expr->u.op.args;
412 1.1 mrg expr->u.op.args = NULL;
413 1.1 mrg return args;
414 1.1 mrg }
415 1.1 mrg
416 1.1 mrg /* Set the arguments of the operation expression "expr" to "args",
417 1.1 mrg * where the arguments of "args" may be missing
418 1.1 mrg * due to a preceding call to isl_ast_expr_op_take_args.
419 1.1 mrg * However, in this case, "expr" only has a single reference and
420 1.1 mrg * then the call to isl_ast_expr_cow has no effect.
421 1.1 mrg */
422 1.1 mrg static __isl_give isl_ast_expr *isl_ast_expr_op_restore_args(
423 1.1 mrg __isl_take isl_ast_expr *expr, __isl_take isl_ast_expr_list *args)
424 1.1 mrg {
425 1.1 mrg if (isl_ast_expr_check_op(expr) < 0 || !args)
426 1.1 mrg goto error;
427 1.1 mrg if (expr->u.op.args == args) {
428 1.1 mrg isl_ast_expr_list_free(args);
429 1.1 mrg return expr;
430 1.1 mrg }
431 1.1 mrg
432 1.1 mrg expr = isl_ast_expr_cow(expr);
433 1.1 mrg if (!expr)
434 1.1 mrg goto error;
435 1.1 mrg
436 1.1 mrg isl_ast_expr_list_free(expr->u.op.args);
437 1.1 mrg expr->u.op.args = args;
438 1.1 mrg
439 1.1 mrg return expr;
440 1.1 mrg error:
441 1.1 mrg isl_ast_expr_free(expr);
442 1.1 mrg isl_ast_expr_list_free(args);
443 1.1 mrg return NULL;
444 1.1 mrg }
445 1.1 mrg
446 1.1 mrg /* Add "arg" to the arguments of the operation expression "expr".
447 1.1 mrg */
448 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr,
449 1.1 mrg __isl_take isl_ast_expr *arg)
450 1.1 mrg {
451 1.1 mrg isl_ast_expr_list *args;
452 1.1 mrg
453 1.1 mrg args = isl_ast_expr_op_take_args(expr);
454 1.1 mrg args = isl_ast_expr_list_add(args, arg);
455 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args);
456 1.1 mrg
457 1.1 mrg return expr;
458 1.1 mrg }
459 1.1 mrg
460 1.1 mrg /* Replace the argument at position "pos" of "expr" by "arg".
461 1.1 mrg */
462 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
463 1.1 mrg int pos, __isl_take isl_ast_expr *arg)
464 1.1 mrg {
465 1.1 mrg isl_ast_expr_list *args;
466 1.1 mrg
467 1.1 mrg args = isl_ast_expr_op_take_args(expr);
468 1.1 mrg args = isl_ast_expr_list_set_at(args, pos, arg);
469 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args);
470 1.1 mrg
471 1.1 mrg return expr;
472 1.1 mrg }
473 1.1 mrg
474 1.1 mrg /* Are the lists of AST expressions "list1" and "list2" the same?
475 1.1 mrg */
476 1.1 mrg static isl_bool isl_ast_expr_list_is_equal(__isl_keep isl_ast_expr_list *list1,
477 1.1 mrg __isl_keep isl_ast_expr_list *list2)
478 1.1 mrg {
479 1.1 mrg int i;
480 1.1 mrg isl_size n1, n2;
481 1.1 mrg
482 1.1 mrg if (!list1 || !list2)
483 1.1 mrg return isl_bool_error;
484 1.1 mrg if (list1 == list2)
485 1.1 mrg return isl_bool_true;
486 1.1 mrg
487 1.1 mrg n1 = isl_ast_expr_list_size(list1);
488 1.1 mrg n2 = isl_ast_expr_list_size(list2);
489 1.1 mrg if (n1 < 0 || n2 < 0)
490 1.1 mrg return isl_bool_error;
491 1.1 mrg if (n1 != n2)
492 1.1 mrg return isl_bool_false;
493 1.1 mrg for (i = 0; i < n1; ++i) {
494 1.1 mrg isl_ast_expr *expr1, *expr2;
495 1.1 mrg isl_bool equal;
496 1.1 mrg
497 1.1 mrg expr1 = isl_ast_expr_list_get_at(list1, i);
498 1.1 mrg expr2 = isl_ast_expr_list_get_at(list2, i);
499 1.1 mrg equal = isl_ast_expr_is_equal(expr1, expr2);
500 1.1 mrg isl_ast_expr_free(expr1);
501 1.1 mrg isl_ast_expr_free(expr2);
502 1.1 mrg if (equal < 0 || !equal)
503 1.1 mrg return equal;
504 1.1 mrg }
505 1.1 mrg
506 1.1 mrg return isl_bool_true;
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg /* Is "expr1" equal to "expr2"?
510 1.1 mrg */
511 1.1 mrg isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
512 1.1 mrg __isl_keep isl_ast_expr *expr2)
513 1.1 mrg {
514 1.1 mrg if (!expr1 || !expr2)
515 1.1 mrg return isl_bool_error;
516 1.1 mrg
517 1.1 mrg if (expr1 == expr2)
518 1.1 mrg return isl_bool_true;
519 1.1 mrg if (expr1->type != expr2->type)
520 1.1 mrg return isl_bool_false;
521 1.1 mrg switch (expr1->type) {
522 1.1 mrg case isl_ast_expr_int:
523 1.1 mrg return isl_val_eq(expr1->u.v, expr2->u.v);
524 1.1 mrg case isl_ast_expr_id:
525 1.1 mrg return isl_bool_ok(expr1->u.id == expr2->u.id);
526 1.1 mrg case isl_ast_expr_op:
527 1.1 mrg if (expr1->u.op.op != expr2->u.op.op)
528 1.1 mrg return isl_bool_false;
529 1.1 mrg return isl_ast_expr_list_is_equal(expr1->u.op.args,
530 1.1 mrg expr2->u.op.args);
531 1.1 mrg case isl_ast_expr_error:
532 1.1 mrg return isl_bool_error;
533 1.1 mrg }
534 1.1 mrg
535 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal,
536 1.1 mrg "unhandled case", return isl_bool_error);
537 1.1 mrg }
538 1.1 mrg
539 1.1 mrg /* Create a new id expression representing "id".
540 1.1 mrg */
541 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
542 1.1 mrg {
543 1.1 mrg isl_ctx *ctx;
544 1.1 mrg isl_ast_expr *expr;
545 1.1 mrg
546 1.1 mrg if (!id)
547 1.1 mrg return NULL;
548 1.1 mrg
549 1.1 mrg ctx = isl_id_get_ctx(id);
550 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr);
551 1.1 mrg if (!expr)
552 1.1 mrg goto error;
553 1.1 mrg
554 1.1 mrg expr->ctx = ctx;
555 1.1 mrg isl_ctx_ref(ctx);
556 1.1 mrg expr->ref = 1;
557 1.1 mrg expr->type = isl_ast_expr_id;
558 1.1 mrg expr->u.id = id;
559 1.1 mrg
560 1.1 mrg return expr;
561 1.1 mrg error:
562 1.1 mrg isl_id_free(id);
563 1.1 mrg return NULL;
564 1.1 mrg }
565 1.1 mrg
566 1.1 mrg /* Create a new integer expression representing "i".
567 1.1 mrg */
568 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
569 1.1 mrg {
570 1.1 mrg isl_ast_expr *expr;
571 1.1 mrg
572 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr);
573 1.1 mrg if (!expr)
574 1.1 mrg return NULL;
575 1.1 mrg
576 1.1 mrg expr->ctx = ctx;
577 1.1 mrg isl_ctx_ref(ctx);
578 1.1 mrg expr->ref = 1;
579 1.1 mrg expr->type = isl_ast_expr_int;
580 1.1 mrg expr->u.v = isl_val_int_from_si(ctx, i);
581 1.1 mrg if (!expr->u.v)
582 1.1 mrg return isl_ast_expr_free(expr);
583 1.1 mrg
584 1.1 mrg return expr;
585 1.1 mrg }
586 1.1 mrg
587 1.1 mrg /* Create a new integer expression representing "v".
588 1.1 mrg */
589 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
590 1.1 mrg {
591 1.1 mrg isl_ctx *ctx;
592 1.1 mrg isl_ast_expr *expr;
593 1.1 mrg
594 1.1 mrg if (!v)
595 1.1 mrg return NULL;
596 1.1 mrg if (!isl_val_is_int(v))
597 1.1 mrg isl_die(isl_val_get_ctx(v), isl_error_invalid,
598 1.1 mrg "expecting integer value", goto error);
599 1.1 mrg
600 1.1 mrg ctx = isl_val_get_ctx(v);
601 1.1 mrg expr = isl_calloc_type(ctx, isl_ast_expr);
602 1.1 mrg if (!expr)
603 1.1 mrg goto error;
604 1.1 mrg
605 1.1 mrg expr->ctx = ctx;
606 1.1 mrg isl_ctx_ref(ctx);
607 1.1 mrg expr->ref = 1;
608 1.1 mrg expr->type = isl_ast_expr_int;
609 1.1 mrg expr->u.v = v;
610 1.1 mrg
611 1.1 mrg return expr;
612 1.1 mrg error:
613 1.1 mrg isl_val_free(v);
614 1.1 mrg return NULL;
615 1.1 mrg }
616 1.1 mrg
617 1.1 mrg /* Create an expression representing the unary operation "type" applied to
618 1.1 mrg * "arg".
619 1.1 mrg */
620 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_unary(
621 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg)
622 1.1 mrg {
623 1.1 mrg isl_ctx *ctx;
624 1.1 mrg isl_ast_expr *expr = NULL;
625 1.1 mrg isl_ast_expr_list *args;
626 1.1 mrg
627 1.1 mrg if (!arg)
628 1.1 mrg return NULL;
629 1.1 mrg
630 1.1 mrg ctx = isl_ast_expr_get_ctx(arg);
631 1.1 mrg expr = isl_ast_expr_alloc_op(ctx, type, 1);
632 1.1 mrg
633 1.1 mrg args = isl_ast_expr_op_take_args(expr);
634 1.1 mrg args = isl_ast_expr_list_add(args, arg);
635 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args);
636 1.1 mrg
637 1.1 mrg return expr;
638 1.1 mrg }
639 1.1 mrg
640 1.1 mrg /* Create an expression representing the negation of "arg".
641 1.1 mrg */
642 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
643 1.1 mrg {
644 1.1 mrg return isl_ast_expr_alloc_unary(isl_ast_expr_op_minus, arg);
645 1.1 mrg }
646 1.1 mrg
647 1.1 mrg /* Create an expression representing the address of "expr".
648 1.1 mrg */
649 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
650 1.1 mrg {
651 1.1 mrg if (!expr)
652 1.1 mrg return NULL;
653 1.1 mrg
654 1.1 mrg if (isl_ast_expr_get_type(expr) != isl_ast_expr_op ||
655 1.1 mrg isl_ast_expr_get_op_type(expr) != isl_ast_expr_op_access)
656 1.1 mrg isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
657 1.1 mrg "can only take address of access expressions",
658 1.1 mrg return isl_ast_expr_free(expr));
659 1.1 mrg
660 1.1 mrg return isl_ast_expr_alloc_unary(isl_ast_expr_op_address_of, expr);
661 1.1 mrg }
662 1.1 mrg
663 1.1 mrg /* Create an expression representing the binary operation "type"
664 1.1 mrg * applied to "expr1" and "expr2".
665 1.1 mrg */
666 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_alloc_binary(
667 1.1 mrg enum isl_ast_expr_op_type type,
668 1.1 mrg __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
669 1.1 mrg {
670 1.1 mrg isl_ctx *ctx;
671 1.1 mrg isl_ast_expr *expr = NULL;
672 1.1 mrg isl_ast_expr_list *args;
673 1.1 mrg
674 1.1 mrg if (!expr1 || !expr2)
675 1.1 mrg goto error;
676 1.1 mrg
677 1.1 mrg ctx = isl_ast_expr_get_ctx(expr1);
678 1.1 mrg expr = isl_ast_expr_alloc_op(ctx, type, 2);
679 1.1 mrg
680 1.1 mrg args = isl_ast_expr_op_take_args(expr);
681 1.1 mrg args = isl_ast_expr_list_add(args, expr1);
682 1.1 mrg args = isl_ast_expr_list_add(args, expr2);
683 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args);
684 1.1 mrg
685 1.1 mrg return expr;
686 1.1 mrg error:
687 1.1 mrg isl_ast_expr_free(expr1);
688 1.1 mrg isl_ast_expr_free(expr2);
689 1.1 mrg return NULL;
690 1.1 mrg }
691 1.1 mrg
692 1.1 mrg /* Create an expression representing the sum of "expr1" and "expr2".
693 1.1 mrg */
694 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
695 1.1 mrg __isl_take isl_ast_expr *expr2)
696 1.1 mrg {
697 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_add, expr1, expr2);
698 1.1 mrg }
699 1.1 mrg
700 1.1 mrg /* Create an expression representing the difference of "expr1" and "expr2".
701 1.1 mrg */
702 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
703 1.1 mrg __isl_take isl_ast_expr *expr2)
704 1.1 mrg {
705 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_sub, expr1, expr2);
706 1.1 mrg }
707 1.1 mrg
708 1.1 mrg /* Create an expression representing the product of "expr1" and "expr2".
709 1.1 mrg */
710 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
711 1.1 mrg __isl_take isl_ast_expr *expr2)
712 1.1 mrg {
713 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_mul, expr1, expr2);
714 1.1 mrg }
715 1.1 mrg
716 1.1 mrg /* Create an expression representing the quotient of "expr1" and "expr2".
717 1.1 mrg */
718 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
719 1.1 mrg __isl_take isl_ast_expr *expr2)
720 1.1 mrg {
721 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_div, expr1, expr2);
722 1.1 mrg }
723 1.1 mrg
724 1.1 mrg /* Create an expression representing the quotient of the integer
725 1.1 mrg * division of "expr1" by "expr2", where "expr1" is known to be
726 1.1 mrg * non-negative.
727 1.1 mrg */
728 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
729 1.1 mrg __isl_take isl_ast_expr *expr2)
730 1.1 mrg {
731 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_q, expr1, expr2);
732 1.1 mrg }
733 1.1 mrg
734 1.1 mrg /* Create an expression representing the remainder of the integer
735 1.1 mrg * division of "expr1" by "expr2", where "expr1" is known to be
736 1.1 mrg * non-negative.
737 1.1 mrg */
738 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
739 1.1 mrg __isl_take isl_ast_expr *expr2)
740 1.1 mrg {
741 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_r, expr1, expr2);
742 1.1 mrg }
743 1.1 mrg
744 1.1 mrg /* Create an expression representing the conjunction of "expr1" and "expr2".
745 1.1 mrg */
746 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
747 1.1 mrg __isl_take isl_ast_expr *expr2)
748 1.1 mrg {
749 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_and, expr1, expr2);
750 1.1 mrg }
751 1.1 mrg
752 1.1 mrg /* Create an expression representing the conjunction of "expr1" and "expr2",
753 1.1 mrg * where "expr2" is evaluated only if "expr1" is evaluated to true.
754 1.1 mrg */
755 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
756 1.1 mrg __isl_take isl_ast_expr *expr2)
757 1.1 mrg {
758 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_and_then, expr1, expr2);
759 1.1 mrg }
760 1.1 mrg
761 1.1 mrg /* Create an expression representing the disjunction of "expr1" and "expr2".
762 1.1 mrg */
763 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
764 1.1 mrg __isl_take isl_ast_expr *expr2)
765 1.1 mrg {
766 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_or, expr1, expr2);
767 1.1 mrg }
768 1.1 mrg
769 1.1 mrg /* Create an expression representing the disjunction of "expr1" and "expr2",
770 1.1 mrg * where "expr2" is evaluated only if "expr1" is evaluated to false.
771 1.1 mrg */
772 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
773 1.1 mrg __isl_take isl_ast_expr *expr2)
774 1.1 mrg {
775 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_or_else, expr1, expr2);
776 1.1 mrg }
777 1.1 mrg
778 1.1 mrg /* Create an expression representing "expr1" less than or equal to "expr2".
779 1.1 mrg */
780 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
781 1.1 mrg __isl_take isl_ast_expr *expr2)
782 1.1 mrg {
783 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, expr1, expr2);
784 1.1 mrg }
785 1.1 mrg
786 1.1 mrg /* Create an expression representing "expr1" less than "expr2".
787 1.1 mrg */
788 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
789 1.1 mrg __isl_take isl_ast_expr *expr2)
790 1.1 mrg {
791 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_lt, expr1, expr2);
792 1.1 mrg }
793 1.1 mrg
794 1.1 mrg /* Create an expression representing "expr1" greater than or equal to "expr2".
795 1.1 mrg */
796 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1,
797 1.1 mrg __isl_take isl_ast_expr *expr2)
798 1.1 mrg {
799 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_ge, expr1, expr2);
800 1.1 mrg }
801 1.1 mrg
802 1.1 mrg /* Create an expression representing "expr1" greater than "expr2".
803 1.1 mrg */
804 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1,
805 1.1 mrg __isl_take isl_ast_expr *expr2)
806 1.1 mrg {
807 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_gt, expr1, expr2);
808 1.1 mrg }
809 1.1 mrg
810 1.1 mrg /* Create an expression representing "expr1" equal to "expr2".
811 1.1 mrg */
812 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
813 1.1 mrg __isl_take isl_ast_expr *expr2)
814 1.1 mrg {
815 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_eq, expr1, expr2);
816 1.1 mrg }
817 1.1 mrg
818 1.1 mrg /* Create an expression of type "type" with as arguments "arg0" followed
819 1.1 mrg * by "arguments".
820 1.1 mrg */
821 1.1 mrg static __isl_give isl_ast_expr *ast_expr_with_arguments(
822 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg0,
823 1.1 mrg __isl_take isl_ast_expr_list *arguments)
824 1.1 mrg {
825 1.1 mrg arguments = isl_ast_expr_list_insert(arguments, 0, arg0);
826 1.1 mrg return alloc_op(type, arguments);
827 1.1 mrg }
828 1.1 mrg
829 1.1 mrg /* Create an expression representing an access to "array" with index
830 1.1 mrg * expressions "indices".
831 1.1 mrg */
832 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
833 1.1 mrg __isl_take isl_ast_expr_list *indices)
834 1.1 mrg {
835 1.1 mrg return ast_expr_with_arguments(isl_ast_expr_op_access, array, indices);
836 1.1 mrg }
837 1.1 mrg
838 1.1 mrg /* Create an expression representing a call to "function" with argument
839 1.1 mrg * expressions "arguments".
840 1.1 mrg */
841 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
842 1.1 mrg __isl_take isl_ast_expr_list *arguments)
843 1.1 mrg {
844 1.1 mrg return ast_expr_with_arguments(isl_ast_expr_op_call, function, arguments);
845 1.1 mrg }
846 1.1 mrg
847 1.1 mrg /* Wrapper around isl_ast_expr_substitute_ids for use
848 1.1 mrg * as an isl_ast_expr_list_map callback.
849 1.1 mrg */
850 1.1 mrg static __isl_give isl_ast_expr *substitute_ids(__isl_take isl_ast_expr *expr,
851 1.1 mrg void *user)
852 1.1 mrg {
853 1.1 mrg isl_id_to_ast_expr *id2expr = user;
854 1.1 mrg
855 1.1 mrg return isl_ast_expr_substitute_ids(expr,
856 1.1 mrg isl_id_to_ast_expr_copy(id2expr));
857 1.1 mrg }
858 1.1 mrg
859 1.1 mrg /* For each subexpression of "expr" of type isl_ast_expr_id,
860 1.1 mrg * if it appears in "id2expr", then replace it by the corresponding
861 1.1 mrg * expression.
862 1.1 mrg */
863 1.1 mrg __isl_give isl_ast_expr *isl_ast_expr_substitute_ids(
864 1.1 mrg __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr)
865 1.1 mrg {
866 1.1 mrg isl_maybe_isl_ast_expr m;
867 1.1 mrg isl_ast_expr_list *args;
868 1.1 mrg
869 1.1 mrg if (!expr || !id2expr)
870 1.1 mrg goto error;
871 1.1 mrg
872 1.1 mrg switch (expr->type) {
873 1.1 mrg case isl_ast_expr_int:
874 1.1 mrg break;
875 1.1 mrg case isl_ast_expr_id:
876 1.1 mrg m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id);
877 1.1 mrg if (m.valid < 0)
878 1.1 mrg goto error;
879 1.1 mrg if (!m.valid)
880 1.1 mrg break;
881 1.1 mrg isl_ast_expr_free(expr);
882 1.1 mrg expr = m.value;
883 1.1 mrg break;
884 1.1 mrg case isl_ast_expr_op:
885 1.1 mrg args = isl_ast_expr_op_take_args(expr);
886 1.1 mrg args = isl_ast_expr_list_map(args, &substitute_ids, id2expr);
887 1.1 mrg expr = isl_ast_expr_op_restore_args(expr, args);
888 1.1 mrg break;
889 1.1 mrg case isl_ast_expr_error:
890 1.1 mrg expr = isl_ast_expr_free(expr);
891 1.1 mrg break;
892 1.1 mrg }
893 1.1 mrg
894 1.1 mrg isl_id_to_ast_expr_free(id2expr);
895 1.1 mrg return expr;
896 1.1 mrg error:
897 1.1 mrg isl_ast_expr_free(expr);
898 1.1 mrg isl_id_to_ast_expr_free(id2expr);
899 1.1 mrg return NULL;
900 1.1 mrg }
901 1.1 mrg
902 1.1 mrg isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
903 1.1 mrg {
904 1.1 mrg return node ? node->ctx : NULL;
905 1.1 mrg }
906 1.1 mrg
907 1.1 mrg enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
908 1.1 mrg {
909 1.1 mrg return node ? node->type : isl_ast_node_error;
910 1.1 mrg }
911 1.1 mrg
912 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
913 1.1 mrg enum isl_ast_node_type type)
914 1.1 mrg {
915 1.1 mrg isl_ast_node *node;
916 1.1 mrg
917 1.1 mrg node = isl_calloc_type(ctx, isl_ast_node);
918 1.1 mrg if (!node)
919 1.1 mrg return NULL;
920 1.1 mrg
921 1.1 mrg node->ctx = ctx;
922 1.1 mrg isl_ctx_ref(ctx);
923 1.1 mrg node->ref = 1;
924 1.1 mrg node->type = type;
925 1.1 mrg
926 1.1 mrg return node;
927 1.1 mrg }
928 1.1 mrg
929 1.1 mrg /* Create an if node with the given guard.
930 1.1 mrg *
931 1.1 mrg * The then body needs to be filled in later.
932 1.1 mrg */
933 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
934 1.1 mrg {
935 1.1 mrg isl_ast_node *node;
936 1.1 mrg
937 1.1 mrg if (!guard)
938 1.1 mrg return NULL;
939 1.1 mrg
940 1.1 mrg node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
941 1.1 mrg if (!node)
942 1.1 mrg goto error;
943 1.1 mrg node->u.i.guard = guard;
944 1.1 mrg
945 1.1 mrg return node;
946 1.1 mrg error:
947 1.1 mrg isl_ast_expr_free(guard);
948 1.1 mrg return NULL;
949 1.1 mrg }
950 1.1 mrg
951 1.1 mrg /* Create a for node with the given iterator.
952 1.1 mrg *
953 1.1 mrg * The remaining fields need to be filled in later.
954 1.1 mrg */
955 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
956 1.1 mrg {
957 1.1 mrg isl_ast_node *node;
958 1.1 mrg isl_ctx *ctx;
959 1.1 mrg
960 1.1 mrg if (!id)
961 1.1 mrg return NULL;
962 1.1 mrg
963 1.1 mrg ctx = isl_id_get_ctx(id);
964 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_for);
965 1.1 mrg if (!node)
966 1.1 mrg goto error;
967 1.1 mrg
968 1.1 mrg node->u.f.iterator = isl_ast_expr_from_id(id);
969 1.1 mrg if (!node->u.f.iterator)
970 1.1 mrg return isl_ast_node_free(node);
971 1.1 mrg
972 1.1 mrg return node;
973 1.1 mrg error:
974 1.1 mrg isl_id_free(id);
975 1.1 mrg return NULL;
976 1.1 mrg }
977 1.1 mrg
978 1.1 mrg /* Create a mark node, marking "node" with "id".
979 1.1 mrg */
980 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id,
981 1.1 mrg __isl_take isl_ast_node *node)
982 1.1 mrg {
983 1.1 mrg isl_ctx *ctx;
984 1.1 mrg isl_ast_node *mark;
985 1.1 mrg
986 1.1 mrg if (!id || !node)
987 1.1 mrg goto error;
988 1.1 mrg
989 1.1 mrg ctx = isl_id_get_ctx(id);
990 1.1 mrg mark = isl_ast_node_alloc(ctx, isl_ast_node_mark);
991 1.1 mrg if (!mark)
992 1.1 mrg goto error;
993 1.1 mrg
994 1.1 mrg mark->u.m.mark = id;
995 1.1 mrg mark->u.m.node = node;
996 1.1 mrg
997 1.1 mrg return mark;
998 1.1 mrg error:
999 1.1 mrg isl_id_free(id);
1000 1.1 mrg isl_ast_node_free(node);
1001 1.1 mrg return NULL;
1002 1.1 mrg }
1003 1.1 mrg
1004 1.1 mrg /* Create a user node evaluating "expr".
1005 1.1 mrg */
1006 1.1 mrg __isl_give isl_ast_node *isl_ast_node_user_from_expr(
1007 1.1 mrg __isl_take isl_ast_expr *expr)
1008 1.1 mrg {
1009 1.1 mrg isl_ctx *ctx;
1010 1.1 mrg isl_ast_node *node;
1011 1.1 mrg
1012 1.1 mrg if (!expr)
1013 1.1 mrg return NULL;
1014 1.1 mrg
1015 1.1 mrg ctx = isl_ast_expr_get_ctx(expr);
1016 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_user);
1017 1.1 mrg if (!node)
1018 1.1 mrg goto error;
1019 1.1 mrg
1020 1.1 mrg node->u.e.expr = expr;
1021 1.1 mrg
1022 1.1 mrg return node;
1023 1.1 mrg error:
1024 1.1 mrg isl_ast_expr_free(expr);
1025 1.1 mrg return NULL;
1026 1.1 mrg }
1027 1.1 mrg
1028 1.1 mrg /* This is an alternative name for the function above.
1029 1.1 mrg */
1030 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
1031 1.1 mrg {
1032 1.1 mrg return isl_ast_node_user_from_expr(expr);
1033 1.1 mrg }
1034 1.1 mrg
1035 1.1 mrg /* Create a block node with the given children.
1036 1.1 mrg */
1037 1.1 mrg __isl_give isl_ast_node *isl_ast_node_block_from_children(
1038 1.1 mrg __isl_take isl_ast_node_list *list)
1039 1.1 mrg {
1040 1.1 mrg isl_ast_node *node;
1041 1.1 mrg isl_ctx *ctx;
1042 1.1 mrg
1043 1.1 mrg if (!list)
1044 1.1 mrg return NULL;
1045 1.1 mrg
1046 1.1 mrg ctx = isl_ast_node_list_get_ctx(list);
1047 1.1 mrg node = isl_ast_node_alloc(ctx, isl_ast_node_block);
1048 1.1 mrg if (!node)
1049 1.1 mrg goto error;
1050 1.1 mrg
1051 1.1 mrg node->u.b.children = list;
1052 1.1 mrg
1053 1.1 mrg return node;
1054 1.1 mrg error:
1055 1.1 mrg isl_ast_node_list_free(list);
1056 1.1 mrg return NULL;
1057 1.1 mrg }
1058 1.1 mrg
1059 1.1 mrg /* This is an alternative name for the function above.
1060 1.1 mrg */
1061 1.1 mrg __isl_give isl_ast_node *isl_ast_node_alloc_block(
1062 1.1 mrg __isl_take isl_ast_node_list *list)
1063 1.1 mrg {
1064 1.1 mrg return isl_ast_node_block_from_children(list);
1065 1.1 mrg }
1066 1.1 mrg
1067 1.1 mrg /* Represent the given list of nodes as a single node, either by
1068 1.1 mrg * extract the node from a single element list or by creating
1069 1.1 mrg * a block node with the list of nodes as children.
1070 1.1 mrg */
1071 1.1 mrg __isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
1072 1.1 mrg __isl_take isl_ast_node_list *list)
1073 1.1 mrg {
1074 1.1 mrg isl_size n;
1075 1.1 mrg isl_ast_node *node;
1076 1.1 mrg
1077 1.1 mrg n = isl_ast_node_list_n_ast_node(list);
1078 1.1 mrg if (n < 0)
1079 1.1 mrg goto error;
1080 1.1 mrg if (n != 1)
1081 1.1 mrg return isl_ast_node_alloc_block(list);
1082 1.1 mrg
1083 1.1 mrg node = isl_ast_node_list_get_ast_node(list, 0);
1084 1.1 mrg isl_ast_node_list_free(list);
1085 1.1 mrg
1086 1.1 mrg return node;
1087 1.1 mrg error:
1088 1.1 mrg isl_ast_node_list_free(list);
1089 1.1 mrg return NULL;
1090 1.1 mrg }
1091 1.1 mrg
1092 1.1 mrg __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
1093 1.1 mrg {
1094 1.1 mrg if (!node)
1095 1.1 mrg return NULL;
1096 1.1 mrg
1097 1.1 mrg node->ref++;
1098 1.1 mrg return node;
1099 1.1 mrg }
1100 1.1 mrg
1101 1.1 mrg /* Return a fresh copy of "node".
1102 1.1 mrg *
1103 1.1 mrg * In the case of a degenerate for node, take into account
1104 1.1 mrg * that "cond" and "inc" are NULL.
1105 1.1 mrg */
1106 1.1 mrg __isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
1107 1.1 mrg {
1108 1.1 mrg isl_ast_node *dup;
1109 1.1 mrg
1110 1.1 mrg if (!node)
1111 1.1 mrg return NULL;
1112 1.1 mrg
1113 1.1 mrg dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
1114 1.1 mrg if (!dup)
1115 1.1 mrg return NULL;
1116 1.1 mrg
1117 1.1 mrg switch (node->type) {
1118 1.1 mrg case isl_ast_node_if:
1119 1.1 mrg dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
1120 1.1 mrg dup->u.i.then = isl_ast_node_copy(node->u.i.then);
1121 1.1 mrg dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
1122 1.1 mrg if (!dup->u.i.guard || !dup->u.i.then ||
1123 1.1 mrg (node->u.i.else_node && !dup->u.i.else_node))
1124 1.1 mrg return isl_ast_node_free(dup);
1125 1.1 mrg break;
1126 1.1 mrg case isl_ast_node_for:
1127 1.1 mrg dup->u.f.degenerate = node->u.f.degenerate;
1128 1.1 mrg dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
1129 1.1 mrg dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
1130 1.1 mrg dup->u.f.body = isl_ast_node_copy(node->u.f.body);
1131 1.1 mrg if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.body)
1132 1.1 mrg return isl_ast_node_free(dup);
1133 1.1 mrg if (node->u.f.degenerate)
1134 1.1 mrg break;
1135 1.1 mrg dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
1136 1.1 mrg dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
1137 1.1 mrg if (!dup->u.f.cond || !dup->u.f.inc)
1138 1.1 mrg return isl_ast_node_free(dup);
1139 1.1 mrg break;
1140 1.1 mrg case isl_ast_node_block:
1141 1.1 mrg dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
1142 1.1 mrg if (!dup->u.b.children)
1143 1.1 mrg return isl_ast_node_free(dup);
1144 1.1 mrg break;
1145 1.1 mrg case isl_ast_node_mark:
1146 1.1 mrg dup->u.m.mark = isl_id_copy(node->u.m.mark);
1147 1.1 mrg dup->u.m.node = isl_ast_node_copy(node->u.m.node);
1148 1.1 mrg if (!dup->u.m.mark || !dup->u.m.node)
1149 1.1 mrg return isl_ast_node_free(dup);
1150 1.1 mrg break;
1151 1.1 mrg case isl_ast_node_user:
1152 1.1 mrg dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
1153 1.1 mrg if (!dup->u.e.expr)
1154 1.1 mrg return isl_ast_node_free(dup);
1155 1.1 mrg break;
1156 1.1 mrg case isl_ast_node_error:
1157 1.1 mrg break;
1158 1.1 mrg }
1159 1.1 mrg
1160 1.1 mrg if (!node->annotation)
1161 1.1 mrg return dup;
1162 1.1 mrg dup->annotation = isl_id_copy(node->annotation);
1163 1.1 mrg if (!dup->annotation)
1164 1.1 mrg return isl_ast_node_free(dup);
1165 1.1 mrg
1166 1.1 mrg return dup;
1167 1.1 mrg }
1168 1.1 mrg
1169 1.1 mrg __isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
1170 1.1 mrg {
1171 1.1 mrg if (!node)
1172 1.1 mrg return NULL;
1173 1.1 mrg
1174 1.1 mrg if (node->ref == 1)
1175 1.1 mrg return node;
1176 1.1 mrg node->ref--;
1177 1.1 mrg return isl_ast_node_dup(node);
1178 1.1 mrg }
1179 1.1 mrg
1180 1.1 mrg __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node)
1181 1.1 mrg {
1182 1.1 mrg if (!node)
1183 1.1 mrg return NULL;
1184 1.1 mrg
1185 1.1 mrg if (--node->ref > 0)
1186 1.1 mrg return NULL;
1187 1.1 mrg
1188 1.1 mrg switch (node->type) {
1189 1.1 mrg case isl_ast_node_if:
1190 1.1 mrg isl_ast_expr_free(node->u.i.guard);
1191 1.1 mrg isl_ast_node_free(node->u.i.then);
1192 1.1 mrg isl_ast_node_free(node->u.i.else_node);
1193 1.1 mrg break;
1194 1.1 mrg case isl_ast_node_for:
1195 1.1 mrg isl_ast_expr_free(node->u.f.iterator);
1196 1.1 mrg isl_ast_expr_free(node->u.f.init);
1197 1.1 mrg isl_ast_expr_free(node->u.f.cond);
1198 1.1 mrg isl_ast_expr_free(node->u.f.inc);
1199 1.1 mrg isl_ast_node_free(node->u.f.body);
1200 1.1 mrg break;
1201 1.1 mrg case isl_ast_node_block:
1202 1.1 mrg isl_ast_node_list_free(node->u.b.children);
1203 1.1 mrg break;
1204 1.1 mrg case isl_ast_node_mark:
1205 1.1 mrg isl_id_free(node->u.m.mark);
1206 1.1 mrg isl_ast_node_free(node->u.m.node);
1207 1.1 mrg break;
1208 1.1 mrg case isl_ast_node_user:
1209 1.1 mrg isl_ast_expr_free(node->u.e.expr);
1210 1.1 mrg break;
1211 1.1 mrg case isl_ast_node_error:
1212 1.1 mrg break;
1213 1.1 mrg }
1214 1.1 mrg
1215 1.1 mrg isl_id_free(node->annotation);
1216 1.1 mrg isl_ctx_deref(node->ctx);
1217 1.1 mrg free(node);
1218 1.1 mrg
1219 1.1 mrg return NULL;
1220 1.1 mrg }
1221 1.1 mrg
1222 1.1 mrg /* Check that "node" is of type "type", printing "msg" if not.
1223 1.1 mrg */
1224 1.1 mrg static isl_stat isl_ast_node_check_type(__isl_keep isl_ast_node *node,
1225 1.1 mrg enum isl_ast_node_type type, const char *msg)
1226 1.1 mrg {
1227 1.1 mrg if (!node)
1228 1.1 mrg return isl_stat_error;
1229 1.1 mrg if (node->type != type)
1230 1.1 mrg isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, msg,
1231 1.1 mrg return isl_stat_error);
1232 1.1 mrg return isl_stat_ok;
1233 1.1 mrg }
1234 1.1 mrg
1235 1.1 mrg /* Check that "node" is of type isl_ast_node_block.
1236 1.1 mrg */
1237 1.1 mrg static isl_stat isl_ast_node_check_block(__isl_keep isl_ast_node *node)
1238 1.1 mrg {
1239 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_block,
1240 1.1 mrg "not a block node");
1241 1.1 mrg }
1242 1.1 mrg
1243 1.1 mrg /* Check that "node" is of type isl_ast_node_if.
1244 1.1 mrg */
1245 1.1 mrg static isl_stat isl_ast_node_check_if(__isl_keep isl_ast_node *node)
1246 1.1 mrg {
1247 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_if, "not an if node");
1248 1.1 mrg }
1249 1.1 mrg
1250 1.1 mrg /* Check that "node" is of type isl_ast_node_for.
1251 1.1 mrg */
1252 1.1 mrg static isl_stat isl_ast_node_check_for(__isl_keep isl_ast_node *node)
1253 1.1 mrg {
1254 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_for,
1255 1.1 mrg "not a for node");
1256 1.1 mrg }
1257 1.1 mrg
1258 1.1 mrg /* Check that "node" is of type isl_ast_node_mark.
1259 1.1 mrg */
1260 1.1 mrg static isl_stat isl_ast_node_check_mark(__isl_keep isl_ast_node *node)
1261 1.1 mrg {
1262 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_mark,
1263 1.1 mrg "not a mark node");
1264 1.1 mrg }
1265 1.1 mrg
1266 1.1 mrg /* Check that "node" is of type isl_ast_node_user.
1267 1.1 mrg */
1268 1.1 mrg static isl_stat isl_ast_node_check_user(__isl_keep isl_ast_node *node)
1269 1.1 mrg {
1270 1.1 mrg return isl_ast_node_check_type(node, isl_ast_node_user,
1271 1.1 mrg "not a user node");
1272 1.1 mrg }
1273 1.1 mrg
1274 1.1 mrg #undef NODE_TYPE
1275 1.1 mrg #define NODE_TYPE for
1276 1.1 mrg #undef FIELD_NAME
1277 1.1 mrg #define FIELD_NAME init
1278 1.1 mrg #undef FIELD_TYPE
1279 1.1 mrg #define FIELD_TYPE isl_ast_expr
1280 1.1 mrg #undef FIELD
1281 1.1 mrg #define FIELD u.f.init
1282 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1283 1.1 mrg
1284 1.1 mrg #undef NODE_TYPE
1285 1.1 mrg #define NODE_TYPE for
1286 1.1 mrg #undef FIELD_NAME
1287 1.1 mrg #define FIELD_NAME cond
1288 1.1 mrg #undef FIELD_TYPE
1289 1.1 mrg #define FIELD_TYPE isl_ast_expr
1290 1.1 mrg #undef FIELD
1291 1.1 mrg #define FIELD u.f.cond
1292 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1293 1.1 mrg
1294 1.1 mrg #undef NODE_TYPE
1295 1.1 mrg #define NODE_TYPE for
1296 1.1 mrg #undef FIELD_NAME
1297 1.1 mrg #define FIELD_NAME inc
1298 1.1 mrg #undef FIELD_TYPE
1299 1.1 mrg #define FIELD_TYPE isl_ast_expr
1300 1.1 mrg #undef FIELD
1301 1.1 mrg #define FIELD u.f.inc
1302 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1303 1.1 mrg
1304 1.1 mrg #undef NODE_TYPE
1305 1.1 mrg #define NODE_TYPE for
1306 1.1 mrg #undef FIELD_NAME
1307 1.1 mrg #define FIELD_NAME body
1308 1.1 mrg #undef FIELD_TYPE
1309 1.1 mrg #define FIELD_TYPE isl_ast_node
1310 1.1 mrg #undef FIELD
1311 1.1 mrg #define FIELD u.f.body
1312 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1313 1.1 mrg
1314 1.1 mrg /* Return the body of the for-node "node",
1315 1.1 mrg * This may be either a copy or the body itself
1316 1.1 mrg * if there is only one reference to "node".
1317 1.1 mrg * This allows the body to be modified inplace
1318 1.1 mrg * if both "node" and its body have only a single reference.
1319 1.1 mrg * The caller is not allowed to modify "node" between this call and
1320 1.1 mrg * the subsequent call to isl_ast_node_for_restore_body.
1321 1.1 mrg * The only exception is that isl_ast_node_free can be called instead.
1322 1.1 mrg */
1323 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_for_take_body(
1324 1.1 mrg __isl_keep isl_ast_node *node)
1325 1.1 mrg {
1326 1.1 mrg isl_ast_node *body;
1327 1.1 mrg
1328 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1329 1.1 mrg return NULL;
1330 1.1 mrg if (node->ref != 1)
1331 1.1 mrg return isl_ast_node_for_get_body(node);
1332 1.1 mrg body = node->u.f.body;
1333 1.1 mrg node->u.f.body = NULL;
1334 1.1 mrg return body;
1335 1.1 mrg }
1336 1.1 mrg
1337 1.1 mrg /* Set the body of the for-node "node" to "body",
1338 1.1 mrg * where the body of "node" may be missing
1339 1.1 mrg * due to a preceding call to isl_ast_node_for_take_body.
1340 1.1 mrg * However, in this case, "node" only has a single reference.
1341 1.1 mrg */
1342 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_for_restore_body(
1343 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
1344 1.1 mrg {
1345 1.1 mrg return isl_ast_node_for_set_body(node, body);
1346 1.1 mrg }
1347 1.1 mrg
1348 1.1 mrg __isl_give isl_ast_node *isl_ast_node_for_get_body(
1349 1.1 mrg __isl_keep isl_ast_node *node)
1350 1.1 mrg {
1351 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1352 1.1 mrg return NULL;
1353 1.1 mrg return isl_ast_node_copy(node->u.f.body);
1354 1.1 mrg }
1355 1.1 mrg
1356 1.1 mrg /* Mark the given for node as being degenerate.
1357 1.1 mrg */
1358 1.1 mrg __isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
1359 1.1 mrg __isl_take isl_ast_node *node)
1360 1.1 mrg {
1361 1.1 mrg node = isl_ast_node_cow(node);
1362 1.1 mrg if (!node)
1363 1.1 mrg return NULL;
1364 1.1 mrg node->u.f.degenerate = 1;
1365 1.1 mrg return node;
1366 1.1 mrg }
1367 1.1 mrg
1368 1.1 mrg isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
1369 1.1 mrg {
1370 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1371 1.1 mrg return isl_bool_error;
1372 1.1 mrg return isl_bool_ok(node->u.f.degenerate);
1373 1.1 mrg }
1374 1.1 mrg
1375 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
1376 1.1 mrg __isl_keep isl_ast_node *node)
1377 1.1 mrg {
1378 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1379 1.1 mrg return NULL;
1380 1.1 mrg return isl_ast_expr_copy(node->u.f.iterator);
1381 1.1 mrg }
1382 1.1 mrg
1383 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_init(
1384 1.1 mrg __isl_keep isl_ast_node *node)
1385 1.1 mrg {
1386 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1387 1.1 mrg return NULL;
1388 1.1 mrg return isl_ast_expr_copy(node->u.f.init);
1389 1.1 mrg }
1390 1.1 mrg
1391 1.1 mrg /* Return the condition expression of the given for node.
1392 1.1 mrg *
1393 1.1 mrg * If the for node is degenerate, then the condition is not explicitly
1394 1.1 mrg * stored in the node. Instead, it is constructed as
1395 1.1 mrg *
1396 1.1 mrg * iterator <= init
1397 1.1 mrg */
1398 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_cond(
1399 1.1 mrg __isl_keep isl_ast_node *node)
1400 1.1 mrg {
1401 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1402 1.1 mrg return NULL;
1403 1.1 mrg if (!node->u.f.degenerate)
1404 1.1 mrg return isl_ast_expr_copy(node->u.f.cond);
1405 1.1 mrg
1406 1.1 mrg return isl_ast_expr_alloc_binary(isl_ast_expr_op_le,
1407 1.1 mrg isl_ast_expr_copy(node->u.f.iterator),
1408 1.1 mrg isl_ast_expr_copy(node->u.f.init));
1409 1.1 mrg }
1410 1.1 mrg
1411 1.1 mrg /* Return the increment of the given for node.
1412 1.1 mrg *
1413 1.1 mrg * If the for node is degenerate, then the increment is not explicitly
1414 1.1 mrg * stored in the node. We simply return "1".
1415 1.1 mrg */
1416 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_for_get_inc(
1417 1.1 mrg __isl_keep isl_ast_node *node)
1418 1.1 mrg {
1419 1.1 mrg if (isl_ast_node_check_for(node) < 0)
1420 1.1 mrg return NULL;
1421 1.1 mrg if (!node->u.f.degenerate)
1422 1.1 mrg return isl_ast_expr_copy(node->u.f.inc);
1423 1.1 mrg return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
1424 1.1 mrg }
1425 1.1 mrg
1426 1.1 mrg #undef NODE_TYPE
1427 1.1 mrg #define NODE_TYPE if
1428 1.1 mrg #undef FIELD_NAME
1429 1.1 mrg #define FIELD_NAME then
1430 1.1 mrg #undef FIELD_TYPE
1431 1.1 mrg #define FIELD_TYPE isl_ast_node
1432 1.1 mrg #undef FIELD
1433 1.1 mrg #define FIELD u.i.then
1434 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1435 1.1 mrg
1436 1.1 mrg /* Return the then-branch of the if-node "node",
1437 1.1 mrg * This may be either a copy or the branch itself
1438 1.1 mrg * if there is only one reference to "node".
1439 1.1 mrg * This allows the branch to be modified inplace
1440 1.1 mrg * if both "node" and its then-branch have only a single reference.
1441 1.1 mrg * The caller is not allowed to modify "node" between this call and
1442 1.1 mrg * the subsequent call to isl_ast_node_if_restore_then_node.
1443 1.1 mrg * The only exception is that isl_ast_node_free can be called instead.
1444 1.1 mrg */
1445 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_take_then_node(
1446 1.1 mrg __isl_keep isl_ast_node *node)
1447 1.1 mrg {
1448 1.1 mrg isl_ast_node *then_node;
1449 1.1 mrg
1450 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1451 1.1 mrg return NULL;
1452 1.1 mrg if (node->ref != 1)
1453 1.1 mrg return isl_ast_node_if_get_then_node(node);
1454 1.1 mrg then_node = node->u.i.then;
1455 1.1 mrg node->u.i.then = NULL;
1456 1.1 mrg return then_node;
1457 1.1 mrg }
1458 1.1 mrg
1459 1.1 mrg /* Set the then-branch of the if-node "node" to "child",
1460 1.1 mrg * where the then-branch of "node" may be missing
1461 1.1 mrg * due to a preceding call to isl_ast_node_if_take_then_node.
1462 1.1 mrg * However, in this case, "node" only has a single reference.
1463 1.1 mrg */
1464 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_restore_then_node(
1465 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1466 1.1 mrg {
1467 1.1 mrg return isl_ast_node_if_set_then(node, child);
1468 1.1 mrg }
1469 1.1 mrg
1470 1.1 mrg /* Return the then-node of the given if-node.
1471 1.1 mrg */
1472 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_then_node(
1473 1.1 mrg __isl_keep isl_ast_node *node)
1474 1.1 mrg {
1475 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1476 1.1 mrg return NULL;
1477 1.1 mrg return isl_ast_node_copy(node->u.i.then);
1478 1.1 mrg }
1479 1.1 mrg
1480 1.1 mrg /* This is an alternative name for the function above.
1481 1.1 mrg */
1482 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_then(
1483 1.1 mrg __isl_keep isl_ast_node *node)
1484 1.1 mrg {
1485 1.1 mrg return isl_ast_node_if_get_then_node(node);
1486 1.1 mrg }
1487 1.1 mrg
1488 1.1 mrg /* Does the given if-node have an else-node?
1489 1.1 mrg */
1490 1.1 mrg isl_bool isl_ast_node_if_has_else_node(__isl_keep isl_ast_node *node)
1491 1.1 mrg {
1492 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1493 1.1 mrg return isl_bool_error;
1494 1.1 mrg return isl_bool_ok(node->u.i.else_node != NULL);
1495 1.1 mrg }
1496 1.1 mrg
1497 1.1 mrg /* This is an alternative name for the function above.
1498 1.1 mrg */
1499 1.1 mrg isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node)
1500 1.1 mrg {
1501 1.1 mrg return isl_ast_node_if_has_else_node(node);
1502 1.1 mrg }
1503 1.1 mrg
1504 1.1 mrg /* Return the else-node of the given if-node,
1505 1.1 mrg * assuming there is one.
1506 1.1 mrg */
1507 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_else_node(
1508 1.1 mrg __isl_keep isl_ast_node *node)
1509 1.1 mrg {
1510 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1511 1.1 mrg return NULL;
1512 1.1 mrg return isl_ast_node_copy(node->u.i.else_node);
1513 1.1 mrg }
1514 1.1 mrg
1515 1.1 mrg /* This is an alternative name for the function above.
1516 1.1 mrg */
1517 1.1 mrg __isl_give isl_ast_node *isl_ast_node_if_get_else(
1518 1.1 mrg __isl_keep isl_ast_node *node)
1519 1.1 mrg {
1520 1.1 mrg return isl_ast_node_if_get_else_node(node);
1521 1.1 mrg }
1522 1.1 mrg
1523 1.1 mrg #undef NODE_TYPE
1524 1.1 mrg #define NODE_TYPE if
1525 1.1 mrg #undef FIELD_NAME
1526 1.1 mrg #define FIELD_NAME else_node
1527 1.1 mrg #undef FIELD_TYPE
1528 1.1 mrg #define FIELD_TYPE isl_ast_node
1529 1.1 mrg #undef FIELD
1530 1.1 mrg #define FIELD u.i.else_node
1531 1.1 mrg static
1532 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1533 1.1 mrg
1534 1.1 mrg /* Return the else-branch of the if-node "node",
1535 1.1 mrg * This may be either a copy or the branch itself
1536 1.1 mrg * if there is only one reference to "node".
1537 1.1 mrg * This allows the branch to be modified inplace
1538 1.1 mrg * if both "node" and its else-branch have only a single reference.
1539 1.1 mrg * The caller is not allowed to modify "node" between this call and
1540 1.1 mrg * the subsequent call to isl_ast_node_if_restore_else_node.
1541 1.1 mrg * The only exception is that isl_ast_node_free can be called instead.
1542 1.1 mrg */
1543 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_take_else_node(
1544 1.1 mrg __isl_keep isl_ast_node *node)
1545 1.1 mrg {
1546 1.1 mrg isl_ast_node *else_node;
1547 1.1 mrg
1548 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1549 1.1 mrg return NULL;
1550 1.1 mrg if (node->ref != 1)
1551 1.1 mrg return isl_ast_node_if_get_else_node(node);
1552 1.1 mrg else_node = node->u.i.else_node;
1553 1.1 mrg node->u.i.else_node = NULL;
1554 1.1 mrg return else_node;
1555 1.1 mrg }
1556 1.1 mrg
1557 1.1 mrg /* Set the else-branch of the if-node "node" to "child",
1558 1.1 mrg * where the else-branch of "node" may be missing
1559 1.1 mrg * due to a preceding call to isl_ast_node_if_take_else_node.
1560 1.1 mrg * However, in this case, "node" only has a single reference.
1561 1.1 mrg */
1562 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_if_restore_else_node(
1563 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1564 1.1 mrg {
1565 1.1 mrg return isl_ast_node_if_set_else_node(node, child);
1566 1.1 mrg }
1567 1.1 mrg
1568 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_if_get_cond(
1569 1.1 mrg __isl_keep isl_ast_node *node)
1570 1.1 mrg {
1571 1.1 mrg if (isl_ast_node_check_if(node) < 0)
1572 1.1 mrg return NULL;
1573 1.1 mrg return isl_ast_expr_copy(node->u.i.guard);
1574 1.1 mrg }
1575 1.1 mrg
1576 1.1 mrg __isl_give isl_ast_node_list *isl_ast_node_block_get_children(
1577 1.1 mrg __isl_keep isl_ast_node *node)
1578 1.1 mrg {
1579 1.1 mrg if (isl_ast_node_check_block(node) < 0)
1580 1.1 mrg return NULL;
1581 1.1 mrg return isl_ast_node_list_copy(node->u.b.children);
1582 1.1 mrg }
1583 1.1 mrg
1584 1.1 mrg #undef NODE_TYPE
1585 1.1 mrg #define NODE_TYPE block
1586 1.1 mrg #undef FIELD_NAME
1587 1.1 mrg #define FIELD_NAME children
1588 1.1 mrg #undef FIELD_TYPE
1589 1.1 mrg #define FIELD_TYPE isl_ast_node_list
1590 1.1 mrg #undef FIELD
1591 1.1 mrg #define FIELD u.b.children
1592 1.1 mrg static
1593 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1594 1.1 mrg
1595 1.1 mrg /* Return the children of the block-node "node",
1596 1.1 mrg * This may be either a copy or the children themselves
1597 1.1 mrg * if there is only one reference to "node".
1598 1.1 mrg * This allows the children to be modified inplace
1599 1.1 mrg * if both "node" and its children have only a single reference.
1600 1.1 mrg * The caller is not allowed to modify "node" between this call and
1601 1.1 mrg * the subsequent call to isl_ast_node_block_restore_children.
1602 1.1 mrg * The only exception is that isl_ast_node_free can be called instead.
1603 1.1 mrg */
1604 1.1 mrg static __isl_give isl_ast_node_list *isl_ast_node_block_take_children(
1605 1.1 mrg __isl_keep isl_ast_node *node)
1606 1.1 mrg {
1607 1.1 mrg isl_ast_node_list *children;
1608 1.1 mrg
1609 1.1 mrg if (isl_ast_node_check_block(node) < 0)
1610 1.1 mrg return NULL;
1611 1.1 mrg if (node->ref != 1)
1612 1.1 mrg return isl_ast_node_block_get_children(node);
1613 1.1 mrg children = node->u.b.children;
1614 1.1 mrg node->u.b.children = NULL;
1615 1.1 mrg return children;
1616 1.1 mrg }
1617 1.1 mrg
1618 1.1 mrg /* Set the children of the block-node "node" to "children",
1619 1.1 mrg * where the children of "node" may be missing
1620 1.1 mrg * due to a preceding call to isl_ast_node_block_take_children.
1621 1.1 mrg * However, in this case, "node" only has a single reference.
1622 1.1 mrg */
1623 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_block_restore_children(
1624 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node_list *children)
1625 1.1 mrg {
1626 1.1 mrg return isl_ast_node_block_set_children(node, children);
1627 1.1 mrg }
1628 1.1 mrg
1629 1.1 mrg __isl_give isl_ast_expr *isl_ast_node_user_get_expr(
1630 1.1 mrg __isl_keep isl_ast_node *node)
1631 1.1 mrg {
1632 1.1 mrg if (isl_ast_node_check_user(node) < 0)
1633 1.1 mrg return NULL;
1634 1.1 mrg
1635 1.1 mrg return isl_ast_expr_copy(node->u.e.expr);
1636 1.1 mrg }
1637 1.1 mrg
1638 1.1 mrg /* Return the mark identifier of the mark node "node".
1639 1.1 mrg */
1640 1.1 mrg __isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
1641 1.1 mrg {
1642 1.1 mrg if (isl_ast_node_check_mark(node) < 0)
1643 1.1 mrg return NULL;
1644 1.1 mrg
1645 1.1 mrg return isl_id_copy(node->u.m.mark);
1646 1.1 mrg }
1647 1.1 mrg
1648 1.1 mrg /* Return the node marked by mark node "node".
1649 1.1 mrg */
1650 1.1 mrg __isl_give isl_ast_node *isl_ast_node_mark_get_node(
1651 1.1 mrg __isl_keep isl_ast_node *node)
1652 1.1 mrg {
1653 1.1 mrg if (isl_ast_node_check_mark(node) < 0)
1654 1.1 mrg return NULL;
1655 1.1 mrg
1656 1.1 mrg return isl_ast_node_copy(node->u.m.node);
1657 1.1 mrg }
1658 1.1 mrg
1659 1.1 mrg #undef NODE_TYPE
1660 1.1 mrg #define NODE_TYPE mark
1661 1.1 mrg #undef FIELD_NAME
1662 1.1 mrg #define FIELD_NAME node
1663 1.1 mrg #undef FIELD_TYPE
1664 1.1 mrg #define FIELD_TYPE isl_ast_node
1665 1.1 mrg #undef FIELD
1666 1.1 mrg #define FIELD u.m.node
1667 1.1 mrg static
1668 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1669 1.1 mrg
1670 1.1 mrg /* Return the child of the mark-node "node",
1671 1.1 mrg * This may be either a copy or the child itself
1672 1.1 mrg * if there is only one reference to "node".
1673 1.1 mrg * This allows the child to be modified inplace
1674 1.1 mrg * if both "node" and its child have only a single reference.
1675 1.1 mrg * The caller is not allowed to modify "node" between this call and
1676 1.1 mrg * the subsequent call to isl_ast_node_mark_restore_node.
1677 1.1 mrg * The only exception is that isl_ast_node_free can be called instead.
1678 1.1 mrg */
1679 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_mark_take_node(
1680 1.1 mrg __isl_keep isl_ast_node *node)
1681 1.1 mrg {
1682 1.1 mrg isl_ast_node *child;
1683 1.1 mrg
1684 1.1 mrg if (isl_ast_node_check_mark(node) < 0)
1685 1.1 mrg return NULL;
1686 1.1 mrg if (node->ref != 1)
1687 1.1 mrg return isl_ast_node_mark_get_node(node);
1688 1.1 mrg child = node->u.m.node;
1689 1.1 mrg node->u.m.node = NULL;
1690 1.1 mrg return child;
1691 1.1 mrg }
1692 1.1 mrg
1693 1.1 mrg /* Set the child of the mark-node "node" to "child",
1694 1.1 mrg * where the child of "node" may be missing
1695 1.1 mrg * due to a preceding call to isl_ast_node_mark_take_node.
1696 1.1 mrg * However, in this case, "node" only has a single reference.
1697 1.1 mrg */
1698 1.1 mrg static __isl_give isl_ast_node *isl_ast_node_mark_restore_node(
1699 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1700 1.1 mrg {
1701 1.1 mrg return isl_ast_node_mark_set_node(node, child);
1702 1.1 mrg }
1703 1.1 mrg
1704 1.1 mrg __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
1705 1.1 mrg {
1706 1.1 mrg return node ? isl_id_copy(node->annotation) : NULL;
1707 1.1 mrg }
1708 1.1 mrg
1709 1.1 mrg /* Check that "node" is of any type.
1710 1.1 mrg * That is, simply check that it is a valid node.
1711 1.1 mrg */
1712 1.1 mrg static isl_stat isl_ast_node_check_any(__isl_keep isl_ast_node *node)
1713 1.1 mrg {
1714 1.1 mrg return isl_stat_non_null(node);
1715 1.1 mrg }
1716 1.1 mrg
1717 1.1 mrg #undef NODE_TYPE
1718 1.1 mrg #define NODE_TYPE any
1719 1.1 mrg #undef FIELD_NAME
1720 1.1 mrg #define FIELD_NAME annotation
1721 1.1 mrg #undef FIELD_TYPE
1722 1.1 mrg #define FIELD_TYPE isl_id
1723 1.1 mrg #undef FIELD
1724 1.1 mrg #define FIELD annotation
1725 1.1 mrg static
1726 1.1 mrg #include "isl_ast_node_set_field_templ.c"
1727 1.1 mrg
1728 1.1 mrg /* Replace node->annotation by "annotation".
1729 1.1 mrg */
1730 1.1 mrg __isl_give isl_ast_node *isl_ast_node_set_annotation(
1731 1.1 mrg __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1732 1.1 mrg {
1733 1.1 mrg return isl_ast_node_any_set_annotation(node, annotation);
1734 1.1 mrg }
1735 1.1 mrg
1736 1.1 mrg static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node,
1737 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1738 1.1 mrg int *more, void *user),
1739 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1740 1.1 mrg void *user),
1741 1.1 mrg void *user);
1742 1.1 mrg
1743 1.1 mrg /* Traverse the elements of "list" and all their descendants
1744 1.1 mrg * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1745 1.1 mrg * whenever a node is left.
1746 1.1 mrg *
1747 1.1 mrg * Return the updated node.
1748 1.1 mrg */
1749 1.1 mrg static __isl_give isl_ast_node_list *traverse_list(
1750 1.1 mrg __isl_take isl_ast_node_list *list,
1751 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1752 1.1 mrg int *more, void *user),
1753 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1754 1.1 mrg void *user),
1755 1.1 mrg void *user)
1756 1.1 mrg {
1757 1.1 mrg int i;
1758 1.1 mrg isl_size n;
1759 1.1 mrg
1760 1.1 mrg n = isl_ast_node_list_size(list);
1761 1.1 mrg if (n < 0)
1762 1.1 mrg return isl_ast_node_list_free(list);
1763 1.1 mrg
1764 1.1 mrg for (i = 0; i < n; ++i) {
1765 1.1 mrg isl_ast_node *node;
1766 1.1 mrg
1767 1.1 mrg node = isl_ast_node_list_get_at(list, i);
1768 1.1 mrg node = traverse(node, enter, leave, user);
1769 1.1 mrg list = isl_ast_node_list_set_at(list, i, node);
1770 1.1 mrg }
1771 1.1 mrg
1772 1.1 mrg return list;
1773 1.1 mrg }
1774 1.1 mrg
1775 1.1 mrg /* Traverse the descendants of "node" (including the node itself)
1776 1.1 mrg * in depth first preorder. Call "enter" whenever a node is entered and "leave"
1777 1.1 mrg * whenever a node is left.
1778 1.1 mrg *
1779 1.1 mrg * If "enter" sets the "more" argument to zero, then the subtree rooted
1780 1.1 mrg * at the given node is skipped.
1781 1.1 mrg *
1782 1.1 mrg * Return the updated node.
1783 1.1 mrg */
1784 1.1 mrg static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node,
1785 1.1 mrg __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node,
1786 1.1 mrg int *more, void *user),
1787 1.1 mrg __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node,
1788 1.1 mrg void *user),
1789 1.1 mrg void *user)
1790 1.1 mrg {
1791 1.1 mrg int more;
1792 1.1 mrg isl_bool has_else;
1793 1.1 mrg isl_ast_node *child;
1794 1.1 mrg isl_ast_node_list *children;
1795 1.1 mrg
1796 1.1 mrg node = enter(node, &more, user);
1797 1.1 mrg if (!node)
1798 1.1 mrg return NULL;
1799 1.1 mrg if (!more)
1800 1.1 mrg return node;
1801 1.1 mrg
1802 1.1 mrg switch (node->type) {
1803 1.1 mrg case isl_ast_node_for:
1804 1.1 mrg child = isl_ast_node_for_take_body(node);
1805 1.1 mrg child = traverse(child, enter, leave, user);
1806 1.1 mrg node = isl_ast_node_for_restore_body(node, child);
1807 1.1 mrg return leave(node, user);
1808 1.1 mrg case isl_ast_node_if:
1809 1.1 mrg child = isl_ast_node_if_take_then_node(node);
1810 1.1 mrg child = traverse(child, enter, leave, user);
1811 1.1 mrg node = isl_ast_node_if_restore_then_node(node, child);
1812 1.1 mrg has_else = isl_ast_node_if_has_else_node(node);
1813 1.1 mrg if (has_else < 0)
1814 1.1 mrg return isl_ast_node_free(node);
1815 1.1 mrg if (!has_else)
1816 1.1 mrg return leave(node, user);
1817 1.1 mrg child = isl_ast_node_if_take_else_node(node);
1818 1.1 mrg child = traverse(child, enter, leave, user);
1819 1.1 mrg node = isl_ast_node_if_restore_else_node(node, child);
1820 1.1 mrg return leave(node, user);
1821 1.1 mrg case isl_ast_node_block:
1822 1.1 mrg children = isl_ast_node_block_take_children(node);
1823 1.1 mrg children = traverse_list(children, enter, leave, user);
1824 1.1 mrg node = isl_ast_node_block_restore_children(node, children);
1825 1.1 mrg return leave(node, user);
1826 1.1 mrg case isl_ast_node_mark:
1827 1.1 mrg child = isl_ast_node_mark_take_node(node);
1828 1.1 mrg child = traverse(child, enter, leave, user);
1829 1.1 mrg node = isl_ast_node_mark_restore_node(node, child);
1830 1.1 mrg return leave(node, user);
1831 1.1 mrg case isl_ast_node_user:
1832 1.1 mrg return leave(node, user);
1833 1.1 mrg case isl_ast_node_error:
1834 1.1 mrg return isl_ast_node_free(node);
1835 1.1 mrg }
1836 1.1 mrg
1837 1.1 mrg return node;
1838 1.1 mrg }
1839 1.1 mrg
1840 1.1 mrg /* Internal data structure storing the arguments of
1841 1.1 mrg * isl_ast_node_foreach_descendant_top_down.
1842 1.1 mrg */
1843 1.1 mrg struct isl_ast_node_preorder_data {
1844 1.1 mrg isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user);
1845 1.1 mrg void *user;
1846 1.1 mrg };
1847 1.1 mrg
1848 1.1 mrg /* Enter "node" and set *more to continue traversing its descendants.
1849 1.1 mrg *
1850 1.1 mrg * In the case of a depth first preorder traversal, call data->fn and
1851 1.1 mrg * let it decide whether to continue.
1852 1.1 mrg */
1853 1.1 mrg static __isl_give isl_ast_node *preorder_enter(__isl_take isl_ast_node *node,
1854 1.1 mrg int *more, void *user)
1855 1.1 mrg {
1856 1.1 mrg struct isl_ast_node_preorder_data *data = user;
1857 1.1 mrg isl_bool m;
1858 1.1 mrg
1859 1.1 mrg if (!node)
1860 1.1 mrg return NULL;
1861 1.1 mrg m = data->fn(node, data->user);
1862 1.1 mrg if (m < 0)
1863 1.1 mrg return isl_ast_node_free(node);
1864 1.1 mrg *more = m;
1865 1.1 mrg return node;
1866 1.1 mrg }
1867 1.1 mrg
1868 1.1 mrg /* Leave "node".
1869 1.1 mrg *
1870 1.1 mrg * In the case of a depth first preorder traversal, nothing needs to be done.
1871 1.1 mrg */
1872 1.1 mrg static __isl_give isl_ast_node *preorder_leave(__isl_take isl_ast_node *node,
1873 1.1 mrg void *user)
1874 1.1 mrg {
1875 1.1 mrg return node;
1876 1.1 mrg }
1877 1.1 mrg
1878 1.1 mrg /* Traverse the descendants of "node" (including the node itself)
1879 1.1 mrg * in depth first preorder.
1880 1.1 mrg *
1881 1.1 mrg * If "fn" returns isl_bool_error on any of the nodes, then the traversal
1882 1.1 mrg * is aborted.
1883 1.1 mrg * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
1884 1.1 mrg * at that node is skipped.
1885 1.1 mrg *
1886 1.1 mrg * Return isl_stat_ok on success and isl_stat_error on failure.
1887 1.1 mrg */
1888 1.1 mrg isl_stat isl_ast_node_foreach_descendant_top_down(
1889 1.1 mrg __isl_keep isl_ast_node *node,
1890 1.1 mrg isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1891 1.1 mrg {
1892 1.1 mrg struct isl_ast_node_preorder_data data = { fn, user };
1893 1.1 mrg
1894 1.1 mrg node = isl_ast_node_copy(node);
1895 1.1 mrg node = traverse(node, &preorder_enter, &preorder_leave, &data);
1896 1.1 mrg isl_ast_node_free(node);
1897 1.1 mrg
1898 1.1 mrg return isl_stat_non_null(node);
1899 1.1 mrg }
1900 1.1 mrg
1901 1.1 mrg /* Internal data structure storing the arguments of
1902 1.1 mrg * isl_ast_node_map_descendant_bottom_up.
1903 1.1 mrg */
1904 1.1 mrg struct isl_ast_node_postorder_data {
1905 1.1 mrg __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node,
1906 1.1 mrg void *user);
1907 1.1 mrg void *user;
1908 1.1 mrg };
1909 1.1 mrg
1910 1.1 mrg /* Enter "node" and set *more to continue traversing its descendants.
1911 1.1 mrg *
1912 1.1 mrg * In the case of a depth-first post-order traversal,
1913 1.1 mrg * nothing needs to be done and traversal always continues.
1914 1.1 mrg */
1915 1.1 mrg static __isl_give isl_ast_node *postorder_enter(__isl_take isl_ast_node *node,
1916 1.1 mrg int *more, void *user)
1917 1.1 mrg {
1918 1.1 mrg *more = 1;
1919 1.1 mrg return node;
1920 1.1 mrg }
1921 1.1 mrg
1922 1.1 mrg /* Leave "node".
1923 1.1 mrg *
1924 1.1 mrg * In the case of a depth-first post-order traversal, call data->fn.
1925 1.1 mrg */
1926 1.1 mrg static __isl_give isl_ast_node *postorder_leave(__isl_take isl_ast_node *node,
1927 1.1 mrg void *user)
1928 1.1 mrg {
1929 1.1 mrg struct isl_ast_node_postorder_data *data = user;
1930 1.1 mrg
1931 1.1 mrg if (!node)
1932 1.1 mrg return NULL;
1933 1.1 mrg
1934 1.1 mrg node = data->fn(node, data->user);
1935 1.1 mrg return node;
1936 1.1 mrg }
1937 1.1 mrg
1938 1.1 mrg /* Traverse the descendants of "node" (including the node itself)
1939 1.1 mrg * in depth-first post-order, where the user callback is allowed to modify the
1940 1.1 mrg * visited node.
1941 1.1 mrg *
1942 1.1 mrg * Return the updated node.
1943 1.1 mrg */
1944 1.1 mrg __isl_give isl_ast_node *isl_ast_node_map_descendant_bottom_up(
1945 1.1 mrg __isl_take isl_ast_node *node,
1946 1.1 mrg __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node,
1947 1.1 mrg void *user), void *user)
1948 1.1 mrg {
1949 1.1 mrg struct isl_ast_node_postorder_data data = { fn, user };
1950 1.1 mrg
1951 1.1 mrg return traverse(node, &postorder_enter, &postorder_leave, &data);
1952 1.1 mrg }
1953 1.1 mrg
1954 1.1 mrg /* Textual C representation of the various operators.
1955 1.1 mrg */
1956 1.1 mrg static char *op_str_c[] = {
1957 1.1 mrg [isl_ast_expr_op_and] = "&&",
1958 1.1 mrg [isl_ast_expr_op_and_then] = "&&",
1959 1.1 mrg [isl_ast_expr_op_or] = "||",
1960 1.1 mrg [isl_ast_expr_op_or_else] = "||",
1961 1.1 mrg [isl_ast_expr_op_max] = "max",
1962 1.1 mrg [isl_ast_expr_op_min] = "min",
1963 1.1 mrg [isl_ast_expr_op_minus] = "-",
1964 1.1 mrg [isl_ast_expr_op_add] = "+",
1965 1.1 mrg [isl_ast_expr_op_sub] = "-",
1966 1.1 mrg [isl_ast_expr_op_mul] = "*",
1967 1.1 mrg [isl_ast_expr_op_fdiv_q] = "floord",
1968 1.1 mrg [isl_ast_expr_op_pdiv_q] = "/",
1969 1.1 mrg [isl_ast_expr_op_pdiv_r] = "%",
1970 1.1 mrg [isl_ast_expr_op_zdiv_r] = "%",
1971 1.1 mrg [isl_ast_expr_op_div] = "/",
1972 1.1 mrg [isl_ast_expr_op_eq] = "==",
1973 1.1 mrg [isl_ast_expr_op_le] = "<=",
1974 1.1 mrg [isl_ast_expr_op_ge] = ">=",
1975 1.1 mrg [isl_ast_expr_op_lt] = "<",
1976 1.1 mrg [isl_ast_expr_op_gt] = ">",
1977 1.1 mrg [isl_ast_expr_op_member] = ".",
1978 1.1 mrg [isl_ast_expr_op_address_of] = "&"
1979 1.1 mrg };
1980 1.1 mrg
1981 1.1 mrg /* Precedence in C of the various operators.
1982 1.1 mrg * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1983 1.1 mrg * Lowest value means highest precedence.
1984 1.1 mrg */
1985 1.1 mrg static int op_prec[] = {
1986 1.1 mrg [isl_ast_expr_op_and] = 13,
1987 1.1 mrg [isl_ast_expr_op_and_then] = 13,
1988 1.1 mrg [isl_ast_expr_op_or] = 14,
1989 1.1 mrg [isl_ast_expr_op_or_else] = 14,
1990 1.1 mrg [isl_ast_expr_op_max] = 2,
1991 1.1 mrg [isl_ast_expr_op_min] = 2,
1992 1.1 mrg [isl_ast_expr_op_minus] = 3,
1993 1.1 mrg [isl_ast_expr_op_add] = 6,
1994 1.1 mrg [isl_ast_expr_op_sub] = 6,
1995 1.1 mrg [isl_ast_expr_op_mul] = 5,
1996 1.1 mrg [isl_ast_expr_op_div] = 5,
1997 1.1 mrg [isl_ast_expr_op_fdiv_q] = 2,
1998 1.1 mrg [isl_ast_expr_op_pdiv_q] = 5,
1999 1.1 mrg [isl_ast_expr_op_pdiv_r] = 5,
2000 1.1 mrg [isl_ast_expr_op_zdiv_r] = 5,
2001 1.1 mrg [isl_ast_expr_op_cond] = 15,
2002 1.1 mrg [isl_ast_expr_op_select] = 15,
2003 1.1 mrg [isl_ast_expr_op_eq] = 9,
2004 1.1 mrg [isl_ast_expr_op_le] = 8,
2005 1.1 mrg [isl_ast_expr_op_ge] = 8,
2006 1.1 mrg [isl_ast_expr_op_lt] = 8,
2007 1.1 mrg [isl_ast_expr_op_gt] = 8,
2008 1.1 mrg [isl_ast_expr_op_call] = 2,
2009 1.1 mrg [isl_ast_expr_op_access] = 2,
2010 1.1 mrg [isl_ast_expr_op_member] = 2,
2011 1.1 mrg [isl_ast_expr_op_address_of] = 3
2012 1.1 mrg };
2013 1.1 mrg
2014 1.1 mrg /* Is the operator left-to-right associative?
2015 1.1 mrg */
2016 1.1 mrg static int op_left[] = {
2017 1.1 mrg [isl_ast_expr_op_and] = 1,
2018 1.1 mrg [isl_ast_expr_op_and_then] = 1,
2019 1.1 mrg [isl_ast_expr_op_or] = 1,
2020 1.1 mrg [isl_ast_expr_op_or_else] = 1,
2021 1.1 mrg [isl_ast_expr_op_max] = 1,
2022 1.1 mrg [isl_ast_expr_op_min] = 1,
2023 1.1 mrg [isl_ast_expr_op_minus] = 0,
2024 1.1 mrg [isl_ast_expr_op_add] = 1,
2025 1.1 mrg [isl_ast_expr_op_sub] = 1,
2026 1.1 mrg [isl_ast_expr_op_mul] = 1,
2027 1.1 mrg [isl_ast_expr_op_div] = 1,
2028 1.1 mrg [isl_ast_expr_op_fdiv_q] = 1,
2029 1.1 mrg [isl_ast_expr_op_pdiv_q] = 1,
2030 1.1 mrg [isl_ast_expr_op_pdiv_r] = 1,
2031 1.1 mrg [isl_ast_expr_op_zdiv_r] = 1,
2032 1.1 mrg [isl_ast_expr_op_cond] = 0,
2033 1.1 mrg [isl_ast_expr_op_select] = 0,
2034 1.1 mrg [isl_ast_expr_op_eq] = 1,
2035 1.1 mrg [isl_ast_expr_op_le] = 1,
2036 1.1 mrg [isl_ast_expr_op_ge] = 1,
2037 1.1 mrg [isl_ast_expr_op_lt] = 1,
2038 1.1 mrg [isl_ast_expr_op_gt] = 1,
2039 1.1 mrg [isl_ast_expr_op_call] = 1,
2040 1.1 mrg [isl_ast_expr_op_access] = 1,
2041 1.1 mrg [isl_ast_expr_op_member] = 1,
2042 1.1 mrg [isl_ast_expr_op_address_of] = 0
2043 1.1 mrg };
2044 1.1 mrg
2045 1.1 mrg static int is_and(enum isl_ast_expr_op_type op)
2046 1.1 mrg {
2047 1.1 mrg return op == isl_ast_expr_op_and || op == isl_ast_expr_op_and_then;
2048 1.1 mrg }
2049 1.1 mrg
2050 1.1 mrg static int is_or(enum isl_ast_expr_op_type op)
2051 1.1 mrg {
2052 1.1 mrg return op == isl_ast_expr_op_or || op == isl_ast_expr_op_or_else;
2053 1.1 mrg }
2054 1.1 mrg
2055 1.1 mrg static int is_add_sub(enum isl_ast_expr_op_type op)
2056 1.1 mrg {
2057 1.1 mrg return op == isl_ast_expr_op_add || op == isl_ast_expr_op_sub;
2058 1.1 mrg }
2059 1.1 mrg
2060 1.1 mrg static int is_div_mod(enum isl_ast_expr_op_type op)
2061 1.1 mrg {
2062 1.1 mrg return op == isl_ast_expr_op_div ||
2063 1.1 mrg op == isl_ast_expr_op_pdiv_r ||
2064 1.1 mrg op == isl_ast_expr_op_zdiv_r;
2065 1.1 mrg }
2066 1.1 mrg
2067 1.1 mrg static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
2068 1.1 mrg __isl_keep isl_ast_expr *expr);
2069 1.1 mrg
2070 1.1 mrg /* Do we need/want parentheses around "expr" as a subexpression of
2071 1.1 mrg * an "op" operation? If "left" is set, then "expr" is the left-most
2072 1.1 mrg * operand.
2073 1.1 mrg *
2074 1.1 mrg * We only need parentheses if "expr" represents an operation.
2075 1.1 mrg *
2076 1.1 mrg * If op has a higher precedence than expr->u.op.op, then we need
2077 1.1 mrg * parentheses.
2078 1.1 mrg * If op and expr->u.op.op have the same precedence, but the operations
2079 1.1 mrg * are performed in an order that is different from the associativity,
2080 1.1 mrg * then we need parentheses.
2081 1.1 mrg *
2082 1.1 mrg * An and inside an or technically does not require parentheses,
2083 1.1 mrg * but some compilers complain about that, so we add them anyway.
2084 1.1 mrg *
2085 1.1 mrg * Computations such as "a / b * c" and "a % b + c" can be somewhat
2086 1.1 mrg * difficult to read, so we add parentheses for those as well.
2087 1.1 mrg */
2088 1.1 mrg static int sub_expr_need_parens(enum isl_ast_expr_op_type op,
2089 1.1 mrg __isl_keep isl_ast_expr *expr, int left)
2090 1.1 mrg {
2091 1.1 mrg if (expr->type != isl_ast_expr_op)
2092 1.1 mrg return 0;
2093 1.1 mrg
2094 1.1 mrg if (op_prec[expr->u.op.op] > op_prec[op])
2095 1.1 mrg return 1;
2096 1.1 mrg if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
2097 1.1 mrg return 1;
2098 1.1 mrg
2099 1.1 mrg if (is_or(op) && is_and(expr->u.op.op))
2100 1.1 mrg return 1;
2101 1.1 mrg if (op == isl_ast_expr_op_mul && expr->u.op.op != isl_ast_expr_op_mul &&
2102 1.1 mrg op_prec[expr->u.op.op] == op_prec[op])
2103 1.1 mrg return 1;
2104 1.1 mrg if (is_add_sub(op) && is_div_mod(expr->u.op.op))
2105 1.1 mrg return 1;
2106 1.1 mrg
2107 1.1 mrg return 0;
2108 1.1 mrg }
2109 1.1 mrg
2110 1.1 mrg /* Print the subexpression at position "pos" of operation expression "expr"
2111 1.1 mrg * in C format.
2112 1.1 mrg * If "left" is set, then "expr" is the left-most operand.
2113 1.1 mrg */
2114 1.1 mrg static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p,
2115 1.1 mrg __isl_keep isl_ast_expr *expr, int pos, int left)
2116 1.1 mrg {
2117 1.1 mrg int need_parens;
2118 1.1 mrg isl_ast_expr *arg;
2119 1.1 mrg
2120 1.1 mrg if (!expr)
2121 1.1 mrg return isl_printer_free(p);
2122 1.1 mrg
2123 1.1 mrg arg = isl_ast_expr_list_get_at(expr->u.op.args, pos);
2124 1.1 mrg need_parens = sub_expr_need_parens(expr->u.op.op, arg, left);
2125 1.1 mrg
2126 1.1 mrg if (need_parens)
2127 1.1 mrg p = isl_printer_print_str(p, "(");
2128 1.1 mrg p = print_ast_expr_c(p, arg);
2129 1.1 mrg if (need_parens)
2130 1.1 mrg p = isl_printer_print_str(p, ")");
2131 1.1 mrg
2132 1.1 mrg isl_ast_expr_free(arg);
2133 1.1 mrg
2134 1.1 mrg return p;
2135 1.1 mrg }
2136 1.1 mrg
2137 1.1 mrg #define isl_ast_expr_op_last isl_ast_expr_op_address_of
2138 1.1 mrg
2139 1.1 mrg /* Data structure that holds the user-specified textual
2140 1.1 mrg * representations for the operators in C format.
2141 1.1 mrg * The entries are either NULL or copies of strings.
2142 1.1 mrg * A NULL entry means that the default name should be used.
2143 1.1 mrg */
2144 1.1 mrg struct isl_ast_expr_op_names {
2145 1.1 mrg char *op_str[isl_ast_expr_op_last + 1];
2146 1.1 mrg };
2147 1.1 mrg
2148 1.1 mrg /* Create an empty struct isl_ast_expr_op_names.
2149 1.1 mrg */
2150 1.1 mrg static void *create_names(isl_ctx *ctx)
2151 1.1 mrg {
2152 1.1 mrg return isl_calloc_type(ctx, struct isl_ast_expr_op_names);
2153 1.1 mrg }
2154 1.1 mrg
2155 1.1 mrg /* Free a struct isl_ast_expr_op_names along with all memory
2156 1.1 mrg * owned by the struct.
2157 1.1 mrg */
2158 1.1 mrg static void free_names(void *user)
2159 1.1 mrg {
2160 1.1 mrg int i;
2161 1.1 mrg struct isl_ast_expr_op_names *names = user;
2162 1.1 mrg
2163 1.1 mrg if (!user)
2164 1.1 mrg return;
2165 1.1 mrg
2166 1.1 mrg for (i = 0; i <= isl_ast_expr_op_last; ++i)
2167 1.1 mrg free(names->op_str[i]);
2168 1.1 mrg free(user);
2169 1.1 mrg }
2170 1.1 mrg
2171 1.1 mrg /* Create an identifier that is used to store
2172 1.1 mrg * an isl_ast_expr_op_names note.
2173 1.1 mrg */
2174 1.1 mrg static __isl_give isl_id *names_id(isl_ctx *ctx)
2175 1.1 mrg {
2176 1.1 mrg return isl_id_alloc(ctx, "isl_ast_expr_op_type_names", NULL);
2177 1.1 mrg }
2178 1.1 mrg
2179 1.1 mrg /* Ensure that "p" has a note identified by "id".
2180 1.1 mrg * If there is no such note yet, then it is created by "note_create" and
2181 1.1 mrg * scheduled do be freed by "note_free".
2182 1.1 mrg */
2183 1.1 mrg static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p,
2184 1.1 mrg __isl_keep isl_id *id, void *(*note_create)(isl_ctx *),
2185 1.1 mrg void (*note_free)(void *))
2186 1.1 mrg {
2187 1.1 mrg isl_ctx *ctx;
2188 1.1 mrg isl_id *note_id;
2189 1.1 mrg isl_bool has_note;
2190 1.1 mrg void *note;
2191 1.1 mrg
2192 1.1 mrg has_note = isl_printer_has_note(p, id);
2193 1.1 mrg if (has_note < 0)
2194 1.1 mrg return isl_printer_free(p);
2195 1.1 mrg if (has_note)
2196 1.1 mrg return p;
2197 1.1 mrg
2198 1.1 mrg ctx = isl_printer_get_ctx(p);
2199 1.1 mrg note = note_create(ctx);
2200 1.1 mrg if (!note)
2201 1.1 mrg return isl_printer_free(p);
2202 1.1 mrg note_id = isl_id_alloc(ctx, NULL, note);
2203 1.1 mrg if (!note_id)
2204 1.1 mrg note_free(note);
2205 1.1 mrg else
2206 1.1 mrg note_id = isl_id_set_free_user(note_id, note_free);
2207 1.1 mrg
2208 1.1 mrg p = isl_printer_set_note(p, isl_id_copy(id), note_id);
2209 1.1 mrg
2210 1.1 mrg return p;
2211 1.1 mrg }
2212 1.1 mrg
2213 1.1 mrg /* Ensure that "p" has an isl_ast_expr_op_names note identified by "id".
2214 1.1 mrg */
2215 1.1 mrg static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p,
2216 1.1 mrg __isl_keep isl_id *id)
2217 1.1 mrg {
2218 1.1 mrg return alloc_note(p, id, &create_names, &free_names);
2219 1.1 mrg }
2220 1.1 mrg
2221 1.1 mrg /* Retrieve the note identified by "id" from "p".
2222 1.1 mrg * The note is assumed to exist.
2223 1.1 mrg */
2224 1.1 mrg static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id)
2225 1.1 mrg {
2226 1.1 mrg void *note;
2227 1.1 mrg
2228 1.1 mrg id = isl_printer_get_note(p, isl_id_copy(id));
2229 1.1 mrg note = isl_id_get_user(id);
2230 1.1 mrg isl_id_free(id);
2231 1.1 mrg
2232 1.1 mrg return note;
2233 1.1 mrg }
2234 1.1 mrg
2235 1.1 mrg /* Use "name" to print operations of type "type" to "p".
2236 1.1 mrg *
2237 1.1 mrg * Store the name in an isl_ast_expr_op_names note attached to "p", such that
2238 1.1 mrg * it can be retrieved by get_op_str.
2239 1.1 mrg */
2240 1.1 mrg __isl_give isl_printer *isl_ast_expr_op_type_set_print_name(
2241 1.1 mrg __isl_take isl_printer *p, enum isl_ast_expr_op_type type,
2242 1.1 mrg __isl_keep const char *name)
2243 1.1 mrg {
2244 1.1 mrg isl_id *id;
2245 1.1 mrg struct isl_ast_expr_op_names *names;
2246 1.1 mrg
2247 1.1 mrg if (!p)
2248 1.1 mrg return NULL;
2249 1.1 mrg if (type > isl_ast_expr_op_last)
2250 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_invalid,
2251 1.1 mrg "invalid type", return isl_printer_free(p));
2252 1.1 mrg
2253 1.1 mrg id = names_id(isl_printer_get_ctx(p));
2254 1.1 mrg p = alloc_names(p, id);
2255 1.1 mrg names = get_note(p, id);
2256 1.1 mrg isl_id_free(id);
2257 1.1 mrg if (!names)
2258 1.1 mrg return isl_printer_free(p);
2259 1.1 mrg free(names->op_str[type]);
2260 1.1 mrg names->op_str[type] = strdup(name);
2261 1.1 mrg
2262 1.1 mrg return p;
2263 1.1 mrg }
2264 1.1 mrg
2265 1.1 mrg /* This is an alternative name for the function above.
2266 1.1 mrg */
2267 1.1 mrg __isl_give isl_printer *isl_ast_op_type_set_print_name(
2268 1.1 mrg __isl_take isl_printer *p, enum isl_ast_expr_op_type type,
2269 1.1 mrg __isl_keep const char *name)
2270 1.1 mrg {
2271 1.1 mrg return isl_ast_expr_op_type_set_print_name(p, type, name);
2272 1.1 mrg }
2273 1.1 mrg
2274 1.1 mrg /* Return the textual representation of "type" in C format.
2275 1.1 mrg *
2276 1.1 mrg * If there is a user-specified name in an isl_ast_expr_op_names note
2277 1.1 mrg * associated to "p", then return that.
2278 1.1 mrg * Otherwise, return the default name in op_str_c.
2279 1.1 mrg */
2280 1.1 mrg static const char *get_op_str_c(__isl_keep isl_printer *p,
2281 1.1 mrg enum isl_ast_expr_op_type type)
2282 1.1 mrg {
2283 1.1 mrg isl_id *id;
2284 1.1 mrg isl_bool has_names;
2285 1.1 mrg struct isl_ast_expr_op_names *names = NULL;
2286 1.1 mrg
2287 1.1 mrg id = names_id(isl_printer_get_ctx(p));
2288 1.1 mrg has_names = isl_printer_has_note(p, id);
2289 1.1 mrg if (has_names >= 0 && has_names)
2290 1.1 mrg names = get_note(p, id);
2291 1.1 mrg isl_id_free(id);
2292 1.1 mrg if (names && names->op_str[type])
2293 1.1 mrg return names->op_str[type];
2294 1.1 mrg return op_str_c[type];
2295 1.1 mrg }
2296 1.1 mrg
2297 1.1 mrg /* Print the expression at position "pos" in "list" in C format.
2298 1.1 mrg */
2299 1.1 mrg static __isl_give isl_printer *print_at_c(__isl_take isl_printer *p,
2300 1.1 mrg __isl_keep isl_ast_expr_list *list, int pos)
2301 1.1 mrg {
2302 1.1 mrg isl_ast_expr *expr;
2303 1.1 mrg
2304 1.1 mrg expr = isl_ast_expr_list_get_at(list, pos);
2305 1.1 mrg p = print_ast_expr_c(p, expr);
2306 1.1 mrg isl_ast_expr_free(expr);
2307 1.1 mrg
2308 1.1 mrg return p;
2309 1.1 mrg }
2310 1.1 mrg
2311 1.1 mrg /* Print a min or max reduction "expr" in C format.
2312 1.1 mrg */
2313 1.1 mrg static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p,
2314 1.1 mrg __isl_keep isl_ast_expr *expr)
2315 1.1 mrg {
2316 1.1 mrg int i = 0;
2317 1.1 mrg isl_size n;
2318 1.1 mrg
2319 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args);
2320 1.1 mrg if (n < 0)
2321 1.1 mrg return isl_printer_free(p);
2322 1.1 mrg
2323 1.1 mrg for (i = 1; i < n; ++i) {
2324 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
2325 1.1 mrg p = isl_printer_print_str(p, "(");
2326 1.1 mrg }
2327 1.1 mrg p = print_at_c(p, expr->u.op.args, 0);
2328 1.1 mrg for (i = 1; i < n; ++i) {
2329 1.1 mrg p = isl_printer_print_str(p, ", ");
2330 1.1 mrg p = print_at_c(p, expr->u.op.args, i);
2331 1.1 mrg p = isl_printer_print_str(p, ")");
2332 1.1 mrg }
2333 1.1 mrg
2334 1.1 mrg return p;
2335 1.1 mrg }
2336 1.1 mrg
2337 1.1 mrg /* Print a function call "expr" in C format.
2338 1.1 mrg *
2339 1.1 mrg * The first argument represents the function to be called.
2340 1.1 mrg */
2341 1.1 mrg static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p,
2342 1.1 mrg __isl_keep isl_ast_expr *expr)
2343 1.1 mrg {
2344 1.1 mrg int i = 0;
2345 1.1 mrg isl_size n;
2346 1.1 mrg
2347 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args);
2348 1.1 mrg if (n < 0)
2349 1.1 mrg return isl_printer_free(p);
2350 1.1 mrg
2351 1.1 mrg p = print_at_c(p, expr->u.op.args, 0);
2352 1.1 mrg p = isl_printer_print_str(p, "(");
2353 1.1 mrg for (i = 1; i < n; ++i) {
2354 1.1 mrg if (i != 1)
2355 1.1 mrg p = isl_printer_print_str(p, ", ");
2356 1.1 mrg p = print_at_c(p, expr->u.op.args, i);
2357 1.1 mrg }
2358 1.1 mrg p = isl_printer_print_str(p, ")");
2359 1.1 mrg
2360 1.1 mrg return p;
2361 1.1 mrg }
2362 1.1 mrg
2363 1.1 mrg /* Print an array access "expr" in C format.
2364 1.1 mrg *
2365 1.1 mrg * The first argument represents the array being accessed.
2366 1.1 mrg */
2367 1.1 mrg static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p,
2368 1.1 mrg __isl_keep isl_ast_expr *expr)
2369 1.1 mrg {
2370 1.1 mrg int i = 0;
2371 1.1 mrg isl_size n;
2372 1.1 mrg
2373 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args);
2374 1.1 mrg if (n < 0)
2375 1.1 mrg return isl_printer_free(p);
2376 1.1 mrg
2377 1.1 mrg p = print_at_c(p, expr->u.op.args, 0);
2378 1.1 mrg for (i = 1; i < n; ++i) {
2379 1.1 mrg p = isl_printer_print_str(p, "[");
2380 1.1 mrg p = print_at_c(p, expr->u.op.args, i);
2381 1.1 mrg p = isl_printer_print_str(p, "]");
2382 1.1 mrg }
2383 1.1 mrg
2384 1.1 mrg return p;
2385 1.1 mrg }
2386 1.1 mrg
2387 1.1 mrg /* Print "expr" to "p" in C format.
2388 1.1 mrg */
2389 1.1 mrg static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
2390 1.1 mrg __isl_keep isl_ast_expr *expr)
2391 1.1 mrg {
2392 1.1 mrg isl_size n;
2393 1.1 mrg
2394 1.1 mrg if (!p)
2395 1.1 mrg return NULL;
2396 1.1 mrg if (!expr)
2397 1.1 mrg return isl_printer_free(p);
2398 1.1 mrg
2399 1.1 mrg switch (expr->type) {
2400 1.1 mrg case isl_ast_expr_op:
2401 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_call) {
2402 1.1 mrg p = print_call_c(p, expr);
2403 1.1 mrg break;
2404 1.1 mrg }
2405 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_access) {
2406 1.1 mrg p = print_access_c(p, expr);
2407 1.1 mrg break;
2408 1.1 mrg }
2409 1.1 mrg n = isl_ast_expr_list_size(expr->u.op.args);
2410 1.1 mrg if (n < 0)
2411 1.1 mrg return isl_printer_free(p);
2412 1.1 mrg if (n == 1) {
2413 1.1 mrg p = isl_printer_print_str(p,
2414 1.1 mrg get_op_str_c(p, expr->u.op.op));
2415 1.1 mrg p = print_sub_expr_c(p, expr, 0, 0);
2416 1.1 mrg break;
2417 1.1 mrg }
2418 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_fdiv_q) {
2419 1.1 mrg const char *name;
2420 1.1 mrg
2421 1.1 mrg name = get_op_str_c(p, isl_ast_expr_op_fdiv_q);
2422 1.1 mrg p = isl_printer_print_str(p, name);
2423 1.1 mrg p = isl_printer_print_str(p, "(");
2424 1.1 mrg p = print_at_c(p, expr->u.op.args, 0);
2425 1.1 mrg p = isl_printer_print_str(p, ", ");
2426 1.1 mrg p = print_at_c(p, expr->u.op.args, 1);
2427 1.1 mrg p = isl_printer_print_str(p, ")");
2428 1.1 mrg break;
2429 1.1 mrg }
2430 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_max ||
2431 1.1 mrg expr->u.op.op == isl_ast_expr_op_min) {
2432 1.1 mrg p = print_min_max_c(p, expr);
2433 1.1 mrg break;
2434 1.1 mrg }
2435 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_cond ||
2436 1.1 mrg expr->u.op.op == isl_ast_expr_op_select) {
2437 1.1 mrg p = print_at_c(p, expr->u.op.args, 0);
2438 1.1 mrg p = isl_printer_print_str(p, " ? ");
2439 1.1 mrg p = print_at_c(p, expr->u.op.args, 1);
2440 1.1 mrg p = isl_printer_print_str(p, " : ");
2441 1.1 mrg p = print_at_c(p, expr->u.op.args, 2);
2442 1.1 mrg break;
2443 1.1 mrg }
2444 1.1 mrg if (n != 2)
2445 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_internal,
2446 1.1 mrg "operation should have two arguments",
2447 1.1 mrg return isl_printer_free(p));
2448 1.1 mrg p = print_sub_expr_c(p, expr, 0, 1);
2449 1.1 mrg if (expr->u.op.op != isl_ast_expr_op_member)
2450 1.1 mrg p = isl_printer_print_str(p, " ");
2451 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
2452 1.1 mrg if (expr->u.op.op != isl_ast_expr_op_member)
2453 1.1 mrg p = isl_printer_print_str(p, " ");
2454 1.1 mrg p = print_sub_expr_c(p, expr, 1, 0);
2455 1.1 mrg break;
2456 1.1 mrg case isl_ast_expr_id:
2457 1.1 mrg p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
2458 1.1 mrg break;
2459 1.1 mrg case isl_ast_expr_int:
2460 1.1 mrg p = isl_printer_print_val(p, expr->u.v);
2461 1.1 mrg break;
2462 1.1 mrg case isl_ast_expr_error:
2463 1.1 mrg break;
2464 1.1 mrg }
2465 1.1 mrg
2466 1.1 mrg return p;
2467 1.1 mrg }
2468 1.1 mrg
2469 1.1 mrg /* Textual representation of the isl_ast_expr_op_type elements
2470 1.1 mrg * for use in a YAML representation of an isl_ast_expr.
2471 1.1 mrg */
2472 1.1 mrg static char *op_str[] = {
2473 1.1 mrg [isl_ast_expr_op_and] = "and",
2474 1.1 mrg [isl_ast_expr_op_and_then] = "and_then",
2475 1.1 mrg [isl_ast_expr_op_or] = "or",
2476 1.1 mrg [isl_ast_expr_op_or_else] = "or_else",
2477 1.1 mrg [isl_ast_expr_op_max] = "max",
2478 1.1 mrg [isl_ast_expr_op_min] = "min",
2479 1.1 mrg [isl_ast_expr_op_minus] = "minus",
2480 1.1 mrg [isl_ast_expr_op_add] = "add",
2481 1.1 mrg [isl_ast_expr_op_sub] = "sub",
2482 1.1 mrg [isl_ast_expr_op_mul] = "mul",
2483 1.1 mrg [isl_ast_expr_op_div] = "div",
2484 1.1 mrg [isl_ast_expr_op_fdiv_q] = "fdiv_q",
2485 1.1 mrg [isl_ast_expr_op_pdiv_q] = "pdiv_q",
2486 1.1 mrg [isl_ast_expr_op_pdiv_r] = "pdiv_r",
2487 1.1 mrg [isl_ast_expr_op_zdiv_r] = "zdiv_r",
2488 1.1 mrg [isl_ast_expr_op_cond] = "cond",
2489 1.1 mrg [isl_ast_expr_op_select] = "select",
2490 1.1 mrg [isl_ast_expr_op_eq] = "eq",
2491 1.1 mrg [isl_ast_expr_op_le] = "le",
2492 1.1 mrg [isl_ast_expr_op_lt] = "lt",
2493 1.1 mrg [isl_ast_expr_op_ge] = "ge",
2494 1.1 mrg [isl_ast_expr_op_gt] = "gt",
2495 1.1 mrg [isl_ast_expr_op_call] = "call",
2496 1.1 mrg [isl_ast_expr_op_access] = "access",
2497 1.1 mrg [isl_ast_expr_op_member] = "member",
2498 1.1 mrg [isl_ast_expr_op_address_of] = "address_of"
2499 1.1 mrg };
2500 1.1 mrg
2501 1.1 mrg static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
2502 1.1 mrg __isl_keep isl_ast_expr *expr);
2503 1.1 mrg
2504 1.1 mrg /* Print the arguments of "expr" to "p" in isl format.
2505 1.1 mrg *
2506 1.1 mrg * If there are no arguments, then nothing needs to be printed.
2507 1.1 mrg * Otherwise add an "args" key to the current mapping with as value
2508 1.1 mrg * the list of arguments of "expr".
2509 1.1 mrg */
2510 1.1 mrg static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p,
2511 1.1 mrg __isl_keep isl_ast_expr *expr)
2512 1.1 mrg {
2513 1.1 mrg int i;
2514 1.1 mrg isl_size n;
2515 1.1 mrg
2516 1.1 mrg n = isl_ast_expr_get_op_n_arg(expr);
2517 1.1 mrg if (n < 0)
2518 1.1 mrg return isl_printer_free(p);
2519 1.1 mrg if (n == 0)
2520 1.1 mrg return p;
2521 1.1 mrg
2522 1.1 mrg p = isl_printer_print_str(p, "args");
2523 1.1 mrg p = isl_printer_yaml_next(p);
2524 1.1 mrg p = isl_printer_yaml_start_sequence(p);
2525 1.1 mrg for (i = 0; i < n; ++i) {
2526 1.1 mrg isl_ast_expr *arg;
2527 1.1 mrg
2528 1.1 mrg arg = isl_ast_expr_get_op_arg(expr, i);
2529 1.1 mrg p = print_ast_expr_isl(p, arg);
2530 1.1 mrg isl_ast_expr_free(arg);
2531 1.1 mrg p = isl_printer_yaml_next(p);
2532 1.1 mrg }
2533 1.1 mrg p = isl_printer_yaml_end_sequence(p);
2534 1.1 mrg
2535 1.1 mrg return p;
2536 1.1 mrg }
2537 1.1 mrg
2538 1.1 mrg /* Textual representations of the YAML keys for an isl_ast_expr object.
2539 1.1 mrg */
2540 1.1 mrg static char *expr_str[] = {
2541 1.1 mrg [isl_ast_expr_op] = "op",
2542 1.1 mrg [isl_ast_expr_id] = "id",
2543 1.1 mrg [isl_ast_expr_int] = "val",
2544 1.1 mrg };
2545 1.1 mrg
2546 1.1 mrg /* Print "expr" to "p" in isl format.
2547 1.1 mrg *
2548 1.1 mrg * In particular, print the isl_ast_expr as a YAML document.
2549 1.1 mrg */
2550 1.1 mrg static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
2551 1.1 mrg __isl_keep isl_ast_expr *expr)
2552 1.1 mrg {
2553 1.1 mrg enum isl_ast_expr_type type;
2554 1.1 mrg enum isl_ast_expr_op_type op;
2555 1.1 mrg isl_id *id;
2556 1.1 mrg isl_val *v;
2557 1.1 mrg
2558 1.1 mrg if (!expr)
2559 1.1 mrg return isl_printer_free(p);
2560 1.1 mrg
2561 1.1 mrg p = isl_printer_yaml_start_mapping(p);
2562 1.1 mrg type = isl_ast_expr_get_type(expr);
2563 1.1 mrg switch (type) {
2564 1.1 mrg case isl_ast_expr_error:
2565 1.1 mrg return isl_printer_free(p);
2566 1.1 mrg case isl_ast_expr_op:
2567 1.1 mrg op = isl_ast_expr_get_op_type(expr);
2568 1.1 mrg if (op == isl_ast_expr_op_error)
2569 1.1 mrg return isl_printer_free(p);
2570 1.1 mrg p = isl_printer_print_str(p, expr_str[type]);
2571 1.1 mrg p = isl_printer_yaml_next(p);
2572 1.1 mrg p = isl_printer_print_str(p, op_str[op]);
2573 1.1 mrg p = isl_printer_yaml_next(p);
2574 1.1 mrg p = print_arguments(p, expr);
2575 1.1 mrg break;
2576 1.1 mrg case isl_ast_expr_id:
2577 1.1 mrg p = isl_printer_print_str(p, expr_str[type]);
2578 1.1 mrg p = isl_printer_yaml_next(p);
2579 1.1 mrg id = isl_ast_expr_get_id(expr);
2580 1.1 mrg p = isl_printer_print_id(p, id);
2581 1.1 mrg isl_id_free(id);
2582 1.1 mrg break;
2583 1.1 mrg case isl_ast_expr_int:
2584 1.1 mrg p = isl_printer_print_str(p, expr_str[type]);
2585 1.1 mrg p = isl_printer_yaml_next(p);
2586 1.1 mrg v = isl_ast_expr_get_val(expr);
2587 1.1 mrg p = isl_printer_print_val(p, v);
2588 1.1 mrg isl_val_free(v);
2589 1.1 mrg break;
2590 1.1 mrg }
2591 1.1 mrg p = isl_printer_yaml_end_mapping(p);
2592 1.1 mrg
2593 1.1 mrg return p;
2594 1.1 mrg }
2595 1.1 mrg
2596 1.1 mrg /* Print "expr" to "p".
2597 1.1 mrg *
2598 1.1 mrg * Only an isl and a C format are supported.
2599 1.1 mrg */
2600 1.1 mrg __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
2601 1.1 mrg __isl_keep isl_ast_expr *expr)
2602 1.1 mrg {
2603 1.1 mrg int format;
2604 1.1 mrg
2605 1.1 mrg if (!p)
2606 1.1 mrg return NULL;
2607 1.1 mrg
2608 1.1 mrg format = isl_printer_get_output_format(p);
2609 1.1 mrg switch (format) {
2610 1.1 mrg case ISL_FORMAT_ISL:
2611 1.1 mrg p = print_ast_expr_isl(p, expr);
2612 1.1 mrg break;
2613 1.1 mrg case ISL_FORMAT_C:
2614 1.1 mrg p = print_ast_expr_c(p, expr);
2615 1.1 mrg break;
2616 1.1 mrg default:
2617 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2618 1.1 mrg "output format not supported for ast_expr",
2619 1.1 mrg return isl_printer_free(p));
2620 1.1 mrg }
2621 1.1 mrg
2622 1.1 mrg return p;
2623 1.1 mrg }
2624 1.1 mrg
2625 1.1 mrg #undef KEY
2626 1.1 mrg #define KEY enum isl_ast_expr_op_type
2627 1.1 mrg #undef KEY_ERROR
2628 1.1 mrg #define KEY_ERROR isl_ast_expr_op_error
2629 1.1 mrg #undef KEY_END
2630 1.1 mrg #define KEY_END (isl_ast_expr_op_address_of + 1)
2631 1.1 mrg #undef KEY_STR
2632 1.1 mrg #define KEY_STR op_str
2633 1.1 mrg #undef KEY_EXTRACT
2634 1.1 mrg #define KEY_EXTRACT extract_op_type
2635 1.1 mrg #undef KEY_GET
2636 1.1 mrg #define KEY_GET get_op_type
2637 1.1 mrg #include "extract_key.c"
2638 1.1 mrg
2639 1.1 mrg /* Return the next token, which is assumed to be a key in a YAML mapping,
2640 1.1 mrg * from "s" as a string.
2641 1.1 mrg */
2642 1.1 mrg static __isl_give char *next_key(__isl_keep isl_stream *s)
2643 1.1 mrg {
2644 1.1 mrg struct isl_token *tok;
2645 1.1 mrg char *str;
2646 1.1 mrg isl_ctx *ctx;
2647 1.1 mrg
2648 1.1 mrg if (!s)
2649 1.1 mrg return NULL;
2650 1.1 mrg tok = isl_stream_next_token(s);
2651 1.1 mrg if (!tok) {
2652 1.1 mrg isl_stream_error(s, NULL, "unexpected EOF");
2653 1.1 mrg return NULL;
2654 1.1 mrg }
2655 1.1 mrg ctx = isl_stream_get_ctx(s);
2656 1.1 mrg str = isl_token_get_str(ctx, tok);
2657 1.1 mrg isl_token_free(tok);
2658 1.1 mrg return str;
2659 1.1 mrg }
2660 1.1 mrg
2661 1.1 mrg /* Remove the next token, which is assumed to be the key "expected"
2662 1.1 mrg * in a YAML mapping, from "s" and move to the corresponding value.
2663 1.1 mrg */
2664 1.1 mrg static isl_stat eat_key(__isl_keep isl_stream *s, const char *expected)
2665 1.1 mrg {
2666 1.1 mrg char *str;
2667 1.1 mrg int ok;
2668 1.1 mrg
2669 1.1 mrg str = next_key(s);
2670 1.1 mrg if (!str)
2671 1.1 mrg return isl_stat_error;
2672 1.1 mrg ok = !strcmp(str, expected);
2673 1.1 mrg free(str);
2674 1.1 mrg
2675 1.1 mrg if (!ok) {
2676 1.1 mrg isl_stream_error(s, NULL, "expecting different key");
2677 1.1 mrg return isl_stat_error;
2678 1.1 mrg }
2679 1.1 mrg
2680 1.1 mrg if (isl_stream_yaml_next(s) < 0)
2681 1.1 mrg return isl_stat_error;
2682 1.1 mrg
2683 1.1 mrg return isl_stat_ok;
2684 1.1 mrg }
2685 1.1 mrg
2686 1.1 mrg #undef EL_BASE
2687 1.1 mrg #define EL_BASE ast_expr
2688 1.1 mrg
2689 1.1 mrg #include <isl_list_read_yaml_templ.c>
2690 1.1 mrg
2691 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_op from "s",
2692 1.1 mrg * where the "op" key has already been read by the caller.
2693 1.1 mrg *
2694 1.1 mrg * Read the operation type and the arguments and
2695 1.1 mrg * return the corresponding isl_ast_expr object.
2696 1.1 mrg */
2697 1.1 mrg static __isl_give isl_ast_expr *read_op(__isl_keep isl_stream *s)
2698 1.1 mrg {
2699 1.1 mrg enum isl_ast_expr_op_type op;
2700 1.1 mrg isl_ast_expr_list *list;
2701 1.1 mrg
2702 1.1 mrg op = get_op_type(s);
2703 1.1 mrg if (op < 0)
2704 1.1 mrg return NULL;
2705 1.1 mrg if (isl_stream_yaml_next(s) < 0)
2706 1.1 mrg return NULL;
2707 1.1 mrg if (eat_key(s, "args") < 0)
2708 1.1 mrg return NULL;
2709 1.1 mrg
2710 1.1 mrg list = isl_stream_yaml_read_ast_expr_list(s);
2711 1.1 mrg
2712 1.1 mrg return alloc_op(op, list);
2713 1.1 mrg }
2714 1.1 mrg
2715 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_id from "s",
2716 1.1 mrg * where the "id" key has already been read by the caller.
2717 1.1 mrg */
2718 1.1 mrg static __isl_give isl_ast_expr *read_id(__isl_keep isl_stream *s)
2719 1.1 mrg {
2720 1.1 mrg return isl_ast_expr_from_id(isl_stream_read_id(s));
2721 1.1 mrg }
2722 1.1 mrg
2723 1.1 mrg /* Read an isl_ast_expr object of type isl_ast_expr_int from "s",
2724 1.1 mrg * where the "val" key has already been read by the caller.
2725 1.1 mrg */
2726 1.1 mrg static __isl_give isl_ast_expr *read_int(__isl_keep isl_stream *s)
2727 1.1 mrg {
2728 1.1 mrg return isl_ast_expr_from_val(isl_stream_read_val(s));
2729 1.1 mrg }
2730 1.1 mrg
2731 1.1 mrg #undef KEY
2732 1.1 mrg #define KEY enum isl_ast_expr_type
2733 1.1 mrg #undef KEY_ERROR
2734 1.1 mrg #define KEY_ERROR isl_ast_expr_error
2735 1.1 mrg #undef KEY_END
2736 1.1 mrg #define KEY_END (isl_ast_expr_int + 1)
2737 1.1 mrg #undef KEY_STR
2738 1.1 mrg #define KEY_STR expr_str
2739 1.1 mrg #undef KEY_EXTRACT
2740 1.1 mrg #define KEY_EXTRACT extract_expr_type
2741 1.1 mrg #undef KEY_GET
2742 1.1 mrg #define KEY_GET get_expr_type
2743 1.1 mrg #include "extract_key.c"
2744 1.1 mrg
2745 1.1 mrg /* Read an isl_ast_expr object from "s".
2746 1.1 mrg *
2747 1.1 mrg * The keys in the YAML mapping are assumed to appear
2748 1.1 mrg * in the same order as the one in which they are printed
2749 1.1 mrg * by print_ast_expr_isl.
2750 1.1 mrg * In particular, the isl_ast_expr_op type, which is the only one
2751 1.1 mrg * with more than one element, is identified by the "op" key and
2752 1.1 mrg * not by the "args" key.
2753 1.1 mrg */
2754 1.1 mrg __isl_give isl_ast_expr *isl_stream_read_ast_expr(__isl_keep isl_stream *s)
2755 1.1 mrg {
2756 1.1 mrg enum isl_ast_expr_type type;
2757 1.1 mrg isl_bool more;
2758 1.1 mrg isl_ast_expr *expr;
2759 1.1 mrg
2760 1.1 mrg if (isl_stream_yaml_read_start_mapping(s))
2761 1.1 mrg return NULL;
2762 1.1 mrg more = isl_stream_yaml_next(s);
2763 1.1 mrg if (more < 0)
2764 1.1 mrg return NULL;
2765 1.1 mrg if (!more) {
2766 1.1 mrg isl_stream_error(s, NULL, "missing key");
2767 1.1 mrg return NULL;
2768 1.1 mrg }
2769 1.1 mrg
2770 1.1 mrg type = get_expr_type(s);
2771 1.1 mrg if (type < 0)
2772 1.1 mrg return NULL;
2773 1.1 mrg if (isl_stream_yaml_next(s) < 0)
2774 1.1 mrg return NULL;
2775 1.1 mrg switch (type) {
2776 1.1 mrg case isl_ast_expr_op:
2777 1.1 mrg expr = read_op(s);
2778 1.1 mrg break;
2779 1.1 mrg case isl_ast_expr_id:
2780 1.1 mrg expr = read_id(s);
2781 1.1 mrg break;
2782 1.1 mrg case isl_ast_expr_int:
2783 1.1 mrg expr = read_int(s);
2784 1.1 mrg break;
2785 1.1 mrg case isl_ast_expr_error:
2786 1.1 mrg return NULL;
2787 1.1 mrg }
2788 1.1 mrg
2789 1.1 mrg if (isl_stream_yaml_read_end_mapping(s) < 0)
2790 1.1 mrg return isl_ast_expr_free(expr);
2791 1.1 mrg
2792 1.1 mrg return expr;
2793 1.1 mrg }
2794 1.1 mrg
2795 1.1 mrg static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2796 1.1 mrg __isl_keep isl_ast_node *node);
2797 1.1 mrg
2798 1.1 mrg /* Print a YAML sequence containing the entries in "list" to "p".
2799 1.1 mrg */
2800 1.1 mrg static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p,
2801 1.1 mrg __isl_keep isl_ast_node_list *list)
2802 1.1 mrg {
2803 1.1 mrg int i;
2804 1.1 mrg isl_size n;
2805 1.1 mrg
2806 1.1 mrg n = isl_ast_node_list_n_ast_node(list);
2807 1.1 mrg if (n < 0)
2808 1.1 mrg return isl_printer_free(p);
2809 1.1 mrg
2810 1.1 mrg p = isl_printer_yaml_start_sequence(p);
2811 1.1 mrg for (i = 0; i < n; ++i) {
2812 1.1 mrg isl_ast_node *node;
2813 1.1 mrg
2814 1.1 mrg node = isl_ast_node_list_get_ast_node(list, i);
2815 1.1 mrg p = print_ast_node_isl(p, node);
2816 1.1 mrg isl_ast_node_free(node);
2817 1.1 mrg p = isl_printer_yaml_next(p);
2818 1.1 mrg }
2819 1.1 mrg p = isl_printer_yaml_end_sequence(p);
2820 1.1 mrg
2821 1.1 mrg return p;
2822 1.1 mrg }
2823 1.1 mrg
2824 1.1 mrg /* Print "node" to "p" in "isl format".
2825 1.1 mrg *
2826 1.1 mrg * In particular, print the isl_ast_node as a YAML document.
2827 1.1 mrg */
2828 1.1 mrg static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2829 1.1 mrg __isl_keep isl_ast_node *node)
2830 1.1 mrg {
2831 1.1 mrg switch (node->type) {
2832 1.1 mrg case isl_ast_node_for:
2833 1.1 mrg p = isl_printer_yaml_start_mapping(p);
2834 1.1 mrg p = isl_printer_print_str(p, "iterator");
2835 1.1 mrg p = isl_printer_yaml_next(p);
2836 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.iterator);
2837 1.1 mrg p = isl_printer_yaml_next(p);
2838 1.1 mrg if (node->u.f.degenerate) {
2839 1.1 mrg p = isl_printer_print_str(p, "value");
2840 1.1 mrg p = isl_printer_yaml_next(p);
2841 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init);
2842 1.1 mrg p = isl_printer_yaml_next(p);
2843 1.1 mrg } else {
2844 1.1 mrg p = isl_printer_print_str(p, "init");
2845 1.1 mrg p = isl_printer_yaml_next(p);
2846 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init);
2847 1.1 mrg p = isl_printer_yaml_next(p);
2848 1.1 mrg p = isl_printer_print_str(p, "cond");
2849 1.1 mrg p = isl_printer_yaml_next(p);
2850 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.cond);
2851 1.1 mrg p = isl_printer_yaml_next(p);
2852 1.1 mrg p = isl_printer_print_str(p, "inc");
2853 1.1 mrg p = isl_printer_yaml_next(p);
2854 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.inc);
2855 1.1 mrg p = isl_printer_yaml_next(p);
2856 1.1 mrg }
2857 1.1 mrg if (node->u.f.body) {
2858 1.1 mrg p = isl_printer_print_str(p, "body");
2859 1.1 mrg p = isl_printer_yaml_next(p);
2860 1.1 mrg p = isl_printer_print_ast_node(p, node->u.f.body);
2861 1.1 mrg p = isl_printer_yaml_next(p);
2862 1.1 mrg }
2863 1.1 mrg p = isl_printer_yaml_end_mapping(p);
2864 1.1 mrg break;
2865 1.1 mrg case isl_ast_node_mark:
2866 1.1 mrg p = isl_printer_yaml_start_mapping(p);
2867 1.1 mrg p = isl_printer_print_str(p, "mark");
2868 1.1 mrg p = isl_printer_yaml_next(p);
2869 1.1 mrg p = isl_printer_print_id(p, node->u.m.mark);
2870 1.1 mrg p = isl_printer_yaml_next(p);
2871 1.1 mrg p = isl_printer_print_str(p, "node");
2872 1.1 mrg p = isl_printer_yaml_next(p);
2873 1.1 mrg p = isl_printer_print_ast_node(p, node->u.m.node);
2874 1.1 mrg p = isl_printer_yaml_end_mapping(p);
2875 1.1 mrg break;
2876 1.1 mrg case isl_ast_node_user:
2877 1.1 mrg p = isl_printer_yaml_start_mapping(p);
2878 1.1 mrg p = isl_printer_print_str(p, "user");
2879 1.1 mrg p = isl_printer_yaml_next(p);
2880 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.e.expr);
2881 1.1 mrg p = isl_printer_yaml_end_mapping(p);
2882 1.1 mrg break;
2883 1.1 mrg case isl_ast_node_if:
2884 1.1 mrg p = isl_printer_yaml_start_mapping(p);
2885 1.1 mrg p = isl_printer_print_str(p, "guard");
2886 1.1 mrg p = isl_printer_yaml_next(p);
2887 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.i.guard);
2888 1.1 mrg p = isl_printer_yaml_next(p);
2889 1.1 mrg if (node->u.i.then) {
2890 1.1 mrg p = isl_printer_print_str(p, "then");
2891 1.1 mrg p = isl_printer_yaml_next(p);
2892 1.1 mrg p = isl_printer_print_ast_node(p, node->u.i.then);
2893 1.1 mrg p = isl_printer_yaml_next(p);
2894 1.1 mrg }
2895 1.1 mrg if (node->u.i.else_node) {
2896 1.1 mrg p = isl_printer_print_str(p, "else");
2897 1.1 mrg p = isl_printer_yaml_next(p);
2898 1.1 mrg p = isl_printer_print_ast_node(p, node->u.i.else_node);
2899 1.1 mrg }
2900 1.1 mrg p = isl_printer_yaml_end_mapping(p);
2901 1.1 mrg break;
2902 1.1 mrg case isl_ast_node_block:
2903 1.1 mrg p = print_ast_node_list(p, node->u.b.children);
2904 1.1 mrg break;
2905 1.1 mrg case isl_ast_node_error:
2906 1.1 mrg break;
2907 1.1 mrg }
2908 1.1 mrg return p;
2909 1.1 mrg }
2910 1.1 mrg
2911 1.1 mrg /* Do we need to print a block around the body "node" of a for or if node?
2912 1.1 mrg *
2913 1.1 mrg * If the node is a block, then we need to print a block.
2914 1.1 mrg * Also if the node is a degenerate for then we will print it as
2915 1.1 mrg * an assignment followed by the body of the for loop, so we need a block
2916 1.1 mrg * as well.
2917 1.1 mrg * If the node is an if node with an else, then we print a block
2918 1.1 mrg * to avoid spurious dangling else warnings emitted by some compilers.
2919 1.1 mrg * If the node is a mark, then in principle, we would have to check
2920 1.1 mrg * the child of the mark node. However, even if the child would not
2921 1.1 mrg * require us to print a block, for readability it is probably best
2922 1.1 mrg * to print a block anyway.
2923 1.1 mrg * If the ast_always_print_block option has been set, then we print a block.
2924 1.1 mrg */
2925 1.1 mrg static int need_block(__isl_keep isl_ast_node *node)
2926 1.1 mrg {
2927 1.1 mrg isl_ctx *ctx;
2928 1.1 mrg
2929 1.1 mrg if (node->type == isl_ast_node_block)
2930 1.1 mrg return 1;
2931 1.1 mrg if (node->type == isl_ast_node_for && node->u.f.degenerate)
2932 1.1 mrg return 1;
2933 1.1 mrg if (node->type == isl_ast_node_if && node->u.i.else_node)
2934 1.1 mrg return 1;
2935 1.1 mrg if (node->type == isl_ast_node_mark)
2936 1.1 mrg return 1;
2937 1.1 mrg
2938 1.1 mrg ctx = isl_ast_node_get_ctx(node);
2939 1.1 mrg return isl_options_get_ast_always_print_block(ctx);
2940 1.1 mrg }
2941 1.1 mrg
2942 1.1 mrg static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2943 1.1 mrg __isl_keep isl_ast_node *node,
2944 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list);
2945 1.1 mrg static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2946 1.1 mrg __isl_keep isl_ast_node *node,
2947 1.1 mrg __isl_keep isl_ast_print_options *options, int new_line,
2948 1.1 mrg int force_block);
2949 1.1 mrg
2950 1.1 mrg /* Print the body "node" of a for or if node.
2951 1.1 mrg * If "else_node" is set, then it is printed as well.
2952 1.1 mrg * If "force_block" is set, then print out the body as a block.
2953 1.1 mrg *
2954 1.1 mrg * We first check if we need to print out a block.
2955 1.1 mrg * We always print out a block if there is an else node to make
2956 1.1 mrg * sure that the else node is matched to the correct if node.
2957 1.1 mrg * For consistency, the corresponding else node is also printed as a block.
2958 1.1 mrg *
2959 1.1 mrg * If the else node is itself an if, then we print it as
2960 1.1 mrg *
2961 1.1 mrg * } else if (..) {
2962 1.1 mrg * }
2963 1.1 mrg *
2964 1.1 mrg * Otherwise the else node is printed as
2965 1.1 mrg *
2966 1.1 mrg * } else {
2967 1.1 mrg * node
2968 1.1 mrg * }
2969 1.1 mrg */
2970 1.1 mrg static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
2971 1.1 mrg __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
2972 1.1 mrg __isl_keep isl_ast_print_options *options, int force_block)
2973 1.1 mrg {
2974 1.1 mrg if (!node)
2975 1.1 mrg return isl_printer_free(p);
2976 1.1 mrg
2977 1.1 mrg if (!force_block && !else_node && !need_block(node)) {
2978 1.1 mrg p = isl_printer_end_line(p);
2979 1.1 mrg p = isl_printer_indent(p, 2);
2980 1.1 mrg p = isl_ast_node_print(node, p,
2981 1.1 mrg isl_ast_print_options_copy(options));
2982 1.1 mrg p = isl_printer_indent(p, -2);
2983 1.1 mrg return p;
2984 1.1 mrg }
2985 1.1 mrg
2986 1.1 mrg p = isl_printer_print_str(p, " {");
2987 1.1 mrg p = isl_printer_end_line(p);
2988 1.1 mrg p = isl_printer_indent(p, 2);
2989 1.1 mrg p = print_ast_node_c(p, node, options, 1, 0);
2990 1.1 mrg p = isl_printer_indent(p, -2);
2991 1.1 mrg p = isl_printer_start_line(p);
2992 1.1 mrg p = isl_printer_print_str(p, "}");
2993 1.1 mrg if (else_node) {
2994 1.1 mrg if (else_node->type == isl_ast_node_if) {
2995 1.1 mrg p = isl_printer_print_str(p, " else ");
2996 1.1 mrg p = print_if_c(p, else_node, options, 0, 1);
2997 1.1 mrg } else {
2998 1.1 mrg p = isl_printer_print_str(p, " else");
2999 1.1 mrg p = print_body_c(p, else_node, NULL, options, 1);
3000 1.1 mrg }
3001 1.1 mrg } else
3002 1.1 mrg p = isl_printer_end_line(p);
3003 1.1 mrg
3004 1.1 mrg return p;
3005 1.1 mrg }
3006 1.1 mrg
3007 1.1 mrg /* Print the start of a compound statement.
3008 1.1 mrg */
3009 1.1 mrg static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
3010 1.1 mrg {
3011 1.1 mrg p = isl_printer_start_line(p);
3012 1.1 mrg p = isl_printer_print_str(p, "{");
3013 1.1 mrg p = isl_printer_end_line(p);
3014 1.1 mrg p = isl_printer_indent(p, 2);
3015 1.1 mrg
3016 1.1 mrg return p;
3017 1.1 mrg }
3018 1.1 mrg
3019 1.1 mrg /* Print the end of a compound statement.
3020 1.1 mrg */
3021 1.1 mrg static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
3022 1.1 mrg {
3023 1.1 mrg p = isl_printer_indent(p, -2);
3024 1.1 mrg p = isl_printer_start_line(p);
3025 1.1 mrg p = isl_printer_print_str(p, "}");
3026 1.1 mrg p = isl_printer_end_line(p);
3027 1.1 mrg
3028 1.1 mrg return p;
3029 1.1 mrg }
3030 1.1 mrg
3031 1.1 mrg /* Print the for node "node".
3032 1.1 mrg *
3033 1.1 mrg * If the for node is degenerate, it is printed as
3034 1.1 mrg *
3035 1.1 mrg * type iterator = init;
3036 1.1 mrg * body
3037 1.1 mrg *
3038 1.1 mrg * Otherwise, it is printed as
3039 1.1 mrg *
3040 1.1 mrg * for (type iterator = init; cond; iterator += inc)
3041 1.1 mrg * body
3042 1.1 mrg *
3043 1.1 mrg * "in_block" is set if we are currently inside a block.
3044 1.1 mrg * "in_list" is set if the current node is not alone in the block.
3045 1.1 mrg * If we are not in a block or if the current not is not alone in the block
3046 1.1 mrg * then we print a block around a degenerate for loop such that the variable
3047 1.1 mrg * declaration will not conflict with any potential other declaration
3048 1.1 mrg * of the same variable.
3049 1.1 mrg */
3050 1.1 mrg static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
3051 1.1 mrg __isl_keep isl_ast_node *node,
3052 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list)
3053 1.1 mrg {
3054 1.1 mrg isl_id *id;
3055 1.1 mrg const char *name;
3056 1.1 mrg const char *type;
3057 1.1 mrg
3058 1.1 mrg type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
3059 1.1 mrg if (!node->u.f.degenerate) {
3060 1.1 mrg id = isl_ast_expr_get_id(node->u.f.iterator);
3061 1.1 mrg name = isl_id_get_name(id);
3062 1.1 mrg isl_id_free(id);
3063 1.1 mrg p = isl_printer_start_line(p);
3064 1.1 mrg p = isl_printer_print_str(p, "for (");
3065 1.1 mrg p = isl_printer_print_str(p, type);
3066 1.1 mrg p = isl_printer_print_str(p, " ");
3067 1.1 mrg p = isl_printer_print_str(p, name);
3068 1.1 mrg p = isl_printer_print_str(p, " = ");
3069 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init);
3070 1.1 mrg p = isl_printer_print_str(p, "; ");
3071 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.cond);
3072 1.1 mrg p = isl_printer_print_str(p, "; ");
3073 1.1 mrg p = isl_printer_print_str(p, name);
3074 1.1 mrg p = isl_printer_print_str(p, " += ");
3075 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.inc);
3076 1.1 mrg p = isl_printer_print_str(p, ")");
3077 1.1 mrg p = print_body_c(p, node->u.f.body, NULL, options, 0);
3078 1.1 mrg } else {
3079 1.1 mrg id = isl_ast_expr_get_id(node->u.f.iterator);
3080 1.1 mrg name = isl_id_get_name(id);
3081 1.1 mrg isl_id_free(id);
3082 1.1 mrg if (!in_block || in_list)
3083 1.1 mrg p = start_block(p);
3084 1.1 mrg p = isl_printer_start_line(p);
3085 1.1 mrg p = isl_printer_print_str(p, type);
3086 1.1 mrg p = isl_printer_print_str(p, " ");
3087 1.1 mrg p = isl_printer_print_str(p, name);
3088 1.1 mrg p = isl_printer_print_str(p, " = ");
3089 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.f.init);
3090 1.1 mrg p = isl_printer_print_str(p, ";");
3091 1.1 mrg p = isl_printer_end_line(p);
3092 1.1 mrg p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
3093 1.1 mrg if (!in_block || in_list)
3094 1.1 mrg p = end_block(p);
3095 1.1 mrg }
3096 1.1 mrg
3097 1.1 mrg return p;
3098 1.1 mrg }
3099 1.1 mrg
3100 1.1 mrg /* Print the if node "node".
3101 1.1 mrg * If "new_line" is set then the if node should be printed on a new line.
3102 1.1 mrg * If "force_block" is set, then print out the body as a block.
3103 1.1 mrg */
3104 1.1 mrg static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
3105 1.1 mrg __isl_keep isl_ast_node *node,
3106 1.1 mrg __isl_keep isl_ast_print_options *options, int new_line,
3107 1.1 mrg int force_block)
3108 1.1 mrg {
3109 1.1 mrg if (new_line)
3110 1.1 mrg p = isl_printer_start_line(p);
3111 1.1 mrg p = isl_printer_print_str(p, "if (");
3112 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.i.guard);
3113 1.1 mrg p = isl_printer_print_str(p, ")");
3114 1.1 mrg p = print_body_c(p, node->u.i.then, node->u.i.else_node, options,
3115 1.1 mrg force_block);
3116 1.1 mrg
3117 1.1 mrg return p;
3118 1.1 mrg }
3119 1.1 mrg
3120 1.1 mrg /* Print the "node" to "p".
3121 1.1 mrg *
3122 1.1 mrg * "in_block" is set if we are currently inside a block.
3123 1.1 mrg * If so, we do not print a block around the children of a block node.
3124 1.1 mrg * We do this to avoid an extra block around the body of a degenerate
3125 1.1 mrg * for node.
3126 1.1 mrg *
3127 1.1 mrg * "in_list" is set if the current node is not alone in the block.
3128 1.1 mrg */
3129 1.1 mrg static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
3130 1.1 mrg __isl_keep isl_ast_node *node,
3131 1.1 mrg __isl_keep isl_ast_print_options *options, int in_block, int in_list)
3132 1.1 mrg {
3133 1.1 mrg switch (node->type) {
3134 1.1 mrg case isl_ast_node_for:
3135 1.1 mrg if (options->print_for)
3136 1.1 mrg return options->print_for(p,
3137 1.1 mrg isl_ast_print_options_copy(options),
3138 1.1 mrg node, options->print_for_user);
3139 1.1 mrg p = print_for_c(p, node, options, in_block, in_list);
3140 1.1 mrg break;
3141 1.1 mrg case isl_ast_node_if:
3142 1.1 mrg p = print_if_c(p, node, options, 1, 0);
3143 1.1 mrg break;
3144 1.1 mrg case isl_ast_node_block:
3145 1.1 mrg if (!in_block)
3146 1.1 mrg p = start_block(p);
3147 1.1 mrg p = isl_ast_node_list_print(node->u.b.children, p, options);
3148 1.1 mrg if (!in_block)
3149 1.1 mrg p = end_block(p);
3150 1.1 mrg break;
3151 1.1 mrg case isl_ast_node_mark:
3152 1.1 mrg p = isl_printer_start_line(p);
3153 1.1 mrg p = isl_printer_print_str(p, "// ");
3154 1.1 mrg p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark));
3155 1.1 mrg p = isl_printer_end_line(p);
3156 1.1 mrg p = print_ast_node_c(p, node->u.m.node, options, 0, in_list);
3157 1.1 mrg break;
3158 1.1 mrg case isl_ast_node_user:
3159 1.1 mrg if (options->print_user)
3160 1.1 mrg return options->print_user(p,
3161 1.1 mrg isl_ast_print_options_copy(options),
3162 1.1 mrg node, options->print_user_user);
3163 1.1 mrg p = isl_printer_start_line(p);
3164 1.1 mrg p = isl_printer_print_ast_expr(p, node->u.e.expr);
3165 1.1 mrg p = isl_printer_print_str(p, ";");
3166 1.1 mrg p = isl_printer_end_line(p);
3167 1.1 mrg break;
3168 1.1 mrg case isl_ast_node_error:
3169 1.1 mrg break;
3170 1.1 mrg }
3171 1.1 mrg return p;
3172 1.1 mrg }
3173 1.1 mrg
3174 1.1 mrg /* Print the for node "node" to "p".
3175 1.1 mrg */
3176 1.1 mrg __isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
3177 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3178 1.1 mrg {
3179 1.1 mrg if (isl_ast_node_check_for(node) < 0 || !options)
3180 1.1 mrg goto error;
3181 1.1 mrg p = print_for_c(p, node, options, 0, 0);
3182 1.1 mrg isl_ast_print_options_free(options);
3183 1.1 mrg return p;
3184 1.1 mrg error:
3185 1.1 mrg isl_ast_print_options_free(options);
3186 1.1 mrg isl_printer_free(p);
3187 1.1 mrg return NULL;
3188 1.1 mrg }
3189 1.1 mrg
3190 1.1 mrg /* Print the if node "node" to "p".
3191 1.1 mrg */
3192 1.1 mrg __isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
3193 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3194 1.1 mrg {
3195 1.1 mrg if (isl_ast_node_check_if(node) < 0 || !options)
3196 1.1 mrg goto error;
3197 1.1 mrg p = print_if_c(p, node, options, 1, 0);
3198 1.1 mrg isl_ast_print_options_free(options);
3199 1.1 mrg return p;
3200 1.1 mrg error:
3201 1.1 mrg isl_ast_print_options_free(options);
3202 1.1 mrg isl_printer_free(p);
3203 1.1 mrg return NULL;
3204 1.1 mrg }
3205 1.1 mrg
3206 1.1 mrg /* Print "node" to "p".
3207 1.1 mrg *
3208 1.1 mrg * "node" is assumed to be either the outermost node in an AST or
3209 1.1 mrg * a node that is known not to be a block.
3210 1.1 mrg * If "node" is a block (and is therefore outermost) and
3211 1.1 mrg * if the ast_print_outermost_block options is not set,
3212 1.1 mrg * then act as if the printing occurs inside a block, such
3213 1.1 mrg * that no "extra" block will get printed.
3214 1.1 mrg */
3215 1.1 mrg __isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
3216 1.1 mrg __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
3217 1.1 mrg {
3218 1.1 mrg int in_block = 0;
3219 1.1 mrg
3220 1.1 mrg if (!options || !node)
3221 1.1 mrg goto error;
3222 1.1 mrg if (node->type == isl_ast_node_block) {
3223 1.1 mrg isl_ctx *ctx;
3224 1.1 mrg
3225 1.1 mrg ctx = isl_ast_node_get_ctx(node);
3226 1.1 mrg in_block = !isl_options_get_ast_print_outermost_block(ctx);
3227 1.1 mrg }
3228 1.1 mrg p = print_ast_node_c(p, node, options, in_block, 0);
3229 1.1 mrg isl_ast_print_options_free(options);
3230 1.1 mrg return p;
3231 1.1 mrg error:
3232 1.1 mrg isl_ast_print_options_free(options);
3233 1.1 mrg isl_printer_free(p);
3234 1.1 mrg return NULL;
3235 1.1 mrg }
3236 1.1 mrg
3237 1.1 mrg /* Print "node" to "p".
3238 1.1 mrg */
3239 1.1 mrg __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
3240 1.1 mrg __isl_keep isl_ast_node *node)
3241 1.1 mrg {
3242 1.1 mrg int format;
3243 1.1 mrg isl_ast_print_options *options;
3244 1.1 mrg
3245 1.1 mrg if (!p)
3246 1.1 mrg return NULL;
3247 1.1 mrg
3248 1.1 mrg format = isl_printer_get_output_format(p);
3249 1.1 mrg switch (format) {
3250 1.1 mrg case ISL_FORMAT_ISL:
3251 1.1 mrg p = print_ast_node_isl(p, node);
3252 1.1 mrg break;
3253 1.1 mrg case ISL_FORMAT_C:
3254 1.1 mrg options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
3255 1.1 mrg p = isl_ast_node_print(node, p, options);
3256 1.1 mrg break;
3257 1.1 mrg default:
3258 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3259 1.1 mrg "output format not supported for ast_node",
3260 1.1 mrg return isl_printer_free(p));
3261 1.1 mrg }
3262 1.1 mrg
3263 1.1 mrg return p;
3264 1.1 mrg }
3265 1.1 mrg
3266 1.1 mrg /* Print the list of nodes "list" to "p".
3267 1.1 mrg */
3268 1.1 mrg __isl_give isl_printer *isl_ast_node_list_print(
3269 1.1 mrg __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
3270 1.1 mrg __isl_keep isl_ast_print_options *options)
3271 1.1 mrg {
3272 1.1 mrg int i;
3273 1.1 mrg
3274 1.1 mrg if (!p || !list || !options)
3275 1.1 mrg return isl_printer_free(p);
3276 1.1 mrg
3277 1.1 mrg for (i = 0; i < list->n; ++i)
3278 1.1 mrg p = print_ast_node_c(p, list->p[i], options, 1, 1);
3279 1.1 mrg
3280 1.1 mrg return p;
3281 1.1 mrg }
3282 1.1 mrg
3283 1.1 mrg /* Is the next token on "s" the start of a YAML sequence
3284 1.1 mrg * (rather than a YAML mapping)?
3285 1.1 mrg *
3286 1.1 mrg * A YAML sequence starts with either a '[' or a '-', depending on the format.
3287 1.1 mrg */
3288 1.1 mrg static isl_bool next_is_sequence(__isl_keep isl_stream *s)
3289 1.1 mrg {
3290 1.1 mrg struct isl_token *tok;
3291 1.1 mrg int type;
3292 1.1 mrg int seq;
3293 1.1 mrg
3294 1.1 mrg tok = isl_stream_next_token(s);
3295 1.1 mrg if (!tok)
3296 1.1 mrg return isl_bool_error;
3297 1.1 mrg type = isl_token_get_type(tok);
3298 1.1 mrg seq = type == '[' || type == '-';
3299 1.1 mrg isl_stream_push_token(s, tok);
3300 1.1 mrg
3301 1.1 mrg return isl_bool_ok(seq);
3302 1.1 mrg }
3303 1.1 mrg
3304 1.1 mrg #undef EL_BASE
3305 1.1 mrg #define EL_BASE ast_node
3306 1.1 mrg
3307 1.1 mrg #include <isl_list_read_yaml_templ.c>
3308 1.1 mrg
3309 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_block from "s".
3310 1.1 mrg */
3311 1.1 mrg static __isl_give isl_ast_node *read_block(__isl_keep isl_stream *s)
3312 1.1 mrg {
3313 1.1 mrg isl_ast_node_list *children;
3314 1.1 mrg
3315 1.1 mrg children = isl_stream_yaml_read_ast_node_list(s);
3316 1.1 mrg return isl_ast_node_block_from_children(children);
3317 1.1 mrg }
3318 1.1 mrg
3319 1.1 mrg /* Textual representation of the first YAML key used
3320 1.1 mrg * while printing an isl_ast_node of a given type.
3321 1.1 mrg *
3322 1.1 mrg * An isl_ast_node of type isl_ast_node_block is not printed
3323 1.1 mrg * as a YAML mapping and is therefore assigned a dummy key.
3324 1.1 mrg */
3325 1.1 mrg static char *node_first_str[] = {
3326 1.1 mrg [isl_ast_node_for] = "iterator",
3327 1.1 mrg [isl_ast_node_mark] = "mark",
3328 1.1 mrg [isl_ast_node_user] = "user",
3329 1.1 mrg [isl_ast_node_if] = "guard",
3330 1.1 mrg [isl_ast_node_block] = "",
3331 1.1 mrg };
3332 1.1 mrg
3333 1.1 mrg #undef KEY
3334 1.1 mrg #define KEY enum isl_ast_node_type
3335 1.1 mrg #undef KEY_ERROR
3336 1.1 mrg #define KEY_ERROR isl_ast_node_error
3337 1.1 mrg #undef KEY_END
3338 1.1 mrg #define KEY_END (isl_ast_node_user + 1)
3339 1.1 mrg #undef KEY_STR
3340 1.1 mrg #define KEY_STR node_first_str
3341 1.1 mrg #undef KEY_EXTRACT
3342 1.1 mrg #define KEY_EXTRACT extract_node_type
3343 1.1 mrg #undef KEY_GET
3344 1.1 mrg #define KEY_GET get_node_type
3345 1.1 mrg #include "extract_key.c"
3346 1.1 mrg
3347 1.1 mrg static __isl_give isl_ast_node *read_body(__isl_keep isl_stream *s,
3348 1.1 mrg __isl_take isl_ast_node *node)
3349 1.1 mrg {
3350 1.1 mrg if (eat_key(s, "body") < 0)
3351 1.1 mrg return isl_ast_node_free(node);
3352 1.1 mrg node = isl_ast_node_for_set_body(node, isl_stream_read_ast_node(s));
3353 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3354 1.1 mrg return isl_ast_node_free(node);
3355 1.1 mrg return node;
3356 1.1 mrg }
3357 1.1 mrg
3358 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_for from "s",
3359 1.1 mrg * where the initial "iterator" key has already been read by the caller.
3360 1.1 mrg *
3361 1.1 mrg * If the initial value is printed as the value of the key "value",
3362 1.1 mrg * then the for-loop is degenerate and can at most have
3363 1.1 mrg * a further "body" element.
3364 1.1 mrg * Otherwise, the for-loop also has "cond" and "inc" elements.
3365 1.1 mrg */
3366 1.1 mrg static __isl_give isl_ast_node *read_for(__isl_keep isl_stream *s)
3367 1.1 mrg {
3368 1.1 mrg isl_id *id;
3369 1.1 mrg isl_ast_expr *expr;
3370 1.1 mrg isl_ast_node *node;
3371 1.1 mrg char *key;
3372 1.1 mrg isl_bool more;
3373 1.1 mrg int is_value, is_init;
3374 1.1 mrg
3375 1.1 mrg expr = isl_stream_read_ast_expr(s);
3376 1.1 mrg id = isl_ast_expr_id_get_id(expr);
3377 1.1 mrg isl_ast_expr_free(expr);
3378 1.1 mrg if (!id)
3379 1.1 mrg return NULL;
3380 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3381 1.1 mrg id = isl_id_free(id);
3382 1.1 mrg
3383 1.1 mrg node = isl_ast_node_alloc_for(id);
3384 1.1 mrg
3385 1.1 mrg key = next_key(s);
3386 1.1 mrg if (!key)
3387 1.1 mrg return isl_ast_node_free(node);
3388 1.1 mrg is_value = !strcmp(key, "value");
3389 1.1 mrg is_init = !strcmp(key, "init");
3390 1.1 mrg free(key);
3391 1.1 mrg if (!is_value && !is_init)
3392 1.1 mrg isl_die(isl_stream_get_ctx(s), isl_error_invalid,
3393 1.1 mrg "unexpected key", return isl_ast_node_free(node));
3394 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3395 1.1 mrg return isl_ast_node_free(node);
3396 1.1 mrg node = isl_ast_node_for_set_init(node, isl_stream_read_ast_expr(s));
3397 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0)
3398 1.1 mrg return isl_ast_node_free(node);
3399 1.1 mrg if (is_value) {
3400 1.1 mrg node = isl_ast_node_for_mark_degenerate(node);
3401 1.1 mrg if (more)
3402 1.1 mrg node = read_body(s, node);
3403 1.1 mrg return node;
3404 1.1 mrg }
3405 1.1 mrg
3406 1.1 mrg if (eat_key(s, "cond") < 0)
3407 1.1 mrg return isl_ast_node_free(node);
3408 1.1 mrg node = isl_ast_node_for_set_cond(node, isl_stream_read_ast_expr(s));
3409 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3410 1.1 mrg return isl_ast_node_free(node);
3411 1.1 mrg if (eat_key(s, "inc") < 0)
3412 1.1 mrg return isl_ast_node_free(node);
3413 1.1 mrg node = isl_ast_node_for_set_inc(node, isl_stream_read_ast_expr(s));
3414 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0)
3415 1.1 mrg return isl_ast_node_free(node);
3416 1.1 mrg
3417 1.1 mrg if (more)
3418 1.1 mrg node = read_body(s, node);
3419 1.1 mrg
3420 1.1 mrg return node;
3421 1.1 mrg }
3422 1.1 mrg
3423 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_mark from "s",
3424 1.1 mrg * where the initial "mark" key has already been read by the caller.
3425 1.1 mrg */
3426 1.1 mrg static __isl_give isl_ast_node *read_mark(__isl_keep isl_stream *s)
3427 1.1 mrg {
3428 1.1 mrg isl_id *id;
3429 1.1 mrg isl_ast_node *node;
3430 1.1 mrg
3431 1.1 mrg id = isl_stream_read_id(s);
3432 1.1 mrg if (!id)
3433 1.1 mrg return NULL;
3434 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3435 1.1 mrg goto error;
3436 1.1 mrg if (eat_key(s, "node") < 0)
3437 1.1 mrg goto error;
3438 1.1 mrg node = isl_stream_read_ast_node(s);
3439 1.1 mrg node = isl_ast_node_alloc_mark(id, node);
3440 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3441 1.1 mrg return isl_ast_node_free(node);
3442 1.1 mrg return node;
3443 1.1 mrg error:
3444 1.1 mrg isl_id_free(id);
3445 1.1 mrg return NULL;
3446 1.1 mrg }
3447 1.1 mrg
3448 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_user from "s",
3449 1.1 mrg * where the "user" key has already been read by the caller.
3450 1.1 mrg */
3451 1.1 mrg static __isl_give isl_ast_node *read_user(__isl_keep isl_stream *s)
3452 1.1 mrg {
3453 1.1 mrg isl_ast_node *node;
3454 1.1 mrg
3455 1.1 mrg node = isl_ast_node_alloc_user(isl_stream_read_ast_expr(s));
3456 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3457 1.1 mrg return isl_ast_node_free(node);
3458 1.1 mrg return node;
3459 1.1 mrg }
3460 1.1 mrg
3461 1.1 mrg /* Read an isl_ast_node object of type isl_ast_node_if from "s",
3462 1.1 mrg * where the initial "guard" key has already been read by the caller.
3463 1.1 mrg */
3464 1.1 mrg static __isl_give isl_ast_node *read_if(__isl_keep isl_stream *s)
3465 1.1 mrg {
3466 1.1 mrg isl_bool more;
3467 1.1 mrg isl_ast_node *node;
3468 1.1 mrg
3469 1.1 mrg node = isl_ast_node_alloc_if(isl_stream_read_ast_expr(s));
3470 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0)
3471 1.1 mrg return isl_ast_node_free(node);
3472 1.1 mrg if (!more)
3473 1.1 mrg return node;
3474 1.1 mrg
3475 1.1 mrg if (eat_key(s, "then") < 0)
3476 1.1 mrg return isl_ast_node_free(node);
3477 1.1 mrg node = isl_ast_node_if_set_then(node, isl_stream_read_ast_node(s));
3478 1.1 mrg if ((more = isl_stream_yaml_next(s)) < 0)
3479 1.1 mrg return isl_ast_node_free(node);
3480 1.1 mrg if (!more)
3481 1.1 mrg return node;
3482 1.1 mrg
3483 1.1 mrg if (eat_key(s, "else") < 0)
3484 1.1 mrg return isl_ast_node_free(node);
3485 1.1 mrg node = isl_ast_node_if_set_else_node(node, isl_stream_read_ast_node(s));
3486 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3487 1.1 mrg return isl_ast_node_free(node);
3488 1.1 mrg
3489 1.1 mrg return node;
3490 1.1 mrg }
3491 1.1 mrg
3492 1.1 mrg /* Read an isl_ast_node object from "s".
3493 1.1 mrg *
3494 1.1 mrg * A block node is printed as a YAML sequence by print_ast_node_isl.
3495 1.1 mrg * Every other node type is printed as a YAML mapping.
3496 1.1 mrg *
3497 1.1 mrg * First check if the next element is a sequence and if so,
3498 1.1 mrg * read a block node.
3499 1.1 mrg * Otherwise, read a node based on the first mapping key
3500 1.1 mrg * that is used to print a node type.
3501 1.1 mrg * Note that the keys in the YAML mapping are assumed to appear
3502 1.1 mrg * in the same order as the one in which they are printed
3503 1.1 mrg * by print_ast_node_isl.
3504 1.1 mrg */
3505 1.1 mrg __isl_give isl_ast_node *isl_stream_read_ast_node(__isl_keep isl_stream *s)
3506 1.1 mrg {
3507 1.1 mrg enum isl_ast_node_type type;
3508 1.1 mrg isl_bool more;
3509 1.1 mrg isl_bool seq;
3510 1.1 mrg isl_ast_node *node;
3511 1.1 mrg
3512 1.1 mrg seq = next_is_sequence(s);
3513 1.1 mrg if (seq < 0)
3514 1.1 mrg return NULL;
3515 1.1 mrg if (seq)
3516 1.1 mrg return read_block(s);
3517 1.1 mrg
3518 1.1 mrg if (isl_stream_yaml_read_start_mapping(s))
3519 1.1 mrg return NULL;
3520 1.1 mrg more = isl_stream_yaml_next(s);
3521 1.1 mrg if (more < 0)
3522 1.1 mrg return NULL;
3523 1.1 mrg if (!more) {
3524 1.1 mrg isl_stream_error(s, NULL, "missing key");
3525 1.1 mrg return NULL;
3526 1.1 mrg }
3527 1.1 mrg
3528 1.1 mrg type = get_node_type(s);
3529 1.1 mrg if (type < 0)
3530 1.1 mrg return NULL;
3531 1.1 mrg if (isl_stream_yaml_next(s) < 0)
3532 1.1 mrg return NULL;
3533 1.1 mrg
3534 1.1 mrg switch (type) {
3535 1.1 mrg case isl_ast_node_block:
3536 1.1 mrg isl_die(isl_stream_get_ctx(s), isl_error_internal,
3537 1.1 mrg "block cannot be detected as mapping",
3538 1.1 mrg return NULL);
3539 1.1 mrg case isl_ast_node_for:
3540 1.1 mrg node = read_for(s);
3541 1.1 mrg break;
3542 1.1 mrg case isl_ast_node_mark:
3543 1.1 mrg node = read_mark(s);
3544 1.1 mrg break;
3545 1.1 mrg case isl_ast_node_user:
3546 1.1 mrg node = read_user(s);
3547 1.1 mrg break;
3548 1.1 mrg case isl_ast_node_if:
3549 1.1 mrg node = read_if(s);
3550 1.1 mrg break;
3551 1.1 mrg case isl_ast_node_error:
3552 1.1 mrg return NULL;
3553 1.1 mrg }
3554 1.1 mrg
3555 1.1 mrg if (isl_stream_yaml_read_end_mapping(s) < 0)
3556 1.1 mrg return isl_ast_node_free(node);
3557 1.1 mrg
3558 1.1 mrg return node;
3559 1.1 mrg }
3560 1.1 mrg
3561 1.1 mrg #define ISL_AST_MACRO_FDIV_Q (1 << 0)
3562 1.1 mrg #define ISL_AST_MACRO_MIN (1 << 1)
3563 1.1 mrg #define ISL_AST_MACRO_MAX (1 << 2)
3564 1.1 mrg #define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FDIV_Q | \
3565 1.1 mrg ISL_AST_MACRO_MIN | \
3566 1.1 mrg ISL_AST_MACRO_MAX)
3567 1.1 mrg
3568 1.1 mrg static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros);
3569 1.1 mrg
3570 1.1 mrg /* Wrapper around ast_expr_required_macros for use
3571 1.1 mrg * as an isl_ast_expr_list_foreach callback.
3572 1.1 mrg */
3573 1.1 mrg static isl_stat entry_required_macros(__isl_take isl_ast_expr *expr, void *user)
3574 1.1 mrg {
3575 1.1 mrg int *macros = user;
3576 1.1 mrg
3577 1.1 mrg *macros = ast_expr_required_macros(expr, *macros);
3578 1.1 mrg isl_ast_expr_free(expr);
3579 1.1 mrg
3580 1.1 mrg return isl_stat_ok;
3581 1.1 mrg }
3582 1.1 mrg
3583 1.1 mrg /* If "expr" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3584 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3585 1.1 mrg */
3586 1.1 mrg static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
3587 1.1 mrg {
3588 1.1 mrg if (macros == ISL_AST_MACRO_ALL)
3589 1.1 mrg return macros;
3590 1.1 mrg
3591 1.1 mrg if (expr->type != isl_ast_expr_op)
3592 1.1 mrg return macros;
3593 1.1 mrg
3594 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_min)
3595 1.1 mrg macros |= ISL_AST_MACRO_MIN;
3596 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_max)
3597 1.1 mrg macros |= ISL_AST_MACRO_MAX;
3598 1.1 mrg if (expr->u.op.op == isl_ast_expr_op_fdiv_q)
3599 1.1 mrg macros |= ISL_AST_MACRO_FDIV_Q;
3600 1.1 mrg
3601 1.1 mrg isl_ast_expr_list_foreach(expr->u.op.args,
3602 1.1 mrg &entry_required_macros, ¯os);
3603 1.1 mrg
3604 1.1 mrg return macros;
3605 1.1 mrg }
3606 1.1 mrg
3607 1.1 mrg static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
3608 1.1 mrg int macros);
3609 1.1 mrg
3610 1.1 mrg /* If "node" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3611 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3612 1.1 mrg */
3613 1.1 mrg static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
3614 1.1 mrg {
3615 1.1 mrg if (macros == ISL_AST_MACRO_ALL)
3616 1.1 mrg return macros;
3617 1.1 mrg
3618 1.1 mrg switch (node->type) {
3619 1.1 mrg case isl_ast_node_for:
3620 1.1 mrg macros = ast_expr_required_macros(node->u.f.init, macros);
3621 1.1 mrg if (!node->u.f.degenerate) {
3622 1.1 mrg macros = ast_expr_required_macros(node->u.f.cond,
3623 1.1 mrg macros);
3624 1.1 mrg macros = ast_expr_required_macros(node->u.f.inc,
3625 1.1 mrg macros);
3626 1.1 mrg }
3627 1.1 mrg macros = ast_node_required_macros(node->u.f.body, macros);
3628 1.1 mrg break;
3629 1.1 mrg case isl_ast_node_if:
3630 1.1 mrg macros = ast_expr_required_macros(node->u.i.guard, macros);
3631 1.1 mrg macros = ast_node_required_macros(node->u.i.then, macros);
3632 1.1 mrg if (node->u.i.else_node)
3633 1.1 mrg macros = ast_node_required_macros(node->u.i.else_node,
3634 1.1 mrg macros);
3635 1.1 mrg break;
3636 1.1 mrg case isl_ast_node_block:
3637 1.1 mrg macros = ast_node_list_required_macros(node->u.b.children,
3638 1.1 mrg macros);
3639 1.1 mrg break;
3640 1.1 mrg case isl_ast_node_mark:
3641 1.1 mrg macros = ast_node_required_macros(node->u.m.node, macros);
3642 1.1 mrg break;
3643 1.1 mrg case isl_ast_node_user:
3644 1.1 mrg macros = ast_expr_required_macros(node->u.e.expr, macros);
3645 1.1 mrg break;
3646 1.1 mrg case isl_ast_node_error:
3647 1.1 mrg break;
3648 1.1 mrg }
3649 1.1 mrg
3650 1.1 mrg return macros;
3651 1.1 mrg }
3652 1.1 mrg
3653 1.1 mrg /* If "list" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or
3654 1.1 mrg * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros".
3655 1.1 mrg */
3656 1.1 mrg static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
3657 1.1 mrg int macros)
3658 1.1 mrg {
3659 1.1 mrg int i;
3660 1.1 mrg
3661 1.1 mrg for (i = 0; i < list->n; ++i)
3662 1.1 mrg macros = ast_node_required_macros(list->p[i], macros);
3663 1.1 mrg
3664 1.1 mrg return macros;
3665 1.1 mrg }
3666 1.1 mrg
3667 1.1 mrg /* Data structure for keeping track of whether a macro definition
3668 1.1 mrg * for a given type has already been printed.
3669 1.1 mrg * The value is zero if no definition has been printed and non-zero otherwise.
3670 1.1 mrg */
3671 1.1 mrg struct isl_ast_expr_op_printed {
3672 1.1 mrg char printed[isl_ast_expr_op_last + 1];
3673 1.1 mrg };
3674 1.1 mrg
3675 1.1 mrg /* Create an empty struct isl_ast_expr_op_printed.
3676 1.1 mrg */
3677 1.1 mrg static void *create_printed(isl_ctx *ctx)
3678 1.1 mrg {
3679 1.1 mrg return isl_calloc_type(ctx, struct isl_ast_expr_op_printed);
3680 1.1 mrg }
3681 1.1 mrg
3682 1.1 mrg /* Free a struct isl_ast_expr_op_printed.
3683 1.1 mrg */
3684 1.1 mrg static void free_printed(void *user)
3685 1.1 mrg {
3686 1.1 mrg free(user);
3687 1.1 mrg }
3688 1.1 mrg
3689 1.1 mrg /* Ensure that "p" has an isl_ast_expr_op_printed note identified by "id".
3690 1.1 mrg */
3691 1.1 mrg static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p,
3692 1.1 mrg __isl_keep isl_id *id)
3693 1.1 mrg {
3694 1.1 mrg return alloc_note(p, id, &create_printed, &free_printed);
3695 1.1 mrg }
3696 1.1 mrg
3697 1.1 mrg /* Create an identifier that is used to store
3698 1.1 mrg * an isl_ast_expr_op_printed note.
3699 1.1 mrg */
3700 1.1 mrg static __isl_give isl_id *printed_id(isl_ctx *ctx)
3701 1.1 mrg {
3702 1.1 mrg return isl_id_alloc(ctx, "isl_ast_expr_op_type_printed", NULL);
3703 1.1 mrg }
3704 1.1 mrg
3705 1.1 mrg /* Did the user specify that a macro definition should only be
3706 1.1 mrg * printed once and has a macro definition for "type" already
3707 1.1 mrg * been printed to "p"?
3708 1.1 mrg * If definitions should only be printed once, but a definition
3709 1.1 mrg * for "p" has not yet been printed, then mark it as having been
3710 1.1 mrg * printed so that it will not printed again.
3711 1.1 mrg * The actual printing is taken care of by the caller.
3712 1.1 mrg */
3713 1.1 mrg static isl_bool already_printed_once(__isl_keep isl_printer *p,
3714 1.1 mrg enum isl_ast_expr_op_type type)
3715 1.1 mrg {
3716 1.1 mrg isl_ctx *ctx;
3717 1.1 mrg isl_id *id;
3718 1.1 mrg struct isl_ast_expr_op_printed *printed;
3719 1.1 mrg
3720 1.1 mrg if (!p)
3721 1.1 mrg return isl_bool_error;
3722 1.1 mrg
3723 1.1 mrg ctx = isl_printer_get_ctx(p);
3724 1.1 mrg if (!isl_options_get_ast_print_macro_once(ctx))
3725 1.1 mrg return isl_bool_false;
3726 1.1 mrg
3727 1.1 mrg if (type > isl_ast_expr_op_last)
3728 1.1 mrg isl_die(isl_printer_get_ctx(p), isl_error_invalid,
3729 1.1 mrg "invalid type", return isl_bool_error);
3730 1.1 mrg
3731 1.1 mrg id = printed_id(isl_printer_get_ctx(p));
3732 1.1 mrg p = alloc_printed(p, id);
3733 1.1 mrg printed = get_note(p, id);
3734 1.1 mrg isl_id_free(id);
3735 1.1 mrg if (!printed)
3736 1.1 mrg return isl_bool_error;
3737 1.1 mrg
3738 1.1 mrg if (printed->printed[type])
3739 1.1 mrg return isl_bool_true;
3740 1.1 mrg
3741 1.1 mrg printed->printed[type] = 1;
3742 1.1 mrg return isl_bool_false;
3743 1.1 mrg }
3744 1.1 mrg
3745 1.1 mrg /* Print a macro definition for the operator "type".
3746 1.1 mrg *
3747 1.1 mrg * If the user has specified that a macro definition should
3748 1.1 mrg * only be printed once to any given printer and if the macro definition
3749 1.1 mrg * has already been printed to "p", then do not print the definition.
3750 1.1 mrg */
3751 1.1 mrg __isl_give isl_printer *isl_ast_expr_op_type_print_macro(
3752 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_printer *p)
3753 1.1 mrg {
3754 1.1 mrg isl_bool skip;
3755 1.1 mrg
3756 1.1 mrg skip = already_printed_once(p, type);
3757 1.1 mrg if (skip < 0)
3758 1.1 mrg return isl_printer_free(p);
3759 1.1 mrg if (skip)
3760 1.1 mrg return p;
3761 1.1 mrg
3762 1.1 mrg switch (type) {
3763 1.1 mrg case isl_ast_expr_op_min:
3764 1.1 mrg p = isl_printer_start_line(p);
3765 1.1 mrg p = isl_printer_print_str(p, "#define ");
3766 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type));
3767 1.1 mrg p = isl_printer_print_str(p,
3768 1.1 mrg "(x,y) ((x) < (y) ? (x) : (y))");
3769 1.1 mrg p = isl_printer_end_line(p);
3770 1.1 mrg break;
3771 1.1 mrg case isl_ast_expr_op_max:
3772 1.1 mrg p = isl_printer_start_line(p);
3773 1.1 mrg p = isl_printer_print_str(p, "#define ");
3774 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type));
3775 1.1 mrg p = isl_printer_print_str(p,
3776 1.1 mrg "(x,y) ((x) > (y) ? (x) : (y))");
3777 1.1 mrg p = isl_printer_end_line(p);
3778 1.1 mrg break;
3779 1.1 mrg case isl_ast_expr_op_fdiv_q:
3780 1.1 mrg p = isl_printer_start_line(p);
3781 1.1 mrg p = isl_printer_print_str(p, "#define ");
3782 1.1 mrg p = isl_printer_print_str(p, get_op_str_c(p, type));
3783 1.1 mrg p = isl_printer_print_str(p,
3784 1.1 mrg "(n,d) "
3785 1.1 mrg "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
3786 1.1 mrg p = isl_printer_end_line(p);
3787 1.1 mrg break;
3788 1.1 mrg default:
3789 1.1 mrg break;
3790 1.1 mrg }
3791 1.1 mrg
3792 1.1 mrg return p;
3793 1.1 mrg }
3794 1.1 mrg
3795 1.1 mrg /* This is an alternative name for the function above.
3796 1.1 mrg */
3797 1.1 mrg __isl_give isl_printer *isl_ast_op_type_print_macro(
3798 1.1 mrg enum isl_ast_expr_op_type type, __isl_take isl_printer *p)
3799 1.1 mrg {
3800 1.1 mrg return isl_ast_expr_op_type_print_macro(type, p);
3801 1.1 mrg }
3802 1.1 mrg
3803 1.1 mrg /* Call "fn" for each type of operation represented in the "macros"
3804 1.1 mrg * bit vector.
3805 1.1 mrg */
3806 1.1 mrg static isl_stat foreach_ast_expr_op_type(int macros,
3807 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3808 1.1 mrg {
3809 1.1 mrg if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_expr_op_min, user) < 0)
3810 1.1 mrg return isl_stat_error;
3811 1.1 mrg if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_expr_op_max, user) < 0)
3812 1.1 mrg return isl_stat_error;
3813 1.1 mrg if (macros & ISL_AST_MACRO_FDIV_Q &&
3814 1.1 mrg fn(isl_ast_expr_op_fdiv_q, user) < 0)
3815 1.1 mrg return isl_stat_error;
3816 1.1 mrg
3817 1.1 mrg return isl_stat_ok;
3818 1.1 mrg }
3819 1.1 mrg
3820 1.1 mrg /* Call "fn" for each type of operation that appears in "expr"
3821 1.1 mrg * and that requires a macro definition.
3822 1.1 mrg */
3823 1.1 mrg isl_stat isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr *expr,
3824 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3825 1.1 mrg {
3826 1.1 mrg int macros;
3827 1.1 mrg
3828 1.1 mrg if (!expr)
3829 1.1 mrg return isl_stat_error;
3830 1.1 mrg
3831 1.1 mrg macros = ast_expr_required_macros(expr, 0);
3832 1.1 mrg return foreach_ast_expr_op_type(macros, fn, user);
3833 1.1 mrg }
3834 1.1 mrg
3835 1.1 mrg /* This is an alternative name for the function above.
3836 1.1 mrg */
3837 1.1 mrg isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr,
3838 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3839 1.1 mrg {
3840 1.1 mrg return isl_ast_expr_foreach_ast_expr_op_type(expr, fn, user);
3841 1.1 mrg }
3842 1.1 mrg
3843 1.1 mrg /* Call "fn" for each type of operation that appears in "node"
3844 1.1 mrg * and that requires a macro definition.
3845 1.1 mrg */
3846 1.1 mrg isl_stat isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node *node,
3847 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3848 1.1 mrg {
3849 1.1 mrg int macros;
3850 1.1 mrg
3851 1.1 mrg if (!node)
3852 1.1 mrg return isl_stat_error;
3853 1.1 mrg
3854 1.1 mrg macros = ast_node_required_macros(node, 0);
3855 1.1 mrg return foreach_ast_expr_op_type(macros, fn, user);
3856 1.1 mrg }
3857 1.1 mrg
3858 1.1 mrg /* This is an alternative name for the function above.
3859 1.1 mrg */
3860 1.1 mrg isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
3861 1.1 mrg isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user)
3862 1.1 mrg {
3863 1.1 mrg return isl_ast_node_foreach_ast_expr_op_type(node, fn, user);
3864 1.1 mrg }
3865 1.1 mrg
3866 1.1 mrg static isl_stat ast_op_type_print_macro(enum isl_ast_expr_op_type type,
3867 1.1 mrg void *user)
3868 1.1 mrg {
3869 1.1 mrg isl_printer **p = user;
3870 1.1 mrg
3871 1.1 mrg *p = isl_ast_expr_op_type_print_macro(type, *p);
3872 1.1 mrg
3873 1.1 mrg return isl_stat_ok;
3874 1.1 mrg }
3875 1.1 mrg
3876 1.1 mrg /* Print macro definitions for all the macros used in the result
3877 1.1 mrg * of printing "expr".
3878 1.1 mrg */
3879 1.1 mrg __isl_give isl_printer *isl_ast_expr_print_macros(
3880 1.1 mrg __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
3881 1.1 mrg {
3882 1.1 mrg if (isl_ast_expr_foreach_ast_expr_op_type(expr,
3883 1.1 mrg &ast_op_type_print_macro, &p) < 0)
3884 1.1 mrg return isl_printer_free(p);
3885 1.1 mrg return p;
3886 1.1 mrg }
3887 1.1 mrg
3888 1.1 mrg /* Print macro definitions for all the macros used in the result
3889 1.1 mrg * of printing "node".
3890 1.1 mrg */
3891 1.1 mrg __isl_give isl_printer *isl_ast_node_print_macros(
3892 1.1 mrg __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
3893 1.1 mrg {
3894 1.1 mrg if (isl_ast_node_foreach_ast_expr_op_type(node,
3895 1.1 mrg &ast_op_type_print_macro, &p) < 0)
3896 1.1 mrg return isl_printer_free(p);
3897 1.1 mrg return p;
3898 1.1 mrg }
3899 1.1 mrg
3900 1.1 mrg /* Return a string containing C code representing this isl_ast_expr.
3901 1.1 mrg */
3902 1.1 mrg __isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr)
3903 1.1 mrg {
3904 1.1 mrg isl_printer *p;
3905 1.1 mrg char *str;
3906 1.1 mrg
3907 1.1 mrg if (!expr)
3908 1.1 mrg return NULL;
3909 1.1 mrg
3910 1.1 mrg p = isl_printer_to_str(isl_ast_expr_get_ctx(expr));
3911 1.1 mrg p = isl_printer_set_output_format(p, ISL_FORMAT_C);
3912 1.1 mrg p = isl_printer_print_ast_expr(p, expr);
3913 1.1 mrg
3914 1.1 mrg str = isl_printer_get_str(p);
3915 1.1 mrg
3916 1.1 mrg isl_printer_free(p);
3917 1.1 mrg
3918 1.1 mrg return str;
3919 1.1 mrg }
3920 1.1 mrg
3921 1.1 mrg /* Return a string containing C code representing this isl_ast_node.
3922 1.1 mrg */
3923 1.1 mrg __isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node)
3924 1.1 mrg {
3925 1.1 mrg isl_printer *p;
3926 1.1 mrg char *str;
3927 1.1 mrg
3928 1.1 mrg if (!node)
3929 1.1 mrg return NULL;
3930 1.1 mrg
3931 1.1 mrg p = isl_printer_to_str(isl_ast_node_get_ctx(node));
3932 1.1 mrg p = isl_printer_set_output_format(p, ISL_FORMAT_C);
3933 1.1 mrg p = isl_printer_print_ast_node(p, node);
3934 1.1 mrg
3935 1.1 mrg str = isl_printer_get_str(p);
3936 1.1 mrg
3937 1.1 mrg isl_printer_free(p);
3938 1.1 mrg
3939 1.1 mrg return str;
3940 1.1 mrg }
3941