~ubuntu-branches/ubuntu/trusty/cloog/trusty

« back to all changes in this revision

Viewing changes to isl/isl_pw_templ.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-12-15 18:39:17 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111215183917-uqggmujou8wna9js
Tags: 0.17.0-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#define S(TYPE,NAME) xS(TYPE,NAME)
5
5
 
6
6
#ifdef HAS_TYPE
7
 
static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim,
 
7
__isl_give PW *FN(PW,alloc_size)(__isl_take isl_space *dim,
8
8
        enum isl_fold type, int n)
9
9
#else
10
 
static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n)
 
10
__isl_give PW *FN(PW,alloc_size)(__isl_take isl_space *dim, int n)
11
11
#endif
12
12
{
13
13
        isl_ctx *ctx;
15
15
 
16
16
        if (!dim)
17
17
                return NULL;
18
 
        ctx = isl_dim_get_ctx(dim);
 
18
        ctx = isl_space_get_ctx(dim);
19
19
        isl_assert(ctx, n >= 0, goto error);
20
20
        pw = isl_alloc(ctx, struct PW,
21
21
                        sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)));
31
31
        pw->dim = dim;
32
32
        return pw;
33
33
error:
34
 
        isl_dim_free(dim);
 
34
        isl_space_free(dim);
35
35
        return NULL;
36
36
}
37
37
 
38
38
#ifdef HAS_TYPE
39
 
__isl_give PW *FN(PW,ZERO)(__isl_take isl_dim *dim, enum isl_fold type)
 
39
__isl_give PW *FN(PW,ZERO)(__isl_take isl_space *dim, enum isl_fold type)
40
40
{
41
 
        return FN(PW,alloc_)(dim, type, 0);
 
41
        return FN(PW,alloc_size)(dim, type, 0);
42
42
}
43
43
#else
44
 
__isl_give PW *FN(PW,ZERO)(__isl_take isl_dim *dim)
 
44
__isl_give PW *FN(PW,ZERO)(__isl_take isl_space *dim)
45
45
{
46
 
        return FN(PW,alloc_)(dim, 0);
 
46
        return FN(PW,alloc_size)(dim, 0);
47
47
}
48
48
#endif
49
49
 
51
51
        __isl_take isl_set *set, __isl_take EL *el)
52
52
{
53
53
        isl_ctx *ctx;
54
 
        isl_dim *el_dim = NULL;
 
54
        isl_space *el_dim = NULL;
55
55
 
56
56
        if (!pw || !set || !el)
57
57
                goto error;
68
68
                isl_die(ctx, isl_error_invalid, "fold types don't match",
69
69
                        goto error);
70
70
#endif
71
 
        el_dim = FN(EL,get_dim(el));
72
 
        isl_assert(ctx, isl_dim_equal(pw->dim, el_dim), goto error);
 
71
        el_dim = FN(EL,get_space(el));
 
72
        isl_assert(ctx, isl_space_is_equal(pw->dim, el_dim), goto error);
73
73
        isl_assert(ctx, pw->n < pw->size, goto error);
74
74
 
75
75
        pw->p[pw->n].set = set;
76
76
        pw->p[pw->n].FIELD = el;
77
77
        pw->n++;
78
78
        
79
 
        isl_dim_free(el_dim);
 
79
        isl_space_free(el_dim);
80
80
        return pw;
81
81
error:
82
 
        isl_dim_free(el_dim);
 
82
        isl_space_free(el_dim);
83
83
        FN(PW,free)(pw);
84
84
        isl_set_free(set);
85
85
        FN(EL,free)(el);
99
99
                goto error;
100
100
 
101
101
#ifdef HAS_TYPE
102
 
        pw = FN(PW,alloc_)(isl_set_get_dim(set), type, 1);
 
102
        pw = FN(PW,alloc_size)(FN(EL,get_space)(el), type, 1);
103
103
#else
104
 
        pw = FN(PW,alloc_)(isl_set_get_dim(set), 1);
 
104
        pw = FN(PW,alloc_size)(FN(EL,get_space)(el), 1);
105
105
#endif
106
106
 
107
107
        return FN(PW,add_piece)(pw, set, el);
120
120
                return NULL;
121
121
 
122
122
#ifdef HAS_TYPE
123
 
        dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->type, pw->n);
 
123
        dup = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->type, pw->n);
124
124
#else
125
 
        dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->n);
 
125
        dup = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->n);
126
126
#endif
127
127
        if (!dup)
128
128
                return NULL;
167
167
                isl_set_free(pw->p[i].set);
168
168
                FN(EL,free)(pw->p[i].FIELD);
169
169
        }
170
 
        isl_dim_free(pw->dim);
 
170
        isl_space_free(pw->dim);
171
171
        free(pw);
172
172
 
173
173
        return NULL;
174
174
}
175
175
 
 
176
const char *FN(PW,get_dim_name)(__isl_keep PW *pw, enum isl_dim_type type,
 
177
        unsigned pos)
 
178
{
 
179
        return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL;
 
180
}
 
181
 
 
182
int FN(PW,has_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, unsigned pos)
 
183
{
 
184
        return pw ? isl_space_has_dim_id(pw->dim, type, pos) : -1;
 
185
}
 
186
 
 
187
__isl_give isl_id *FN(PW,get_dim_id)(__isl_keep PW *pw, enum isl_dim_type type,
 
188
        unsigned pos)
 
189
{
 
190
        return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL;
 
191
}
 
192
 
 
193
const char *FN(PW,get_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type)
 
194
{
 
195
        return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL;
 
196
}
 
197
 
 
198
int FN(PW,has_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type)
 
199
{
 
200
        return pw ? isl_space_has_tuple_id(pw->dim, type) : -1;
 
201
}
 
202
 
 
203
__isl_give isl_id *FN(PW,get_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type)
 
204
{
 
205
        return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL;
 
206
}
 
207
 
176
208
int FN(PW,IS_ZERO)(__isl_keep PW *pw)
177
209
{
178
210
        if (!pw)
181
213
        return pw->n == 0;
182
214
}
183
215
 
184
 
__isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2)
 
216
#ifndef NO_REALIGN
 
217
__isl_give PW *FN(PW,realign_domain)(__isl_take PW *pw,
 
218
        __isl_take isl_reordering *exp)
 
219
{
 
220
        int i;
 
221
 
 
222
        pw = FN(PW,cow)(pw);
 
223
        if (!pw || !exp)
 
224
                return NULL;
 
225
 
 
226
        for (i = 0; i < pw->n; ++i) {
 
227
                pw->p[i].set = isl_set_realign(pw->p[i].set,
 
228
                                                    isl_reordering_copy(exp));
 
229
                if (!pw->p[i].set)
 
230
                        goto error;
 
231
                pw->p[i].FIELD = FN(EL,realign_domain)(pw->p[i].FIELD,
 
232
                                                    isl_reordering_copy(exp));
 
233
                if (!pw->p[i].FIELD)
 
234
                        goto error;
 
235
        }
 
236
 
 
237
        pw = FN(PW,reset_domain_space)(pw, isl_space_copy(exp->dim));
 
238
 
 
239
        isl_reordering_free(exp);
 
240
        return pw;
 
241
error:
 
242
        isl_reordering_free(exp);
 
243
        FN(PW,free)(pw);
 
244
        return NULL;
 
245
}
 
246
 
 
247
/* Align the parameters of "pw" to those of "model".
 
248
 */
 
249
__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_space *model)
 
250
{
 
251
        isl_ctx *ctx;
 
252
 
 
253
        if (!pw || !model)
 
254
                goto error;
 
255
 
 
256
        ctx = isl_space_get_ctx(model);
 
257
        if (!isl_space_has_named_params(model))
 
258
                isl_die(ctx, isl_error_invalid,
 
259
                        "model has unnamed parameters", goto error);
 
260
        if (!isl_space_has_named_params(pw->dim))
 
261
                isl_die(ctx, isl_error_invalid,
 
262
                        "input has unnamed parameters", goto error);
 
263
        if (!isl_space_match(pw->dim, isl_dim_param, model, isl_dim_param)) {
 
264
                isl_reordering *exp;
 
265
 
 
266
                model = isl_space_drop_dims(model, isl_dim_in,
 
267
                                        0, isl_space_dim(model, isl_dim_in));
 
268
                model = isl_space_drop_dims(model, isl_dim_out,
 
269
                                        0, isl_space_dim(model, isl_dim_out));
 
270
                exp = isl_parameter_alignment_reordering(pw->dim, model);
 
271
                exp = isl_reordering_extend_space(exp,
 
272
                                        FN(PW,get_domain_space)(pw));
 
273
                pw = FN(PW,realign_domain)(pw, exp);
 
274
        }
 
275
 
 
276
        isl_space_free(model);
 
277
        return pw;
 
278
error:
 
279
        isl_space_free(model);
 
280
        FN(PW,free)(pw);
 
281
        return NULL;
 
282
}
 
283
 
 
284
static __isl_give PW *FN(PW,align_params_pw_pw_and)(__isl_take PW *pw1,
 
285
        __isl_take PW *pw2,
 
286
        __isl_give PW *(*fn)(__isl_take PW *pw1, __isl_take PW *pw2))
 
287
{
 
288
        isl_ctx *ctx;
 
289
 
 
290
        if (!pw1 || !pw2)
 
291
                goto error;
 
292
        if (isl_space_match(pw1->dim, isl_dim_param, pw2->dim, isl_dim_param))
 
293
                return fn(pw1, pw2);
 
294
        ctx = FN(PW,get_ctx)(pw1);
 
295
        if (!isl_space_has_named_params(pw1->dim) ||
 
296
            !isl_space_has_named_params(pw2->dim))
 
297
                isl_die(ctx, isl_error_invalid,
 
298
                        "unaligned unnamed parameters", goto error);
 
299
        pw1 = FN(PW,align_params)(pw1, FN(PW,get_space)(pw2));
 
300
        pw2 = FN(PW,align_params)(pw2, FN(PW,get_space)(pw1));
 
301
        return fn(pw1, pw2);
 
302
error:
 
303
        FN(PW,free)(pw1);
 
304
        FN(PW,free)(pw2);
 
305
        return NULL;
 
306
}
 
307
 
 
308
static __isl_give PW *FN(PW,align_params_pw_set_and)(__isl_take PW *pw,
 
309
        __isl_take isl_set *set,
 
310
        __isl_give PW *(*fn)(__isl_take PW *pw, __isl_take isl_set *set))
 
311
{
 
312
        isl_ctx *ctx;
 
313
 
 
314
        if (!pw || !set)
 
315
                goto error;
 
316
        if (isl_space_match(pw->dim, isl_dim_param, set->dim, isl_dim_param))
 
317
                return fn(pw, set);
 
318
        ctx = FN(PW,get_ctx)(pw);
 
319
        if (!isl_space_has_named_params(pw->dim) ||
 
320
            !isl_space_has_named_params(set->dim))
 
321
                isl_die(ctx, isl_error_invalid,
 
322
                        "unaligned unnamed parameters", goto error);
 
323
        pw = FN(PW,align_params)(pw, isl_set_get_space(set));
 
324
        set = isl_set_align_params(set, FN(PW,get_space)(pw));
 
325
        return fn(pw, set);
 
326
error:
 
327
        FN(PW,free)(pw);
 
328
        isl_set_free(set);
 
329
        return NULL;
 
330
}
 
331
#endif
 
332
 
 
333
static __isl_give PW *FN(PW,union_add_aligned)(__isl_take PW *pw1,
 
334
        __isl_take PW *pw2)
185
335
{
186
336
        int i, j, n;
187
337
        struct PW *res;
191
341
        if (!pw1 || !pw2)
192
342
                goto error;
193
343
 
194
 
        ctx = isl_dim_get_ctx(pw1->dim);
 
344
        ctx = isl_space_get_ctx(pw1->dim);
195
345
#ifdef HAS_TYPE
196
346
        if (pw1->type != pw2->type)
197
347
                isl_die(ctx, isl_error_invalid,
198
348
                        "fold types don't match", goto error);
199
349
#endif
200
 
        isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
 
350
        isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error);
201
351
 
202
352
        if (FN(PW,IS_ZERO)(pw1)) {
203
353
                FN(PW,free)(pw1);
211
361
 
212
362
        n = (pw1->n + 1) * (pw2->n + 1);
213
363
#ifdef HAS_TYPE
214
 
        res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, n);
 
364
        res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->type, n);
215
365
#else
216
 
        res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), n);
 
366
        res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), n);
217
367
#endif
218
368
 
219
369
        for (i = 0; i < pw1->n; ++i) {
257
407
        return NULL;
258
408
}
259
409
 
260
 
__isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2)
 
410
/* Private version of "union_add".  For isl_pw_qpolynomial and
 
411
 * isl_pw_qpolynomial_fold, we prefer to simply call it "add".
 
412
 */
 
413
static __isl_give PW *FN(PW,union_add_)(__isl_take PW *pw1, __isl_take PW *pw2)
 
414
{
 
415
        return FN(PW,align_params_pw_pw_and)(pw1, pw2,
 
416
                                                &FN(PW,union_add_aligned));
 
417
}
 
418
 
 
419
/* Make sure "pw" has room for at least "n" more pieces.
 
420
 *
 
421
 * If there is only one reference to pw, we extend it in place.
 
422
 * Otherwise, we create a new PW and copy the pieces.
 
423
 */
 
424
static __isl_give PW *FN(PW,grow)(__isl_take PW *pw, int n)
261
425
{
262
426
        int i;
263
427
        isl_ctx *ctx;
264
428
        PW *res;
265
429
 
 
430
        if (!pw)
 
431
                return NULL;
 
432
        if (pw->n + n <= pw->size)
 
433
                return pw;
 
434
        ctx = FN(PW,get_ctx)(pw);
 
435
        n += pw->n;
 
436
        if (pw->ref == 1) {
 
437
                res = isl_realloc(ctx, pw, struct PW,
 
438
                            sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)));
 
439
                if (!res)
 
440
                        return FN(PW,free)(pw);
 
441
                res->size = n;
 
442
                return res;
 
443
        }
 
444
#ifdef HAS_TYPE
 
445
        res = FN(PW,alloc_size)(isl_space_copy(pw->dim), pw->type, n);
 
446
#else
 
447
        res = FN(PW,alloc_size)(isl_space_copy(pw->dim), n);
 
448
#endif
 
449
        if (!res)
 
450
                return FN(PW,free)(pw);
 
451
        for (i = 0; i < pw->n; ++i)
 
452
                res = FN(PW,add_piece)(res, isl_set_copy(pw->p[i].set),
 
453
                                            FN(EL,copy)(pw->p[i].FIELD));
 
454
        FN(PW,free)(pw);
 
455
        return res;
 
456
}
 
457
 
 
458
static __isl_give PW *FN(PW,add_disjoint_aligned)(__isl_take PW *pw1,
 
459
        __isl_take PW *pw2)
 
460
{
 
461
        int i;
 
462
        isl_ctx *ctx;
 
463
 
266
464
        if (!pw1 || !pw2)
267
465
                goto error;
268
466
 
269
 
        ctx = isl_dim_get_ctx(pw1->dim);
 
467
        if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n)
 
468
                return FN(PW,add_disjoint_aligned)(pw2, pw1);
 
469
 
 
470
        ctx = isl_space_get_ctx(pw1->dim);
270
471
#ifdef HAS_TYPE
271
472
        if (pw1->type != pw2->type)
272
473
                isl_die(ctx, isl_error_invalid,
273
474
                        "fold types don't match", goto error);
274
475
#endif
275
 
        isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
 
476
        isl_assert(ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error);
276
477
 
277
478
        if (FN(PW,IS_ZERO)(pw1)) {
278
479
                FN(PW,free)(pw1);
284
485
                return pw1;
285
486
        }
286
487
 
287
 
#ifdef HAS_TYPE
288
 
        res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, pw1->n + pw2->n);
289
 
#else
290
 
        res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->n + pw2->n);
291
 
#endif
292
 
 
293
 
        for (i = 0; i < pw1->n; ++i)
294
 
                res = FN(PW,add_piece)(res,
295
 
                                isl_set_copy(pw1->p[i].set),
296
 
                                FN(EL,copy)(pw1->p[i].FIELD));
 
488
        pw1 = FN(PW,grow)(pw1, pw2->n);
 
489
        if (!pw1)
 
490
                goto error;
297
491
 
298
492
        for (i = 0; i < pw2->n; ++i)
299
 
                res = FN(PW,add_piece)(res,
 
493
                pw1 = FN(PW,add_piece)(pw1,
300
494
                                isl_set_copy(pw2->p[i].set),
301
495
                                FN(EL,copy)(pw2->p[i].FIELD));
302
496
 
303
 
        FN(PW,free)(pw1);
304
 
        FN(PW,free)(pw2);
305
 
 
 
497
        FN(PW,free)(pw2);
 
498
 
 
499
        return pw1;
 
500
error:
 
501
        FN(PW,free)(pw1);
 
502
        FN(PW,free)(pw2);
 
503
        return NULL;
 
504
}
 
505
 
 
506
__isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2)
 
507
{
 
508
        return FN(PW,align_params_pw_pw_and)(pw1, pw2,
 
509
                                                &FN(PW,add_disjoint_aligned));
 
510
}
 
511
 
 
512
/* This function is currently only used from isl_aff.c
 
513
 */
 
514
static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1,
 
515
        __isl_take PW *pw2,
 
516
        __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2))
 
517
        __attribute__ ((unused));
 
518
 
 
519
/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
 
520
 */
 
521
static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1,
 
522
        __isl_take PW *pw2,
 
523
        __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2))
 
524
{
 
525
        int i, j, n;
 
526
        PW *res;
 
527
 
 
528
        if (!pw1 || !pw2)
 
529
                goto error;
 
530
 
 
531
        n = pw1->n * pw2->n;
 
532
#ifdef HAS_TYPE
 
533
        res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->type, n);
 
534
#else
 
535
        res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), n);
 
536
#endif
 
537
 
 
538
        for (i = 0; i < pw1->n; ++i) {
 
539
                for (j = 0; j < pw2->n; ++j) {
 
540
                        isl_set *common;
 
541
                        EL *res_ij;
 
542
                        common = isl_set_intersect(
 
543
                                        isl_set_copy(pw1->p[i].set),
 
544
                                        isl_set_copy(pw2->p[j].set));
 
545
                        if (isl_set_plain_is_empty(common)) {
 
546
                                isl_set_free(common);
 
547
                                continue;
 
548
                        }
 
549
 
 
550
                        res_ij = fn(FN(EL,copy)(pw1->p[i].FIELD),
 
551
                                    FN(EL,copy)(pw2->p[j].FIELD));
 
552
 
 
553
                        res = FN(PW,add_piece)(res, common, res_ij);
 
554
                }
 
555
        }
 
556
 
 
557
        FN(PW,free)(pw1);
 
558
        FN(PW,free)(pw2);
306
559
        return res;
307
560
error:
308
561
        FN(PW,free)(pw1);
347
600
        int i;
348
601
        int found = 0;
349
602
        isl_ctx *ctx;
350
 
        isl_dim *pnt_dim = NULL;
 
603
        isl_space *pnt_dim = NULL;
351
604
        isl_qpolynomial *qp;
352
605
 
353
606
        if (!pw || !pnt)
354
607
                goto error;
355
608
        ctx = isl_point_get_ctx(pnt);
356
 
        pnt_dim = isl_point_get_dim(pnt);
357
 
        isl_assert(ctx, isl_dim_equal(pnt_dim, pw->dim), goto error);
 
609
        pnt_dim = isl_point_get_space(pnt);
 
610
        isl_assert(ctx, isl_space_is_domain(pnt_dim, pw->dim), goto error);
358
611
 
359
612
        for (i = 0; i < pw->n; ++i) {
360
613
                found = isl_set_contains_point(pw->p[i].set, pnt);
367
620
                qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
368
621
                                            isl_point_copy(pnt));
369
622
        else
370
 
                qp = isl_qpolynomial_zero(isl_dim_copy(pw->dim));
 
623
                qp = isl_qpolynomial_zero_on_domain(FN(PW,get_domain_space)(pw));
371
624
        FN(PW,free)(pw);
372
 
        isl_dim_free(pnt_dim);
 
625
        isl_space_free(pnt_dim);
373
626
        isl_point_free(pnt);
374
627
        return qp;
375
628
error:
376
629
        FN(PW,free)(pw);
377
 
        isl_dim_free(pnt_dim);
 
630
        isl_space_free(pnt_dim);
378
631
        isl_point_free(pnt);
379
632
        return NULL;
380
633
}
388
641
        if (!pw)
389
642
                return NULL;
390
643
 
391
 
        dom = isl_set_empty(isl_dim_copy(pw->dim));
 
644
        dom = isl_set_empty(FN(PW,get_domain_space)(pw));
392
645
        for (i = 0; i < pw->n; ++i)
393
646
                dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set));
394
647
 
397
650
        return dom;
398
651
}
399
652
 
400
 
__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, __isl_take isl_set *set)
 
653
/* Restrict the domain of "pw" by combining each cell
 
654
 * with "set" through a call to "fn", where "fn" may be
 
655
 * isl_set_intersect or isl_set_intersect_params.
 
656
 */
 
657
static __isl_give PW *FN(PW,intersect_aligned)(__isl_take PW *pw,
 
658
        __isl_take isl_set *set,
 
659
        __isl_give isl_set *(*fn)(__isl_take isl_set *set1,
 
660
                                    __isl_take isl_set *set2))
401
661
{
402
662
        int i;
403
663
 
415
675
 
416
676
        for (i = pw->n - 1; i >= 0; --i) {
417
677
                isl_basic_set *aff;
418
 
                pw->p[i].set = isl_set_intersect(pw->p[i].set, isl_set_copy(set));
 
678
                pw->p[i].set = fn(pw->p[i].set, isl_set_copy(set));
419
679
                if (!pw->p[i].set)
420
680
                        goto error;
421
681
                aff = isl_set_affine_hull(isl_set_copy(pw->p[i].set));
422
682
                pw->p[i].FIELD = FN(EL,substitute_equalities)(pw->p[i].FIELD,
423
683
                                                                aff);
 
684
                if (!pw->p[i].FIELD)
 
685
                        goto error;
424
686
                if (isl_set_plain_is_empty(pw->p[i].set)) {
425
687
                        isl_set_free(pw->p[i].set);
426
688
                        FN(EL,free)(pw->p[i].FIELD);
438
700
        return NULL;
439
701
}
440
702
 
441
 
__isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context)
 
703
static __isl_give PW *FN(PW,intersect_domain_aligned)(__isl_take PW *pw,
 
704
        __isl_take isl_set *set)
 
705
{
 
706
        return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect);
 
707
}
 
708
 
 
709
__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw,
 
710
        __isl_take isl_set *context)
 
711
{
 
712
        return FN(PW,align_params_pw_set_and)(pw, context,
 
713
                                        &FN(PW,intersect_domain_aligned));
 
714
}
 
715
 
 
716
static __isl_give PW *FN(PW,intersect_params_aligned)(__isl_take PW *pw,
 
717
        __isl_take isl_set *set)
 
718
{
 
719
        return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect_params);
 
720
}
 
721
 
 
722
/* Intersect the domain of "pw" with the parameter domain "context".
 
723
 */
 
724
__isl_give PW *FN(PW,intersect_params)(__isl_take PW *pw,
 
725
        __isl_take isl_set *context)
 
726
{
 
727
        return FN(PW,align_params_pw_set_and)(pw, context,
 
728
                                        &FN(PW,intersect_params_aligned));
 
729
}
 
730
 
 
731
static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw,
 
732
        __isl_take isl_set *context,
 
733
        __isl_give EL *(*fn_el)(__isl_take EL *el,
 
734
                                    __isl_take isl_set *set),
 
735
        __isl_give isl_set *(*fn_dom)(__isl_take isl_set *set,
 
736
                                    __isl_take isl_basic_set *bset))
442
737
{
443
738
        int i;
444
739
        isl_basic_set *hull = NULL;
451
746
                return pw;
452
747
        }
453
748
 
 
749
        if (!isl_space_match(pw->dim, isl_dim_param,
 
750
                                context->dim, isl_dim_param)) {
 
751
                pw = FN(PW,align_params)(pw, isl_set_get_space(context));
 
752
                context = isl_set_align_params(context, FN(PW,get_space)(pw));
 
753
        }
 
754
 
454
755
        context = isl_set_compute_divs(context);
455
756
        hull = isl_set_simple_hull(isl_set_copy(context));
456
757
 
463
764
                                                 isl_set_copy(context));
464
765
                if (!pw->p[i].set)
465
766
                        goto error;
466
 
                pw->p[i].FIELD = FN(EL,gist)(pw->p[i].FIELD,
 
767
                pw->p[i].FIELD = fn_el(pw->p[i].FIELD,
467
768
                                             isl_set_copy(pw->p[i].set));
468
 
                pw->p[i].set = isl_set_gist_basic_set(pw->p[i].set,
469
 
                                                isl_basic_set_copy(hull));
 
769
                pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull));
470
770
                if (!pw->p[i].set)
471
771
                        goto error;
472
772
                if (isl_set_plain_is_empty(pw->p[i].set)) {
489
789
        return NULL;
490
790
}
491
791
 
 
792
static __isl_give PW *FN(PW,gist_domain_aligned)(__isl_take PW *pw,
 
793
        __isl_take isl_set *set)
 
794
{
 
795
        return FN(PW,gist_aligned)(pw, set, &FN(EL,gist),
 
796
                                        &isl_set_gist_basic_set);
 
797
}
 
798
 
 
799
__isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context)
 
800
{
 
801
        return FN(PW,align_params_pw_set_and)(pw, context,
 
802
                                                &FN(PW,gist_domain_aligned));
 
803
}
 
804
 
 
805
static __isl_give PW *FN(PW,gist_params_aligned)(__isl_take PW *pw,
 
806
        __isl_take isl_set *set)
 
807
{
 
808
        return FN(PW,gist_aligned)(pw, set, &FN(EL,gist_params),
 
809
                                        &isl_set_gist_params_basic_set);
 
810
}
 
811
 
 
812
__isl_give PW *FN(PW,gist_params)(__isl_take PW *pw,
 
813
        __isl_take isl_set *context)
 
814
{
 
815
        return FN(PW,align_params_pw_set_and)(pw, context,
 
816
                                                &FN(PW,gist_params_aligned));
 
817
}
 
818
 
492
819
__isl_give PW *FN(PW,coalesce)(__isl_take PW *pw)
493
820
{
494
821
        int i, j;
526
853
 
527
854
isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw)
528
855
{
529
 
        return pw ? isl_dim_get_ctx(pw->dim) : NULL;
 
856
        return pw ? isl_space_get_ctx(pw->dim) : NULL;
530
857
}
531
858
 
532
859
#ifndef NO_INVOLVES_DIMS
534
861
        unsigned first, unsigned n)
535
862
{
536
863
        int i;
 
864
        enum isl_dim_type set_type;
537
865
 
538
866
        if (!pw)
539
867
                return -1;
540
868
        if (pw->n == 0 || n == 0)
541
869
                return 0;
 
870
 
 
871
        set_type = type == isl_dim_in ? isl_dim_set : type;
 
872
 
542
873
        for (i = 0; i < pw->n; ++i) {
543
874
                int involves = FN(EL,involves_dims)(pw->p[i].FIELD,
544
875
                                                        type, first, n);
545
876
                if (involves < 0 || involves)
546
877
                        return involves;
547
 
                involves = isl_set_involves_dims(pw->p[i].set, type, first, n);
 
878
                involves = isl_set_involves_dims(pw->p[i].set,
 
879
                                                        set_type, first, n);
548
880
                if (involves < 0 || involves)
549
881
                        return involves;
550
882
        }
556
888
        enum isl_dim_type type, unsigned pos, const char *s)
557
889
{
558
890
        int i;
 
891
        enum isl_dim_type set_type;
559
892
 
560
893
        pw = FN(PW,cow)(pw);
561
894
        if (!pw)
562
895
                return NULL;
563
896
 
564
 
        pw->dim = isl_dim_set_name(pw->dim, type, pos, s);
 
897
        set_type = type == isl_dim_in ? isl_dim_set : type;
 
898
 
 
899
        pw->dim = isl_space_set_dim_name(pw->dim, type, pos, s);
565
900
        if (!pw->dim)
566
901
                goto error;
567
902
 
568
903
        for (i = 0; i < pw->n; ++i) {
569
 
                pw->p[i].set = isl_set_set_dim_name(pw->p[i].set, type, pos, s);
 
904
                pw->p[i].set = isl_set_set_dim_name(pw->p[i].set,
 
905
                                                        set_type, pos, s);
570
906
                if (!pw->p[i].set)
571
907
                        goto error;
572
908
                pw->p[i].FIELD = FN(EL,set_dim_name)(pw->p[i].FIELD, type, pos, s);
585
921
        enum isl_dim_type type, unsigned first, unsigned n)
586
922
{
587
923
        int i;
588
 
 
589
 
        if (!pw)
590
 
                return NULL;
591
 
        if (n == 0 && !isl_dim_get_tuple_name(pw->dim, type))
592
 
                return pw;
593
 
 
594
 
        pw = FN(PW,cow)(pw);
595
 
        if (!pw)
596
 
                return NULL;
597
 
        pw->dim = isl_dim_drop(pw->dim, type, first, n);
598
 
        if (!pw->dim)
599
 
                goto error;
600
 
        for (i = 0; i < pw->n; ++i) {
601
 
                pw->p[i].set = isl_set_drop(pw->p[i].set, type, first, n);
602
 
                if (!pw->p[i].set)
603
 
                        goto error;
604
 
                pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n);
605
 
                if (!pw->p[i].FIELD)
606
 
                        goto error;
607
 
        }
608
 
 
609
 
        return pw;
610
 
error:
611
 
        FN(PW,free)(pw);
612
 
        return NULL;
 
924
        enum isl_dim_type set_type;
 
925
 
 
926
        if (!pw)
 
927
                return NULL;
 
928
        if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
 
929
                return pw;
 
930
 
 
931
        set_type = type == isl_dim_in ? isl_dim_set : type;
 
932
 
 
933
        pw = FN(PW,cow)(pw);
 
934
        if (!pw)
 
935
                return NULL;
 
936
        pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
 
937
        if (!pw->dim)
 
938
                goto error;
 
939
        for (i = 0; i < pw->n; ++i) {
 
940
                pw->p[i].set = isl_set_drop(pw->p[i].set, set_type, first, n);
 
941
                if (!pw->p[i].set)
 
942
                        goto error;
 
943
                pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n);
 
944
                if (!pw->p[i].FIELD)
 
945
                        goto error;
 
946
        }
 
947
 
 
948
        return pw;
 
949
error:
 
950
        FN(PW,free)(pw);
 
951
        return NULL;
 
952
}
 
953
 
 
954
/* This function is very similar to drop_dims.
 
955
 * The only difference is that the cells may still involve
 
956
 * the specified dimensions.  They are removed using
 
957
 * isl_set_project_out instead of isl_set_drop.
 
958
 */
 
959
__isl_give PW *FN(PW,project_out)(__isl_take PW *pw,
 
960
        enum isl_dim_type type, unsigned first, unsigned n)
 
961
{
 
962
        int i;
 
963
        enum isl_dim_type set_type;
 
964
 
 
965
        if (!pw)
 
966
                return NULL;
 
967
        if (n == 0 && !isl_space_get_tuple_name(pw->dim, type))
 
968
                return pw;
 
969
 
 
970
        set_type = type == isl_dim_in ? isl_dim_set : type;
 
971
 
 
972
        pw = FN(PW,cow)(pw);
 
973
        if (!pw)
 
974
                return NULL;
 
975
        pw->dim = isl_space_drop_dims(pw->dim, type, first, n);
 
976
        if (!pw->dim)
 
977
                goto error;
 
978
        for (i = 0; i < pw->n; ++i) {
 
979
                pw->p[i].set = isl_set_project_out(pw->p[i].set,
 
980
                                                        set_type, first, n);
 
981
                if (!pw->p[i].set)
 
982
                        goto error;
 
983
                pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n);
 
984
                if (!pw->p[i].FIELD)
 
985
                        goto error;
 
986
        }
 
987
 
 
988
        return pw;
 
989
error:
 
990
        FN(PW,free)(pw);
 
991
        return NULL;
 
992
}
 
993
 
 
994
/* Project the domain of pw onto its parameter space.
 
995
 */
 
996
__isl_give PW *FN(PW,project_domain_on_params)(__isl_take PW *pw)
 
997
{
 
998
        isl_space *space;
 
999
        unsigned n;
 
1000
 
 
1001
        n = FN(PW,dim)(pw, isl_dim_in);
 
1002
        pw = FN(PW,project_out)(pw, isl_dim_in, 0, n);
 
1003
        space = FN(PW,get_domain_space)(pw);
 
1004
        space = isl_space_params(space);
 
1005
        pw = FN(PW,reset_domain_space)(pw, space);
 
1006
        return pw;
613
1007
}
614
1008
#endif
615
1009
 
618
1012
        unsigned first, unsigned n)
619
1013
{
620
1014
        int i;
 
1015
        enum isl_dim_type set_type;
621
1016
 
622
1017
        if (!pw)
623
1018
                return NULL;
624
 
        if (n == 0 && !isl_dim_is_named_or_nested(pw->dim, type))
 
1019
        if (n == 0 && !isl_space_is_named_or_nested(pw->dim, type))
625
1020
                return pw;
626
1021
 
 
1022
        set_type = type == isl_dim_in ? isl_dim_set : type;
 
1023
 
627
1024
        pw = FN(PW,cow)(pw);
628
1025
        if (!pw)
629
1026
                return NULL;
630
1027
 
631
 
        pw->dim = isl_dim_insert(pw->dim, type, first, n);
 
1028
        pw->dim = isl_space_insert_dims(pw->dim, type, first, n);
632
1029
        if (!pw->dim)
633
1030
                goto error;
634
1031
 
635
1032
        for (i = 0; i < pw->n; ++i) {
636
 
                pw->p[i].set = isl_set_insert(pw->p[i].set, type, first, n);
 
1033
                pw->p[i].set = isl_set_insert_dims(pw->p[i].set,
 
1034
                                                            set_type, first, n);
637
1035
                if (!pw->p[i].set)
638
1036
                        goto error;
639
1037
                pw->p[i].FIELD = FN(EL,insert_dims)(pw->p[i].FIELD,
657
1055
        if (!pw)
658
1056
                return NULL;
659
1057
 
 
1058
        if (type == isl_dim_in)
 
1059
                type = isl_dim_set;
 
1060
 
660
1061
        pw = FN(PW,cow)(pw);
661
1062
        if (!pw)
662
1063
                return NULL;
674
1075
 
675
1076
unsigned FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type)
676
1077
{
677
 
        return pw ? isl_dim_size(pw->dim, type) : 0;
 
1078
        return pw ? isl_space_dim(pw->dim, type) : 0;
678
1079
}
679
1080
 
680
1081
__isl_give PW *FN(PW,split_dims)(__isl_take PW *pw,
687
1088
        if (n == 0)
688
1089
                return pw;
689
1090
 
 
1091
        if (type == isl_dim_in)
 
1092
                type = isl_dim_set;
 
1093
 
690
1094
        pw = FN(PW,cow)(pw);
691
1095
        if (!pw)
692
1096
                return NULL;
719
1123
                return NULL;
720
1124
 
721
1125
        if (pw->n == 0) {
722
 
                isl_dim *dim = isl_dim_copy(pw->dim);
 
1126
                isl_space *dim = isl_space_copy(pw->dim);
723
1127
                FN(PW,free)(pw);
724
 
                return isl_qpolynomial_zero(dim);
 
1128
                return isl_qpolynomial_zero_on_domain(isl_space_domain(dim));
725
1129
        }
726
1130
 
727
1131
        opt = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[0].FIELD),
751
1155
}
752
1156
#endif
753
1157
 
754
 
__isl_give isl_dim *FN(PW,get_dim)(__isl_keep PW *pw)
755
 
{
756
 
        return pw ? isl_dim_copy(pw->dim) : NULL;
 
1158
__isl_give isl_space *FN(PW,get_space)(__isl_keep PW *pw)
 
1159
{
 
1160
        return pw ? isl_space_copy(pw->dim) : NULL;
 
1161
}
 
1162
 
 
1163
__isl_give isl_space *FN(PW,get_domain_space)(__isl_keep PW *pw)
 
1164
{
 
1165
        return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL;
757
1166
}
758
1167
 
759
1168
#ifndef NO_RESET_DIM
760
 
__isl_give PW *FN(PW,reset_dim)(__isl_take PW *pw, __isl_take isl_dim *dim)
 
1169
/* Reset the space of "pw".  Since we don't know if the elements
 
1170
 * represent the spaces themselves or their domains, we pass along
 
1171
 * both when we call their reset_space_and_domain.
 
1172
 */
 
1173
static __isl_give PW *FN(PW,reset_space_and_domain)(__isl_take PW *pw,
 
1174
        __isl_take isl_space *space, __isl_take isl_space *domain)
761
1175
{
762
1176
        int i;
763
1177
 
764
1178
        pw = FN(PW,cow)(pw);
765
 
        if (!pw || !dim)
 
1179
        if (!pw || !space || !domain)
766
1180
                goto error;
767
1181
 
768
1182
        for (i = 0; i < pw->n; ++i) {
769
 
                pw->p[i].set = isl_set_reset_dim(pw->p[i].set,
770
 
                                                 isl_dim_copy(dim));
 
1183
                pw->p[i].set = isl_set_reset_space(pw->p[i].set,
 
1184
                                                 isl_space_copy(domain));
771
1185
                if (!pw->p[i].set)
772
1186
                        goto error;
773
 
                pw->p[i].FIELD = FN(EL,reset_dim)(pw->p[i].FIELD,
774
 
                                                  isl_dim_copy(dim));
 
1187
                pw->p[i].FIELD = FN(EL,reset_space_and_domain)(pw->p[i].FIELD,
 
1188
                              isl_space_copy(space), isl_space_copy(domain));
775
1189
                if (!pw->p[i].FIELD)
776
1190
                        goto error;
777
1191
        }
778
 
        isl_dim_free(pw->dim);
779
 
        pw->dim = dim;
 
1192
 
 
1193
        isl_space_free(domain);
 
1194
 
 
1195
        isl_space_free(pw->dim);
 
1196
        pw->dim = space;
780
1197
 
781
1198
        return pw;
782
1199
error:
783
 
        isl_dim_free(dim);
 
1200
        isl_space_free(domain);
 
1201
        isl_space_free(space);
784
1202
        FN(PW,free)(pw);
785
1203
        return NULL;
786
1204
}
 
1205
 
 
1206
__isl_give PW *FN(PW,reset_domain_space)(__isl_take PW *pw,
 
1207
        __isl_take isl_space *domain)
 
1208
{
 
1209
        isl_space *space;
 
1210
 
 
1211
        space = isl_space_extend_domain_with_range(isl_space_copy(domain),
 
1212
                                                   FN(PW,get_space)(pw));
 
1213
        return FN(PW,reset_space_and_domain)(pw, space, domain);
 
1214
}
 
1215
 
 
1216
__isl_give PW *FN(PW,reset_space)(__isl_take PW *pw, __isl_take isl_space *dim)
 
1217
{
 
1218
        isl_space *domain;
 
1219
 
 
1220
        domain = isl_space_domain(isl_space_copy(dim));
 
1221
        return FN(PW,reset_space_and_domain)(pw, dim, domain);
 
1222
}
 
1223
 
 
1224
__isl_give PW *FN(PW,set_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type,
 
1225
        __isl_take isl_id *id)
 
1226
{
 
1227
        isl_space *space;
 
1228
 
 
1229
        pw = FN(PW,cow)(pw);
 
1230
        if (!pw)
 
1231
                return isl_id_free(id);
 
1232
 
 
1233
        space = FN(PW,get_space)(pw);
 
1234
        space = isl_space_set_tuple_id(space, type, id);
 
1235
 
 
1236
        return FN(PW,reset_space)(pw, space);
 
1237
}
 
1238
 
 
1239
__isl_give PW *FN(PW,set_dim_id)(__isl_take PW *pw,
 
1240
        enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
 
1241
{
 
1242
        pw = FN(PW,cow)(pw);
 
1243
        if (!pw)
 
1244
                return isl_id_free(id);
 
1245
        pw->dim = isl_space_set_dim_id(pw->dim, type, pos, id);
 
1246
        return FN(PW,reset_space)(pw, isl_space_copy(pw->dim));
 
1247
}
787
1248
#endif
788
1249
 
789
 
int FN(PW,has_equal_dim)(__isl_keep PW *pw1, __isl_keep PW *pw2)
 
1250
int FN(PW,has_equal_space)(__isl_keep PW *pw1, __isl_keep PW *pw2)
790
1251
{
791
1252
        if (!pw1 || !pw2)
792
1253
                return -1;
793
1254
 
794
 
        return isl_dim_equal(pw1->dim, pw2->dim);
 
1255
        return isl_space_is_equal(pw1->dim, pw2->dim);
795
1256
}
796
1257
 
797
1258
#ifndef NO_MORPH
798
 
__isl_give PW *FN(PW,morph)(__isl_take PW *pw, __isl_take isl_morph *morph)
 
1259
__isl_give PW *FN(PW,morph_domain)(__isl_take PW *pw,
 
1260
        __isl_take isl_morph *morph)
799
1261
{
800
1262
        int i;
801
1263
        isl_ctx *ctx;
803
1265
        if (!pw || !morph)
804
1266
                goto error;
805
1267
 
806
 
        ctx = isl_dim_get_ctx(pw->dim);
807
 
        isl_assert(ctx, isl_dim_equal(pw->dim, morph->dom->dim),
 
1268
        ctx = isl_space_get_ctx(pw->dim);
 
1269
        isl_assert(ctx, isl_space_is_domain(morph->dom->dim, pw->dim),
808
1270
                goto error);
809
1271
 
810
1272
        pw = FN(PW,cow)(pw);
811
1273
        if (!pw)
812
1274
                goto error;
813
 
        isl_dim_free(pw->dim);
814
 
        pw->dim = isl_dim_copy(morph->ran->dim);
 
1275
        pw->dim = isl_space_extend_domain_with_range(
 
1276
                        isl_space_copy(morph->ran->dim), pw->dim);
815
1277
        if (!pw->dim)
816
1278
                goto error;
817
1279
 
819
1281
                pw->p[i].set = isl_morph_set(isl_morph_copy(morph), pw->p[i].set);
820
1282
                if (!pw->p[i].set)
821
1283
                        goto error;
822
 
                pw->p[i].FIELD = FN(EL,morph)(pw->p[i].FIELD,
 
1284
                pw->p[i].FIELD = FN(EL,morph_domain)(pw->p[i].FIELD,
823
1285
                                                isl_morph_copy(morph));
824
1286
                if (!pw->p[i].FIELD)
825
1287
                        goto error;
884
1346
                lift = isl_set_lift(lift);
885
1347
 
886
1348
                copy = FN(EL,copy)(el);
887
 
                copy = FN(EL,lift)(copy, isl_set_get_dim(lift));
 
1349
                copy = FN(EL,lift)(copy, isl_set_get_space(lift));
888
1350
 
889
1351
                if (fn(lift, copy, user) < 0)
890
1352
                        goto error;
939
1401
        if (!pw)
940
1402
                return NULL;
941
1403
 
942
 
        pw->dim = isl_dim_move(pw->dim, dst_type, dst_pos, src_type, src_pos, n);
 
1404
        pw->dim = isl_space_move_dims(pw->dim, dst_type, dst_pos, src_type, src_pos, n);
943
1405
        if (!pw->dim)
944
1406
                goto error;
945
1407
 
946
1408
        for (i = 0; i < pw->n; ++i) {
 
1409
                pw->p[i].FIELD = FN(EL,move_dims)(pw->p[i].FIELD,
 
1410
                                        dst_type, dst_pos, src_type, src_pos, n);
 
1411
                if (!pw->p[i].FIELD)
 
1412
                        goto error;
 
1413
        }
 
1414
 
 
1415
        if (dst_type == isl_dim_in)
 
1416
                dst_type = isl_dim_set;
 
1417
        if (src_type == isl_dim_in)
 
1418
                src_type = isl_dim_set;
 
1419
 
 
1420
        for (i = 0; i < pw->n; ++i) {
947
1421
                pw->p[i].set = isl_set_move_dims(pw->p[i].set,
948
1422
                                                dst_type, dst_pos,
949
1423
                                                src_type, src_pos, n);
950
1424
                if (!pw->p[i].set)
951
1425
                        goto error;
952
 
                pw->p[i].FIELD = FN(EL,move_dims)(pw->p[i].FIELD,
953
 
                                        dst_type, dst_pos, src_type, src_pos, n);
954
 
                if (!pw->p[i].FIELD)
955
 
                        goto error;
956
 
        }
957
 
 
958
 
        return pw;
959
 
error:
960
 
        FN(PW,free)(pw);
961
 
        return NULL;
962
 
}
963
 
#endif
964
 
 
965
 
#ifndef NO_REALIGN
966
 
__isl_give PW *FN(PW,realign)(__isl_take PW *pw, __isl_take isl_reordering *exp)
967
 
{
968
 
        int i;
969
 
 
970
 
        pw = FN(PW,cow)(pw);
971
 
        if (!pw || !exp)
972
 
                return NULL;
973
 
 
974
 
        for (i = 0; i < pw->n; ++i) {
975
 
                pw->p[i].set = isl_set_realign(pw->p[i].set,
976
 
                                                    isl_reordering_copy(exp));
977
 
                if (!pw->p[i].set)
978
 
                        goto error;
979
 
                pw->p[i].FIELD = FN(EL,realign)(pw->p[i].FIELD,
980
 
                                                    isl_reordering_copy(exp));
981
 
                if (!pw->p[i].FIELD)
982
 
                        goto error;
983
 
        }
984
 
 
985
 
        pw = FN(PW,reset_dim)(pw, isl_dim_copy(exp->dim));
986
 
 
987
 
        isl_reordering_free(exp);
988
 
        return pw;
989
 
error:
990
 
        isl_reordering_free(exp);
991
 
        FN(PW,free)(pw);
992
 
        return NULL;
993
 
}
994
 
 
995
 
/* Align the parameters of "pw" to those of "model".
996
 
 */
997
 
__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_dim *model)
998
 
{
999
 
        isl_ctx *ctx;
1000
 
 
1001
 
        if (!pw || !model)
1002
 
                goto error;
1003
 
 
1004
 
        ctx = isl_dim_get_ctx(model);
1005
 
        if (!isl_dim_has_named_params(model))
1006
 
                isl_die(ctx, isl_error_invalid,
1007
 
                        "model has unnamed parameters", goto error);
1008
 
        if (!isl_dim_has_named_params(pw->dim))
1009
 
                isl_die(ctx, isl_error_invalid,
1010
 
                        "input has unnamed parameters", goto error);
1011
 
        if (!isl_dim_match(pw->dim, isl_dim_param, model, isl_dim_param)) {
1012
 
                isl_reordering *exp;
1013
 
 
1014
 
                model = isl_dim_drop(model, isl_dim_in,
1015
 
                                        0, isl_dim_size(model, isl_dim_in));
1016
 
                model = isl_dim_drop(model, isl_dim_out,
1017
 
                                        0, isl_dim_size(model, isl_dim_out));
1018
 
                exp = isl_parameter_alignment_reordering(pw->dim, model);
1019
 
                exp = isl_reordering_extend_dim(exp, FN(PW,get_dim)(pw));
1020
 
                pw = FN(PW,realign)(pw, exp);
1021
 
        }
1022
 
 
1023
 
        isl_dim_free(model);
1024
 
        return pw;
1025
 
error:
1026
 
        isl_dim_free(model);
 
1426
        }
 
1427
 
 
1428
        return pw;
 
1429
error:
1027
1430
        FN(PW,free)(pw);
1028
1431
        return NULL;
1029
1432
}
1035
1438
 
1036
1439
        if (isl_int_is_one(v))
1037
1440
                return pw;
1038
 
        if (pw && isl_int_is_zero(v)) {
 
1441
        if (pw && DEFAULT_IS_ZERO && isl_int_is_zero(v)) {
1039
1442
                PW *zero;
1040
 
                isl_dim *dim = FN(PW,get_dim)(pw);
 
1443
                isl_space *dim = FN(PW,get_space)(pw);
1041
1444
#ifdef HAS_TYPE
1042
1445
                zero = FN(PW,ZERO)(dim, pw->type);
1043
1446
#else
1072
1475
{
1073
1476
        return FN(PW,mul_isl_int)(pw, v);
1074
1477
}
 
1478
 
 
1479
static int FN(PW,qsort_set_cmp)(const void *p1, const void *p2)
 
1480
{
 
1481
        const isl_set *set1 = *(const isl_set **)p1;
 
1482
        const isl_set *set2 = *(const isl_set **)p2;
 
1483
 
 
1484
        return isl_set_plain_cmp(set1, set2);
 
1485
}
 
1486
 
 
1487
/* We normalize in place, but if anything goes wrong we need
 
1488
 * to return NULL, so we need to make sure we don't change the
 
1489
 * meaning of any possible other copies of map.
 
1490
 */
 
1491
__isl_give PW *FN(PW,normalize)(__isl_take PW *pw)
 
1492
{
 
1493
        int i, j;
 
1494
        isl_set *set;
 
1495
 
 
1496
        if (!pw)
 
1497
                return NULL;
 
1498
        for (i = 0; i < pw->n; ++i) {
 
1499
                set = isl_set_normalize(isl_set_copy(pw->p[i].set));
 
1500
                if (!set)
 
1501
                        return FN(PW,free)(pw);
 
1502
                isl_set_free(pw->p[i].set);
 
1503
                pw->p[i].set = set;
 
1504
        }
 
1505
        qsort(pw->p, pw->n, sizeof(pw->p[0]), &FN(PW,qsort_set_cmp));
 
1506
        for (i = pw->n - 1; i >= 1; --i) {
 
1507
                if (!isl_set_plain_is_equal(pw->p[i - 1].set, pw->p[i].set))
 
1508
                        continue;
 
1509
                if (!FN(EL,plain_is_equal)(pw->p[i - 1].FIELD, pw->p[i].FIELD))
 
1510
                        continue;
 
1511
                set = isl_set_union(isl_set_copy(pw->p[i - 1].set),
 
1512
                                    isl_set_copy(pw->p[i].set));
 
1513
                if (!set)
 
1514
                        return FN(PW,free)(pw);
 
1515
                isl_set_free(pw->p[i].set);
 
1516
                FN(EL,free)(pw->p[i].FIELD);
 
1517
                isl_set_free(pw->p[i - 1].set);
 
1518
                pw->p[i - 1].set = set;
 
1519
                for (j = i + 1; j < pw->n; ++j)
 
1520
                        pw->p[j - 1] = pw->p[j];
 
1521
                pw->n--;
 
1522
        }
 
1523
 
 
1524
        return pw;
 
1525
}
 
1526
 
 
1527
/* Is pw1 obviously equal to pw2?
 
1528
 * That is, do they have obviously identical cells and obviously identical
 
1529
 * elements on each cell?
 
1530
 */
 
1531
int FN(PW,plain_is_equal)(__isl_keep PW *pw1, __isl_keep PW *pw2)
 
1532
{
 
1533
        int i;
 
1534
        int equal;
 
1535
 
 
1536
        if (!pw1 || !pw2)
 
1537
                return -1;
 
1538
 
 
1539
        if (pw1 == pw2)
 
1540
                return 1;
 
1541
        if (!isl_space_is_equal(pw1->dim, pw2->dim))
 
1542
                return 0;
 
1543
 
 
1544
        pw1 = FN(PW,copy)(pw1);
 
1545
        pw2 = FN(PW,copy)(pw2);
 
1546
        pw1 = FN(PW,normalize)(pw1);
 
1547
        pw2 = FN(PW,normalize)(pw2);
 
1548
        if (!pw1 || !pw2)
 
1549
                goto error;
 
1550
 
 
1551
        equal = pw1->n == pw2->n;
 
1552
        for (i = 0; equal && i < pw1->n; ++i) {
 
1553
                equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set);
 
1554
                if (equal < 0)
 
1555
                        goto error;
 
1556
                if (!equal)
 
1557
                        break;
 
1558
                equal = FN(EL,plain_is_equal)(pw1->p[i].FIELD, pw2->p[i].FIELD);
 
1559
                if (equal < 0)
 
1560
                        goto error;
 
1561
        }
 
1562
 
 
1563
        FN(PW,free)(pw1);
 
1564
        FN(PW,free)(pw2);
 
1565
        return equal;
 
1566
error:
 
1567
        FN(PW,free)(pw1);
 
1568
        FN(PW,free)(pw2);
 
1569
        return -1;
 
1570
}