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