Bug Summary

File:tools/polly/lib/External/isl/isl_ast.c
Warning:line 2422, column 2
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_ast.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/include -I /usr/include/jsoncpp -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-7~svn329677=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c /build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c
1/*
2 * Copyright 2012-2013 Ecole Normale Superieure
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
8 */
9
10#include <string.h>
11
12#include <isl/val.h>
13#include <isl_ast_private.h>
14
15#undef BASEast_node
16#define BASEast_node ast_expr
17
18#include <isl_list_templ.c>
19
20#undef BASEast_node
21#define BASEast_node ast_node
22
23#include <isl_list_templ.c>
24
25isl_ctx *isl_ast_print_options_get_ctx(
26 __isl_keep isl_ast_print_options *options)
27{
28 return options ? options->ctx : NULL((void*)0);
29}
30
31__isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
32{
33 isl_ast_print_options *options;
34
35 options = isl_calloc_type(ctx, isl_ast_print_options)((isl_ast_print_options *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_print_options
)))
;
36 if (!options)
37 return NULL((void*)0);
38
39 options->ctx = ctx;
40 isl_ctx_ref(ctx);
41 options->ref = 1;
42
43 return options;
44}
45
46__isl_give isl_ast_print_options *isl_ast_print_options_dup(
47 __isl_keep isl_ast_print_options *options)
48{
49 isl_ctx *ctx;
50 isl_ast_print_options *dup;
51
52 if (!options)
53 return NULL((void*)0);
54
55 ctx = isl_ast_print_options_get_ctx(options);
56 dup = isl_ast_print_options_alloc(ctx);
57 if (!dup)
58 return NULL((void*)0);
59
60 dup->print_for = options->print_for;
61 dup->print_for_user = options->print_for_user;
62 dup->print_user = options->print_user;
63 dup->print_user_user = options->print_user_user;
64
65 return dup;
66}
67
68__isl_give isl_ast_print_options *isl_ast_print_options_cow(
69 __isl_take isl_ast_print_options *options)
70{
71 if (!options)
72 return NULL((void*)0);
73
74 if (options->ref == 1)
75 return options;
76 options->ref--;
77 return isl_ast_print_options_dup(options);
78}
79
80__isl_give isl_ast_print_options *isl_ast_print_options_copy(
81 __isl_keep isl_ast_print_options *options)
82{
83 if (!options)
84 return NULL((void*)0);
85
86 options->ref++;
87 return options;
88}
89
90__isl_null isl_ast_print_options *isl_ast_print_options_free(
91 __isl_take isl_ast_print_options *options)
92{
93 if (!options)
17
Taking false branch
94 return NULL((void*)0);
95
96 if (--options->ref > 0)
18
Assuming the condition is false
19
Taking false branch
97 return NULL((void*)0);
98
99 isl_ctx_deref(options->ctx);
100
101 free(options);
20
Memory is released
102 return NULL((void*)0);
103}
104
105/* Set the print_user callback of "options" to "print_user".
106 *
107 * If this callback is set, then it used to print user nodes in the AST.
108 * Otherwise, the expression associated to the user node is printed.
109 */
110__isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
111 __isl_take isl_ast_print_options *options,
112 __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
113 __isl_take isl_ast_print_options *options,
114 __isl_keep isl_ast_node *node, void *user),
115 void *user)
116{
117 options = isl_ast_print_options_cow(options);
118 if (!options)
119 return NULL((void*)0);
120
121 options->print_user = print_user;
122 options->print_user_user = user;
123
124 return options;
125}
126
127/* Set the print_for callback of "options" to "print_for".
128 *
129 * If this callback is set, then it used to print for nodes in the AST.
130 */
131__isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
132 __isl_take isl_ast_print_options *options,
133 __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
134 __isl_take isl_ast_print_options *options,
135 __isl_keep isl_ast_node *node, void *user),
136 void *user)
137{
138 options = isl_ast_print_options_cow(options);
139 if (!options)
140 return NULL((void*)0);
141
142 options->print_for = print_for;
143 options->print_for_user = user;
144
145 return options;
146}
147
148__isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr)
149{
150 if (!expr)
151 return NULL((void*)0);
152
153 expr->ref++;
154 return expr;
155}
156
157__isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr)
158{
159 int i;
160 isl_ctx *ctx;
161 isl_ast_expr *dup;
162
163 if (!expr)
164 return NULL((void*)0);
165
166 ctx = isl_ast_expr_get_ctx(expr);
167 switch (expr->type) {
168 case isl_ast_expr_int:
169 dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v));
170 break;
171 case isl_ast_expr_id:
172 dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id));
173 break;
174 case isl_ast_expr_op:
175 dup = isl_ast_expr_alloc_op(ctx,
176 expr->u.op.op, expr->u.op.n_arg);
177 if (!dup)
178 return NULL((void*)0);
179 for (i = 0; i < expr->u.op.n_arg; ++i)
180 dup->u.op.args[i] =
181 isl_ast_expr_copy(expr->u.op.args[i]);
182 break;
183 case isl_ast_expr_error:
184 dup = NULL((void*)0);
185 }
186
187 if (!dup)
188 return NULL((void*)0);
189
190 return dup;
191}
192
193__isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr)
194{
195 if (!expr)
196 return NULL((void*)0);
197
198 if (expr->ref == 1)
199 return expr;
200 expr->ref--;
201 return isl_ast_expr_dup(expr);
202}
203
204__isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr)
205{
206 int i;
207
208 if (!expr)
209 return NULL((void*)0);
210
211 if (--expr->ref > 0)
212 return NULL((void*)0);
213
214 isl_ctx_deref(expr->ctx);
215
216 switch (expr->type) {
217 case isl_ast_expr_int:
218 isl_val_free(expr->u.v);
219 break;
220 case isl_ast_expr_id:
221 isl_id_free(expr->u.id);
222 break;
223 case isl_ast_expr_op:
224 if (expr->u.op.args)
225 for (i = 0; i < expr->u.op.n_arg; ++i)
226 isl_ast_expr_free(expr->u.op.args[i]);
227 free(expr->u.op.args);
228 break;
229 case isl_ast_expr_error:
230 break;
231 }
232
233 free(expr);
234 return NULL((void*)0);
235}
236
237isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr)
238{
239 return expr ? expr->ctx : NULL((void*)0);
240}
241
242enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
243{
244 return expr ? expr->type : isl_ast_expr_error;
245}
246
247/* Return the integer value represented by "expr".
248 */
249__isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr)
250{
251 if (!expr)
252 return NULL((void*)0);
253 if (expr->type != isl_ast_expr_int)
254 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an int", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 255); return ((void*)0); } while (0)
255 "expression not an int", return NULL)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an int", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 255); return ((void*)0); } while (0)
;
256 return isl_val_copy(expr->u.v);
257}
258
259__isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr)
260{
261 if (!expr)
262 return NULL((void*)0);
263 if (expr->type != isl_ast_expr_id)
264 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an identifier", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 265); return ((void*)0); } while (0)
265 "expression not an identifier", return NULL)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an identifier", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 265); return ((void*)0); } while (0)
;
266
267 return isl_id_copy(expr->u.id);
268}
269
270enum isl_ast_op_type isl_ast_expr_get_op_type(__isl_keep isl_ast_expr *expr)
271{
272 if (!expr)
273 return isl_ast_op_error;
274 if (expr->type != isl_ast_expr_op)
275 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 276); return isl_ast_op_error; } while (0)
276 "expression not an operation", return isl_ast_op_error)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 276); return isl_ast_op_error; } while (0)
;
277 return expr->u.op.op;
278}
279
280int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr)
281{
282 if (!expr)
283 return -1;
284 if (expr->type != isl_ast_expr_op)
285 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 286); return -1; } while (0)
286 "expression not an operation", return -1)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 286); return -1; } while (0)
;
287 return expr->u.op.n_arg;
288}
289
290__isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr,
291 int pos)
292{
293 if (!expr)
294 return NULL((void*)0);
295 if (expr->type != isl_ast_expr_op)
296 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 297); return ((void*)0); } while (0)
297 "expression not an operation", return NULL)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 297); return ((void*)0); } while (0)
;
298 if (pos < 0 || pos >= expr->u.op.n_arg)
299 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 300); return ((void*)0); } while (0)
300 "index out of bounds", return NULL)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 300); return ((void*)0); } while (0)
;
301
302 return isl_ast_expr_copy(expr->u.op.args[pos]);
303}
304
305/* Replace the argument at position "pos" of "expr" by "arg".
306 */
307__isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr,
308 int pos, __isl_take isl_ast_expr *arg)
309{
310 expr = isl_ast_expr_cow(expr);
311 if (!expr || !arg)
312 goto error;
313 if (expr->type != isl_ast_expr_op)
314 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 315); goto error; } while (0)
315 "expression not an operation", goto error)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "expression not an operation", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 315); goto error; } while (0)
;
316 if (pos < 0 || pos >= expr->u.op.n_arg)
317 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 318); goto error; } while (0)
318 "index out of bounds", goto error)do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 318); goto error; } while (0)
;
319
320 isl_ast_expr_free(expr->u.op.args[pos]);
321 expr->u.op.args[pos] = arg;
322
323 return expr;
324error:
325 isl_ast_expr_free(arg);
326 return isl_ast_expr_free(expr);
327}
328
329/* Is "expr1" equal to "expr2"?
330 */
331isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1,
332 __isl_keep isl_ast_expr *expr2)
333{
334 int i;
335
336 if (!expr1 || !expr2)
337 return isl_bool_error;
338
339 if (expr1 == expr2)
340 return isl_bool_true;
341 if (expr1->type != expr2->type)
342 return isl_bool_false;
343 switch (expr1->type) {
344 case isl_ast_expr_int:
345 return isl_val_eq(expr1->u.v, expr2->u.v);
346 case isl_ast_expr_id:
347 return expr1->u.id == expr2->u.id;
348 case isl_ast_expr_op:
349 if (expr1->u.op.op != expr2->u.op.op)
350 return isl_bool_false;
351 if (expr1->u.op.n_arg != expr2->u.op.n_arg)
352 return isl_bool_false;
353 for (i = 0; i < expr1->u.op.n_arg; ++i) {
354 isl_bool equal;
355 equal = isl_ast_expr_is_equal(expr1->u.op.args[i],
356 expr2->u.op.args[i]);
357 if (equal < 0 || !equal)
358 return equal;
359 }
360 return 1;
361 case isl_ast_expr_error:
362 return isl_bool_error;
363 }
364
365 isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal,do { isl_handle_error(isl_ast_expr_get_ctx(expr1), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 366); return isl_bool_error; } while (0)
366 "unhandled case", return isl_bool_error)do { isl_handle_error(isl_ast_expr_get_ctx(expr1), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 366); return isl_bool_error; } while (0)
;
367}
368
369/* Create a new operation expression of operation type "op",
370 * with "n_arg" as yet unspecified arguments.
371 */
372__isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx,
373 enum isl_ast_op_type op, int n_arg)
374{
375 isl_ast_expr *expr;
376
377 expr = isl_calloc_type(ctx, isl_ast_expr)((isl_ast_expr *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_expr
)))
;
378 if (!expr)
379 return NULL((void*)0);
380
381 expr->ctx = ctx;
382 isl_ctx_ref(ctx);
383 expr->ref = 1;
384 expr->type = isl_ast_expr_op;
385 expr->u.op.op = op;
386 expr->u.op.n_arg = n_arg;
387 expr->u.op.args = isl_calloc_array(ctx, isl_ast_expr *, n_arg)((isl_ast_expr * *)isl_calloc_or_die(ctx, n_arg, sizeof(isl_ast_expr
*)))
;
388
389 if (n_arg && !expr->u.op.args)
390 return isl_ast_expr_free(expr);
391
392 return expr;
393}
394
395/* Create a new id expression representing "id".
396 */
397__isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id)
398{
399 isl_ctx *ctx;
400 isl_ast_expr *expr;
401
402 if (!id)
403 return NULL((void*)0);
404
405 ctx = isl_id_get_ctx(id);
406 expr = isl_calloc_type(ctx, isl_ast_expr)((isl_ast_expr *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_expr
)))
;
407 if (!expr)
408 goto error;
409
410 expr->ctx = ctx;
411 isl_ctx_ref(ctx);
412 expr->ref = 1;
413 expr->type = isl_ast_expr_id;
414 expr->u.id = id;
415
416 return expr;
417error:
418 isl_id_free(id);
419 return NULL((void*)0);
420}
421
422/* Create a new integer expression representing "i".
423 */
424__isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
425{
426 isl_ast_expr *expr;
427
428 expr = isl_calloc_type(ctx, isl_ast_expr)((isl_ast_expr *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_expr
)))
;
429 if (!expr)
430 return NULL((void*)0);
431
432 expr->ctx = ctx;
433 isl_ctx_ref(ctx);
434 expr->ref = 1;
435 expr->type = isl_ast_expr_int;
436 expr->u.v = isl_val_int_from_si(ctx, i);
437 if (!expr->u.v)
438 return isl_ast_expr_free(expr);
439
440 return expr;
441}
442
443/* Create a new integer expression representing "v".
444 */
445__isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v)
446{
447 isl_ctx *ctx;
448 isl_ast_expr *expr;
449
450 if (!v)
451 return NULL((void*)0);
452 if (!isl_val_is_int(v))
453 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting integer value"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 454); goto error; } while (0)
454 "expecting integer value", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting integer value"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 454); goto error; } while (0)
;
455
456 ctx = isl_val_get_ctx(v);
457 expr = isl_calloc_type(ctx, isl_ast_expr)((isl_ast_expr *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_expr
)))
;
458 if (!expr)
459 goto error;
460
461 expr->ctx = ctx;
462 isl_ctx_ref(ctx);
463 expr->ref = 1;
464 expr->type = isl_ast_expr_int;
465 expr->u.v = v;
466
467 return expr;
468error:
469 isl_val_free(v);
470 return NULL((void*)0);
471}
472
473/* Create an expression representing the unary operation "type" applied to
474 * "arg".
475 */
476__isl_give isl_ast_expr *isl_ast_expr_alloc_unary(enum isl_ast_op_type type,
477 __isl_take isl_ast_expr *arg)
478{
479 isl_ctx *ctx;
480 isl_ast_expr *expr = NULL((void*)0);
481
482 if (!arg)
483 return NULL((void*)0);
484
485 ctx = isl_ast_expr_get_ctx(arg);
486 expr = isl_ast_expr_alloc_op(ctx, type, 1);
487 if (!expr)
488 goto error;
489
490 expr->u.op.args[0] = arg;
491
492 return expr;
493error:
494 isl_ast_expr_free(arg);
495 return NULL((void*)0);
496}
497
498/* Create an expression representing the negation of "arg".
499 */
500__isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg)
501{
502 return isl_ast_expr_alloc_unary(isl_ast_op_minus, arg);
503}
504
505/* Create an expression representing the address of "expr".
506 */
507__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr)
508{
509 if (!expr)
510 return NULL((void*)0);
511
512 if (isl_ast_expr_get_type(expr) != isl_ast_expr_op ||
513 isl_ast_expr_get_op_type(expr) != isl_ast_op_access)
514 isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "can only take address of access expressions", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 516); return isl_ast_expr_free(expr); } while (0)
515 "can only take address of access expressions",do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "can only take address of access expressions", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 516); return isl_ast_expr_free(expr); } while (0)
516 return isl_ast_expr_free(expr))do { isl_handle_error(isl_ast_expr_get_ctx(expr), isl_error_invalid
, "can only take address of access expressions", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 516); return isl_ast_expr_free(expr); } while (0)
;
517
518 return isl_ast_expr_alloc_unary(isl_ast_op_address_of, expr);
519}
520
521/* Create an expression representing the binary operation "type"
522 * applied to "expr1" and "expr2".
523 */
524__isl_give isl_ast_expr *isl_ast_expr_alloc_binary(enum isl_ast_op_type type,
525 __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
526{
527 isl_ctx *ctx;
528 isl_ast_expr *expr = NULL((void*)0);
529
530 if (!expr1 || !expr2)
531 goto error;
532
533 ctx = isl_ast_expr_get_ctx(expr1);
534 expr = isl_ast_expr_alloc_op(ctx, type, 2);
535 if (!expr)
536 goto error;
537
538 expr->u.op.args[0] = expr1;
539 expr->u.op.args[1] = expr2;
540
541 return expr;
542error:
543 isl_ast_expr_free(expr1);
544 isl_ast_expr_free(expr2);
545 return NULL((void*)0);
546}
547
548/* Create an expression representing the sum of "expr1" and "expr2".
549 */
550__isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1,
551 __isl_take isl_ast_expr *expr2)
552{
553 return isl_ast_expr_alloc_binary(isl_ast_op_add, expr1, expr2);
554}
555
556/* Create an expression representing the difference of "expr1" and "expr2".
557 */
558__isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1,
559 __isl_take isl_ast_expr *expr2)
560{
561 return isl_ast_expr_alloc_binary(isl_ast_op_sub, expr1, expr2);
562}
563
564/* Create an expression representing the product of "expr1" and "expr2".
565 */
566__isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
567 __isl_take isl_ast_expr *expr2)
568{
569 return isl_ast_expr_alloc_binary(isl_ast_op_mul, expr1, expr2);
570}
571
572/* Create an expression representing the quotient of "expr1" and "expr2".
573 */
574__isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
575 __isl_take isl_ast_expr *expr2)
576{
577 return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
578}
579
580/* Create an expression representing the quotient of the integer
581 * division of "expr1" by "expr2", where "expr1" is known to be
582 * non-negative.
583 */
584__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
585 __isl_take isl_ast_expr *expr2)
586{
587 return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_q, expr1, expr2);
588}
589
590/* Create an expression representing the remainder of the integer
591 * division of "expr1" by "expr2", where "expr1" is known to be
592 * non-negative.
593 */
594__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
595 __isl_take isl_ast_expr *expr2)
596{
597 return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr1, expr2);
598}
599
600/* Create an expression representing the conjunction of "expr1" and "expr2".
601 */
602__isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
603 __isl_take isl_ast_expr *expr2)
604{
605 return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
606}
607
608/* Create an expression representing the conjunction of "expr1" and "expr2",
609 * where "expr2" is evaluated only if "expr1" is evaluated to true.
610 */
611__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
612 __isl_take isl_ast_expr *expr2)
613{
614 return isl_ast_expr_alloc_binary(isl_ast_op_and_then, expr1, expr2);
615}
616
617/* Create an expression representing the disjunction of "expr1" and "expr2".
618 */
619__isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
620 __isl_take isl_ast_expr *expr2)
621{
622 return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
623}
624
625/* Create an expression representing the disjunction of "expr1" and "expr2",
626 * where "expr2" is evaluated only if "expr1" is evaluated to false.
627 */
628__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
629 __isl_take isl_ast_expr *expr2)
630{
631 return isl_ast_expr_alloc_binary(isl_ast_op_or_else, expr1, expr2);
632}
633
634/* Create an expression representing "expr1" less than or equal to "expr2".
635 */
636__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
637 __isl_take isl_ast_expr *expr2)
638{
639 return isl_ast_expr_alloc_binary(isl_ast_op_le, expr1, expr2);
640}
641
642/* Create an expression representing "expr1" less than "expr2".
643 */
644__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
645 __isl_take isl_ast_expr *expr2)
646{
647 return isl_ast_expr_alloc_binary(isl_ast_op_lt, expr1, expr2);
648}
649
650/* Create an expression representing "expr1" greater than or equal to "expr2".
651 */
652__isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1,
653 __isl_take isl_ast_expr *expr2)
654{
655 return isl_ast_expr_alloc_binary(isl_ast_op_ge, expr1, expr2);
656}
657
658/* Create an expression representing "expr1" greater than "expr2".
659 */
660__isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1,
661 __isl_take isl_ast_expr *expr2)
662{
663 return isl_ast_expr_alloc_binary(isl_ast_op_gt, expr1, expr2);
664}
665
666/* Create an expression representing "expr1" equal to "expr2".
667 */
668__isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
669 __isl_take isl_ast_expr *expr2)
670{
671 return isl_ast_expr_alloc_binary(isl_ast_op_eq, expr1, expr2);
672}
673
674/* Create an expression of type "type" with as arguments "arg0" followed
675 * by "arguments".
676 */
677static __isl_give isl_ast_expr *ast_expr_with_arguments(
678 enum isl_ast_op_type type, __isl_take isl_ast_expr *arg0,
679 __isl_take isl_ast_expr_list *arguments)
680{
681 int i, n;
682 isl_ctx *ctx;
683 isl_ast_expr *res = NULL((void*)0);
684
685 if (!arg0 || !arguments)
686 goto error;
687
688 ctx = isl_ast_expr_get_ctx(arg0);
689 n = isl_ast_expr_list_n_ast_expr(arguments);
690 res = isl_ast_expr_alloc_op(ctx, type, 1 + n);
691 if (!res)
692 goto error;
693 for (i = 0; i < n; ++i) {
694 isl_ast_expr *arg;
695 arg = isl_ast_expr_list_get_ast_expr(arguments, i);
696 res->u.op.args[1 + i] = arg;
697 if (!arg)
698 goto error;
699 }
700 res->u.op.args[0] = arg0;
701
702 isl_ast_expr_list_free(arguments);
703 return res;
704error:
705 isl_ast_expr_free(arg0);
706 isl_ast_expr_list_free(arguments);
707 isl_ast_expr_free(res);
708 return NULL((void*)0);
709}
710
711/* Create an expression representing an access to "array" with index
712 * expressions "indices".
713 */
714__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
715 __isl_take isl_ast_expr_list *indices)
716{
717 return ast_expr_with_arguments(isl_ast_op_access, array, indices);
718}
719
720/* Create an expression representing a call to "function" with argument
721 * expressions "arguments".
722 */
723__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
724 __isl_take isl_ast_expr_list *arguments)
725{
726 return ast_expr_with_arguments(isl_ast_op_call, function, arguments);
727}
728
729/* For each subexpression of "expr" of type isl_ast_expr_id,
730 * if it appears in "id2expr", then replace it by the corresponding
731 * expression.
732 */
733__isl_give isl_ast_expr *isl_ast_expr_substitute_ids(
734 __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr)
735{
736 int i;
737 isl_maybe_isl_ast_expr m;
738
739 if (!expr || !id2expr)
740 goto error;
741
742 switch (expr->type) {
743 case isl_ast_expr_int:
744 break;
745 case isl_ast_expr_id:
746 m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id);
747 if (m.valid < 0)
748 goto error;
749 if (!m.valid)
750 break;
751 isl_ast_expr_free(expr);
752 expr = m.value;
753 break;
754 case isl_ast_expr_op:
755 for (i = 0; i < expr->u.op.n_arg; ++i) {
756 isl_ast_expr *arg;
757 arg = isl_ast_expr_copy(expr->u.op.args[i]);
758 arg = isl_ast_expr_substitute_ids(arg,
759 isl_id_to_ast_expr_copy(id2expr));
760 if (arg == expr->u.op.args[i]) {
761 isl_ast_expr_free(arg);
762 continue;
763 }
764 if (!arg)
765 expr = isl_ast_expr_free(expr);
766 expr = isl_ast_expr_cow(expr);
767 if (!expr) {
768 isl_ast_expr_free(arg);
769 break;
770 }
771 isl_ast_expr_free(expr->u.op.args[i]);
772 expr->u.op.args[i] = arg;
773 }
774 break;
775 case isl_ast_expr_error:
776 expr = isl_ast_expr_free(expr);
777 break;
778 }
779
780 isl_id_to_ast_expr_free(id2expr);
781 return expr;
782error:
783 isl_ast_expr_free(expr);
784 isl_id_to_ast_expr_free(id2expr);
785 return NULL((void*)0);
786}
787
788isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node)
789{
790 return node ? node->ctx : NULL((void*)0);
791}
792
793enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node)
794{
795 return node ? node->type : isl_ast_node_error;
796}
797
798__isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx,
799 enum isl_ast_node_type type)
800{
801 isl_ast_node *node;
802
803 node = isl_calloc_type(ctx, isl_ast_node)((isl_ast_node *)isl_calloc_or_die(ctx, 1, sizeof(isl_ast_node
)))
;
804 if (!node)
805 return NULL((void*)0);
806
807 node->ctx = ctx;
808 isl_ctx_ref(ctx);
809 node->ref = 1;
810 node->type = type;
811
812 return node;
813}
814
815/* Create an if node with the given guard.
816 *
817 * The then body needs to be filled in later.
818 */
819__isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard)
820{
821 isl_ast_node *node;
822
823 if (!guard)
824 return NULL((void*)0);
825
826 node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if);
827 if (!node)
828 goto error;
829 node->u.i.guard = guard;
830
831 return node;
832error:
833 isl_ast_expr_free(guard);
834 return NULL((void*)0);
835}
836
837/* Create a for node with the given iterator.
838 *
839 * The remaining fields need to be filled in later.
840 */
841__isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id)
842{
843 isl_ast_node *node;
844 isl_ctx *ctx;
845
846 if (!id)
847 return NULL((void*)0);
848
849 ctx = isl_id_get_ctx(id);
850 node = isl_ast_node_alloc(ctx, isl_ast_node_for);
851 if (!node)
852 goto error;
853
854 node->u.f.iterator = isl_ast_expr_from_id(id);
855 if (!node->u.f.iterator)
856 return isl_ast_node_free(node);
857
858 return node;
859error:
860 isl_id_free(id);
861 return NULL((void*)0);
862}
863
864/* Create a mark node, marking "node" with "id".
865 */
866__isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id,
867 __isl_take isl_ast_node *node)
868{
869 isl_ctx *ctx;
870 isl_ast_node *mark;
871
872 if (!id || !node)
873 goto error;
874
875 ctx = isl_id_get_ctx(id);
876 mark = isl_ast_node_alloc(ctx, isl_ast_node_mark);
877 if (!mark)
878 goto error;
879
880 mark->u.m.mark = id;
881 mark->u.m.node = node;
882
883 return mark;
884error:
885 isl_id_free(id);
886 isl_ast_node_free(node);
887 return NULL((void*)0);
888}
889
890/* Create a user node evaluating "expr".
891 */
892__isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
893{
894 isl_ctx *ctx;
895 isl_ast_node *node;
896
897 if (!expr)
898 return NULL((void*)0);
899
900 ctx = isl_ast_expr_get_ctx(expr);
901 node = isl_ast_node_alloc(ctx, isl_ast_node_user);
902 if (!node)
903 goto error;
904
905 node->u.e.expr = expr;
906
907 return node;
908error:
909 isl_ast_expr_free(expr);
910 return NULL((void*)0);
911}
912
913/* Create a block node with the given children.
914 */
915__isl_give isl_ast_node *isl_ast_node_alloc_block(
916 __isl_take isl_ast_node_list *list)
917{
918 isl_ast_node *node;
919 isl_ctx *ctx;
920
921 if (!list)
922 return NULL((void*)0);
923
924 ctx = isl_ast_node_list_get_ctx(list);
925 node = isl_ast_node_alloc(ctx, isl_ast_node_block);
926 if (!node)
927 goto error;
928
929 node->u.b.children = list;
930
931 return node;
932error:
933 isl_ast_node_list_free(list);
934 return NULL((void*)0);
935}
936
937/* Represent the given list of nodes as a single node, either by
938 * extract the node from a single element list or by creating
939 * a block node with the list of nodes as children.
940 */
941__isl_give isl_ast_node *isl_ast_node_from_ast_node_list(
942 __isl_take isl_ast_node_list *list)
943{
944 isl_ast_node *node;
945
946 if (isl_ast_node_list_n_ast_node(list) != 1)
947 return isl_ast_node_alloc_block(list);
948
949 node = isl_ast_node_list_get_ast_node(list, 0);
950 isl_ast_node_list_free(list);
951
952 return node;
953}
954
955__isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node)
956{
957 if (!node)
958 return NULL((void*)0);
959
960 node->ref++;
961 return node;
962}
963
964__isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node)
965{
966 isl_ast_node *dup;
967
968 if (!node)
969 return NULL((void*)0);
970
971 dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type);
972 if (!dup)
973 return NULL((void*)0);
974
975 switch (node->type) {
976 case isl_ast_node_if:
977 dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard);
978 dup->u.i.then = isl_ast_node_copy(node->u.i.then);
979 dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node);
980 if (!dup->u.i.guard || !dup->u.i.then ||
981 (node->u.i.else_node && !dup->u.i.else_node))
982 return isl_ast_node_free(dup);
983 break;
984 case isl_ast_node_for:
985 dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator);
986 dup->u.f.init = isl_ast_expr_copy(node->u.f.init);
987 dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond);
988 dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc);
989 dup->u.f.body = isl_ast_node_copy(node->u.f.body);
990 if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.cond ||
991 !dup->u.f.inc || !dup->u.f.body)
992 return isl_ast_node_free(dup);
993 break;
994 case isl_ast_node_block:
995 dup->u.b.children = isl_ast_node_list_copy(node->u.b.children);
996 if (!dup->u.b.children)
997 return isl_ast_node_free(dup);
998 break;
999 case isl_ast_node_mark:
1000 dup->u.m.mark = isl_id_copy(node->u.m.mark);
1001 dup->u.m.node = isl_ast_node_copy(node->u.m.node);
1002 if (!dup->u.m.mark || !dup->u.m.node)
1003 return isl_ast_node_free(dup);
1004 break;
1005 case isl_ast_node_user:
1006 dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr);
1007 if (!dup->u.e.expr)
1008 return isl_ast_node_free(dup);
1009 break;
1010 case isl_ast_node_error:
1011 break;
1012 }
1013
1014 return dup;
1015}
1016
1017__isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node)
1018{
1019 if (!node)
1020 return NULL((void*)0);
1021
1022 if (node->ref == 1)
1023 return node;
1024 node->ref--;
1025 return isl_ast_node_dup(node);
1026}
1027
1028__isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node)
1029{
1030 if (!node)
1031 return NULL((void*)0);
1032
1033 if (--node->ref > 0)
1034 return NULL((void*)0);
1035
1036 switch (node->type) {
1037 case isl_ast_node_if:
1038 isl_ast_expr_free(node->u.i.guard);
1039 isl_ast_node_free(node->u.i.then);
1040 isl_ast_node_free(node->u.i.else_node);
1041 break;
1042 case isl_ast_node_for:
1043 isl_ast_expr_free(node->u.f.iterator);
1044 isl_ast_expr_free(node->u.f.init);
1045 isl_ast_expr_free(node->u.f.cond);
1046 isl_ast_expr_free(node->u.f.inc);
1047 isl_ast_node_free(node->u.f.body);
1048 break;
1049 case isl_ast_node_block:
1050 isl_ast_node_list_free(node->u.b.children);
1051 break;
1052 case isl_ast_node_mark:
1053 isl_id_free(node->u.m.mark);
1054 isl_ast_node_free(node->u.m.node);
1055 break;
1056 case isl_ast_node_user:
1057 isl_ast_expr_free(node->u.e.expr);
1058 break;
1059 case isl_ast_node_error:
1060 break;
1061 }
1062
1063 isl_id_free(node->annotation);
1064 isl_ctx_deref(node->ctx);
1065 free(node);
1066
1067 return NULL((void*)0);
1068}
1069
1070/* Replace the body of the for node "node" by "body".
1071 */
1072__isl_give isl_ast_node *isl_ast_node_for_set_body(
1073 __isl_take isl_ast_node *node, __isl_take isl_ast_node *body)
1074{
1075 node = isl_ast_node_cow(node);
1076 if (!node || !body)
1077 goto error;
1078 if (node->type != isl_ast_node_for)
1079 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1080); goto error; } while (0)
1080 "not a for node", goto error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1080); goto error; } while (0)
;
1081
1082 isl_ast_node_free(node->u.f.body);
1083 node->u.f.body = body;
1084
1085 return node;
1086error:
1087 isl_ast_node_free(node);
1088 isl_ast_node_free(body);
1089 return NULL((void*)0);
1090}
1091
1092__isl_give isl_ast_node *isl_ast_node_for_get_body(
1093 __isl_keep isl_ast_node *node)
1094{
1095 if (!node)
1096 return NULL((void*)0);
1097 if (node->type != isl_ast_node_for)
1098 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1099); return ((void*)0); } while (0)
1099 "not a for node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1099); return ((void*)0); } while (0)
;
1100 return isl_ast_node_copy(node->u.f.body);
1101}
1102
1103/* Mark the given for node as being degenerate.
1104 */
1105__isl_give isl_ast_node *isl_ast_node_for_mark_degenerate(
1106 __isl_take isl_ast_node *node)
1107{
1108 node = isl_ast_node_cow(node);
1109 if (!node)
1110 return NULL((void*)0);
1111 node->u.f.degenerate = 1;
1112 return node;
1113}
1114
1115isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node)
1116{
1117 if (!node)
1118 return isl_bool_error;
1119 if (node->type != isl_ast_node_for)
1120 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1121); return isl_bool_error; } while (0)
1121 "not a for node", return isl_bool_error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1121); return isl_bool_error; } while (0)
;
1122 return node->u.f.degenerate;
1123}
1124
1125__isl_give isl_ast_expr *isl_ast_node_for_get_iterator(
1126 __isl_keep isl_ast_node *node)
1127{
1128 if (!node)
1129 return NULL((void*)0);
1130 if (node->type != isl_ast_node_for)
1131 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1132); return ((void*)0); } while (0)
1132 "not a for node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1132); return ((void*)0); } while (0)
;
1133 return isl_ast_expr_copy(node->u.f.iterator);
1134}
1135
1136__isl_give isl_ast_expr *isl_ast_node_for_get_init(
1137 __isl_keep isl_ast_node *node)
1138{
1139 if (!node)
1140 return NULL((void*)0);
1141 if (node->type != isl_ast_node_for)
1142 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1143); return ((void*)0); } while (0)
1143 "not a for node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1143); return ((void*)0); } while (0)
;
1144 return isl_ast_expr_copy(node->u.f.init);
1145}
1146
1147/* Return the condition expression of the given for node.
1148 *
1149 * If the for node is degenerate, then the condition is not explicitly
1150 * stored in the node. Instead, it is constructed as
1151 *
1152 * iterator <= init
1153 */
1154__isl_give isl_ast_expr *isl_ast_node_for_get_cond(
1155 __isl_keep isl_ast_node *node)
1156{
1157 if (!node)
1158 return NULL((void*)0);
1159 if (node->type != isl_ast_node_for)
1160 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1161); return ((void*)0); } while (0)
1161 "not a for node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1161); return ((void*)0); } while (0)
;
1162 if (!node->u.f.degenerate)
1163 return isl_ast_expr_copy(node->u.f.cond);
1164
1165 return isl_ast_expr_alloc_binary(isl_ast_op_le,
1166 isl_ast_expr_copy(node->u.f.iterator),
1167 isl_ast_expr_copy(node->u.f.init));
1168}
1169
1170/* Return the increment of the given for node.
1171 *
1172 * If the for node is degenerate, then the increment is not explicitly
1173 * stored in the node. We simply return "1".
1174 */
1175__isl_give isl_ast_expr *isl_ast_node_for_get_inc(
1176 __isl_keep isl_ast_node *node)
1177{
1178 if (!node)
1179 return NULL((void*)0);
1180 if (node->type != isl_ast_node_for)
1181 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1182); return ((void*)0); } while (0)
1182 "not a for node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1182); return ((void*)0); } while (0)
;
1183 if (!node->u.f.degenerate)
1184 return isl_ast_expr_copy(node->u.f.inc);
1185 return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1);
1186}
1187
1188/* Replace the then branch of the if node "node" by "child".
1189 */
1190__isl_give isl_ast_node *isl_ast_node_if_set_then(
1191 __isl_take isl_ast_node *node, __isl_take isl_ast_node *child)
1192{
1193 node = isl_ast_node_cow(node);
1194 if (!node || !child)
1195 goto error;
1196 if (node->type != isl_ast_node_if)
1197 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1198); goto error; } while (0)
1198 "not an if node", goto error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1198); goto error; } while (0)
;
1199
1200 isl_ast_node_free(node->u.i.then);
1201 node->u.i.then = child;
1202
1203 return node;
1204error:
1205 isl_ast_node_free(node);
1206 isl_ast_node_free(child);
1207 return NULL((void*)0);
1208}
1209
1210__isl_give isl_ast_node *isl_ast_node_if_get_then(
1211 __isl_keep isl_ast_node *node)
1212{
1213 if (!node)
1214 return NULL((void*)0);
1215 if (node->type != isl_ast_node_if)
1216 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1217); return ((void*)0); } while (0)
1217 "not an if node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1217); return ((void*)0); } while (0)
;
1218 return isl_ast_node_copy(node->u.i.then);
1219}
1220
1221isl_bool isl_ast_node_if_has_else(
1222 __isl_keep isl_ast_node *node)
1223{
1224 if (!node)
1225 return isl_bool_error;
1226 if (node->type != isl_ast_node_if)
1227 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1228); return isl_bool_error; } while (0)
1228 "not an if node", return isl_bool_error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1228); return isl_bool_error; } while (0)
;
1229 return node->u.i.else_node != NULL((void*)0);
1230}
1231
1232__isl_give isl_ast_node *isl_ast_node_if_get_else(
1233 __isl_keep isl_ast_node *node)
1234{
1235 if (!node)
1236 return NULL((void*)0);
1237 if (node->type != isl_ast_node_if)
1238 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1239); return ((void*)0); } while (0)
1239 "not an if node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1239); return ((void*)0); } while (0)
;
1240 return isl_ast_node_copy(node->u.i.else_node);
1241}
1242
1243__isl_give isl_ast_expr *isl_ast_node_if_get_cond(
1244 __isl_keep isl_ast_node *node)
1245{
1246 if (!node)
1247 return NULL((void*)0);
1248 if (node->type != isl_ast_node_if)
1249 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a guard node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1250); return ((void*)0); } while (0)
1250 "not a guard node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a guard node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1250); return ((void*)0); } while (0)
;
1251 return isl_ast_expr_copy(node->u.i.guard);
1252}
1253
1254__isl_give isl_ast_node_list *isl_ast_node_block_get_children(
1255 __isl_keep isl_ast_node *node)
1256{
1257 if (!node)
1258 return NULL((void*)0);
1259 if (node->type != isl_ast_node_block)
1260 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a block node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1261); return ((void*)0); } while (0)
1261 "not a block node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a block node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1261); return ((void*)0); } while (0)
;
1262 return isl_ast_node_list_copy(node->u.b.children);
1263}
1264
1265__isl_give isl_ast_expr *isl_ast_node_user_get_expr(
1266 __isl_keep isl_ast_node *node)
1267{
1268 if (!node)
1269 return NULL((void*)0);
1270 if (node->type != isl_ast_node_user)
1271 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a user node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1272); return ((void*)0); } while (0)
1272 "not a user node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a user node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1272); return ((void*)0); } while (0)
;
1273
1274 return isl_ast_expr_copy(node->u.e.expr);
1275}
1276
1277/* Return the mark identifier of the mark node "node".
1278 */
1279__isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node)
1280{
1281 if (!node)
1282 return NULL((void*)0);
1283 if (node->type != isl_ast_node_mark)
1284 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1285); return ((void*)0); } while (0)
1285 "not a mark node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1285); return ((void*)0); } while (0)
;
1286
1287 return isl_id_copy(node->u.m.mark);
1288}
1289
1290/* Return the node marked by mark node "node".
1291 */
1292__isl_give isl_ast_node *isl_ast_node_mark_get_node(
1293 __isl_keep isl_ast_node *node)
1294{
1295 if (!node)
1296 return NULL((void*)0);
1297 if (node->type != isl_ast_node_mark)
1298 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1299); return ((void*)0); } while (0)
1299 "not a mark node", return NULL)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1299); return ((void*)0); } while (0)
;
1300
1301 return isl_ast_node_copy(node->u.m.node);
1302}
1303
1304__isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node)
1305{
1306 return node ? isl_id_copy(node->annotation) : NULL((void*)0);
1307}
1308
1309/* Replace node->annotation by "annotation".
1310 */
1311__isl_give isl_ast_node *isl_ast_node_set_annotation(
1312 __isl_take isl_ast_node *node, __isl_take isl_id *annotation)
1313{
1314 node = isl_ast_node_cow(node);
1315 if (!node || !annotation)
1316 goto error;
1317
1318 isl_id_free(node->annotation);
1319 node->annotation = annotation;
1320
1321 return node;
1322error:
1323 isl_id_free(annotation);
1324 return isl_ast_node_free(node);
1325}
1326
1327/* Traverse the elements of "list" and all their descendants
1328 * in depth first preorder.
1329 *
1330 * Return isl_stat_ok on success and isl_stat_error on failure.
1331 */
1332static isl_stat nodelist_foreach(__isl_keep isl_ast_node_list *list,
1333 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1334{
1335 int i;
1336
1337 if (!list)
1338 return isl_stat_error;
1339
1340 for (i = 0; i < list->n; ++i) {
1341 isl_stat ok;
1342 isl_ast_node *node = list->p[i];
1343
1344 ok = isl_ast_node_foreach_descendant_top_down(node, fn, user);
1345 if (ok < 0)
1346 return isl_stat_error;
1347 }
1348
1349 return isl_stat_ok;
1350}
1351
1352/* Traverse the descendants of "node" (including the node itself)
1353 * in depth first preorder.
1354 *
1355 * If "fn" returns isl_bool_error on any of the nodes, then the traversal
1356 * is aborted.
1357 * If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
1358 * at that node is skipped.
1359 *
1360 * Return isl_stat_ok on success and isl_stat_error on failure.
1361 */
1362isl_stat isl_ast_node_foreach_descendant_top_down(
1363 __isl_keep isl_ast_node *node,
1364 isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user)
1365{
1366 isl_bool more;
1367 isl_stat ok;
1368
1369 if (!node)
1370 return isl_stat_error;
1371
1372 more = fn(node, user);
1373 if (more < 0)
1374 return isl_stat_error;
1375 if (!more)
1376 return isl_stat_ok;
1377
1378 switch (node->type) {
1379 case isl_ast_node_for:
1380 node = node->u.f.body;
1381 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1382 case isl_ast_node_if:
1383 ok = isl_ast_node_foreach_descendant_top_down(node->u.i.then,
1384 fn, user);
1385 if (ok < 0)
1386 return isl_stat_error;
1387 if (!node->u.i.else_node)
1388 return isl_stat_ok;
1389 node = node->u.i.else_node;
1390 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1391 case isl_ast_node_block:
1392 return nodelist_foreach(node->u.b.children, fn, user);
1393 case isl_ast_node_mark:
1394 node = node->u.m.node;
1395 return isl_ast_node_foreach_descendant_top_down(node, fn, user);
1396 case isl_ast_node_user:
1397 break;
1398 case isl_ast_node_error:
1399 return isl_stat_error;
1400 }
1401
1402 return isl_stat_ok;
1403}
1404
1405/* Textual C representation of the various operators.
1406 */
1407static char *op_str_c[] = {
1408 [isl_ast_op_and] = "&&",
1409 [isl_ast_op_and_then] = "&&",
1410 [isl_ast_op_or] = "||",
1411 [isl_ast_op_or_else] = "||",
1412 [isl_ast_op_max] = "max",
1413 [isl_ast_op_min] = "min",
1414 [isl_ast_op_minus] = "-",
1415 [isl_ast_op_add] = "+",
1416 [isl_ast_op_sub] = "-",
1417 [isl_ast_op_mul] = "*",
1418 [isl_ast_op_fdiv_q] = "floord",
1419 [isl_ast_op_pdiv_q] = "/",
1420 [isl_ast_op_pdiv_r] = "%",
1421 [isl_ast_op_zdiv_r] = "%",
1422 [isl_ast_op_div] = "/",
1423 [isl_ast_op_eq] = "==",
1424 [isl_ast_op_le] = "<=",
1425 [isl_ast_op_ge] = ">=",
1426 [isl_ast_op_lt] = "<",
1427 [isl_ast_op_gt] = ">",
1428 [isl_ast_op_member] = ".",
1429 [isl_ast_op_address_of] = "&"
1430};
1431
1432/* Precedence in C of the various operators.
1433 * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++
1434 * Lowest value means highest precedence.
1435 */
1436static int op_prec[] = {
1437 [isl_ast_op_and] = 13,
1438 [isl_ast_op_and_then] = 13,
1439 [isl_ast_op_or] = 14,
1440 [isl_ast_op_or_else] = 14,
1441 [isl_ast_op_max] = 2,
1442 [isl_ast_op_min] = 2,
1443 [isl_ast_op_minus] = 3,
1444 [isl_ast_op_add] = 6,
1445 [isl_ast_op_sub] = 6,
1446 [isl_ast_op_mul] = 5,
1447 [isl_ast_op_div] = 5,
1448 [isl_ast_op_fdiv_q] = 2,
1449 [isl_ast_op_pdiv_q] = 5,
1450 [isl_ast_op_pdiv_r] = 5,
1451 [isl_ast_op_zdiv_r] = 5,
1452 [isl_ast_op_cond] = 15,
1453 [isl_ast_op_select] = 15,
1454 [isl_ast_op_eq] = 9,
1455 [isl_ast_op_le] = 8,
1456 [isl_ast_op_ge] = 8,
1457 [isl_ast_op_lt] = 8,
1458 [isl_ast_op_gt] = 8,
1459 [isl_ast_op_call] = 2,
1460 [isl_ast_op_access] = 2,
1461 [isl_ast_op_member] = 2,
1462 [isl_ast_op_address_of] = 3
1463};
1464
1465/* Is the operator left-to-right associative?
1466 */
1467static int op_left[] = {
1468 [isl_ast_op_and] = 1,
1469 [isl_ast_op_and_then] = 1,
1470 [isl_ast_op_or] = 1,
1471 [isl_ast_op_or_else] = 1,
1472 [isl_ast_op_max] = 1,
1473 [isl_ast_op_min] = 1,
1474 [isl_ast_op_minus] = 0,
1475 [isl_ast_op_add] = 1,
1476 [isl_ast_op_sub] = 1,
1477 [isl_ast_op_mul] = 1,
1478 [isl_ast_op_div] = 1,
1479 [isl_ast_op_fdiv_q] = 1,
1480 [isl_ast_op_pdiv_q] = 1,
1481 [isl_ast_op_pdiv_r] = 1,
1482 [isl_ast_op_zdiv_r] = 1,
1483 [isl_ast_op_cond] = 0,
1484 [isl_ast_op_select] = 0,
1485 [isl_ast_op_eq] = 1,
1486 [isl_ast_op_le] = 1,
1487 [isl_ast_op_ge] = 1,
1488 [isl_ast_op_lt] = 1,
1489 [isl_ast_op_gt] = 1,
1490 [isl_ast_op_call] = 1,
1491 [isl_ast_op_access] = 1,
1492 [isl_ast_op_member] = 1,
1493 [isl_ast_op_address_of] = 0
1494};
1495
1496static int is_and(enum isl_ast_op_type op)
1497{
1498 return op == isl_ast_op_and || op == isl_ast_op_and_then;
1499}
1500
1501static int is_or(enum isl_ast_op_type op)
1502{
1503 return op == isl_ast_op_or || op == isl_ast_op_or_else;
1504}
1505
1506static int is_add_sub(enum isl_ast_op_type op)
1507{
1508 return op == isl_ast_op_add || op == isl_ast_op_sub;
1509}
1510
1511static int is_div_mod(enum isl_ast_op_type op)
1512{
1513 return op == isl_ast_op_div ||
1514 op == isl_ast_op_pdiv_r ||
1515 op == isl_ast_op_zdiv_r;
1516}
1517
1518static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
1519 __isl_keep isl_ast_expr *expr);
1520
1521/* Do we need/want parentheses around "expr" as a subexpression of
1522 * an "op" operation? If "left" is set, then "expr" is the left-most
1523 * operand.
1524 *
1525 * We only need parentheses if "expr" represents an operation.
1526 *
1527 * If op has a higher precedence than expr->u.op.op, then we need
1528 * parentheses.
1529 * If op and expr->u.op.op have the same precedence, but the operations
1530 * are performed in an order that is different from the associativity,
1531 * then we need parentheses.
1532 *
1533 * An and inside an or technically does not require parentheses,
1534 * but some compilers complain about that, so we add them anyway.
1535 *
1536 * Computations such as "a / b * c" and "a % b + c" can be somewhat
1537 * difficult to read, so we add parentheses for those as well.
1538 */
1539static int sub_expr_need_parens(enum isl_ast_op_type op,
1540 __isl_keep isl_ast_expr *expr, int left)
1541{
1542 if (expr->type != isl_ast_expr_op)
1543 return 0;
1544
1545 if (op_prec[expr->u.op.op] > op_prec[op])
1546 return 1;
1547 if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op])
1548 return 1;
1549
1550 if (is_or(op) && is_and(expr->u.op.op))
1551 return 1;
1552 if (op == isl_ast_op_mul && expr->u.op.op != isl_ast_op_mul &&
1553 op_prec[expr->u.op.op] == op_prec[op])
1554 return 1;
1555 if (is_add_sub(op) && is_div_mod(expr->u.op.op))
1556 return 1;
1557
1558 return 0;
1559}
1560
1561/* Print "expr" as a subexpression of an "op" operation in C format.
1562 * If "left" is set, then "expr" is the left-most operand.
1563 */
1564static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p,
1565 enum isl_ast_op_type op, __isl_keep isl_ast_expr *expr, int left)
1566{
1567 int need_parens;
1568
1569 need_parens = sub_expr_need_parens(op, expr, left);
1570
1571 if (need_parens)
1572 p = isl_printer_print_str(p, "(");
1573 p = print_ast_expr_c(p, expr);
1574 if (need_parens)
1575 p = isl_printer_print_str(p, ")");
1576 return p;
1577}
1578
1579#define isl_ast_op_lastisl_ast_op_address_of isl_ast_op_address_of
1580
1581/* Data structure that holds the user-specified textual
1582 * representations for the operators in C format.
1583 * The entries are either NULL or copies of strings.
1584 * A NULL entry means that the default name should be used.
1585 */
1586struct isl_ast_op_names {
1587 char *op_str[isl_ast_op_lastisl_ast_op_address_of + 1];
1588};
1589
1590/* Create an empty struct isl_ast_op_names.
1591 */
1592static void *create_names(isl_ctx *ctx)
1593{
1594 return isl_calloc_type(ctx, struct isl_ast_op_names)((struct isl_ast_op_names *)isl_calloc_or_die(ctx, 1, sizeof(
struct isl_ast_op_names)))
;
1595}
1596
1597/* Free a struct isl_ast_op_names along with all memory
1598 * owned by the struct.
1599 */
1600static void free_names(void *user)
1601{
1602 int i;
1603 struct isl_ast_op_names *names = user;
1604
1605 if (!user)
1606 return;
1607
1608 for (i = 0; i <= isl_ast_op_lastisl_ast_op_address_of; ++i)
1609 free(names->op_str[i]);
1610 free(user);
1611}
1612
1613/* Create an identifier that is used to store
1614 * an isl_ast_op_names note.
1615 */
1616static __isl_give isl_id *names_id(isl_ctx *ctx)
1617{
1618 return isl_id_alloc(ctx, "isl_ast_op_type_names", NULL((void*)0));
1619}
1620
1621/* Ensure that "p" has a note identified by "id".
1622 * If there is no such note yet, then it is created by "note_create" and
1623 * scheduled do be freed by "note_free".
1624 */
1625static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p,
1626 __isl_keep isl_id *id, void *(*note_create)(isl_ctx *),
1627 void (*note_free)(void *))
1628{
1629 isl_ctx *ctx;
1630 isl_id *note_id;
1631 isl_bool has_note;
1632 void *note;
1633
1634 has_note = isl_printer_has_note(p, id);
1635 if (has_note < 0)
1636 return isl_printer_free(p);
1637 if (has_note)
1638 return p;
1639
1640 ctx = isl_printer_get_ctx(p);
1641 note = note_create(ctx);
1642 if (!note)
1643 return isl_printer_free(p);
1644 note_id = isl_id_alloc(ctx, NULL((void*)0), note);
1645 if (!note_id)
1646 note_free(note);
1647 else
1648 note_id = isl_id_set_free_user(note_id, note_free);
1649
1650 p = isl_printer_set_note(p, isl_id_copy(id), note_id);
1651
1652 return p;
1653}
1654
1655/* Ensure that "p" has an isl_ast_op_names note identified by "id".
1656 */
1657static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p,
1658 __isl_keep isl_id *id)
1659{
1660 return alloc_note(p, id, &create_names, &free_names);
1661}
1662
1663/* Retrieve the note identified by "id" from "p".
1664 * The note is assumed to exist.
1665 */
1666static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id)
1667{
1668 void *note;
1669
1670 id = isl_printer_get_note(p, isl_id_copy(id));
1671 note = isl_id_get_user(id);
1672 isl_id_free(id);
1673
1674 return note;
1675}
1676
1677/* Use "name" to print operations of type "type" to "p".
1678 *
1679 * Store the name in an isl_ast_op_names note attached to "p", such that
1680 * it can be retrieved by get_op_str.
1681 */
1682__isl_give isl_printer *isl_ast_op_type_set_print_name(
1683 __isl_take isl_printer *p, enum isl_ast_op_type type,
1684 __isl_keep const char *name)
1685{
1686 isl_id *id;
1687 struct isl_ast_op_names *names;
1688
1689 if (!p)
1690 return NULL((void*)0);
1691 if (type > isl_ast_op_lastisl_ast_op_address_of)
1692 isl_die(isl_printer_get_ctx(p), isl_error_invalid,do { isl_handle_error(isl_printer_get_ctx(p), isl_error_invalid
, "invalid type", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1693); return isl_printer_free(p); } while (0)
1693 "invalid type", return isl_printer_free(p))do { isl_handle_error(isl_printer_get_ctx(p), isl_error_invalid
, "invalid type", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1693); return isl_printer_free(p); } while (0)
;
1694
1695 id = names_id(isl_printer_get_ctx(p));
1696 p = alloc_names(p, id);
1697 names = get_note(p, id);
1698 isl_id_free(id);
1699 if (!names)
1700 return isl_printer_free(p);
1701 free(names->op_str[type]);
1702 names->op_str[type] = strdup(name);
1703
1704 return p;
1705}
1706
1707/* Return the textual representation of "type" in C format.
1708 *
1709 * If there is a user-specified name in an isl_ast_op_names note
1710 * associated to "p", then return that.
1711 * Otherwise, return the default name in op_str.
1712 */
1713static const char *get_op_str_c(__isl_keep isl_printer *p,
1714 enum isl_ast_op_type type)
1715{
1716 isl_id *id;
1717 isl_bool has_names;
1718 struct isl_ast_op_names *names = NULL((void*)0);
1719
1720 id = names_id(isl_printer_get_ctx(p));
1721 has_names = isl_printer_has_note(p, id);
1722 if (has_names >= 0 && has_names)
1723 names = get_note(p, id);
1724 isl_id_free(id);
1725 if (names && names->op_str[type])
1726 return names->op_str[type];
1727 return op_str_c[type];
1728}
1729
1730/* Print a min or max reduction "expr" in C format.
1731 */
1732static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p,
1733 __isl_keep isl_ast_expr *expr)
1734{
1735 int i = 0;
1736
1737 for (i = 1; i < expr->u.op.n_arg; ++i) {
1738 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
1739 p = isl_printer_print_str(p, "(");
1740 }
1741 p = isl_printer_print_ast_expr(p, expr->u.op.args[0]);
1742 for (i = 1; i < expr->u.op.n_arg; ++i) {
1743 p = isl_printer_print_str(p, ", ");
1744 p = print_ast_expr_c(p, expr->u.op.args[i]);
1745 p = isl_printer_print_str(p, ")");
1746 }
1747
1748 return p;
1749}
1750
1751/* Print a function call "expr" in C format.
1752 *
1753 * The first argument represents the function to be called.
1754 */
1755static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p,
1756 __isl_keep isl_ast_expr *expr)
1757{
1758 int i = 0;
1759
1760 p = print_ast_expr_c(p, expr->u.op.args[0]);
1761 p = isl_printer_print_str(p, "(");
1762 for (i = 1; i < expr->u.op.n_arg; ++i) {
1763 if (i != 1)
1764 p = isl_printer_print_str(p, ", ");
1765 p = print_ast_expr_c(p, expr->u.op.args[i]);
1766 }
1767 p = isl_printer_print_str(p, ")");
1768
1769 return p;
1770}
1771
1772/* Print an array access "expr" in C format.
1773 *
1774 * The first argument represents the array being accessed.
1775 */
1776static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p,
1777 __isl_keep isl_ast_expr *expr)
1778{
1779 int i = 0;
1780
1781 p = print_ast_expr_c(p, expr->u.op.args[0]);
1782 for (i = 1; i < expr->u.op.n_arg; ++i) {
1783 p = isl_printer_print_str(p, "[");
1784 p = print_ast_expr_c(p, expr->u.op.args[i]);
1785 p = isl_printer_print_str(p, "]");
1786 }
1787
1788 return p;
1789}
1790
1791/* Print "expr" to "p" in C format.
1792 */
1793static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p,
1794 __isl_keep isl_ast_expr *expr)
1795{
1796 if (!p)
1797 return NULL((void*)0);
1798 if (!expr)
1799 return isl_printer_free(p);
1800
1801 switch (expr->type) {
1802 case isl_ast_expr_op:
1803 if (expr->u.op.op == isl_ast_op_call) {
1804 p = print_call_c(p, expr);
1805 break;
1806 }
1807 if (expr->u.op.op == isl_ast_op_access) {
1808 p = print_access_c(p, expr);
1809 break;
1810 }
1811 if (expr->u.op.n_arg == 1) {
1812 p = isl_printer_print_str(p,
1813 get_op_str_c(p, expr->u.op.op));
1814 p = print_sub_expr_c(p, expr->u.op.op,
1815 expr->u.op.args[0], 0);
1816 break;
1817 }
1818 if (expr->u.op.op == isl_ast_op_fdiv_q) {
1819 const char *name = get_op_str_c(p, isl_ast_op_fdiv_q);
1820 p = isl_printer_print_str(p, name);
1821 p = isl_printer_print_str(p, "(");
1822 p = print_ast_expr_c(p, expr->u.op.args[0]);
1823 p = isl_printer_print_str(p, ", ");
1824 p = print_ast_expr_c(p, expr->u.op.args[1]);
1825 p = isl_printer_print_str(p, ")");
1826 break;
1827 }
1828 if (expr->u.op.op == isl_ast_op_max ||
1829 expr->u.op.op == isl_ast_op_min) {
1830 p = print_min_max_c(p, expr);
1831 break;
1832 }
1833 if (expr->u.op.op == isl_ast_op_cond ||
1834 expr->u.op.op == isl_ast_op_select) {
1835 p = print_ast_expr_c(p, expr->u.op.args[0]);
1836 p = isl_printer_print_str(p, " ? ");
1837 p = print_ast_expr_c(p, expr->u.op.args[1]);
1838 p = isl_printer_print_str(p, " : ");
1839 p = print_ast_expr_c(p, expr->u.op.args[2]);
1840 break;
1841 }
1842 if (expr->u.op.n_arg != 2)
1843 isl_die(isl_printer_get_ctx(p), isl_error_internal,do { isl_handle_error(isl_printer_get_ctx(p), isl_error_internal
, "operation should have two arguments", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1845); return isl_printer_free(p); } while (0)
1844 "operation should have two arguments",do { isl_handle_error(isl_printer_get_ctx(p), isl_error_internal
, "operation should have two arguments", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1845); return isl_printer_free(p); } while (0)
1845 return isl_printer_free(p))do { isl_handle_error(isl_printer_get_ctx(p), isl_error_internal
, "operation should have two arguments", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 1845); return isl_printer_free(p); } while (0)
;
1846 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[0], 1);
1847 if (expr->u.op.op != isl_ast_op_member)
1848 p = isl_printer_print_str(p, " ");
1849 p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op));
1850 if (expr->u.op.op != isl_ast_op_member)
1851 p = isl_printer_print_str(p, " ");
1852 p = print_sub_expr_c(p, expr->u.op.op, expr->u.op.args[1], 0);
1853 break;
1854 case isl_ast_expr_id:
1855 p = isl_printer_print_str(p, isl_id_get_name(expr->u.id));
1856 break;
1857 case isl_ast_expr_int:
1858 p = isl_printer_print_val(p, expr->u.v);
1859 break;
1860 case isl_ast_expr_error:
1861 break;
1862 }
1863
1864 return p;
1865}
1866
1867/* Textual representation of the isl_ast_op_type elements
1868 * for use in a YAML representation of an isl_ast_expr.
1869 */
1870static char *op_str[] = {
1871 [isl_ast_op_and] = "and",
1872 [isl_ast_op_and_then] = "and_then",
1873 [isl_ast_op_or] = "or",
1874 [isl_ast_op_or_else] = "or_else",
1875 [isl_ast_op_max] = "max",
1876 [isl_ast_op_min] = "min",
1877 [isl_ast_op_minus] = "minus",
1878 [isl_ast_op_add] = "add",
1879 [isl_ast_op_sub] = "sub",
1880 [isl_ast_op_mul] = "mul",
1881 [isl_ast_op_div] = "div",
1882 [isl_ast_op_fdiv_q] = "fdiv_q",
1883 [isl_ast_op_pdiv_q] = "pdiv_q",
1884 [isl_ast_op_pdiv_r] = "pdiv_r",
1885 [isl_ast_op_zdiv_r] = "zdiv_r",
1886 [isl_ast_op_cond] = "cond",
1887 [isl_ast_op_select] = "select",
1888 [isl_ast_op_eq] = "eq",
1889 [isl_ast_op_le] = "le",
1890 [isl_ast_op_lt] = "lt",
1891 [isl_ast_op_ge] = "ge",
1892 [isl_ast_op_gt] = "gt",
1893 [isl_ast_op_call] = "call",
1894 [isl_ast_op_access] = "access",
1895 [isl_ast_op_member] = "member",
1896 [isl_ast_op_address_of] = "address_of"
1897};
1898
1899static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
1900 __isl_keep isl_ast_expr *expr);
1901
1902/* Print the arguments of "expr" to "p" in isl format.
1903 *
1904 * If there are no arguments, then nothing needs to be printed.
1905 * Otherwise add an "args" key to the current mapping with as value
1906 * the list of arguments of "expr".
1907 */
1908static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p,
1909 __isl_keep isl_ast_expr *expr)
1910{
1911 int i, n;
1912
1913 n = isl_ast_expr_get_op_n_arg(expr);
1914 if (n < 0)
1915 return isl_printer_free(p);
1916 if (n == 0)
1917 return p;
1918
1919 p = isl_printer_print_str(p, "args");
1920 p = isl_printer_yaml_next(p);
1921 p = isl_printer_yaml_start_sequence(p);
1922 for (i = 0; i < n; ++i) {
1923 isl_ast_expr *arg;
1924
1925 arg = isl_ast_expr_get_op_arg(expr, i);
1926 p = print_ast_expr_isl(p, arg);
1927 isl_ast_expr_free(arg);
1928 p = isl_printer_yaml_next(p);
1929 }
1930 p = isl_printer_yaml_end_sequence(p);
1931
1932 return p;
1933}
1934
1935/* Print "expr" to "p" in isl format.
1936 *
1937 * In particular, print the isl_ast_expr as a YAML document.
1938 */
1939static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p,
1940 __isl_keep isl_ast_expr *expr)
1941{
1942 enum isl_ast_expr_type type;
1943 enum isl_ast_op_type op;
1944 isl_id *id;
1945 isl_val *v;
1946
1947 if (!expr)
1948 return isl_printer_free(p);
1949
1950 p = isl_printer_yaml_start_mapping(p);
1951 type = isl_ast_expr_get_type(expr);
1952 switch (type) {
1953 case isl_ast_expr_error:
1954 return isl_printer_free(p);
1955 case isl_ast_expr_op:
1956 op = isl_ast_expr_get_op_type(expr);
1957 if (op == isl_ast_op_error)
1958 return isl_printer_free(p);
1959 p = isl_printer_print_str(p, "op");
1960 p = isl_printer_yaml_next(p);
1961 p = isl_printer_print_str(p, op_str[op]);
1962 p = isl_printer_yaml_next(p);
1963 p = print_arguments(p, expr);
1964 break;
1965 case isl_ast_expr_id:
1966 p = isl_printer_print_str(p, "id");
1967 p = isl_printer_yaml_next(p);
1968 id = isl_ast_expr_get_id(expr);
1969 p = isl_printer_print_id(p, id);
1970 isl_id_free(id);
1971 break;
1972 case isl_ast_expr_int:
1973 p = isl_printer_print_str(p, "val");
1974 p = isl_printer_yaml_next(p);
1975 v = isl_ast_expr_get_val(expr);
1976 p = isl_printer_print_val(p, v);
1977 isl_val_free(v);
1978 break;
1979 }
1980 p = isl_printer_yaml_end_mapping(p);
1981
1982 return p;
1983}
1984
1985/* Print "expr" to "p".
1986 *
1987 * Only an isl and a C format are supported.
1988 */
1989__isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p,
1990 __isl_keep isl_ast_expr *expr)
1991{
1992 int format;
1993
1994 if (!p)
1995 return NULL((void*)0);
1996
1997 format = isl_printer_get_output_format(p);
1998 switch (format) {
1999 case ISL_FORMAT_ISL0:
2000 p = print_ast_expr_isl(p, expr);
2001 break;
2002 case ISL_FORMAT_C4:
2003 p = print_ast_expr_c(p, expr);
2004 break;
2005 default:
2006 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_expr", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2008); return isl_printer_free(p); } while (0)
2007 "output format not supported for ast_expr",do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_expr", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2008); return isl_printer_free(p); } while (0)
2008 return isl_printer_free(p))do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_expr", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2008); return isl_printer_free(p); } while (0)
;
2009 }
2010
2011 return p;
2012}
2013
2014static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2015 __isl_keep isl_ast_node *node);
2016
2017/* Print a YAML sequence containing the entries in "list" to "p".
2018 */
2019static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p,
2020 __isl_keep isl_ast_node_list *list)
2021{
2022 int i, n;
2023
2024 n = isl_ast_node_list_n_ast_node(list);
2025 if (n < 0)
2026 return isl_printer_free(p);
2027
2028 p = isl_printer_yaml_start_sequence(p);
2029 for (i = 0; i < n; ++i) {
2030 isl_ast_node *node;
2031
2032 node = isl_ast_node_list_get_ast_node(list, i);
2033 p = print_ast_node_isl(p, node);
2034 isl_ast_node_free(node);
2035 p = isl_printer_yaml_next(p);
2036 }
2037 p = isl_printer_yaml_end_sequence(p);
2038
2039 return p;
2040}
2041
2042/* Print "node" to "p" in "isl format".
2043 *
2044 * In particular, print the isl_ast_node as a YAML document.
2045 */
2046static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p,
2047 __isl_keep isl_ast_node *node)
2048{
2049 switch (node->type) {
2050 case isl_ast_node_for:
2051 p = isl_printer_yaml_start_mapping(p);
2052 p = isl_printer_print_str(p, "iterator");
2053 p = isl_printer_yaml_next(p);
2054 p = isl_printer_print_ast_expr(p, node->u.f.iterator);
2055 p = isl_printer_yaml_next(p);
2056 if (node->u.f.degenerate) {
2057 p = isl_printer_print_str(p, "value");
2058 p = isl_printer_yaml_next(p);
2059 p = isl_printer_print_ast_expr(p, node->u.f.init);
2060 p = isl_printer_yaml_next(p);
2061 } else {
2062 p = isl_printer_print_str(p, "init");
2063 p = isl_printer_yaml_next(p);
2064 p = isl_printer_print_ast_expr(p, node->u.f.init);
2065 p = isl_printer_yaml_next(p);
2066 p = isl_printer_print_str(p, "cond");
2067 p = isl_printer_yaml_next(p);
2068 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2069 p = isl_printer_yaml_next(p);
2070 p = isl_printer_print_str(p, "inc");
2071 p = isl_printer_yaml_next(p);
2072 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2073 p = isl_printer_yaml_next(p);
2074 }
2075 if (node->u.f.body) {
2076 p = isl_printer_print_str(p, "body");
2077 p = isl_printer_yaml_next(p);
2078 p = isl_printer_print_ast_node(p, node->u.f.body);
2079 p = isl_printer_yaml_next(p);
2080 }
2081 p = isl_printer_yaml_end_mapping(p);
2082 break;
2083 case isl_ast_node_mark:
2084 p = isl_printer_yaml_start_mapping(p);
2085 p = isl_printer_print_str(p, "mark");
2086 p = isl_printer_yaml_next(p);
2087 p = isl_printer_print_id(p, node->u.m.mark);
2088 p = isl_printer_yaml_next(p);
2089 p = isl_printer_print_str(p, "node");
2090 p = isl_printer_yaml_next(p);
2091 p = isl_printer_print_ast_node(p, node->u.m.node);
2092 p = isl_printer_yaml_end_mapping(p);
2093 break;
2094 case isl_ast_node_user:
2095 p = isl_printer_yaml_start_mapping(p);
2096 p = isl_printer_print_str(p, "user");
2097 p = isl_printer_yaml_next(p);
2098 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2099 p = isl_printer_yaml_end_mapping(p);
2100 break;
2101 case isl_ast_node_if:
2102 p = isl_printer_yaml_start_mapping(p);
2103 p = isl_printer_print_str(p, "guard");
2104 p = isl_printer_yaml_next(p);
2105 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2106 p = isl_printer_yaml_next(p);
2107 if (node->u.i.then) {
2108 p = isl_printer_print_str(p, "then");
2109 p = isl_printer_yaml_next(p);
2110 p = isl_printer_print_ast_node(p, node->u.i.then);
2111 p = isl_printer_yaml_next(p);
2112 }
2113 if (node->u.i.else_node) {
2114 p = isl_printer_print_str(p, "else");
2115 p = isl_printer_yaml_next(p);
2116 p = isl_printer_print_ast_node(p, node->u.i.else_node);
2117 }
2118 p = isl_printer_yaml_end_mapping(p);
2119 break;
2120 case isl_ast_node_block:
2121 p = print_ast_node_list(p, node->u.b.children);
2122 break;
2123 case isl_ast_node_error:
2124 break;
2125 }
2126 return p;
2127}
2128
2129/* Do we need to print a block around the body "node" of a for or if node?
2130 *
2131 * If the node is a block, then we need to print a block.
2132 * Also if the node is a degenerate for then we will print it as
2133 * an assignment followed by the body of the for loop, so we need a block
2134 * as well.
2135 * If the node is an if node with an else, then we print a block
2136 * to avoid spurious dangling else warnings emitted by some compilers.
2137 * If the node is a mark, then in principle, we would have to check
2138 * the child of the mark node. However, even if the child would not
2139 * require us to print a block, for readability it is probably best
2140 * to print a block anyway.
2141 * If the ast_always_print_block option has been set, then we print a block.
2142 */
2143static int need_block(__isl_keep isl_ast_node *node)
2144{
2145 isl_ctx *ctx;
2146
2147 if (node->type == isl_ast_node_block)
2148 return 1;
2149 if (node->type == isl_ast_node_for && node->u.f.degenerate)
2150 return 1;
2151 if (node->type == isl_ast_node_if && node->u.i.else_node)
2152 return 1;
2153 if (node->type == isl_ast_node_mark)
2154 return 1;
2155
2156 ctx = isl_ast_node_get_ctx(node);
2157 return isl_options_get_ast_always_print_block(ctx);
2158}
2159
2160static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2161 __isl_keep isl_ast_node *node,
2162 __isl_keep isl_ast_print_options *options, int in_block, int in_list);
2163static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2164 __isl_keep isl_ast_node *node,
2165 __isl_keep isl_ast_print_options *options, int new_line,
2166 int force_block);
2167
2168/* Print the body "node" of a for or if node.
2169 * If "else_node" is set, then it is printed as well.
2170 * If "force_block" is set, then print out the body as a block.
2171 *
2172 * We first check if we need to print out a block.
2173 * We always print out a block if there is an else node to make
2174 * sure that the else node is matched to the correct if node.
2175 * For consistency, the corresponding else node is also printed as a block.
2176 *
2177 * If the else node is itself an if, then we print it as
2178 *
2179 * } else if (..) {
2180 * }
2181 *
2182 * Otherwise the else node is printed as
2183 *
2184 * } else {
2185 * node
2186 * }
2187 */
2188static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p,
2189 __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node,
2190 __isl_keep isl_ast_print_options *options, int force_block)
2191{
2192 if (!node)
9
Assuming 'node' is non-null
10
Taking false branch
2193 return isl_printer_free(p);
2194
2195 if (!force_block && !else_node && !need_block(node)) {
11
Assuming 'else_node' is null
12
Assuming the condition is true
13
Taking true branch
2196 p = isl_printer_end_line(p);
2197 p = isl_printer_indent(p, 2);
2198 p = isl_ast_node_print(node, p,
14
Calling 'isl_ast_node_print'
22
Returning; memory was released via 3rd parameter
2199 isl_ast_print_options_copy(options));
2200 p = isl_printer_indent(p, -2);
2201 return p;
2202 }
2203
2204 p = isl_printer_print_str(p, " {");
2205 p = isl_printer_end_line(p);
2206 p = isl_printer_indent(p, 2);
2207 p = print_ast_node_c(p, node, options, 1, 0);
2208 p = isl_printer_indent(p, -2);
2209 p = isl_printer_start_line(p);
2210 p = isl_printer_print_str(p, "}");
2211 if (else_node) {
2212 if (else_node->type == isl_ast_node_if) {
2213 p = isl_printer_print_str(p, " else ");
2214 p = print_if_c(p, else_node, options, 0, 1);
2215 } else {
2216 p = isl_printer_print_str(p, " else");
2217 p = print_body_c(p, else_node, NULL((void*)0), options, 1);
2218 }
2219 } else
2220 p = isl_printer_end_line(p);
2221
2222 return p;
2223}
2224
2225/* Print the start of a compound statement.
2226 */
2227static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
2228{
2229 p = isl_printer_start_line(p);
2230 p = isl_printer_print_str(p, "{");
2231 p = isl_printer_end_line(p);
2232 p = isl_printer_indent(p, 2);
2233
2234 return p;
2235}
2236
2237/* Print the end of a compound statement.
2238 */
2239static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
2240{
2241 p = isl_printer_indent(p, -2);
2242 p = isl_printer_start_line(p);
2243 p = isl_printer_print_str(p, "}");
2244 p = isl_printer_end_line(p);
2245
2246 return p;
2247}
2248
2249/* Print the for node "node".
2250 *
2251 * If the for node is degenerate, it is printed as
2252 *
2253 * type iterator = init;
2254 * body
2255 *
2256 * Otherwise, it is printed as
2257 *
2258 * for (type iterator = init; cond; iterator += inc)
2259 * body
2260 *
2261 * "in_block" is set if we are currently inside a block.
2262 * "in_list" is set if the current node is not alone in the block.
2263 * If we are not in a block or if the current not is not alone in the block
2264 * then we print a block around a degenerate for loop such that the variable
2265 * declaration will not conflict with any potential other declaration
2266 * of the same variable.
2267 */
2268static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
2269 __isl_keep isl_ast_node *node,
2270 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2271{
2272 isl_id *id;
2273 const char *name;
2274 const char *type;
2275
2276 type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p));
2277 if (!node->u.f.degenerate) {
2278 id = isl_ast_expr_get_id(node->u.f.iterator);
2279 name = isl_id_get_name(id);
2280 isl_id_free(id);
2281 p = isl_printer_start_line(p);
2282 p = isl_printer_print_str(p, "for (");
2283 p = isl_printer_print_str(p, type);
2284 p = isl_printer_print_str(p, " ");
2285 p = isl_printer_print_str(p, name);
2286 p = isl_printer_print_str(p, " = ");
2287 p = isl_printer_print_ast_expr(p, node->u.f.init);
2288 p = isl_printer_print_str(p, "; ");
2289 p = isl_printer_print_ast_expr(p, node->u.f.cond);
2290 p = isl_printer_print_str(p, "; ");
2291 p = isl_printer_print_str(p, name);
2292 p = isl_printer_print_str(p, " += ");
2293 p = isl_printer_print_ast_expr(p, node->u.f.inc);
2294 p = isl_printer_print_str(p, ")");
2295 p = print_body_c(p, node->u.f.body, NULL((void*)0), options, 0);
2296 } else {
2297 id = isl_ast_expr_get_id(node->u.f.iterator);
2298 name = isl_id_get_name(id);
2299 isl_id_free(id);
2300 if (!in_block || in_list)
2301 p = start_block(p);
2302 p = isl_printer_start_line(p);
2303 p = isl_printer_print_str(p, type);
2304 p = isl_printer_print_str(p, " ");
2305 p = isl_printer_print_str(p, name);
2306 p = isl_printer_print_str(p, " = ");
2307 p = isl_printer_print_ast_expr(p, node->u.f.init);
2308 p = isl_printer_print_str(p, ";");
2309 p = isl_printer_end_line(p);
2310 p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
2311 if (!in_block || in_list)
2312 p = end_block(p);
2313 }
2314
2315 return p;
2316}
2317
2318/* Print the if node "node".
2319 * If "new_line" is set then the if node should be printed on a new line.
2320 * If "force_block" is set, then print out the body as a block.
2321 */
2322static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
2323 __isl_keep isl_ast_node *node,
2324 __isl_keep isl_ast_print_options *options, int new_line,
2325 int force_block)
2326{
2327 if (new_line)
7
Taking true branch
2328 p = isl_printer_start_line(p);
2329 p = isl_printer_print_str(p, "if (");
2330 p = isl_printer_print_ast_expr(p, node->u.i.guard);
2331 p = isl_printer_print_str(p, ")");
2332 p = print_body_c(p, node->u.i.then, node->u.i.else_node, options,
8
Calling 'print_body_c'
23
Returning; memory was released via 4th parameter
2333 force_block);
2334
2335 return p;
2336}
2337
2338/* Print the "node" to "p".
2339 *
2340 * "in_block" is set if we are currently inside a block.
2341 * If so, we do not print a block around the children of a block node.
2342 * We do this to avoid an extra block around the body of a degenerate
2343 * for node.
2344 *
2345 * "in_list" is set if the current node is not alone in the block.
2346 */
2347static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
2348 __isl_keep isl_ast_node *node,
2349 __isl_keep isl_ast_print_options *options, int in_block, int in_list)
2350{
2351 switch (node->type) {
2352 case isl_ast_node_for:
2353 if (options->print_for)
2354 return options->print_for(p,
2355 isl_ast_print_options_copy(options),
2356 node, options->print_for_user);
2357 p = print_for_c(p, node, options, in_block, in_list);
2358 break;
2359 case isl_ast_node_if:
2360 p = print_if_c(p, node, options, 1, 0);
2361 break;
2362 case isl_ast_node_block:
2363 if (!in_block)
2364 p = start_block(p);
2365 p = isl_ast_node_list_print(node->u.b.children, p, options);
2366 if (!in_block)
2367 p = end_block(p);
2368 break;
2369 case isl_ast_node_mark:
2370 p = isl_printer_start_line(p);
2371 p = isl_printer_print_str(p, "// ");
2372 p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark));
2373 p = isl_printer_end_line(p);
2374 p = print_ast_node_c(p, node->u.m.node, options, 0, in_list);
2375 break;
2376 case isl_ast_node_user:
2377 if (options->print_user)
2378 return options->print_user(p,
2379 isl_ast_print_options_copy(options),
2380 node, options->print_user_user);
2381 p = isl_printer_start_line(p);
2382 p = isl_printer_print_ast_expr(p, node->u.e.expr);
2383 p = isl_printer_print_str(p, ";");
2384 p = isl_printer_end_line(p);
2385 break;
2386 case isl_ast_node_error:
2387 break;
2388 }
2389 return p;
2390}
2391
2392/* Print the for node "node" to "p".
2393 */
2394__isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
2395 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2396{
2397 if (!node || !options)
2398 goto error;
2399 if (node->type != isl_ast_node_for)
2400 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2401); goto error; } while (0)
2401 "not a for node", goto error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not a for node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2401); goto error; } while (0)
;
2402 p = print_for_c(p, node, options, 0, 0);
2403 isl_ast_print_options_free(options);
2404 return p;
2405error:
2406 isl_ast_print_options_free(options);
2407 isl_printer_free(p);
2408 return NULL((void*)0);
2409}
2410
2411/* Print the if node "node" to "p".
2412 */
2413__isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
2414 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2415{
2416 if (!node || !options)
1
Assuming 'node' is non-null
2
Assuming 'options' is non-null
3
Taking false branch
2417 goto error;
2418 if (node->type != isl_ast_node_if)
4
Assuming the condition is false
5
Taking false branch
2419 isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2420); goto error; } while (0)
2420 "not an if node", goto error)do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_invalid
, "not an if node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2420); goto error; } while (0)
;
2421 p = print_if_c(p, node, options, 1, 0);
6
Calling 'print_if_c'
24
Returning; memory was released via 3rd parameter
2422 isl_ast_print_options_free(options);
25
Use of memory after it is freed
2423 return p;
2424error:
2425 isl_ast_print_options_free(options);
2426 isl_printer_free(p);
2427 return NULL((void*)0);
2428}
2429
2430/* Print "node" to "p".
2431 */
2432__isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
2433 __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
2434{
2435 if (!options || !node)
15
Taking false branch
2436 goto error;
2437 p = print_ast_node_c(p, node, options, 0, 0);
2438 isl_ast_print_options_free(options);
16
Calling 'isl_ast_print_options_free'
21
Returning; memory was released via 1st parameter
2439 return p;
2440error:
2441 isl_ast_print_options_free(options);
2442 isl_printer_free(p);
2443 return NULL((void*)0);
2444}
2445
2446/* Print "node" to "p".
2447 */
2448__isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p,
2449 __isl_keep isl_ast_node *node)
2450{
2451 int format;
2452 isl_ast_print_options *options;
2453
2454 if (!p)
2455 return NULL((void*)0);
2456
2457 format = isl_printer_get_output_format(p);
2458 switch (format) {
2459 case ISL_FORMAT_ISL0:
2460 p = print_ast_node_isl(p, node);
2461 break;
2462 case ISL_FORMAT_C4:
2463 options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
2464 p = isl_ast_node_print(node, p, options);
2465 break;
2466 default:
2467 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2469); return isl_printer_free(p); } while (0)
2468 "output format not supported for ast_node",do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2469); return isl_printer_free(p); } while (0)
2469 return isl_printer_free(p))do { isl_handle_error(isl_printer_get_ctx(p), isl_error_unsupported
, "output format not supported for ast_node", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2469); return isl_printer_free(p); } while (0)
;
2470 }
2471
2472 return p;
2473}
2474
2475/* Print the list of nodes "list" to "p".
2476 */
2477__isl_give isl_printer *isl_ast_node_list_print(
2478 __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p,
2479 __isl_keep isl_ast_print_options *options)
2480{
2481 int i;
2482
2483 if (!p || !list || !options)
2484 return isl_printer_free(p);
2485
2486 for (i = 0; i < list->n; ++i)
2487 p = print_ast_node_c(p, list->p[i], options, 1, 1);
2488
2489 return p;
2490}
2491
2492#define ISL_AST_MACRO_FLOORD(1 << 0) (1 << 0)
2493#define ISL_AST_MACRO_MIN(1 << 1) (1 << 1)
2494#define ISL_AST_MACRO_MAX(1 << 2) (1 << 2)
2495#define ISL_AST_MACRO_ALL((1 << 0) | (1 << 1) | (1 << 2)) (ISL_AST_MACRO_FLOORD(1 << 0) | \
2496 ISL_AST_MACRO_MIN(1 << 1) | \
2497 ISL_AST_MACRO_MAX(1 << 2))
2498
2499/* If "expr" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2500 * then set the corresponding bit in "macros".
2501 */
2502static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros)
2503{
2504 int i;
2505
2506 if (macros == ISL_AST_MACRO_ALL((1 << 0) | (1 << 1) | (1 << 2)))
2507 return macros;
2508
2509 if (expr->type != isl_ast_expr_op)
2510 return macros;
2511
2512 if (expr->u.op.op == isl_ast_op_min)
2513 macros |= ISL_AST_MACRO_MIN(1 << 1);
2514 if (expr->u.op.op == isl_ast_op_max)
2515 macros |= ISL_AST_MACRO_MAX(1 << 2);
2516 if (expr->u.op.op == isl_ast_op_fdiv_q)
2517 macros |= ISL_AST_MACRO_FLOORD(1 << 0);
2518
2519 for (i = 0; i < expr->u.op.n_arg; ++i)
2520 macros = ast_expr_required_macros(expr->u.op.args[i], macros);
2521
2522 return macros;
2523}
2524
2525static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
2526 int macros);
2527
2528/* If "node" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2529 * then set the corresponding bit in "macros".
2530 */
2531static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros)
2532{
2533 if (macros == ISL_AST_MACRO_ALL((1 << 0) | (1 << 1) | (1 << 2)))
2534 return macros;
2535
2536 switch (node->type) {
2537 case isl_ast_node_for:
2538 macros = ast_expr_required_macros(node->u.f.init, macros);
2539 if (!node->u.f.degenerate) {
2540 macros = ast_expr_required_macros(node->u.f.cond,
2541 macros);
2542 macros = ast_expr_required_macros(node->u.f.inc,
2543 macros);
2544 }
2545 macros = ast_node_required_macros(node->u.f.body, macros);
2546 break;
2547 case isl_ast_node_if:
2548 macros = ast_expr_required_macros(node->u.i.guard, macros);
2549 macros = ast_node_required_macros(node->u.i.then, macros);
2550 if (node->u.i.else_node)
2551 macros = ast_node_required_macros(node->u.i.else_node,
2552 macros);
2553 break;
2554 case isl_ast_node_block:
2555 macros = ast_node_list_required_macros(node->u.b.children,
2556 macros);
2557 break;
2558 case isl_ast_node_mark:
2559 macros = ast_node_required_macros(node->u.m.node, macros);
2560 break;
2561 case isl_ast_node_user:
2562 macros = ast_expr_required_macros(node->u.e.expr, macros);
2563 break;
2564 case isl_ast_node_error:
2565 break;
2566 }
2567
2568 return macros;
2569}
2570
2571/* If "list" contains an isl_ast_op_min, isl_ast_op_max or isl_ast_op_fdiv_q
2572 * then set the corresponding bit in "macros".
2573 */
2574static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list,
2575 int macros)
2576{
2577 int i;
2578
2579 for (i = 0; i < list->n; ++i)
2580 macros = ast_node_required_macros(list->p[i], macros);
2581
2582 return macros;
2583}
2584
2585/* Data structure for keeping track of whether a macro definition
2586 * for a given type has already been printed.
2587 * The value is zero if no definition has been printed and non-zero otherwise.
2588 */
2589struct isl_ast_op_printed {
2590 char printed[isl_ast_op_lastisl_ast_op_address_of + 1];
2591};
2592
2593/* Create an empty struct isl_ast_op_printed.
2594 */
2595static void *create_printed(isl_ctx *ctx)
2596{
2597 return isl_calloc_type(ctx, struct isl_ast_op_printed)((struct isl_ast_op_printed *)isl_calloc_or_die(ctx, 1, sizeof
(struct isl_ast_op_printed)))
;
2598}
2599
2600/* Free a struct isl_ast_op_printed.
2601 */
2602static void free_printed(void *user)
2603{
2604 free(user);
2605}
2606
2607/* Ensure that "p" has an isl_ast_op_printed note identified by "id".
2608 */
2609static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p,
2610 __isl_keep isl_id *id)
2611{
2612 return alloc_note(p, id, &create_printed, &free_printed);
2613}
2614
2615/* Create an identifier that is used to store
2616 * an isl_ast_op_printed note.
2617 */
2618static __isl_give isl_id *printed_id(isl_ctx *ctx)
2619{
2620 return isl_id_alloc(ctx, "isl_ast_op_type_printed", NULL((void*)0));
2621}
2622
2623/* Did the user specify that a macro definition should only be
2624 * printed once and has a macro definition for "type" already
2625 * been printed to "p"?
2626 * If definitions should only be printed once, but a definition
2627 * for "p" has not yet been printed, then mark it as having been
2628 * printed so that it will not printed again.
2629 * The actual printing is taken care of by the caller.
2630 */
2631static isl_bool already_printed_once(__isl_keep isl_printer *p,
2632 enum isl_ast_op_type type)
2633{
2634 isl_ctx *ctx;
2635 isl_id *id;
2636 struct isl_ast_op_printed *printed;
2637
2638 if (!p)
2639 return isl_bool_error;
2640
2641 ctx = isl_printer_get_ctx(p);
2642 if (!isl_options_get_ast_print_macro_once(ctx))
2643 return isl_bool_false;
2644
2645 if (type > isl_ast_op_lastisl_ast_op_address_of)
2646 isl_die(isl_printer_get_ctx(p), isl_error_invalid,do { isl_handle_error(isl_printer_get_ctx(p), isl_error_invalid
, "invalid type", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2647); return isl_bool_error; } while (0)
2647 "invalid type", return isl_bool_error)do { isl_handle_error(isl_printer_get_ctx(p), isl_error_invalid
, "invalid type", "/build/llvm-toolchain-snapshot-7~svn329677/tools/polly/lib/External/isl/isl_ast.c"
, 2647); return isl_bool_error; } while (0)
;
2648
2649 id = printed_id(isl_printer_get_ctx(p));
2650 p = alloc_printed(p, id);
2651 printed = get_note(p, id);
2652 isl_id_free(id);
2653 if (!printed)
2654 return isl_bool_error;
2655
2656 if (printed->printed[type])
2657 return isl_bool_true;
2658
2659 printed->printed[type] = 1;
2660 return isl_bool_false;
2661}
2662
2663/* Print a macro definition for the operator "type".
2664 *
2665 * If the user has specified that a macro definition should
2666 * only be printed once to any given printer and if the macro definition
2667 * has already been printed to "p", then do not print the definition.
2668 */
2669__isl_give isl_printer *isl_ast_op_type_print_macro(
2670 enum isl_ast_op_type type, __isl_take isl_printer *p)
2671{
2672 isl_bool skip;
2673
2674 skip = already_printed_once(p, type);
2675 if (skip < 0)
2676 return isl_printer_free(p);
2677 if (skip)
2678 return p;
2679
2680 switch (type) {
2681 case isl_ast_op_min:
2682 p = isl_printer_start_line(p);
2683 p = isl_printer_print_str(p, "#define ");
2684 p = isl_printer_print_str(p, get_op_str_c(p, type));
2685 p = isl_printer_print_str(p,
2686 "(x,y) ((x) < (y) ? (x) : (y))");
2687 p = isl_printer_end_line(p);
2688 break;
2689 case isl_ast_op_max:
2690 p = isl_printer_start_line(p);
2691 p = isl_printer_print_str(p, "#define ");
2692 p = isl_printer_print_str(p, get_op_str_c(p, type));
2693 p = isl_printer_print_str(p,
2694 "(x,y) ((x) > (y) ? (x) : (y))");
2695 p = isl_printer_end_line(p);
2696 break;
2697 case isl_ast_op_fdiv_q:
2698 p = isl_printer_start_line(p);
2699 p = isl_printer_print_str(p, "#define ");
2700 p = isl_printer_print_str(p, get_op_str_c(p, type));
2701 p = isl_printer_print_str(p,
2702 "(n,d) "
2703 "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))");
2704 p = isl_printer_end_line(p);
2705 break;
2706 default:
2707 break;
2708 }
2709
2710 return p;
2711}
2712
2713/* Call "fn" for each type of operation represented in the "macros"
2714 * bit vector.
2715 */
2716static isl_stat foreach_ast_op_type(int macros,
2717 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2718{
2719 if (macros & ISL_AST_MACRO_MIN(1 << 1) && fn(isl_ast_op_min, user) < 0)
2720 return isl_stat_error;
2721 if (macros & ISL_AST_MACRO_MAX(1 << 2) && fn(isl_ast_op_max, user) < 0)
2722 return isl_stat_error;
2723 if (macros & ISL_AST_MACRO_FLOORD(1 << 0) && fn(isl_ast_op_fdiv_q, user) < 0)
2724 return isl_stat_error;
2725
2726 return isl_stat_ok;
2727}
2728
2729/* Call "fn" for each type of operation that appears in "expr"
2730 * and that requires a macro definition.
2731 */
2732isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr,
2733 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2734{
2735 int macros;
2736
2737 if (!expr)
2738 return isl_stat_error;
2739
2740 macros = ast_expr_required_macros(expr, 0);
2741 return foreach_ast_op_type(macros, fn, user);
2742}
2743
2744/* Call "fn" for each type of operation that appears in "node"
2745 * and that requires a macro definition.
2746 */
2747isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node,
2748 isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user)
2749{
2750 int macros;
2751
2752 if (!node)
2753 return isl_stat_error;
2754
2755 macros = ast_node_required_macros(node, 0);
2756 return foreach_ast_op_type(macros, fn, user);
2757}
2758
2759static isl_stat ast_op_type_print_macro(enum isl_ast_op_type type, void *user)
2760{
2761 isl_printer **p = user;
2762
2763 *p = isl_ast_op_type_print_macro(type, *p);
2764
2765 return isl_stat_ok;
2766}
2767
2768/* Print macro definitions for all the macros used in the result
2769 * of printing "expr".
2770 */
2771__isl_give isl_printer *isl_ast_expr_print_macros(
2772 __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p)
2773{
2774 if (isl_ast_expr_foreach_ast_op_type(expr,
2775 &ast_op_type_print_macro, &p) < 0)
2776 return isl_printer_free(p);
2777 return p;
2778}
2779
2780/* Print macro definitions for all the macros used in the result
2781 * of printing "node".
2782 */
2783__isl_give isl_printer *isl_ast_node_print_macros(
2784 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
2785{
2786 if (isl_ast_node_foreach_ast_op_type(node,
2787 &ast_op_type_print_macro, &p) < 0)
2788 return isl_printer_free(p);
2789 return p;
2790}
2791
2792/* Return a string containing C code representing this isl_ast_expr.
2793 */
2794__isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr)
2795{
2796 isl_printer *p;
2797 char *str;
2798
2799 if (!expr)
2800 return NULL((void*)0);
2801
2802 p = isl_printer_to_str(isl_ast_expr_get_ctx(expr));
2803 p = isl_printer_set_output_format(p, ISL_FORMAT_C4);
2804 p = isl_printer_print_ast_expr(p, expr);
2805
2806 str = isl_printer_get_str(p);
2807
2808 isl_printer_free(p);
2809
2810 return str;
2811}
2812
2813/* Return a string containing C code representing this isl_ast_node.
2814 */
2815__isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node)
2816{
2817 isl_printer *p;
2818 char *str;
2819
2820 if (!node)
2821 return NULL((void*)0);
2822
2823 p = isl_printer_to_str(isl_ast_node_get_ctx(node));
2824 p = isl_printer_set_output_format(p, ISL_FORMAT_C4);
2825 p = isl_printer_print_ast_node(p, node);
2826
2827 str = isl_printer_get_str(p);
2828
2829 isl_printer_free(p);
2830
2831 return str;
2832}