Coverage Report

Created: 2017-10-03 07:32

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