Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_ast_build_expr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2012-2014 Ecole Normale Superieure
3
 * Copyright 2014      INRIA Rocquencourt
4
 *
5
 * Use of this software is governed by the MIT license
6
 *
7
 * Written by Sven Verdoolaege,
8
 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
9
 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
10
 * B.P. 105 - 78153 Le Chesnay, France
11
 */
12
13
#include <isl/id.h>
14
#include <isl/space.h>
15
#include <isl/constraint.h>
16
#include <isl/ilp.h>
17
#include <isl/val.h>
18
#include <isl_ast_build_expr.h>
19
#include <isl_ast_private.h>
20
#include <isl_ast_build_private.h>
21
#include <isl_sort.h>
22
23
/* Compute the "opposite" of the (numerator of the) argument of a div
24
 * with denominator "d".
25
 *
26
 * In particular, compute
27
 *
28
 *  -aff + (d - 1)
29
 */
30
static __isl_give isl_aff *oppose_div_arg(__isl_take isl_aff *aff,
31
  __isl_take isl_val *d)
32
32
{
33
32
  aff = isl_aff_neg(aff);
34
32
  aff = isl_aff_add_constant_val(aff, d);
35
32
  aff = isl_aff_add_constant_si(aff, -1);
36
32
37
32
  return aff;
38
32
}
39
40
/* Internal data structure used inside isl_ast_expr_add_term.
41
 * The domain of "build" is used to simplify the expressions.
42
 * "build" needs to be set by the caller of isl_ast_expr_add_term.
43
 * "cst" is the constant term of the expression in which the added term
44
 * appears.  It may be modified by isl_ast_expr_add_term.
45
 *
46
 * "v" is the coefficient of the term that is being constructed and
47
 * is set internally by isl_ast_expr_add_term.
48
 */
49
struct isl_ast_add_term_data {
50
  isl_ast_build *build;
51
  isl_val *cst;
52
  isl_val *v;
53
};
54
55
/* Given the numerator "aff" of the argument of an integer division
56
 * with denominator "d", check if it can be made non-negative over
57
 * data->build->domain by stealing part of the constant term of
58
 * the expression in which the integer division appears.
59
 *
60
 * In particular, the outer expression is of the form
61
 *
62
 *  v * floor(aff/d) + cst
63
 *
64
 * We already know that "aff" itself may attain negative values.
65
 * Here we check if aff + d*floor(cst/v) is non-negative, such
66
 * that we could rewrite the expression to
67
 *
68
 *  v * floor((aff + d*floor(cst/v))/d) + cst - v*floor(cst/v)
69
 *
70
 * Note that aff + d*floor(cst/v) can only possibly be non-negative
71
 * if data->cst and data->v have the same sign.
72
 * Similarly, if floor(cst/v) is zero, then there is no point in
73
 * checking again.
74
 */
75
static int is_non_neg_after_stealing(__isl_keep isl_aff *aff,
76
  __isl_keep isl_val *d, struct isl_ast_add_term_data *data)
77
21
{
78
21
  isl_aff *shifted;
79
21
  isl_val *shift;
80
21
  int is_zero;
81
21
  int non_neg;
82
21
83
21
  if (isl_val_sgn(data->cst) != isl_val_sgn(data->v))
84
17
    return 0;
85
4
86
4
  shift = isl_val_div(isl_val_copy(data->cst), isl_val_copy(data->v));
87
4
  shift = isl_val_floor(shift);
88
4
  is_zero = isl_val_is_zero(shift);
89
4
  if (is_zero < 0 || is_zero) {
90
4
    isl_val_free(shift);
91
4
    return is_zero < 0 ? 
-10
: 0;
92
4
  }
93
0
  shift = isl_val_mul(shift, isl_val_copy(d));
94
0
  shifted = isl_aff_copy(aff);
95
0
  shifted = isl_aff_add_constant_val(shifted, shift);
96
0
  non_neg = isl_ast_build_aff_is_nonneg(data->build, shifted);
97
0
  isl_aff_free(shifted);
98
0
99
0
  return non_neg;
100
0
}
101
102
/* Given the numerator "aff' of the argument of an integer division
103
 * with denominator "d", steal part of the constant term of
104
 * the expression in which the integer division appears to make it
105
 * non-negative over data->build->domain.
106
 *
107
 * In particular, the outer expression is of the form
108
 *
109
 *  v * floor(aff/d) + cst
110
 *
111
 * We know that "aff" itself may attain negative values,
112
 * but that aff + d*floor(cst/v) is non-negative.
113
 * Find the minimal positive value that we need to add to "aff"
114
 * to make it positive and adjust data->cst accordingly.
115
 * That is, compute the minimal value "m" of "aff" over
116
 * data->build->domain and take
117
 *
118
 *  s = ceil(m/d)
119
 *
120
 * such that
121
 *
122
 *  aff + d * s >= 0
123
 *
124
 * and rewrite the expression to
125
 *
126
 *  v * floor((aff + s*d)/d) + (cst - v*s)
127
 */
128
static __isl_give isl_aff *steal_from_cst(__isl_take isl_aff *aff,
129
  __isl_keep isl_val *d, struct isl_ast_add_term_data *data)
130
0
{
131
0
  isl_set *domain;
132
0
  isl_val *shift, *t;
133
0
134
0
  domain = isl_ast_build_get_domain(data->build);
135
0
  shift = isl_set_min_val(domain, aff);
136
0
  isl_set_free(domain);
137
0
138
0
  shift = isl_val_neg(shift);
139
0
  shift = isl_val_div(shift, isl_val_copy(d));
140
0
  shift = isl_val_ceil(shift);
141
0
142
0
  t = isl_val_copy(shift);
143
0
  t = isl_val_mul(t, isl_val_copy(data->v));
144
0
  data->cst = isl_val_sub(data->cst, t);
145
0
146
0
  shift = isl_val_mul(shift, isl_val_copy(d));
147
0
  return isl_aff_add_constant_val(aff, shift);
148
0
}
149
150
/* Create an isl_ast_expr evaluating the div at position "pos" in "ls".
151
 * The result is simplified in terms of data->build->domain.
152
 * This function may change (the sign of) data->v.
153
 *
154
 * "ls" is known to be non-NULL.
155
 *
156
 * Let the div be of the form floor(e/d).
157
 * If the ast_build_prefer_pdiv option is set then we check if "e"
158
 * is non-negative, so that we can generate
159
 *
160
 *  (pdiv_q, expr(e), expr(d))
161
 *
162
 * instead of
163
 *
164
 *  (fdiv_q, expr(e), expr(d))
165
 *
166
 * If the ast_build_prefer_pdiv option is set and
167
 * if "e" is not non-negative, then we check if "-e + d - 1" is non-negative.
168
 * If so, we can rewrite
169
 *
170
 *  floor(e/d) = -ceil(-e/d) = -floor((-e + d - 1)/d)
171
 *
172
 * and still use pdiv_q, while changing the sign of data->v.
173
 *
174
 * Otherwise, we check if
175
 *
176
 *  e + d*floor(cst/v)
177
 *
178
 * is non-negative and if so, replace floor(e/d) by
179
 *
180
 *  floor((e + s*d)/d) - s
181
 *
182
 * with s the minimal shift that makes the argument non-negative.
183
 */
184
static __isl_give isl_ast_expr *var_div(struct isl_ast_add_term_data *data,
185
  __isl_keep isl_local_space *ls, int pos)
186
40
{
187
40
  isl_ctx *ctx = isl_local_space_get_ctx(ls);
188
40
  isl_aff *aff;
189
40
  isl_ast_expr *num, *den;
190
40
  isl_val *d;
191
40
  enum isl_ast_op_type type;
192
40
193
40
  aff = isl_local_space_get_div(ls, pos);
194
40
  d = isl_aff_get_denominator_val(aff);
195
40
  aff = isl_aff_scale_val(aff, isl_val_copy(d));
196
40
  den = isl_ast_expr_from_val(isl_val_copy(d));
197
40
198
40
  type = isl_ast_op_fdiv_q;
199
40
  if (isl_options_get_ast_build_prefer_pdiv(ctx)) {
200
40
    int non_neg = isl_ast_build_aff_is_nonneg(data->build, aff);
201
40
    if (non_neg >= 0 && !non_neg) {
202
21
      isl_aff *opp = oppose_div_arg(isl_aff_copy(aff),
203
21
              isl_val_copy(d));
204
21
      non_neg = isl_ast_build_aff_is_nonneg(data->build, opp);
205
21
      if (non_neg >= 0 && non_neg) {
206
0
        data->v = isl_val_neg(data->v);
207
0
        isl_aff_free(aff);
208
0
        aff = opp;
209
0
      } else
210
21
        isl_aff_free(opp);
211
21
    }
212
40
    if (non_neg >= 0 && !non_neg) {
213
21
      non_neg = is_non_neg_after_stealing(aff, d, data);
214
21
      if (non_neg >= 0 && non_neg)
215
0
        aff = steal_from_cst(aff, d, data);
216
21
    }
217
40
    if (non_neg < 0)
218
0
      aff = isl_aff_free(aff);
219
40
    else if (non_neg)
220
19
      type = isl_ast_op_pdiv_q;
221
40
  }
222
40
223
40
  isl_val_free(d);
224
40
  num = isl_ast_expr_from_aff(aff, data->build);
225
40
  return isl_ast_expr_alloc_binary(type, num, den);
226
40
}
227
228
/* Create an isl_ast_expr evaluating the specified dimension of "ls".
229
 * The result is simplified in terms of data->build->domain.
230
 * This function may change (the sign of) data->v.
231
 *
232
 * The isl_ast_expr is constructed based on the type of the dimension.
233
 * - divs are constructed by var_div
234
 * - set variables are constructed from the iterator isl_ids in data->build
235
 * - parameters are constructed from the isl_ids in "ls"
236
 */
237
static __isl_give isl_ast_expr *var(struct isl_ast_add_term_data *data,
238
  __isl_keep isl_local_space *ls, enum isl_dim_type type, int pos)
239
9.33k
{
240
9.33k
  isl_ctx *ctx = isl_local_space_get_ctx(ls);
241
9.33k
  isl_id *id;
242
9.33k
243
9.33k
  if (type == isl_dim_div)
244
40
    return var_div(data, ls, pos);
245
9.29k
246
9.29k
  if (type == isl_dim_set) {
247
8.02k
    id = isl_ast_build_get_iterator_id(data->build, pos);
248
8.02k
    return isl_ast_expr_from_id(id);
249
8.02k
  }
250
1.26k
251
1.26k
  if (!isl_local_space_has_dim_id(ls, type, pos))
252
1.26k
    
isl_die0
(ctx, isl_error_internal, "unnamed dimension",
253
1.26k
      return NULL);
254
1.26k
  id = isl_local_space_get_dim_id(ls, type, pos);
255
1.26k
  return isl_ast_expr_from_id(id);
256
1.26k
}
257
258
/* Does "expr" represent the zero integer?
259
 */
260
static int ast_expr_is_zero(__isl_keep isl_ast_expr *expr)
261
29.4k
{
262
29.4k
  if (!expr)
263
0
    return -1;
264
29.4k
  if (expr->type != isl_ast_expr_int)
265
9.36k
    return 0;
266
20.0k
  return isl_val_is_zero(expr->u.v);
267
20.0k
}
268
269
/* Create an expression representing the sum of "expr1" and "expr2",
270
 * provided neither of the two expressions is identically zero.
271
 */
272
static __isl_give isl_ast_expr *ast_expr_add(__isl_take isl_ast_expr *expr1,
273
  __isl_take isl_ast_expr *expr2)
274
13.6k
{
275
13.6k
  if (!expr1 || !expr2)
276
0
    goto error;
277
13.6k
278
13.6k
  if (ast_expr_is_zero(expr1)) {
279
8.29k
    isl_ast_expr_free(expr1);
280
8.29k
    return expr2;
281
8.29k
  }
282
5.33k
283
5.33k
  if (ast_expr_is_zero(expr2)) {
284
0
    isl_ast_expr_free(expr2);
285
0
    return expr1;
286
0
  }
287
5.33k
288
5.33k
  return isl_ast_expr_add(expr1, expr2);
289
0
error:
290
0
  isl_ast_expr_free(expr1);
291
0
  isl_ast_expr_free(expr2);
292
0
  return NULL;
293
5.33k
}
294
295
/* Subtract expr2 from expr1.
296
 *
297
 * If expr2 is zero, we simply return expr1.
298
 * If expr1 is zero, we return
299
 *
300
 *  (isl_ast_op_minus, expr2)
301
 *
302
 * Otherwise, we return
303
 *
304
 *  (isl_ast_op_sub, expr1, expr2)
305
 */
306
static __isl_give isl_ast_expr *ast_expr_sub(__isl_take isl_ast_expr *expr1,
307
  __isl_take isl_ast_expr *expr2)
308
8.75k
{
309
8.75k
  if (!expr1 || !expr2)
310
0
    goto error;
311
8.75k
312
8.75k
  if (ast_expr_is_zero(expr2)) {
313
8.47k
    isl_ast_expr_free(expr2);
314
8.47k
    return expr1;
315
8.47k
  }
316
284
317
284
  if (ast_expr_is_zero(expr1)) {
318
47
    isl_ast_expr_free(expr1);
319
47
    return isl_ast_expr_neg(expr2);
320
47
  }
321
237
322
237
  return isl_ast_expr_sub(expr1, expr2);
323
0
error:
324
0
  isl_ast_expr_free(expr1);
325
0
  isl_ast_expr_free(expr2);
326
0
  return NULL;
327
237
}
328
329
/* Return an isl_ast_expr that represents
330
 *
331
 *  v * (aff mod d)
332
 *
333
 * v is assumed to be non-negative.
334
 * The result is simplified in terms of build->domain.
335
 */
336
static __isl_give isl_ast_expr *isl_ast_expr_mod(__isl_keep isl_val *v,
337
  __isl_keep isl_aff *aff, __isl_keep isl_val *d,
338
  __isl_keep isl_ast_build *build)
339
92
{
340
92
  isl_ast_expr *expr;
341
92
  isl_ast_expr *c;
342
92
343
92
  if (!aff)
344
0
    return NULL;
345
92
346
92
  expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build);
347
92
348
92
  c = isl_ast_expr_from_val(isl_val_copy(d));
349
92
  expr = isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr, c);
350
92
351
92
  if (!isl_val_is_one(v)) {
352
0
    c = isl_ast_expr_from_val(isl_val_copy(v));
353
0
    expr = isl_ast_expr_mul(c, expr);
354
0
  }
355
92
356
92
  return expr;
357
92
}
358
359
/* Create an isl_ast_expr that scales "expr" by "v".
360
 *
361
 * If v is 1, we simply return expr.
362
 * If v is -1, we return
363
 *
364
 *  (isl_ast_op_minus, expr)
365
 *
366
 * Otherwise, we return
367
 *
368
 *  (isl_ast_op_mul, expr(v), expr)
369
 */
370
static __isl_give isl_ast_expr *scale(__isl_take isl_ast_expr *expr,
371
  __isl_take isl_val *v)
372
9.33k
{
373
9.33k
  isl_ast_expr *c;
374
9.33k
375
9.33k
  if (!expr || !v)
376
0
    goto error;
377
9.33k
  if (isl_val_is_one(v)) {
378
3.86k
    isl_val_free(v);
379
3.86k
    return expr;
380
3.86k
  }
381
5.47k
382
5.47k
  if (isl_val_is_negone(v)) {
383
34
    isl_val_free(v);
384
34
    expr = isl_ast_expr_neg(expr);
385
5.43k
  } else {
386
5.43k
    c = isl_ast_expr_from_val(v);
387
5.43k
    expr = isl_ast_expr_mul(c, expr);
388
5.43k
  }
389
5.47k
390
5.47k
  return expr;
391
0
error:
392
0
  isl_val_free(v);
393
0
  isl_ast_expr_free(expr);
394
0
  return NULL;
395
5.47k
}
396
397
/* Add an expression for "*v" times the specified dimension of "ls"
398
 * to expr.
399
 * If the dimension is an integer division, then this function
400
 * may modify data->cst in order to make the numerator non-negative.
401
 * The result is simplified in terms of data->build->domain.
402
 *
403
 * Let e be the expression for the specified dimension,
404
 * multiplied by the absolute value of "*v".
405
 * If "*v" is negative, we create
406
 *
407
 *  (isl_ast_op_sub, expr, e)
408
 *
409
 * except when expr is trivially zero, in which case we create
410
 *
411
 *  (isl_ast_op_minus, e)
412
 *
413
 * instead.
414
 *
415
 * If "*v" is positive, we simply create
416
 *
417
 *  (isl_ast_op_add, expr, e)
418
 *
419
 */
420
static __isl_give isl_ast_expr *isl_ast_expr_add_term(
421
  __isl_take isl_ast_expr *expr,
422
  __isl_keep isl_local_space *ls, enum isl_dim_type type, int pos,
423
  __isl_take isl_val *v, struct isl_ast_add_term_data *data)
424
9.33k
{
425
9.33k
  isl_ast_expr *term;
426
9.33k
427
9.33k
  if (!expr)
428
0
    return NULL;
429
9.33k
430
9.33k
  data->v = v;
431
9.33k
  term = var(data, ls, type, pos);
432
9.33k
  v = data->v;
433
9.33k
434
9.33k
  if (isl_val_is_neg(v) && 
!ast_expr_is_zero(expr)126
) {
435
47
    v = isl_val_neg(v);
436
47
    term = scale(term, v);
437
47
    return ast_expr_sub(expr, term);
438
9.28k
  } else {
439
9.28k
    term = scale(term, v);
440
9.28k
    return ast_expr_add(expr, term);
441
9.28k
  }
442
9.33k
}
443
444
/* Add an expression for "v" to expr.
445
 */
446
static __isl_give isl_ast_expr *isl_ast_expr_add_int(
447
  __isl_take isl_ast_expr *expr, __isl_take isl_val *v)
448
9.12k
{
449
9.12k
  isl_ast_expr *expr_int;
450
9.12k
451
9.12k
  if (!expr || !v)
452
0
    goto error;
453
9.12k
454
9.12k
  if (isl_val_is_zero(v)) {
455
4.70k
    isl_val_free(v);
456
4.70k
    return expr;
457
4.70k
  }
458
4.42k
459
4.42k
  if (isl_val_is_neg(v) && 
!ast_expr_is_zero(expr)293
) {
460
190
    v = isl_val_neg(v);
461
190
    expr_int = isl_ast_expr_from_val(v);
462
190
    return ast_expr_sub(expr, expr_int);
463
4.23k
  } else {
464
4.23k
    expr_int = isl_ast_expr_from_val(v);
465
4.23k
    return ast_expr_add(expr, expr_int);
466
4.23k
  }
467
0
error:
468
0
  isl_ast_expr_free(expr);
469
0
  isl_val_free(v);
470
0
  return NULL;
471
4.42k
}
472
473
/* Internal data structure used inside extract_modulos.
474
 *
475
 * If any modulo expressions are detected in "aff", then the
476
 * expression is removed from "aff" and added to either "pos" or "neg"
477
 * depending on the sign of the coefficient of the modulo expression
478
 * inside "aff".
479
 *
480
 * "add" is an expression that needs to be added to "aff" at the end of
481
 * the computation.  It is NULL as long as no modulos have been extracted.
482
 *
483
 * "i" is the position in "aff" of the div under investigation
484
 * "v" is the coefficient in "aff" of the div
485
 * "div" is the argument of the div, with the denominator removed
486
 * "d" is the original denominator of the argument of the div
487
 *
488
 * "nonneg" is an affine expression that is non-negative over "build"
489
 * and that can be used to extract a modulo expression from "div".
490
 * In particular, if "sign" is 1, then the coefficients of "nonneg"
491
 * are equal to those of "div" modulo "d".  If "sign" is -1, then
492
 * the coefficients of "nonneg" are opposite to those of "div" modulo "d".
493
 * If "sign" is 0, then no such affine expression has been found (yet).
494
 */
495
struct isl_extract_mod_data {
496
  isl_ast_build *build;
497
  isl_aff *aff;
498
499
  isl_ast_expr *pos;
500
  isl_ast_expr *neg;
501
502
  isl_aff *add;
503
504
  int i;
505
  isl_val *v;
506
  isl_val *d;
507
  isl_aff *div;
508
509
  isl_aff *nonneg;
510
  int sign;
511
};
512
513
/* Given that data->v * div_i in data->aff is equal to
514
 *
515
 *  f * (term - (arg mod d))
516
 *
517
 * with data->d * f = data->v, add
518
 *
519
 *  f * term
520
 *
521
 * to data->add and
522
 *
523
 *  abs(f) * (arg mod d)
524
 *
525
 * to data->neg or data->pos depending on the sign of -f.
526
 */
527
static int extract_term_and_mod(struct isl_extract_mod_data *data,
528
  __isl_take isl_aff *term, __isl_take isl_aff *arg)
529
92
{
530
92
  isl_ast_expr *expr;
531
92
  int s;
532
92
533
92
  data->v = isl_val_div(data->v, isl_val_copy(data->d));
534
92
  s = isl_val_sgn(data->v);
535
92
  data->v = isl_val_abs(data->v);
536
92
  expr = isl_ast_expr_mod(data->v, arg, data->d, data->build);
537
92
  isl_aff_free(arg);
538
92
  if (s > 0)
539
47
    data->neg = ast_expr_add(data->neg, expr);
540
45
  else
541
45
    data->pos = ast_expr_add(data->pos, expr);
542
92
  data->aff = isl_aff_set_coefficient_si(data->aff,
543
92
            isl_dim_div, data->i, 0);
544
92
  if (s < 0)
545
45
    data->v = isl_val_neg(data->v);
546
92
  term = isl_aff_scale_val(term, isl_val_copy(data->v));
547
92
548
92
  if (!data->add)
549
92
    data->add = term;
550
0
  else
551
0
    data->add = isl_aff_add(data->add, term);
552
92
  if (!data->add)
553
0
    return -1;
554
92
555
92
  return 0;
556
92
}
557
558
/* Given that data->v * div_i in data->aff is of the form
559
 *
560
 *  f * d * floor(div/d)
561
 *
562
 * with div nonnegative on data->build, rewrite it as
563
 *
564
 *  f * (div - (div mod d)) = f * div - f * (div mod d)
565
 *
566
 * and add
567
 *
568
 *  f * div
569
 *
570
 * to data->add and
571
 *
572
 *  abs(f) * (div mod d)
573
 *
574
 * to data->neg or data->pos depending on the sign of -f.
575
 */
576
static int extract_mod(struct isl_extract_mod_data *data)
577
80
{
578
80
  return extract_term_and_mod(data, isl_aff_copy(data->div),
579
80
      isl_aff_copy(data->div));
580
80
}
581
582
/* Given that data->v * div_i in data->aff is of the form
583
 *
584
 *  f * d * floor(div/d)          (1)
585
 *
586
 * check if div is non-negative on data->build and, if so,
587
 * extract the corresponding modulo from data->aff.
588
 * If not, then check if
589
 *
590
 *  -div + d - 1
591
 *
592
 * is non-negative on data->build.  If so, replace (1) by
593
 *
594
 *  -f * d * floor((-div + d - 1)/d)
595
 *
596
 * and extract the corresponding modulo from data->aff.
597
 *
598
 * This function may modify data->div.
599
 */
600
static int extract_nonneg_mod(struct isl_extract_mod_data *data)
601
84
{
602
84
  int mod;
603
84
604
84
  mod = isl_ast_build_aff_is_nonneg(data->build, data->div);
605
84
  if (mod < 0)
606
0
    goto error;
607
84
  if (mod)
608
76
    return extract_mod(data);
609
8
610
8
  data->div = oppose_div_arg(data->div, isl_val_copy(data->d));
611
8
  mod = isl_ast_build_aff_is_nonneg(data->build, data->div);
612
8
  if (mod < 0)
613
0
    goto error;
614
8
  if (mod) {
615
4
    data->v = isl_val_neg(data->v);
616
4
    return extract_mod(data);
617
4
  }
618
4
619
4
  return 0;
620
0
error:
621
0
  data->aff = isl_aff_free(data->aff);
622
0
  return -1;
623
4
}
624
625
/* Is the affine expression of constraint "c" "simpler" than data->nonneg
626
 * for use in extracting a modulo expression?
627
 *
628
 * We currently only consider the constant term of the affine expression.
629
 * In particular, we prefer the affine expression with the smallest constant
630
 * term.
631
 * This means that if there are two constraints, say x >= 0 and -x + 10 >= 0,
632
 * then we would pick x >= 0
633
 *
634
 * More detailed heuristics could be used if it turns out that there is a need.
635
 */
636
static int mod_constraint_is_simpler(struct isl_extract_mod_data *data,
637
  __isl_keep isl_constraint *c)
638
17
{
639
17
  isl_val *v1, *v2;
640
17
  int simpler;
641
17
642
17
  if (!data->nonneg)
643
12
    return 1;
644
5
645
5
  v1 = isl_val_abs(isl_constraint_get_constant_val(c));
646
5
  v2 = isl_val_abs(isl_aff_get_constant_val(data->nonneg));
647
5
  simpler = isl_val_lt(v1, v2);
648
5
  isl_val_free(v1);
649
5
  isl_val_free(v2);
650
5
651
5
  return simpler;
652
5
}
653
654
/* Check if the coefficients of "c" are either equal or opposite to those
655
 * of data->div modulo data->d.  If so, and if "c" is "simpler" than
656
 * data->nonneg, then replace data->nonneg by the affine expression of "c"
657
 * and set data->sign accordingly.
658
 *
659
 * Both "c" and data->div are assumed not to involve any integer divisions.
660
 *
661
 * Before we start the actual comparison, we first quickly check if
662
 * "c" and data->div have the same non-zero coefficients.
663
 * If not, then we assume that "c" is not of the desired form.
664
 * Note that while the coefficients of data->div can be reasonably expected
665
 * not to involve any coefficients that are multiples of d, "c" may
666
 * very well involve such coefficients.  This means that we may actually
667
 * miss some cases.
668
 *
669
 * If the constant term is "too large", then the constraint is rejected,
670
 * where "too large" is fairly arbitrarily set to 1 << 15.
671
 * We do this to avoid picking up constraints that bound a variable
672
 * by a very large number, say the largest or smallest possible
673
 * variable in the representation of some integer type.
674
 */
675
static isl_stat check_parallel_or_opposite(__isl_take isl_constraint *c,
676
  void *user)
677
1.19k
{
678
1.19k
  struct isl_extract_mod_data *data = user;
679
1.19k
  enum isl_dim_type c_type[2] = { isl_dim_param, isl_dim_set };
680
1.19k
  enum isl_dim_type a_type[2] = { isl_dim_param, isl_dim_in };
681
1.19k
  int i, t;
682
1.19k
  int n[2];
683
1.19k
  int parallel = 1, opposite = 1;
684
1.19k
685
3.58k
  for (t = 0; t < 2; 
++t2.38k
) {
686
2.38k
    n[t] = isl_constraint_dim(c, c_type[t]);
687
15.6k
    for (i = 0; i < n[t]; 
++i13.3k
) {
688
13.3k
      int a, b;
689
13.3k
690
13.3k
      a = isl_constraint_involves_dims(c, c_type[t], i, 1);
691
13.3k
      b = isl_aff_involves_dims(data->div, a_type[t], i, 1);
692
13.3k
      if (a != b)
693
2.35k
        parallel = opposite = 0;
694
13.3k
    }
695
2.38k
  }
696
1.19k
697
1.19k
  if (parallel || 
opposite1.09k
) {
698
101
    isl_val *v;
699
101
700
101
    v = isl_val_abs(isl_constraint_get_constant_val(c));
701
101
    if (isl_val_cmp_si(v, 1 << 15) > 0)
702
84
      parallel = opposite = 0;
703
101
    isl_val_free(v);
704
101
  }
705
1.19k
706
3.58k
  for (t = 0; t < 2; 
++t2.38k
) {
707
2.43k
    for (i = 0; i < n[t]; 
++i48
) {
708
2.37k
      isl_val *v1, *v2;
709
2.37k
710
2.37k
      if (!parallel && 
!opposite2.33k
)
711
2.32k
        break;
712
48
      v1 = isl_constraint_get_coefficient_val(c,
713
48
                c_type[t], i);
714
48
      v2 = isl_aff_get_coefficient_val(data->div,
715
48
                a_type[t], i);
716
48
      if (parallel) {
717
35
        v1 = isl_val_sub(v1, isl_val_copy(v2));
718
35
        parallel = isl_val_is_divisible_by(v1, data->d);
719
35
        v1 = isl_val_add(v1, isl_val_copy(v2));
720
35
      }
721
48
      if (opposite) {
722
47
        v1 = isl_val_add(v1, isl_val_copy(v2));
723
47
        opposite = isl_val_is_divisible_by(v1, data->d);
724
47
      }
725
48
      isl_val_free(v1);
726
48
      isl_val_free(v2);
727
48
    }
728
2.38k
  }
729
1.19k
730
1.19k
  if ((parallel || 
opposite1.18k
) &&
mod_constraint_is_simpler(data, c)17
) {
731
12
    isl_aff_free(data->nonneg);
732
12
    data->nonneg = isl_constraint_get_aff(c);
733
12
    data->sign = parallel ? 
19
:
-13
;
734
12
  }
735
1.19k
736
1.19k
  isl_constraint_free(c);
737
1.19k
738
1.19k
  if (data->sign != 0 && 
data->nonneg == NULL44
)
739
1.19k
    
return isl_stat_error0
;
740
1.19k
741
1.19k
  return isl_stat_ok;
742
1.19k
}
743
744
/* Given that data->v * div_i in data->aff is of the form
745
 *
746
 *  f * d * floor(div/d)          (1)
747
 *
748
 * see if we can find an expression div' that is non-negative over data->build
749
 * and that is related to div through
750
 *
751
 *  div' = div + d * e
752
 *
753
 * or
754
 *
755
 *  div' = -div + d - 1 + d * e
756
 *
757
 * with e some affine expression.
758
 * If so, we write (1) as
759
 *
760
 *  f * div + f * (div' mod d)
761
 *
762
 * or
763
 *
764
 *  -f * (-div + d - 1) - f * (div' mod d)
765
 *
766
 * exploiting (in the second case) the fact that
767
 *
768
 *  f * d * floor(div/d) =  -f * d * floor((-div + d - 1)/d)
769
 *
770
 *
771
 * We first try to find an appropriate expression for div'
772
 * from the constraints of data->build->domain (which is therefore
773
 * guaranteed to be non-negative on data->build), where we remove
774
 * any integer divisions from the constraints and skip this step
775
 * if "div" itself involves any integer divisions.
776
 * If we cannot find an appropriate expression this way, then
777
 * we pass control to extract_nonneg_mod where check
778
 * if div or "-div + d -1" themselves happen to be
779
 * non-negative on data->build.
780
 *
781
 * While looking for an appropriate constraint in data->build->domain,
782
 * we ignore the constant term, so after finding such a constraint,
783
 * we still need to fix up the constant term.
784
 * In particular, if a is the constant term of "div"
785
 * (or d - 1 - the constant term of "div" if data->sign < 0)
786
 * and b is the constant term of the constraint, then we need to find
787
 * a non-negative constant c such that
788
 *
789
 *  b + c \equiv a  mod d
790
 *
791
 * We therefore take
792
 *
793
 *  c = (a - b) mod d
794
 *
795
 * and add it to b to obtain the constant term of div'.
796
 * If this constant term is "too negative", then we add an appropriate
797
 * multiple of d to make it positive.
798
 *
799
 *
800
 * Note that the above is a only a very simple heuristic for finding an
801
 * appropriate expression.  We could try a bit harder by also considering
802
 * sums of constraints that involve disjoint sets of variables or
803
 * we could consider arbitrary linear combinations of constraints,
804
 * although that could potentially be much more expensive as it involves
805
 * the solution of an LP problem.
806
 *
807
 * In particular, if v_i is a column vector representing constraint i,
808
 * w represents div and e_i is the i-th unit vector, then we are looking
809
 * for a solution of the constraints
810
 *
811
 *  \sum_i lambda_i v_i = w + \sum_i alpha_i d e_i
812
 *
813
 * with \lambda_i >= 0 and alpha_i of unrestricted sign.
814
 * If we are not just interested in a non-negative expression, but
815
 * also in one with a minimal range, then we don't just want
816
 * c = \sum_i lambda_i v_i to be non-negative over the domain,
817
 * but also beta - c = \sum_i mu_i v_i, where beta is a scalar
818
 * that we want to minimize and we now also have to take into account
819
 * the constant terms of the constraints.
820
 * Alternatively, we could first compute the dual of the domain
821
 * and plug in the constraints on the coefficients.
822
 */
823
static int try_extract_mod(struct isl_extract_mod_data *data)
824
96
{
825
96
  isl_basic_set *hull;
826
96
  isl_val *v1, *v2;
827
96
  int r, n;
828
96
829
96
  if (!data->build)
830
0
    goto error;
831
96
832
96
  n = isl_aff_dim(data->div, isl_dim_div);
833
96
834
96
  if (isl_aff_involves_dims(data->div, isl_dim_div, 0, n))
835
0
    return extract_nonneg_mod(data);
836
96
837
96
  hull = isl_set_simple_hull(isl_set_copy(data->build->domain));
838
96
  hull = isl_basic_set_remove_divs(hull);
839
96
  data->sign = 0;
840
96
  data->nonneg = NULL;
841
96
  r = isl_basic_set_foreach_constraint(hull, &check_parallel_or_opposite,
842
96
          data);
843
96
  isl_basic_set_free(hull);
844
96
845
96
  if (!data->sign || 
r < 012
) {
846
84
    isl_aff_free(data->nonneg);
847
84
    if (r < 0)
848
0
      goto error;
849
84
    return extract_nonneg_mod(data);
850
84
  }
851
12
852
12
  v1 = isl_aff_get_constant_val(data->div);
853
12
  v2 = isl_aff_get_constant_val(data->nonneg);
854
12
  if (data->sign < 0) {
855
3
    v1 = isl_val_neg(v1);
856
3
    v1 = isl_val_add(v1, isl_val_copy(data->d));
857
3
    v1 = isl_val_sub_ui(v1, 1);
858
3
  }
859
12
  v1 = isl_val_sub(v1, isl_val_copy(v2));
860
12
  v1 = isl_val_mod(v1, isl_val_copy(data->d));
861
12
  v1 = isl_val_add(v1, v2);
862
12
  v2 = isl_val_div(isl_val_copy(v1), isl_val_copy(data->d));
863
12
  v2 = isl_val_ceil(v2);
864
12
  if (isl_val_is_neg(v2)) {
865
1
    v2 = isl_val_mul(v2, isl_val_copy(data->d));
866
1
    v1 = isl_val_sub(v1, isl_val_copy(v2));
867
1
  }
868
12
  data->nonneg = isl_aff_set_constant_val(data->nonneg, v1);
869
12
  isl_val_free(v2);
870
12
871
12
  if (data->sign < 0) {
872
3
    data->div = oppose_div_arg(data->div, isl_val_copy(data->d));
873
3
    data->v = isl_val_neg(data->v);
874
3
  }
875
12
876
12
  return extract_term_and_mod(data,
877
12
            isl_aff_copy(data->div), data->nonneg);
878
0
error:
879
0
  data->aff = isl_aff_free(data->aff);
880
0
  return -1;
881
12
}
882
883
/* Check if "data->aff" involves any (implicit) modulo computations based
884
 * on div "data->i".
885
 * If so, remove them from aff and add expressions corresponding
886
 * to those modulo computations to data->pos and/or data->neg.
887
 *
888
 * "aff" is assumed to be an integer affine expression.
889
 *
890
 * In particular, check if (v * div_j) is of the form
891
 *
892
 *  f * m * floor(a / m)
893
 *
894
 * and, if so, rewrite it as
895
 *
896
 *  f * (a - (a mod m)) = f * a - f * (a mod m)
897
 *
898
 * and extract out -f * (a mod m).
899
 * In particular, if f > 0, we add (f * (a mod m)) to *neg.
900
 * If f < 0, we add ((-f) * (a mod m)) to *pos.
901
 *
902
 * Note that in order to represent "a mod m" as
903
 *
904
 *  (isl_ast_op_pdiv_r, a, m)
905
 *
906
 * we need to make sure that a is non-negative.
907
 * If not, we check if "-a + m - 1" is non-negative.
908
 * If so, we can rewrite
909
 *
910
 *  floor(a/m) = -ceil(-a/m) = -floor((-a + m - 1)/m)
911
 *
912
 * and still extract a modulo.
913
 */
914
static int extract_modulo(struct isl_extract_mod_data *data)
915
96
{
916
96
  data->div = isl_aff_get_div(data->aff, data->i);
917
96
  data->d = isl_aff_get_denominator_val(data->div);
918
96
  if (isl_val_is_divisible_by(data->v, data->d)) {
919
96
    data->div = isl_aff_scale_val(data->div, isl_val_copy(data->d));
920
96
    if (try_extract_mod(data) < 0)
921
0
      data->aff = isl_aff_free(data->aff);
922
96
  }
923
96
  isl_aff_free(data->div);
924
96
  isl_val_free(data->d);
925
96
  return 0;
926
96
}
927
928
/* Check if "aff" involves any (implicit) modulo computations.
929
 * If so, remove them from aff and add expressions corresponding
930
 * to those modulo computations to *pos and/or *neg.
931
 * We only do this if the option ast_build_prefer_pdiv is set.
932
 *
933
 * "aff" is assumed to be an integer affine expression.
934
 *
935
 * A modulo expression is of the form
936
 *
937
 *  a mod m = a - m * floor(a / m)
938
 *
939
 * To detect them in aff, we look for terms of the form
940
 *
941
 *  f * m * floor(a / m)
942
 *
943
 * rewrite them as
944
 *
945
 *  f * (a - (a mod m)) = f * a - f * (a mod m)
946
 *
947
 * and extract out -f * (a mod m).
948
 * In particular, if f > 0, we add (f * (a mod m)) to *neg.
949
 * If f < 0, we add ((-f) * (a mod m)) to *pos.
950
 */
951
static __isl_give isl_aff *extract_modulos(__isl_take isl_aff *aff,
952
  __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg,
953
  __isl_keep isl_ast_build *build)
954
9.12k
{
955
9.12k
  struct isl_extract_mod_data data = { build, aff, *pos, *neg };
956
9.12k
  isl_ctx *ctx;
957
9.12k
  int n;
958
9.12k
959
9.12k
  if (!aff)
960
0
    return NULL;
961
9.12k
962
9.12k
  ctx = isl_aff_get_ctx(aff);
963
9.12k
  if (!isl_options_get_ast_build_prefer_pdiv(ctx))
964
0
    return aff;
965
9.12k
966
9.12k
  n = isl_aff_dim(data.aff, isl_dim_div);
967
9.48k
  for (data.i = 0; data.i < n; 
++data.i362
) {
968
362
    data.v = isl_aff_get_coefficient_val(data.aff,
969
362
              isl_dim_div, data.i);
970
362
    if (!data.v)
971
0
      return isl_aff_free(aff);
972
362
    if (isl_val_is_zero(data.v) ||
973
362
        
isl_val_is_one(data.v)132
||
isl_val_is_negone(data.v)96
) {
974
266
      isl_val_free(data.v);
975
266
      continue;
976
266
    }
977
96
    if (extract_modulo(&data) < 0)
978
0
      data.aff = isl_aff_free(data.aff);
979
96
    isl_val_free(data.v);
980
96
    if (!data.aff)
981
0
      break;
982
96
  }
983
9.12k
984
9.12k
  if (data.add)
985
92
    data.aff = isl_aff_add(data.aff, data.add);
986
9.12k
987
9.12k
  *pos = data.pos;
988
9.12k
  *neg = data.neg;
989
9.12k
  return data.aff;
990
9.12k
}
991
992
/* Check if aff involves any non-integer coefficients.
993
 * If so, split aff into
994
 *
995
 *  aff = aff1 + (aff2 / d)
996
 *
997
 * with both aff1 and aff2 having only integer coefficients.
998
 * Return aff1 and add (aff2 / d) to *expr.
999
 */
1000
static __isl_give isl_aff *extract_rational(__isl_take isl_aff *aff,
1001
  __isl_keep isl_ast_expr **expr, __isl_keep isl_ast_build *build)
1002
8.51k
{
1003
8.51k
  int i, j, n;
1004
8.51k
  isl_aff *rat = NULL;
1005
8.51k
  isl_local_space *ls = NULL;
1006
8.51k
  isl_ast_expr *rat_expr;
1007
8.51k
  isl_val *v, *d;
1008
8.51k
  enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div };
1009
8.51k
  enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div };
1010
8.51k
1011
8.51k
  if (!aff)
1012
0
    return NULL;
1013
8.51k
  d = isl_aff_get_denominator_val(aff);
1014
8.51k
  if (!d)
1015
0
    goto error;
1016
8.51k
  if (isl_val_is_one(d)) {
1017
8.51k
    isl_val_free(d);
1018
8.51k
    return aff;
1019
8.51k
  }
1020
7
1021
7
  aff = isl_aff_scale_val(aff, isl_val_copy(d));
1022
7
1023
7
  ls = isl_aff_get_domain_local_space(aff);
1024
7
  rat = isl_aff_zero_on_domain(isl_local_space_copy(ls));
1025
7
1026
28
  for (i = 0; i < 3; 
++i21
) {
1027
21
    n = isl_aff_dim(aff, t[i]);
1028
42
    for (j = 0; j < n; 
++j21
) {
1029
21
      isl_aff *rat_j;
1030
21
1031
21
      v = isl_aff_get_coefficient_val(aff, t[i], j);
1032
21
      if (!v)
1033
0
        goto error;
1034
21
      if (isl_val_is_divisible_by(v, d)) {
1035
12
        isl_val_free(v);
1036
12
        continue;
1037
12
      }
1038
9
      rat_j = isl_aff_var_on_domain(isl_local_space_copy(ls),
1039
9
              l[i], j);
1040
9
      rat_j = isl_aff_scale_val(rat_j, v);
1041
9
      rat = isl_aff_add(rat, rat_j);
1042
9
    }
1043
21
  }
1044
7
1045
7
  v = isl_aff_get_constant_val(aff);
1046
7
  if (isl_val_is_divisible_by(v, d)) {
1047
7
    isl_val_free(v);
1048
7
  } else {
1049
0
    isl_aff *rat_0;
1050
0
1051
0
    rat_0 = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
1052
0
    rat = isl_aff_add(rat, rat_0);
1053
0
  }
1054
7
1055
7
  isl_local_space_free(ls);
1056
7
1057
7
  aff = isl_aff_sub(aff, isl_aff_copy(rat));
1058
7
  aff = isl_aff_scale_down_val(aff, isl_val_copy(d));
1059
7
1060
7
  rat_expr = isl_ast_expr_from_aff(rat, build);
1061
7
  rat_expr = isl_ast_expr_div(rat_expr, isl_ast_expr_from_val(d));
1062
7
  *expr = ast_expr_add(*expr, rat_expr);
1063
7
1064
7
  return aff;
1065
0
error:
1066
0
  isl_aff_free(rat);
1067
0
  isl_local_space_free(ls);
1068
0
  isl_aff_free(aff);
1069
0
  isl_val_free(d);
1070
0
  return NULL;
1071
7
}
1072
1073
/* Construct an isl_ast_expr that evaluates the affine expression "aff",
1074
 * The result is simplified in terms of build->domain.
1075
 *
1076
 * We first extract hidden modulo computations from the affine expression
1077
 * and then add terms for each variable with a non-zero coefficient.
1078
 * Finally, if the affine expression has a non-trivial denominator,
1079
 * we divide the resulting isl_ast_expr by this denominator.
1080
 */
1081
__isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff,
1082
  __isl_keep isl_ast_build *build)
1083
8.51k
{
1084
8.51k
  int i, j;
1085
8.51k
  int n;
1086
8.51k
  isl_val *v;
1087
8.51k
  isl_ctx *ctx = isl_aff_get_ctx(aff);
1088
8.51k
  isl_ast_expr *expr, *expr_neg;
1089
8.51k
  enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div };
1090
8.51k
  enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div };
1091
8.51k
  isl_local_space *ls;
1092
8.51k
  struct isl_ast_add_term_data data;
1093
8.51k
1094
8.51k
  if (!aff)
1095
0
    return NULL;
1096
8.51k
1097
8.51k
  expr = isl_ast_expr_alloc_int_si(ctx, 0);
1098
8.51k
  expr_neg = isl_ast_expr_alloc_int_si(ctx, 0);
1099
8.51k
1100
8.51k
  aff = extract_rational(aff, &expr, build);
1101
8.51k
1102
8.51k
  aff = extract_modulos(aff, &expr, &expr_neg, build);
1103
8.51k
  expr = ast_expr_sub(expr, expr_neg);
1104
8.51k
1105
8.51k
  ls = isl_aff_get_domain_local_space(aff);
1106
8.51k
1107
8.51k
  data.build = build;
1108
8.51k
  data.cst = isl_aff_get_constant_val(aff);
1109
34.0k
  for (i = 0; i < 3; 
++i25.5k
) {
1110
25.5k
    n = isl_aff_dim(aff, t[i]);
1111
79.8k
    for (j = 0; j < n; 
++j54.2k
) {
1112
54.2k
      v = isl_aff_get_coefficient_val(aff, t[i], j);
1113
54.2k
      if (!v)
1114
0
        expr = isl_ast_expr_free(expr);
1115
54.2k
      if (isl_val_is_zero(v)) {
1116
45.7k
        isl_val_free(v);
1117
45.7k
        continue;
1118
45.7k
      }
1119
8.53k
      expr = isl_ast_expr_add_term(expr,
1120
8.53k
              ls, l[i], j, v, &data);
1121
8.53k
    }
1122
25.5k
  }
1123
8.51k
1124
8.51k
  expr = isl_ast_expr_add_int(expr, data.cst);
1125
8.51k
1126
8.51k
  isl_local_space_free(ls);
1127
8.51k
  isl_aff_free(aff);
1128
8.51k
  return expr;
1129
8.51k
}
1130
1131
/* Add terms to "expr" for each variable in "aff" with a coefficient
1132
 * with sign equal to "sign".
1133
 * The result is simplified in terms of data->build->domain.
1134
 */
1135
static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr,
1136
  __isl_keep isl_aff *aff, int sign, struct isl_ast_add_term_data *data)
1137
1.21k
{
1138
1.21k
  int i, j;
1139
1.21k
  isl_val *v;
1140
1.21k
  enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div };
1141
1.21k
  enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div };
1142
1.21k
  isl_local_space *ls;
1143
1.21k
1144
1.21k
  ls = isl_aff_get_domain_local_space(aff);
1145
1.21k
1146
4.87k
  for (i = 0; i < 3; 
++i3.65k
) {
1147
3.65k
    int n = isl_aff_dim(aff, t[i]);
1148
8.50k
    for (j = 0; j < n; 
++j4.85k
) {
1149
4.85k
      v = isl_aff_get_coefficient_val(aff, t[i], j);
1150
4.85k
      if (sign * isl_val_sgn(v) <= 0) {
1151
4.05k
        isl_val_free(v);
1152
4.05k
        continue;
1153
4.05k
      }
1154
797
      v = isl_val_abs(v);
1155
797
      expr = isl_ast_expr_add_term(expr,
1156
797
            ls, l[i], j, v, data);
1157
797
    }
1158
3.65k
  }
1159
1.21k
1160
1.21k
  isl_local_space_free(ls);
1161
1.21k
1162
1.21k
  return expr;
1163
1.21k
}
1164
1165
/* Should the constant term "v" be considered positive?
1166
 *
1167
 * A positive constant will be added to "pos" by the caller,
1168
 * while a negative constant will be added to "neg".
1169
 * If either "pos" or "neg" is exactly zero, then we prefer
1170
 * to add the constant "v" to that side, irrespective of the sign of "v".
1171
 * This results in slightly shorter expressions and may reduce the risk
1172
 * of overflows.
1173
 */
1174
static int constant_is_considered_positive(__isl_keep isl_val *v,
1175
  __isl_keep isl_ast_expr *pos, __isl_keep isl_ast_expr *neg)
1176
609
{
1177
609
  if (ast_expr_is_zero(pos))
1178
174
    return 1;
1179
435
  if (ast_expr_is_zero(neg))
1180
300
    return 0;
1181
135
  return isl_val_is_pos(v);
1182
135
}
1183
1184
/* Check if the equality
1185
 *
1186
 *  aff = 0
1187
 *
1188
 * represents a stride constraint on the integer division "pos".
1189
 *
1190
 * In particular, if the integer division "pos" is equal to
1191
 *
1192
 *  floor(e/d)
1193
 *
1194
 * then check if aff is equal to
1195
 *
1196
 *  e - d floor(e/d)
1197
 *
1198
 * or its opposite.
1199
 *
1200
 * If so, the equality is exactly
1201
 *
1202
 *  e mod d = 0
1203
 *
1204
 * Note that in principle we could also accept
1205
 *
1206
 *  e - d floor(e'/d)
1207
 *
1208
 * where e and e' differ by a constant.
1209
 */
1210
static int is_stride_constraint(__isl_keep isl_aff *aff, int pos)
1211
17
{
1212
17
  isl_aff *div;
1213
17
  isl_val *c, *d;
1214
17
  int eq;
1215
17
1216
17
  div = isl_aff_get_div(aff, pos);
1217
17
  c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos);
1218
17
  d = isl_aff_get_denominator_val(div);
1219
17
  eq = isl_val_abs_eq(c, d);
1220
17
  if (eq >= 0 && eq) {
1221
17
    aff = isl_aff_copy(aff);
1222
17
    aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0);
1223
17
    div = isl_aff_scale_val(div, d);
1224
17
    if (isl_val_is_pos(c))
1225
17
      div = isl_aff_neg(div);
1226
17
    eq = isl_aff_plain_is_equal(div, aff);
1227
17
    isl_aff_free(aff);
1228
17
  } else
1229
0
    isl_val_free(d);
1230
17
  isl_val_free(c);
1231
17
  isl_aff_free(div);
1232
17
1233
17
  return eq;
1234
17
}
1235
1236
/* Are all coefficients of "aff" (zero or) negative?
1237
 */
1238
static int all_negative_coefficients(__isl_keep isl_aff *aff)
1239
17
{
1240
17
  int i, n;
1241
17
1242
17
  if (!aff)
1243
0
    return 0;
1244
17
1245
17
  n = isl_aff_dim(aff, isl_dim_param);
1246
38
  for (i = 0; i < n; 
++i21
)
1247
23
    if (isl_aff_coefficient_sgn(aff, isl_dim_param, i) > 0)
1248
2
      return 0;
1249
17
1250
17
  n = isl_aff_dim(aff, isl_dim_in);
1251
78
  for (i = 0; i < n; 
++i63
)
1252
63
    if (isl_aff_coefficient_sgn(aff, isl_dim_in, i) > 0)
1253
0
      return 0;
1254
15
1255
15
  return 1;
1256
15
}
1257
1258
/* Give an equality of the form
1259
 *
1260
 *  aff = e - d floor(e/d) = 0
1261
 *
1262
 * or
1263
 *
1264
 *  aff = -e + d floor(e/d) = 0
1265
 *
1266
 * with the integer division "pos" equal to floor(e/d),
1267
 * construct the AST expression
1268
 *
1269
 *  (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(e), expr(d)), expr(0))
1270
 *
1271
 * If e only has negative coefficients, then construct
1272
 *
1273
 *  (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(-e), expr(d)), expr(0))
1274
 *
1275
 * instead.
1276
 */
1277
static __isl_give isl_ast_expr *extract_stride_constraint(
1278
  __isl_take isl_aff *aff, int pos, __isl_keep isl_ast_build *build)
1279
17
{
1280
17
  isl_ctx *ctx;
1281
17
  isl_val *c;
1282
17
  isl_ast_expr *expr, *cst;
1283
17
1284
17
  if (!aff)
1285
0
    return NULL;
1286
17
1287
17
  ctx = isl_aff_get_ctx(aff);
1288
17
1289
17
  c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos);
1290
17
  aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0);
1291
17
1292
17
  if (all_negative_coefficients(aff))
1293
15
    aff = isl_aff_neg(aff);
1294
17
1295
17
  cst = isl_ast_expr_from_val(isl_val_abs(c));
1296
17
  expr = isl_ast_expr_from_aff(aff, build);
1297
17
1298
17
  expr = isl_ast_expr_alloc_binary(isl_ast_op_zdiv_r, expr, cst);
1299
17
  cst = isl_ast_expr_alloc_int_si(ctx, 0);
1300
17
  expr = isl_ast_expr_alloc_binary(isl_ast_op_eq, expr, cst);
1301
17
1302
17
  return expr;
1303
17
}
1304
1305
/* Construct an isl_ast_expr that evaluates the condition "constraint",
1306
 * The result is simplified in terms of build->domain.
1307
 *
1308
 * We first check if the constraint is an equality of the form
1309
 *
1310
 *  e - d floor(e/d) = 0
1311
 *
1312
 * i.e.,
1313
 *
1314
 *  e mod d = 0
1315
 *
1316
 * If so, we convert it to
1317
 *
1318
 *  (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(e), expr(d)), expr(0))
1319
 *
1320
 * Otherwise, let the constraint by either "a >= 0" or "a == 0".
1321
 * We first extract hidden modulo computations from "a"
1322
 * and then collect all the terms with a positive coefficient in cons_pos
1323
 * and the terms with a negative coefficient in cons_neg.
1324
 *
1325
 * The result is then of the form
1326
 *
1327
 *  (isl_ast_op_ge, expr(pos), expr(-neg)))
1328
 *
1329
 * or
1330
 *
1331
 *  (isl_ast_op_eq, expr(pos), expr(-neg)))
1332
 *
1333
 * However, if the first expression is an integer constant (and the second
1334
 * is not), then we swap the two expressions.  This ensures that we construct,
1335
 * e.g., "i <= 5" rather than "5 >= i".
1336
 *
1337
 * Furthermore, is there are no terms with positive coefficients (or no terms
1338
 * with negative coefficients), then the constant term is added to "pos"
1339
 * (or "neg"), ignoring the sign of the constant term.
1340
 */
1341
static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
1342
  __isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build)
1343
626
{
1344
626
  int i, n;
1345
626
  isl_ctx *ctx;
1346
626
  isl_ast_expr *expr_pos;
1347
626
  isl_ast_expr *expr_neg;
1348
626
  isl_ast_expr *expr;
1349
626
  isl_aff *aff;
1350
626
  int eq;
1351
626
  enum isl_ast_op_type type;
1352
626
  struct isl_ast_add_term_data data;
1353
626
1354
626
  if (!constraint)
1355
0
    return NULL;
1356
626
1357
626
  aff = isl_constraint_get_aff(constraint);
1358
626
  eq = isl_constraint_is_equality(constraint);
1359
626
  isl_constraint_free(constraint);
1360
626
1361
626
  n = isl_aff_dim(aff, isl_dim_div);
1362
626
  if (eq && 
n > 089
)
1363
17
    for (i = 0; i < n; 
++i0
) {
1364
17
      int is_stride;
1365
17
      is_stride = is_stride_constraint(aff, i);
1366
17
      if (is_stride < 0)
1367
0
        goto error;
1368
17
      if (is_stride)
1369
17
        return extract_stride_constraint(aff, i, build);
1370
17
    }
1371
626
1372
626
  ctx = isl_aff_get_ctx(aff);
1373
609
  expr_pos = isl_ast_expr_alloc_int_si(ctx, 0);
1374
609
  expr_neg = isl_ast_expr_alloc_int_si(ctx, 0);
1375
609
1376
609
  aff = extract_modulos(aff, &expr_pos, &expr_neg, build);
1377
609
1378
609
  data.build = build;
1379
609
  data.cst = isl_aff_get_constant_val(aff);
1380
609
  expr_pos = add_signed_terms(expr_pos, aff, 1, &data);
1381
609
  data.cst = isl_val_neg(data.cst);
1382
609
  expr_neg = add_signed_terms(expr_neg, aff, -1, &data);
1383
609
  data.cst = isl_val_neg(data.cst);
1384
609
1385
609
  if (constant_is_considered_positive(data.cst, expr_pos, expr_neg)) {
1386
203
    expr_pos = isl_ast_expr_add_int(expr_pos, data.cst);
1387
406
  } else {
1388
406
    data.cst = isl_val_neg(data.cst);
1389
406
    expr_neg = isl_ast_expr_add_int(expr_neg, data.cst);
1390
406
  }
1391
609
1392
609
  if (isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int &&
1393
609
      
isl_ast_expr_get_type(expr_neg) != isl_ast_expr_int174
) {
1394
172
    type = eq ? 
isl_ast_op_eq0
: isl_ast_op_le;
1395
172
    expr = isl_ast_expr_alloc_binary(type, expr_neg, expr_pos);
1396
437
  } else {
1397
437
    type = eq ? 
isl_ast_op_eq72
:
isl_ast_op_ge365
;
1398
437
    expr = isl_ast_expr_alloc_binary(type, expr_pos, expr_neg);
1399
437
  }
1400
609
1401
609
  isl_aff_free(aff);
1402
609
  return expr;
1403
0
error:
1404
0
  isl_aff_free(aff);
1405
0
  return NULL;
1406
626
}
1407
1408
/* Wrapper around isl_constraint_cmp_last_non_zero for use
1409
 * as a callback to isl_constraint_list_sort.
1410
 * If isl_constraint_cmp_last_non_zero cannot tell the constraints
1411
 * apart, then use isl_constraint_plain_cmp instead.
1412
 */
1413
static int cmp_constraint(__isl_keep isl_constraint *a,
1414
  __isl_keep isl_constraint *b, void *user)
1415
122
{
1416
122
  int cmp;
1417
122
1418
122
  cmp = isl_constraint_cmp_last_non_zero(a, b);
1419
122
  if (cmp != 0)
1420
101
    return cmp;
1421
21
  return isl_constraint_plain_cmp(a, b);
1422
21
}
1423
1424
/* Construct an isl_ast_expr that evaluates the conditions defining "bset".
1425
 * The result is simplified in terms of build->domain.
1426
 *
1427
 * If "bset" is not bounded by any constraint, then we construct
1428
 * the expression "1", i.e., "true".
1429
 *
1430
 * Otherwise, we sort the constraints, putting constraints that involve
1431
 * integer divisions after those that do not, and construct an "and"
1432
 * of the ast expressions of the individual constraints.
1433
 *
1434
 * Each constraint is added to the generated constraints of the build
1435
 * after it has been converted to an AST expression so that it can be used
1436
 * to simplify the following constraints.  This may change the truth value
1437
 * of subsequent constraints that do not satisfy the earlier constraints,
1438
 * but this does not affect the outcome of the conjunction as it is
1439
 * only true if all the conjuncts are true (no matter in what order
1440
 * they are evaluated).  In particular, the constraints that do not
1441
 * involve integer divisions may serve to simplify some constraints
1442
 * that do involve integer divisions.
1443
 */
1444
__isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set(
1445
   __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset)
1446
962
{
1447
962
  int i, n;
1448
962
  isl_constraint *c;
1449
962
  isl_constraint_list *list;
1450
962
  isl_ast_expr *res;
1451
962
  isl_set *set;
1452
962
1453
962
  list = isl_basic_set_get_constraint_list(bset);
1454
962
  isl_basic_set_free(bset);
1455
962
  list = isl_constraint_list_sort(list, &cmp_constraint, NULL);
1456
962
  if (!list)
1457
0
    return NULL;
1458
962
  n = isl_constraint_list_n_constraint(list);
1459
962
  if (n == 0) {
1460
440
    isl_ctx *ctx = isl_constraint_list_get_ctx(list);
1461
440
    isl_constraint_list_free(list);
1462
440
    return isl_ast_expr_alloc_int_si(ctx, 1);
1463
440
  }
1464
522
1465
522
  build = isl_ast_build_copy(build);
1466
522
1467
522
  c = isl_constraint_list_get_constraint(list, 0);
1468
522
  bset = isl_basic_set_from_constraint(isl_constraint_copy(c));
1469
522
  set = isl_set_from_basic_set(bset);
1470
522
  res = isl_ast_expr_from_constraint(c, build);
1471
522
  build = isl_ast_build_restrict_generated(build, set);
1472
522
1473
626
  for (i = 1; i < n; 
++i104
) {
1474
104
    isl_ast_expr *expr;
1475
104
1476
104
    c = isl_constraint_list_get_constraint(list, i);
1477
104
    bset = isl_basic_set_from_constraint(isl_constraint_copy(c));
1478
104
    set = isl_set_from_basic_set(bset);
1479
104
    expr = isl_ast_expr_from_constraint(c, build);
1480
104
    build = isl_ast_build_restrict_generated(build, set);
1481
104
    res = isl_ast_expr_and(res, expr);
1482
104
  }
1483
522
1484
522
  isl_constraint_list_free(list);
1485
522
  isl_ast_build_free(build);
1486
522
  return res;
1487
522
}
1488
1489
/* Construct an isl_ast_expr that evaluates the conditions defining "set".
1490
 * The result is simplified in terms of build->domain.
1491
 *
1492
 * If "set" is an (obviously) empty set, then return the expression "0".
1493
 *
1494
 * If there are multiple disjuncts in the description of the set,
1495
 * then subsequent disjuncts are simplified in a context where
1496
 * the previous disjuncts have been removed from build->domain.
1497
 * In particular, constraints that ensure that there is no overlap
1498
 * with these previous disjuncts, can be removed.
1499
 * This is mostly useful for disjuncts that are only defined by
1500
 * a single constraint (relative to the build domain) as the opposite
1501
 * of that single constraint can then be removed from the other disjuncts.
1502
 * In order not to increase the number of disjuncts in the build domain
1503
 * after subtracting the previous disjuncts of "set", the simple hull
1504
 * is computed after taking the difference with each of these disjuncts.
1505
 * This means that constraints that prevent overlap with a union
1506
 * of multiple previous disjuncts are not removed.
1507
 *
1508
 * "set" lives in the internal schedule space.
1509
 */
1510
__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal(
1511
  __isl_keep isl_ast_build *build, __isl_take isl_set *set)
1512
859
{
1513
859
  int i, n;
1514
859
  isl_basic_set *bset;
1515
859
  isl_basic_set_list *list;
1516
859
  isl_set *domain;
1517
859
  isl_ast_expr *res;
1518
859
1519
859
  list = isl_set_get_basic_set_list(set);
1520
859
  isl_set_free(set);
1521
859
1522
859
  if (!list)
1523
0
    return NULL;
1524
859
  n = isl_basic_set_list_n_basic_set(list);
1525
859
  if (n == 0) {
1526
3
    isl_ctx *ctx = isl_ast_build_get_ctx(build);
1527
3
    isl_basic_set_list_free(list);
1528
3
    return isl_ast_expr_from_val(isl_val_zero(ctx));
1529
3
  }
1530
856
1531
856
  domain = isl_ast_build_get_domain(build);
1532
856
1533
856
  bset = isl_basic_set_list_get_basic_set(list, 0);
1534
856
  set = isl_set_from_basic_set(isl_basic_set_copy(bset));
1535
856
  res = isl_ast_build_expr_from_basic_set(build, bset);
1536
856
1537
962
  for (i = 1; i < n; 
++i106
) {
1538
106
    isl_ast_expr *expr;
1539
106
    isl_set *rest;
1540
106
1541
106
    rest = isl_set_subtract(isl_set_copy(domain), set);
1542
106
    rest = isl_set_from_basic_set(isl_set_simple_hull(rest));
1543
106
    domain = isl_set_intersect(domain, rest);
1544
106
    bset = isl_basic_set_list_get_basic_set(list, i);
1545
106
    set = isl_set_from_basic_set(isl_basic_set_copy(bset));
1546
106
    bset = isl_basic_set_gist(bset,
1547
106
        isl_set_simple_hull(isl_set_copy(domain)));
1548
106
    expr = isl_ast_build_expr_from_basic_set(build, bset);
1549
106
    res = isl_ast_expr_or(res, expr);
1550
106
  }
1551
856
1552
856
  isl_set_free(domain);
1553
856
  isl_set_free(set);
1554
856
  isl_basic_set_list_free(list);
1555
856
  return res;
1556
856
}
1557
1558
/* Construct an isl_ast_expr that evaluates the conditions defining "set".
1559
 * The result is simplified in terms of build->domain.
1560
 *
1561
 * If "set" is an (obviously) empty set, then return the expression "0".
1562
 *
1563
 * "set" lives in the external schedule space.
1564
 *
1565
 * The internal AST expression generation assumes that there are
1566
 * no unknown divs, so make sure an explicit representation is available.
1567
 * Since the set comes from the outside, it may have constraints that
1568
 * are redundant with respect to the build domain.  Remove them first.
1569
 */
1570
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
1571
  __isl_keep isl_ast_build *build, __isl_take isl_set *set)
1572
605
{
1573
605
  if (isl_ast_build_need_schedule_map(build)) {
1574
7
    isl_multi_aff *ma;
1575
7
    ma = isl_ast_build_get_schedule_map_multi_aff(build);
1576
7
    set = isl_set_preimage_multi_aff(set, ma);
1577
7
  }
1578
605
1579
605
  set = isl_set_compute_divs(set);
1580
605
  set = isl_ast_build_compute_gist(build, set);
1581
605
  return isl_ast_build_expr_from_set_internal(build, set);
1582
605
}
1583
1584
/* State of data about previous pieces in
1585
 * isl_ast_build_expr_from_pw_aff_internal.
1586
 *
1587
 * isl_state_none: no data about previous pieces
1588
 * isl_state_single: data about a single previous piece
1589
 * isl_state_min: data represents minimum of several pieces
1590
 * isl_state_max: data represents maximum of several pieces
1591
 */
1592
enum isl_from_pw_aff_state {
1593
  isl_state_none,
1594
  isl_state_single,
1595
  isl_state_min,
1596
  isl_state_max
1597
};
1598
1599
/* Internal date structure representing a single piece in the input of
1600
 * isl_ast_build_expr_from_pw_aff_internal.
1601
 *
1602
 * If "state" is isl_state_none, then "set_list" and "aff_list" are not used.
1603
 * If "state" is isl_state_single, then "set_list" and "aff_list" contain the
1604
 * single previous subpiece.
1605
 * If "state" is isl_state_min, then "set_list" and "aff_list" contain
1606
 * a sequence of several previous subpieces that are equal to the minimum
1607
 * of the entries in "aff_list" over the union of "set_list"
1608
 * If "state" is isl_state_max, then "set_list" and "aff_list" contain
1609
 * a sequence of several previous subpieces that are equal to the maximum
1610
 * of the entries in "aff_list" over the union of "set_list"
1611
 *
1612
 * During the construction of the pieces, "set" is NULL.
1613
 * After the construction, "set" is set to the union of the elements
1614
 * in "set_list", at which point "set_list" is set to NULL.
1615
 */
1616
struct isl_from_pw_aff_piece {
1617
  enum isl_from_pw_aff_state state;
1618
  isl_set *set;
1619
  isl_set_list *set_list;
1620
  isl_aff_list *aff_list;
1621
};
1622
1623
/* Internal data structure for isl_ast_build_expr_from_pw_aff_internal.
1624
 *
1625
 * "build" specifies the domain against which the result is simplified.
1626
 * "dom" is the domain of the entire isl_pw_aff.
1627
 *
1628
 * "n" is the number of pieces constructed already.
1629
 * In particular, during the construction of the pieces, "n" points to
1630
 * the piece that is being constructed.  After the construction of the
1631
 * pieces, "n" is set to the total number of pieces.
1632
 * "max" is the total number of allocated entries.
1633
 * "p" contains the individual pieces.
1634
 */
1635
struct isl_from_pw_aff_data {
1636
  isl_ast_build *build;
1637
  isl_set *dom;
1638
1639
  int n;
1640
  int max;
1641
  struct isl_from_pw_aff_piece *p;
1642
};
1643
1644
/* Initialize "data" based on "build" and "pa".
1645
 */
1646
static isl_stat isl_from_pw_aff_data_init(struct isl_from_pw_aff_data *data,
1647
  __isl_keep isl_ast_build *build, __isl_keep isl_pw_aff *pa)
1648
8.32k
{
1649
8.32k
  int n;
1650
8.32k
  isl_ctx *ctx;
1651
8.32k
1652
8.32k
  ctx = isl_pw_aff_get_ctx(pa);
1653
8.32k
  n = isl_pw_aff_n_piece(pa);
1654
8.32k
  if (n == 0)
1655
8.32k
    
isl_die0
(ctx, isl_error_invalid,
1656
8.32k
      "cannot handle void expression", return isl_stat_error);
1657
8.32k
  data->max = n;
1658
8.32k
  data->p = isl_calloc_array(ctx, struct isl_from_pw_aff_piece, n);
1659
8.32k
  if (!data->p)
1660
0
    return isl_stat_error;
1661
8.32k
  data->build = build;
1662
8.32k
  data->dom = isl_pw_aff_domain(isl_pw_aff_copy(pa));
1663
8.32k
  data->n = 0;
1664
8.32k
1665
8.32k
  return isl_stat_ok;
1666
8.32k
}
1667
1668
/* Free all memory allocated for "data".
1669
 */
1670
static void isl_from_pw_aff_data_clear(struct isl_from_pw_aff_data *data)
1671
8.32k
{
1672
8.32k
  int i;
1673
8.32k
1674
8.32k
  isl_set_free(data->dom);
1675
8.32k
  if (!data->p)
1676
0
    return;
1677
8.32k
1678
16.6k
  
for (i = 0; 8.32k
i < data->max;
++i8.36k
) {
1679
8.36k
    isl_set_free(data->p[i].set);
1680
8.36k
    isl_set_list_free(data->p[i].set_list);
1681
8.36k
    isl_aff_list_free(data->p[i].aff_list);
1682
8.36k
  }
1683
8.32k
  free(data->p);
1684
8.32k
}
1685
1686
/* Initialize the current entry of "data" to an unused piece.
1687
 */
1688
static void set_none(struct isl_from_pw_aff_data *data)
1689
8.32k
{
1690
8.32k
  data->p[data->n].state = isl_state_none;
1691
8.32k
  data->p[data->n].set_list = NULL;
1692
8.32k
  data->p[data->n].aff_list = NULL;
1693
8.32k
}
1694
1695
/* Store "set" and "aff" in the current entry of "data" as a single subpiece.
1696
 */
1697
static void set_single(struct isl_from_pw_aff_data *data,
1698
  __isl_take isl_set *set, __isl_take isl_aff *aff)
1699
8.34k
{
1700
8.34k
  data->p[data->n].state = isl_state_single;
1701
8.34k
  data->p[data->n].set_list = isl_set_list_from_set(set);
1702
8.34k
  data->p[data->n].aff_list = isl_aff_list_from_aff(aff);
1703
8.34k
}
1704
1705
/* Extend the current entry of "data" with "set" and "aff"
1706
 * as a minimum expression.
1707
 */
1708
static isl_stat extend_min(struct isl_from_pw_aff_data *data,
1709
  __isl_take isl_set *set, __isl_take isl_aff *aff)
1710
9
{
1711
9
  int n = data->n;
1712
9
  data->p[n].state = isl_state_min;
1713
9
  data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set);
1714
9
  data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff);
1715
9
1716
9
  if (!data->p[n].set_list || !data->p[n].aff_list)
1717
0
    return isl_stat_error;
1718
9
  return isl_stat_ok;
1719
9
}
1720
1721
/* Extend the current entry of "data" with "set" and "aff"
1722
 * as a maximum expression.
1723
 */
1724
static isl_stat extend_max(struct isl_from_pw_aff_data *data,
1725
  __isl_take isl_set *set, __isl_take isl_aff *aff)
1726
11
{
1727
11
  int n = data->n;
1728
11
  data->p[n].state = isl_state_max;
1729
11
  data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set);
1730
11
  data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff);
1731
11
1732
11
  if (!data->p[n].set_list || !data->p[n].aff_list)
1733
0
    return isl_stat_error;
1734
11
  return isl_stat_ok;
1735
11
}
1736
1737
/* Extend the domain of the current entry of "data", which is assumed
1738
 * to contain a single subpiece, with "set".  If "replace" is set,
1739
 * then also replace the affine function by "aff".  Otherwise,
1740
 * simply free "aff".
1741
 */
1742
static isl_stat extend_domain(struct isl_from_pw_aff_data *data,
1743
  __isl_take isl_set *set, __isl_take isl_aff *aff, int replace)
1744
2
{
1745
2
  int n = data->n;
1746
2
  isl_set *set_n;
1747
2
1748
2
  set_n = isl_set_list_get_set(data->p[n].set_list, 0);
1749
2
  set_n = isl_set_union(set_n, set);
1750
2
  data->p[n].set_list =
1751
2
    isl_set_list_set_set(data->p[n].set_list, 0, set_n);
1752
2
1753
2
  if (replace)
1754
2
    data->p[n].aff_list =
1755
2
      isl_aff_list_set_aff(data->p[n].aff_list, 0, aff);
1756
0
  else
1757
0
    isl_aff_free(aff);
1758
2
1759
2
  if (!data->p[n].set_list || !data->p[n].aff_list)
1760
0
    return isl_stat_error;
1761
2
  return isl_stat_ok;
1762
2
}
1763
1764
/* Construct an isl_ast_expr from "list" within "build".
1765
 * If "state" is isl_state_single, then "list" contains a single entry and
1766
 * an isl_ast_expr is constructed for that entry.
1767
 * Otherwise a min or max expression is constructed from "list"
1768
 * depending on "state".
1769
 */
1770
static __isl_give isl_ast_expr *ast_expr_from_aff_list(
1771
  __isl_take isl_aff_list *list, enum isl_from_pw_aff_state state,
1772
  __isl_keep isl_ast_build *build)
1773
8.34k
{
1774
8.34k
  int i, n;
1775
8.34k
  isl_aff *aff;
1776
8.34k
  isl_ast_expr *expr;
1777
8.34k
  enum isl_ast_op_type op_type;
1778
8.34k
1779
8.34k
  if (state == isl_state_single) {
1780
8.32k
    aff = isl_aff_list_get_aff(list, 0);
1781
8.32k
    isl_aff_list_free(list);
1782
8.32k
    return isl_ast_expr_from_aff(aff, build);
1783
8.32k
  }
1784
20
  n = isl_aff_list_n_aff(list);
1785
20
  op_type = state == isl_state_min ? 
isl_ast_op_min9
:
isl_ast_op_max11
;
1786
20
  expr = isl_ast_expr_alloc_op(isl_ast_build_get_ctx(build), op_type, n);
1787
20
  if (!expr)
1788
0
    goto error;
1789
20
1790
60
  
for (i = 0; 20
i < n;
++i40
) {
1791
40
    isl_ast_expr *expr_i;
1792
40
1793
40
    aff = isl_aff_list_get_aff(list, i);
1794
40
    expr_i = isl_ast_expr_from_aff(aff, build);
1795
40
    if (!expr_i)
1796
0
      goto error;
1797
40
    expr->u.op.args[i] = expr_i;
1798
40
  }
1799
20
1800
20
  isl_aff_list_free(list);
1801
20
  return expr;
1802
0
error:
1803
0
  isl_aff_list_free(list);
1804
0
  isl_ast_expr_free(expr);
1805
0
  return NULL;
1806
20
}
1807
1808
/* Extend the expression in "next" to take into account
1809
 * the piece at position "pos" in "data", allowing for a further extension
1810
 * for the next piece(s).
1811
 * In particular, "next" is set to a select operation that selects
1812
 * an isl_ast_expr corresponding to data->aff_list on data->set and
1813
 * to an expression that will be filled in by later calls.
1814
 * Return a pointer to this location.
1815
 * Afterwards, the state of "data" is set to isl_state_none.
1816
 *
1817
 * The constraints of data->set are added to the generated
1818
 * constraints of the build such that they can be exploited to simplify
1819
 * the AST expression constructed from data->aff_list.
1820
 */
1821
static isl_ast_expr **add_intermediate_piece(struct isl_from_pw_aff_data *data,
1822
  int pos, isl_ast_expr **next)
1823
13
{
1824
13
  isl_ctx *ctx;
1825
13
  isl_ast_build *build;
1826
13
  isl_ast_expr *ternary, *arg;
1827
13
  isl_set *set, *gist;
1828
13
1829
13
  set = data->p[pos].set;
1830
13
  data->p[pos].set = NULL;
1831
13
  ctx = isl_ast_build_get_ctx(data->build);
1832
13
  ternary = isl_ast_expr_alloc_op(ctx, isl_ast_op_select, 3);
1833
13
  gist = isl_set_gist(isl_set_copy(set), isl_set_copy(data->dom));
1834
13
  arg = isl_ast_build_expr_from_set_internal(data->build, gist);
1835
13
  ternary = isl_ast_expr_set_op_arg(ternary, 0, arg);
1836
13
  build = isl_ast_build_copy(data->build);
1837
13
  build = isl_ast_build_restrict_generated(build, set);
1838
13
  arg = ast_expr_from_aff_list(data->p[pos].aff_list,
1839
13
          data->p[pos].state, build);
1840
13
  data->p[pos].aff_list = NULL;
1841
13
  isl_ast_build_free(build);
1842
13
  ternary = isl_ast_expr_set_op_arg(ternary, 1, arg);
1843
13
  data->p[pos].state = isl_state_none;
1844
13
  if (!ternary)
1845
0
    return NULL;
1846
13
1847
13
  *next = ternary;
1848
13
  return &ternary->u.op.args[2];
1849
13
}
1850
1851
/* Extend the expression in "next" to take into account
1852
 * the final piece, located at position "pos" in "data".
1853
 * In particular, "next" is set to evaluate data->aff_list
1854
 * and the domain is ignored.
1855
 * Return isl_stat_ok on success and isl_stat_error on failure.
1856
 *
1857
 * The constraints of data->set are however added to the generated
1858
 * constraints of the build such that they can be exploited to simplify
1859
 * the AST expression constructed from data->aff_list.
1860
 */
1861
static isl_stat add_last_piece(struct isl_from_pw_aff_data *data,
1862
  int pos, isl_ast_expr **next)
1863
8.32k
{
1864
8.32k
  isl_ast_build *build;
1865
8.32k
1866
8.32k
  if (data->p[pos].state == isl_state_none)
1867
8.32k
    
isl_die0
(isl_ast_build_get_ctx(data->build), isl_error_invalid,
1868
8.32k
      "cannot handle void expression", return isl_stat_error);
1869
8.32k
1870
8.32k
  build = isl_ast_build_copy(data->build);
1871
8.32k
  build = isl_ast_build_restrict_generated(build, data->p[pos].set);
1872
8.32k
  data->p[pos].set = NULL;
1873
8.32k
  *next = ast_expr_from_aff_list(data->p[pos].aff_list,
1874
8.32k
            data->p[pos].state, build);
1875
8.32k
  data->p[pos].aff_list = NULL;
1876
8.32k
  isl_ast_build_free(build);
1877
8.32k
  data->p[pos].state = isl_state_none;
1878
8.32k
  if (!*next)
1879
0
    return isl_stat_error;
1880
8.32k
1881
8.32k
  return isl_stat_ok;
1882
8.32k
}
1883
1884
/* Return -1 if the piece "p1" should be sorted before "p2"
1885
 * and 1 if it should be sorted after "p2".
1886
 * Return 0 if they do not need to be sorted in a specific order.
1887
 *
1888
 * Pieces are sorted according to the number of disjuncts
1889
 * in their domains.
1890
 */
1891
static int sort_pieces_cmp(const void *p1, const void *p2, void *arg)
1892
16
{
1893
16
  const struct isl_from_pw_aff_piece *piece1 = p1;
1894
16
  const struct isl_from_pw_aff_piece *piece2 = p2;
1895
16
  int n1, n2;
1896
16
1897
16
  n1 = isl_set_n_basic_set(piece1->set);
1898
16
  n2 = isl_set_n_basic_set(piece2->set);
1899
16
1900
16
  return n1 - n2;
1901
16
}
1902
1903
/* Construct an isl_ast_expr from the pieces in "data".
1904
 * Return the result or NULL on failure.
1905
 *
1906
 * When this function is called, data->n points to the current piece.
1907
 * If this is an effective piece, then first increment data->n such
1908
 * that data->n contains the number of pieces.
1909
 * The "set_list" fields are subsequently replaced by the corresponding
1910
 * "set" fields, after which the pieces are sorted according to
1911
 * the number of disjuncts in these "set" fields.
1912
 *
1913
 * Construct intermediate AST expressions for the initial pieces and
1914
 * finish off with the final pieces.
1915
 */
1916
static isl_ast_expr *build_pieces(struct isl_from_pw_aff_data *data)
1917
8.32k
{
1918
8.32k
  int i;
1919
8.32k
  isl_ast_expr *res = NULL;
1920
8.32k
  isl_ast_expr **next = &res;
1921
8.32k
1922
8.32k
  if (data->p[data->n].state != isl_state_none)
1923
8.32k
    data->n++;
1924
8.32k
  if (data->n == 0)
1925
8.32k
    
isl_die0
(isl_ast_build_get_ctx(data->build), isl_error_invalid,
1926
8.32k
      "cannot handle void expression", return NULL);
1927
8.32k
1928
16.6k
  
for (i = 0; 8.32k
i < data->n;
++i8.34k
) {
1929
8.34k
    data->p[i].set = isl_set_list_union(data->p[i].set_list);
1930
8.34k
    if (data->p[i].state != isl_state_single)
1931
20
      data->p[i].set = isl_set_coalesce(data->p[i].set);
1932
8.34k
    data->p[i].set_list = NULL;
1933
8.34k
  }
1934
8.32k
1935
8.32k
  if (isl_sort(data->p, data->n, sizeof(data->p[0]),
1936
8.32k
      &sort_pieces_cmp, NULL) < 0)
1937
0
    return isl_ast_expr_free(res);
1938
8.32k
1939
8.34k
  
for (i = 0; 8.32k
i + 1 < data->n;
++i13
) {
1940
13
    next = add_intermediate_piece(data, i, next);
1941
13
    if (!next)
1942
0
      return isl_ast_expr_free(res);
1943
13
  }
1944
8.32k
1945
8.32k
  if (add_last_piece(data, data->n - 1, next) < 0)
1946
0
    return isl_ast_expr_free(res);
1947
8.32k
1948
8.32k
  return res;
1949
8.32k
}
1950
1951
/* Is the domain of the current entry of "data", which is assumed
1952
 * to contain a single subpiece, a subset of "set"?
1953
 */
1954
static isl_bool single_is_subset(struct isl_from_pw_aff_data *data,
1955
  __isl_keep isl_set *set)
1956
34
{
1957
34
  isl_bool subset;
1958
34
  isl_set *set_n;
1959
34
1960
34
  set_n = isl_set_list_get_set(data->p[data->n].set_list, 0);
1961
34
  subset = isl_set_is_subset(set_n, set);
1962
34
  isl_set_free(set_n);
1963
34
1964
34
  return subset;
1965
34
}
1966
1967
/* Is "aff" a rational expression, i.e., does it have a denominator
1968
 * different from one?
1969
 */
1970
static isl_bool aff_is_rational(__isl_keep isl_aff *aff)
1971
109
{
1972
109
  isl_bool rational;
1973
109
  isl_val *den;
1974
109
1975
109
  den = isl_aff_get_denominator_val(aff);
1976
109
  rational = isl_bool_not(isl_val_is_one(den));
1977
109
  isl_val_free(den);
1978
109
1979
109
  return rational;
1980
109
}
1981
1982
/* Does "list" consist of a single rational affine expression?
1983
 */
1984
static isl_bool is_single_rational_aff(__isl_keep isl_aff_list *list)
1985
54
{
1986
54
  isl_bool rational;
1987
54
  isl_aff *aff;
1988
54
1989
54
  if (isl_aff_list_n_aff(list) != 1)
1990
1
    return isl_bool_false;
1991
53
  aff = isl_aff_list_get_aff(list, 0);
1992
53
  rational = aff_is_rational(aff);
1993
53
  isl_aff_free(aff);
1994
53
1995
53
  return rational;
1996
53
}
1997
1998
/* Can the list of subpieces in the last piece of "data" be extended with
1999
 * "set" and "aff" based on "test"?
2000
 * In particular, is it the case for each entry (set_i, aff_i) that
2001
 *
2002
 *  test(aff, aff_i) holds on set_i, and
2003
 *  test(aff_i, aff) holds on set?
2004
 *
2005
 * "test" returns the set of elements where the tests holds, meaning
2006
 * that test(aff_i, aff) holds on set if set is a subset of test(aff_i, aff).
2007
 *
2008
 * This function is used to detect min/max expressions.
2009
 * If the ast_build_detect_min_max option is turned off, then
2010
 * do not even try and perform any detection and return false instead.
2011
 *
2012
 * Rational affine expressions are not considered for min/max expressions
2013
 * since the combined expression will be defined on the union of the domains,
2014
 * while a rational expression may only yield integer values
2015
 * on its own definition domain.
2016
 */
2017
static isl_bool extends(struct isl_from_pw_aff_data *data,
2018
  __isl_keep isl_set *set, __isl_keep isl_aff *aff,
2019
  __isl_give isl_basic_set *(*test)(__isl_take isl_aff *aff1,
2020
    __isl_take isl_aff *aff2))
2021
56
{
2022
56
  int i, n;
2023
56
  isl_bool is_rational;
2024
56
  isl_ctx *ctx;
2025
56
  isl_set *dom;
2026
56
2027
56
  is_rational = aff_is_rational(aff);
2028
56
  if (is_rational >= 0 && !is_rational)
2029
54
    is_rational = is_single_rational_aff(data->p[data->n].aff_list);
2030
56
  if (is_rational < 0 || is_rational)
2031
2
    return isl_bool_not(is_rational);
2032
54
2033
54
  ctx = isl_ast_build_get_ctx(data->build);
2034
54
  if (!isl_options_get_ast_build_detect_min_max(ctx))
2035
2
    return isl_bool_false;
2036
52
2037
52
  dom = isl_ast_build_get_domain(data->build);
2038
52
  set = isl_set_intersect(dom, isl_set_copy(set));
2039
52
2040
52
  n = isl_set_list_n_set(data->p[data->n].set_list);
2041
72
  for (i = 0; i < n ; 
++i20
) {
2042
52
    isl_aff *aff_i;
2043
52
    isl_set *valid;
2044
52
    isl_set *dom, *required;
2045
52
    isl_bool is_valid;
2046
52
2047
52
    aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i);
2048
52
    valid = isl_set_from_basic_set(test(isl_aff_copy(aff), aff_i));
2049
52
    required = isl_set_list_get_set(data->p[data->n].set_list, i);
2050
52
    dom = isl_ast_build_get_domain(data->build);
2051
52
    required = isl_set_intersect(dom, required);
2052
52
    is_valid = isl_set_is_subset(required, valid);
2053
52
    isl_set_free(required);
2054
52
    isl_set_free(valid);
2055
52
    if (is_valid < 0 || !is_valid) {
2056
24
      isl_set_free(set);
2057
24
      return is_valid;
2058
24
    }
2059
28
2060
28
    aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i);
2061
28
    valid = isl_set_from_basic_set(test(aff_i, isl_aff_copy(aff)));
2062
28
    is_valid = isl_set_is_subset(set, valid);
2063
28
    isl_set_free(valid);
2064
28
    if (is_valid < 0 || !is_valid) {
2065
8
      isl_set_free(set);
2066
8
      return is_valid;
2067
8
    }
2068
28
  }
2069
52
2070
52
  isl_set_free(set);
2071
20
  return isl_bool_true;
2072
52
}
2073
2074
/* Can the list of pieces in "data" be extended with "set" and "aff"
2075
 * to form/preserve a minimum expression?
2076
 * In particular, is it the case for each entry (set_i, aff_i) that
2077
 *
2078
 *  aff >= aff_i on set_i, and
2079
 *  aff_i >= aff on set?
2080
 */
2081
static isl_bool extends_min(struct isl_from_pw_aff_data *data,
2082
  __isl_keep isl_set *set,  __isl_keep isl_aff *aff)
2083
32
{
2084
32
  return extends(data, set, aff, &isl_aff_ge_basic_set);
2085
32
}
2086
2087
/* Can the list of pieces in "data" be extended with "set" and "aff"
2088
 * to form/preserve a maximum expression?
2089
 * In particular, is it the case for each entry (set_i, aff_i) that
2090
 *
2091
 *  aff <= aff_i on set_i, and
2092
 *  aff_i <= aff on set?
2093
 */
2094
static isl_bool extends_max(struct isl_from_pw_aff_data *data,
2095
  __isl_keep isl_set *set,  __isl_keep isl_aff *aff)
2096
24
{
2097
24
  return extends(data, set, aff, &isl_aff_le_basic_set);
2098
24
}
2099
2100
/* This function is called during the construction of an isl_ast_expr
2101
 * that evaluates an isl_pw_aff.
2102
 * If the last piece of "data" contains a single subpiece and
2103
 * if its affine function is equal to "aff" on a part of the domain
2104
 * that includes either "set" or the domain of that single subpiece,
2105
 * then extend the domain of that single subpiece with "set".
2106
 * If it was the original domain of the single subpiece where
2107
 * the two affine functions are equal, then also replace
2108
 * the affine function of the single subpiece by "aff".
2109
 * If the last piece of "data" contains either a single subpiece
2110
 * or a minimum, then check if this minimum expression can be extended
2111
 * with (set, aff).
2112
 * If so, extend the sequence and return.
2113
 * Perform the same operation for maximum expressions.
2114
 * If no such extension can be performed, then move to the next piece
2115
 * in "data" (if the current piece contains any data), and then store
2116
 * the current subpiece in the current piece of "data" for later handling.
2117
 */
2118
static isl_stat ast_expr_from_pw_aff(__isl_take isl_set *set,
2119
  __isl_take isl_aff *aff, void *user)
2120
8.36k
{
2121
8.36k
  struct isl_from_pw_aff_data *data = user;
2122
8.36k
  isl_bool test;
2123
8.36k
  enum isl_from_pw_aff_state state;
2124
8.36k
2125
8.36k
  state = data->p[data->n].state;
2126
8.36k
  if (state == isl_state_single) {
2127
34
    isl_aff *aff0;
2128
34
    isl_set *eq;
2129
34
    isl_bool subset1, subset2 = isl_bool_false;
2130
34
    aff0 = isl_aff_list_get_aff(data->p[data->n].aff_list, 0);
2131
34
    eq = isl_aff_eq_set(isl_aff_copy(aff), aff0);
2132
34
    subset1 = isl_set_is_subset(set, eq);
2133
34
    if (subset1 >= 0 && !subset1)
2134
34
      subset2 = single_is_subset(data, eq);
2135
34
    isl_set_free(eq);
2136
34
    if (subset1 < 0 || subset2 < 0)
2137
0
      goto error;
2138
34
    if (subset1)
2139
0
      return extend_domain(data, set, aff, 0);
2140
34
    if (subset2)
2141
2
      return extend_domain(data, set, aff, 1);
2142
8.36k
  }
2143
8.36k
  if (state == isl_state_single || 
state == isl_state_min8.33k
) {
2144
32
    test = extends_min(data, set, aff);
2145
32
    if (test < 0)
2146
0
      goto error;
2147
32
    if (test)
2148
9
      return extend_min(data, set, aff);
2149
8.35k
  }
2150
8.35k
  if (state == isl_state_single || 
state == isl_state_max8.33k
) {
2151
24
    test = extends_max(data, set, aff);
2152
24
    if (test < 0)
2153
0
      goto error;
2154
24
    if (test)
2155
11
      return extend_max(data, set, aff);
2156
8.34k
  }
2157
8.34k
  if (state != isl_state_none)
2158
13
    data->n++;
2159
8.34k
  set_single(data, set, aff);
2160
8.34k
2161
8.34k
  return isl_stat_ok;
2162
0
error:
2163
0
  isl_set_free(set);
2164
0
  isl_aff_free(aff);
2165
0
  return isl_stat_error;
2166
8.34k
}
2167
2168
/* Construct an isl_ast_expr that evaluates "pa".
2169
 * The result is simplified in terms of build->domain.
2170
 *
2171
 * The domain of "pa" lives in the internal schedule space.
2172
 */
2173
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff_internal(
2174
  __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa)
2175
8.32k
{
2176
8.32k
  struct isl_from_pw_aff_data data = { NULL };
2177
8.32k
  isl_ast_expr *res = NULL;
2178
8.32k
2179
8.32k
  pa = isl_ast_build_compute_gist_pw_aff(build, pa);
2180
8.32k
  pa = isl_pw_aff_coalesce(pa);
2181
8.32k
  if (!pa)
2182
0
    return NULL;
2183
8.32k
2184
8.32k
  if (isl_from_pw_aff_data_init(&data, build, pa) < 0)
2185
0
    goto error;
2186
8.32k
  set_none(&data);
2187
8.32k
2188
8.32k
  if (isl_pw_aff_foreach_piece(pa, &ast_expr_from_pw_aff, &data) >= 0)
2189
8.32k
    res = build_pieces(&data);
2190
8.32k
2191
8.32k
  isl_pw_aff_free(pa);
2192
8.32k
  isl_from_pw_aff_data_clear(&data);
2193
8.32k
  return res;
2194
0
error:
2195
0
  isl_pw_aff_free(pa);
2196
0
  isl_from_pw_aff_data_clear(&data);
2197
0
  return NULL;
2198
8.32k
}
2199
2200
/* Construct an isl_ast_expr that evaluates "pa".
2201
 * The result is simplified in terms of build->domain.
2202
 *
2203
 * The domain of "pa" lives in the external schedule space.
2204
 */
2205
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff(
2206
  __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa)
2207
45
{
2208
45
  isl_ast_expr *expr;
2209
45
2210
45
  if (isl_ast_build_need_schedule_map(build)) {
2211
0
    isl_multi_aff *ma;
2212
0
    ma = isl_ast_build_get_schedule_map_multi_aff(build);
2213
0
    pa = isl_pw_aff_pullback_multi_aff(pa, ma);
2214
0
  }
2215
45
  expr = isl_ast_build_expr_from_pw_aff_internal(build, pa);
2216
45
  return expr;
2217
45
}
2218
2219
/* Set the ids of the input dimensions of "mpa" to the iterator ids
2220
 * of "build".
2221
 *
2222
 * The domain of "mpa" is assumed to live in the internal schedule domain.
2223
 */
2224
static __isl_give isl_multi_pw_aff *set_iterator_names(
2225
  __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
2226
3.25k
{
2227
3.25k
  int i, n;
2228
3.25k
2229
3.25k
  n = isl_multi_pw_aff_dim(mpa, isl_dim_in);
2230
18.6k
  for (i = 0; i < n; 
++i15.4k
) {
2231
15.4k
    isl_id *id;
2232
15.4k
2233
15.4k
    id = isl_ast_build_get_iterator_id(build, i);
2234
15.4k
    mpa = isl_multi_pw_aff_set_dim_id(mpa, isl_dim_in, i, id);
2235
15.4k
  }
2236
3.25k
2237
3.25k
  return mpa;
2238
3.25k
}
2239
2240
/* Construct an isl_ast_expr of type "type" with as first argument "arg0" and
2241
 * the remaining arguments derived from "mpa".
2242
 * That is, construct a call or access expression that calls/accesses "arg0"
2243
 * with arguments/indices specified by "mpa".
2244
 */
2245
static __isl_give isl_ast_expr *isl_ast_build_with_arguments(
2246
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2247
  __isl_take isl_ast_expr *arg0, __isl_take isl_multi_pw_aff *mpa)
2248
3.25k
{
2249
3.25k
  int i, n;
2250
3.25k
  isl_ctx *ctx;
2251
3.25k
  isl_ast_expr *expr;
2252
3.25k
2253
3.25k
  ctx = isl_ast_build_get_ctx(build);
2254
3.25k
2255
3.25k
  n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
2256
3.25k
  expr = isl_ast_expr_alloc_op(ctx, type, 1 + n);
2257
3.25k
  expr = isl_ast_expr_set_op_arg(expr, 0, arg0);
2258
9.93k
  for (i = 0; i < n; 
++i6.68k
) {
2259
6.68k
    isl_pw_aff *pa;
2260
6.68k
    isl_ast_expr *arg;
2261
6.68k
2262
6.68k
    pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
2263
6.68k
    arg = isl_ast_build_expr_from_pw_aff_internal(build, pa);
2264
6.68k
    expr = isl_ast_expr_set_op_arg(expr, 1 + i, arg);
2265
6.68k
  }
2266
3.25k
2267
3.25k
  isl_multi_pw_aff_free(mpa);
2268
3.25k
  return expr;
2269
3.25k
}
2270
2271
static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal(
2272
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2273
  __isl_take isl_multi_pw_aff *mpa);
2274
2275
/* Construct an isl_ast_expr that accesses the member specified by "mpa".
2276
 * The range of "mpa" is assumed to be wrapped relation.
2277
 * The domain of this wrapped relation specifies the structure being
2278
 * accessed, while the range of this wrapped relation spacifies the
2279
 * member of the structure being accessed.
2280
 *
2281
 * The domain of "mpa" is assumed to live in the internal schedule domain.
2282
 */
2283
static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_member(
2284
  __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
2285
0
{
2286
0
  isl_id *id;
2287
0
  isl_multi_pw_aff *domain;
2288
0
  isl_ast_expr *domain_expr, *expr;
2289
0
  enum isl_ast_op_type type = isl_ast_op_access;
2290
0
2291
0
  domain = isl_multi_pw_aff_copy(mpa);
2292
0
  domain = isl_multi_pw_aff_range_factor_domain(domain);
2293
0
  domain_expr = isl_ast_build_from_multi_pw_aff_internal(build,
2294
0
                type, domain);
2295
0
  mpa = isl_multi_pw_aff_range_factor_range(mpa);
2296
0
  if (!isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out))
2297
0
    isl_die(isl_ast_build_get_ctx(build), isl_error_invalid,
2298
0
      "missing field name", goto error);
2299
0
  id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out);
2300
0
  expr = isl_ast_expr_from_id(id);
2301
0
  expr = isl_ast_expr_alloc_binary(isl_ast_op_member, domain_expr, expr);
2302
0
  return isl_ast_build_with_arguments(build, type, expr, mpa);
2303
0
error:
2304
0
  isl_multi_pw_aff_free(mpa);
2305
0
  return NULL;
2306
0
}
2307
2308
/* Construct an isl_ast_expr of type "type" that calls or accesses
2309
 * the element specified by "mpa".
2310
 * The first argument is obtained from the output tuple name.
2311
 * The remaining arguments are given by the piecewise affine expressions.
2312
 *
2313
 * If the range of "mpa" is a mapped relation, then we assume it
2314
 * represents an access to a member of a structure.
2315
 *
2316
 * The domain of "mpa" is assumed to live in the internal schedule domain.
2317
 */
2318
static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal(
2319
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2320
  __isl_take isl_multi_pw_aff *mpa)
2321
3.25k
{
2322
3.25k
  isl_ctx *ctx;
2323
3.25k
  isl_id *id;
2324
3.25k
  isl_ast_expr *expr;
2325
3.25k
2326
3.25k
  if (!mpa)
2327
0
    goto error;
2328
3.25k
2329
3.25k
  if (type == isl_ast_op_access &&
2330
3.25k
      
isl_multi_pw_aff_range_is_wrapping(mpa)1.01k
)
2331
0
    return isl_ast_build_from_multi_pw_aff_member(build, mpa);
2332
3.25k
2333
3.25k
  mpa = set_iterator_names(build, mpa);
2334
3.25k
  if (!build || !mpa)
2335
0
    goto error;
2336
3.25k
2337
3.25k
  ctx = isl_ast_build_get_ctx(build);
2338
3.25k
2339
3.25k
  if (isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out))
2340
3.25k
    id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out);
2341
0
  else
2342
0
    id = isl_id_alloc(ctx, "", NULL);
2343
3.25k
2344
3.25k
  expr = isl_ast_expr_from_id(id);
2345
3.25k
  return isl_ast_build_with_arguments(build, type, expr, mpa);
2346
0
error:
2347
0
  isl_multi_pw_aff_free(mpa);
2348
0
  return NULL;
2349
3.25k
}
2350
2351
/* Construct an isl_ast_expr of type "type" that calls or accesses
2352
 * the element specified by "pma".
2353
 * The first argument is obtained from the output tuple name.
2354
 * The remaining arguments are given by the piecewise affine expressions.
2355
 *
2356
 * The domain of "pma" is assumed to live in the internal schedule domain.
2357
 */
2358
static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff_internal(
2359
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2360
  __isl_take isl_pw_multi_aff *pma)
2361
2.23k
{
2362
2.23k
  isl_multi_pw_aff *mpa;
2363
2.23k
2364
2.23k
  mpa = isl_multi_pw_aff_from_pw_multi_aff(pma);
2365
2.23k
  return isl_ast_build_from_multi_pw_aff_internal(build, type, mpa);
2366
2.23k
}
2367
2368
/* Construct an isl_ast_expr of type "type" that calls or accesses
2369
 * the element specified by "mpa".
2370
 * The first argument is obtained from the output tuple name.
2371
 * The remaining arguments are given by the piecewise affine expressions.
2372
 *
2373
 * The domain of "mpa" is assumed to live in the external schedule domain.
2374
 */
2375
static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff(
2376
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2377
  __isl_take isl_multi_pw_aff *mpa)
2378
1.01k
{
2379
1.01k
  int is_domain;
2380
1.01k
  isl_ast_expr *expr;
2381
1.01k
  isl_space *space_build, *space_mpa;
2382
1.01k
2383
1.01k
  space_build = isl_ast_build_get_space(build, 0);
2384
1.01k
  space_mpa = isl_multi_pw_aff_get_space(mpa);
2385
1.01k
  is_domain = isl_space_tuple_is_equal(space_build, isl_dim_set,
2386
1.01k
          space_mpa, isl_dim_in);
2387
1.01k
  isl_space_free(space_build);
2388
1.01k
  isl_space_free(space_mpa);
2389
1.01k
  if (is_domain < 0)
2390
0
    goto error;
2391
1.01k
  if (!is_domain)
2392
1.01k
    
isl_die0
(isl_ast_build_get_ctx(build), isl_error_invalid,
2393
1.01k
      "spaces don't match", goto error);
2394
1.01k
2395
1.01k
  if (isl_ast_build_need_schedule_map(build)) {
2396
190
    isl_multi_aff *ma;
2397
190
    ma = isl_ast_build_get_schedule_map_multi_aff(build);
2398
190
    mpa = isl_multi_pw_aff_pullback_multi_aff(mpa, ma);
2399
190
  }
2400
1.01k
2401
1.01k
  expr = isl_ast_build_from_multi_pw_aff_internal(build, type, mpa);
2402
1.01k
  return expr;
2403
0
error:
2404
0
  isl_multi_pw_aff_free(mpa);
2405
0
  return NULL;
2406
1.01k
}
2407
2408
/* Construct an isl_ast_expr that calls the domain element specified by "mpa".
2409
 * The name of the function is obtained from the output tuple name.
2410
 * The arguments are given by the piecewise affine expressions.
2411
 *
2412
 * The domain of "mpa" is assumed to live in the external schedule domain.
2413
 */
2414
__isl_give isl_ast_expr *isl_ast_build_call_from_multi_pw_aff(
2415
  __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
2416
0
{
2417
0
  return isl_ast_build_from_multi_pw_aff(build, isl_ast_op_call, mpa);
2418
0
}
2419
2420
/* Construct an isl_ast_expr that accesses the array element specified by "mpa".
2421
 * The name of the array is obtained from the output tuple name.
2422
 * The index expressions are given by the piecewise affine expressions.
2423
 *
2424
 * The domain of "mpa" is assumed to live in the external schedule domain.
2425
 */
2426
__isl_give isl_ast_expr *isl_ast_build_access_from_multi_pw_aff(
2427
  __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
2428
0
{
2429
0
  return isl_ast_build_from_multi_pw_aff(build, isl_ast_op_access, mpa);
2430
0
}
2431
2432
/* Construct an isl_ast_expr of type "type" that calls or accesses
2433
 * the element specified by "pma".
2434
 * The first argument is obtained from the output tuple name.
2435
 * The remaining arguments are given by the piecewise affine expressions.
2436
 *
2437
 * The domain of "pma" is assumed to live in the external schedule domain.
2438
 */
2439
static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff(
2440
  __isl_keep isl_ast_build *build, enum isl_ast_op_type type,
2441
  __isl_take isl_pw_multi_aff *pma)
2442
1.01k
{
2443
1.01k
  isl_multi_pw_aff *mpa;
2444
1.01k
2445
1.01k
  mpa = isl_multi_pw_aff_from_pw_multi_aff(pma);
2446
1.01k
  return isl_ast_build_from_multi_pw_aff(build, type, mpa);
2447
1.01k
}
2448
2449
/* Construct an isl_ast_expr that calls the domain element specified by "pma".
2450
 * The name of the function is obtained from the output tuple name.
2451
 * The arguments are given by the piecewise affine expressions.
2452
 *
2453
 * The domain of "pma" is assumed to live in the external schedule domain.
2454
 */
2455
__isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff(
2456
  __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
2457
0
{
2458
0
  return isl_ast_build_from_pw_multi_aff(build, isl_ast_op_call, pma);
2459
0
}
2460
2461
/* Construct an isl_ast_expr that accesses the array element specified by "pma".
2462
 * The name of the array is obtained from the output tuple name.
2463
 * The index expressions are given by the piecewise affine expressions.
2464
 *
2465
 * The domain of "pma" is assumed to live in the external schedule domain.
2466
 */
2467
__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff(
2468
  __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
2469
1.01k
{
2470
1.01k
  return isl_ast_build_from_pw_multi_aff(build, isl_ast_op_access, pma);
2471
1.01k
}
2472
2473
/* Construct an isl_ast_expr that calls the domain element
2474
 * specified by "executed".
2475
 *
2476
 * "executed" is assumed to be single-valued, with a domain that lives
2477
 * in the internal schedule space.
2478
 */
2479
__isl_give isl_ast_node *isl_ast_build_call_from_executed(
2480
  __isl_keep isl_ast_build *build, __isl_take isl_map *executed)
2481
2.23k
{
2482
2.23k
  isl_pw_multi_aff *iteration;
2483
2.23k
  isl_ast_expr *expr;
2484
2.23k
2485
2.23k
  iteration = isl_pw_multi_aff_from_map(executed);
2486
2.23k
  iteration = isl_ast_build_compute_gist_pw_multi_aff(build, iteration);
2487
2.23k
  iteration = isl_pw_multi_aff_intersect_domain(iteration,
2488
2.23k
          isl_ast_build_get_domain(build));
2489
2.23k
  expr = isl_ast_build_from_pw_multi_aff_internal(build, isl_ast_op_call,
2490
2.23k
              iteration);
2491
2.23k
  return isl_ast_node_alloc_user(expr);
2492
2.23k
}