Coverage Report

Created: 2018-02-20 12:54

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