~ubuntu-branches/ubuntu/wily/cloog/wily-proposed

« back to all changes in this revision

Viewing changes to isl/isl_aff.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2015-04-24 15:07:57 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20150424150757-wumy8mdonvtgf29j
Tags: 0.18.3-1
* New upstream version.
* Update symbols file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright 2011      INRIA Saclay
3
3
 * Copyright 2011      Sven Verdoolaege
4
 
 * Copyright 2012-2013 Ecole Normale Superieure
 
4
 * Copyright 2012-2014 Ecole Normale Superieure
5
5
 *
6
6
 * Use of this software is governed by the MIT license
7
7
 *
18
18
#include <isl_aff_private.h>
19
19
#include <isl_space_private.h>
20
20
#include <isl_local_space_private.h>
 
21
#include <isl_vec_private.h>
21
22
#include <isl_mat_private.h>
22
23
#include <isl/constraint.h>
23
 
#include <isl/seq.h>
 
24
#include <isl_seq.h>
24
25
#include <isl/set.h>
25
26
#include <isl_val_private.h>
 
27
#include <isl/deprecated/aff_int.h>
26
28
#include <isl_config.h>
27
29
 
28
30
#undef BASE
106
108
        return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
107
109
}
108
110
 
 
111
/* Return an affine expression defined on the specified domain
 
112
 * that represents NaN.
 
113
 */
 
114
__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
 
115
{
 
116
        isl_aff *aff;
 
117
 
 
118
        aff = isl_aff_alloc(ls);
 
119
        if (!aff)
 
120
                return NULL;
 
121
 
 
122
        isl_seq_clr(aff->v->el, aff->v->size);
 
123
 
 
124
        return aff;
 
125
}
 
126
 
 
127
/* Return a piecewise affine expression defined on the specified domain
 
128
 * that represents NaN.
 
129
 */
 
130
__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
 
131
{
 
132
        return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
 
133
}
 
134
 
 
135
/* Return an affine expression that is equal to "val" on
 
136
 * domain local space "ls".
 
137
 */
 
138
__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
 
139
        __isl_take isl_val *val)
 
140
{
 
141
        isl_aff *aff;
 
142
 
 
143
        if (!ls || !val)
 
144
                goto error;
 
145
        if (!isl_val_is_rat(val))
 
146
                isl_die(isl_val_get_ctx(val), isl_error_invalid,
 
147
                        "expecting rational value", goto error);
 
148
 
 
149
        aff = isl_aff_alloc(isl_local_space_copy(ls));
 
150
        if (!aff)
 
151
                goto error;
 
152
 
 
153
        isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
 
154
        isl_int_set(aff->v->el[1], val->n);
 
155
        isl_int_set(aff->v->el[0], val->d);
 
156
 
 
157
        isl_local_space_free(ls);
 
158
        isl_val_free(val);
 
159
        return aff;
 
160
error:
 
161
        isl_local_space_free(ls);
 
162
        isl_val_free(val);
 
163
        return NULL;
 
164
}
 
165
 
109
166
/* Return an affine expression that is equal to the specified dimension
110
167
 * in "ls".
111
168
 */
184
241
        return isl_aff_dup(aff);
185
242
}
186
243
 
187
 
void *isl_aff_free(__isl_take isl_aff *aff)
 
244
__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
188
245
{
189
246
        if (!aff)
190
247
                return NULL;
379
436
        return NULL;
380
437
}
381
438
 
 
439
/* Is "aff" obviously equal to zero?
 
440
 *
 
441
 * If the denominator is zero, then "aff" is not equal to zero.
 
442
 */
382
443
int isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
383
444
{
384
445
        if (!aff)
385
446
                return -1;
386
447
 
 
448
        if (isl_int_is_zero(aff->v->el[0]))
 
449
                return 0;
387
450
        return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
388
451
}
389
452
 
 
453
/* Does "aff" represent NaN?
 
454
 */
 
455
int isl_aff_is_nan(__isl_keep isl_aff *aff)
 
456
{
 
457
        if (!aff)
 
458
                return -1;
 
459
 
 
460
        return isl_seq_first_non_zero(aff->v->el, 2) < 0;
 
461
}
 
462
 
 
463
/* Does "pa" involve any NaNs?
 
464
 */
 
465
int isl_pw_aff_involves_nan(__isl_keep isl_pw_aff *pa)
 
466
{
 
467
        int i;
 
468
 
 
469
        if (!pa)
 
470
                return -1;
 
471
        if (pa->n == 0)
 
472
                return 0;
 
473
 
 
474
        for (i = 0; i < pa->n; ++i) {
 
475
                int is_nan = isl_aff_is_nan(pa->p[i].aff);
 
476
                if (is_nan < 0 || is_nan)
 
477
                        return is_nan;
 
478
        }
 
479
 
 
480
        return 0;
 
481
}
 
482
 
 
483
/* Are "aff1" and "aff2" obviously equal?
 
484
 *
 
485
 * NaN is not equal to anything, not even to another NaN.
 
486
 */
390
487
int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
391
488
{
392
489
        int equal;
394
491
        if (!aff1 || !aff2)
395
492
                return -1;
396
493
 
 
494
        if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
 
495
                return 0;
 
496
 
397
497
        equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
398
498
        if (equal < 0 || !equal)
399
499
                return equal;
401
501
        return isl_vec_is_equal(aff1->v, aff2->v);
402
502
}
403
503
 
 
504
/* Return the common denominator of "aff" in "v".
 
505
 *
 
506
 * We cannot return anything meaningful in case of a NaN.
 
507
 */
404
508
int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
405
509
{
406
510
        if (!aff)
407
511
                return -1;
 
512
        if (isl_aff_is_nan(aff))
 
513
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
514
                        "cannot get denominator of NaN", return -1);
408
515
        isl_int_set(*v, aff->v->el[0]);
409
516
        return 0;
410
517
}
419
526
                return NULL;
420
527
 
421
528
        ctx = isl_aff_get_ctx(aff);
 
529
        if (isl_aff_is_nan(aff))
 
530
                return isl_val_nan(ctx);
422
531
        return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
423
532
}
424
533
 
 
534
/* Return the constant term of "aff" in "v".
 
535
 *
 
536
 * We cannot return anything meaningful in case of a NaN.
 
537
 */
425
538
int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
426
539
{
427
540
        if (!aff)
428
541
                return -1;
 
542
        if (isl_aff_is_nan(aff))
 
543
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
544
                        "cannot get constant term of NaN", return -1);
429
545
        isl_int_set(*v, aff->v->el[1]);
430
546
        return 0;
431
547
}
441
557
                return NULL;
442
558
 
443
559
        ctx = isl_aff_get_ctx(aff);
 
560
        if (isl_aff_is_nan(aff))
 
561
                return isl_val_nan(ctx);
444
562
        v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
445
563
        return isl_val_normalize(v);
446
564
}
447
565
 
 
566
/* Return the coefficient of the variable of type "type" at position "pos"
 
567
 * of "aff" in "v".
 
568
 *
 
569
 * We cannot return anything meaningful in case of a NaN.
 
570
 */
448
571
int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
449
572
        enum isl_dim_type type, int pos, isl_int *v)
450
573
{
462
585
                isl_die(aff->v->ctx, isl_error_invalid,
463
586
                        "position out of bounds", return -1);
464
587
 
 
588
        if (isl_aff_is_nan(aff))
 
589
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
590
                        "cannot get coefficient of NaN", return -1);
465
591
        pos += isl_local_space_offset(aff->ls, type);
466
592
        isl_int_set(*v, aff->v->el[1 + pos]);
467
593
 
492
618
                isl_die(ctx, isl_error_invalid,
493
619
                        "position out of bounds", return NULL);
494
620
 
 
621
        if (isl_aff_is_nan(aff))
 
622
                return isl_val_nan(ctx);
495
623
        pos += isl_local_space_offset(aff->ls, type);
496
624
        v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
497
625
        return isl_val_normalize(v);
498
626
}
499
627
 
 
628
/* Replace the denominator of "aff" by "v".
 
629
 *
 
630
 * A NaN is unaffected by this operation.
 
631
 */
500
632
__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
501
633
{
 
634
        if (!aff)
 
635
                return NULL;
 
636
        if (isl_aff_is_nan(aff))
 
637
                return aff;
502
638
        aff = isl_aff_cow(aff);
503
639
        if (!aff)
504
640
                return NULL;
512
648
        return aff;
513
649
}
514
650
 
 
651
/* Replace the numerator of the constant term of "aff" by "v".
 
652
 *
 
653
 * A NaN is unaffected by this operation.
 
654
 */
515
655
__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
516
656
{
 
657
        if (!aff)
 
658
                return NULL;
 
659
        if (isl_aff_is_nan(aff))
 
660
                return aff;
517
661
        aff = isl_aff_cow(aff);
518
662
        if (!aff)
519
663
                return NULL;
528
672
}
529
673
 
530
674
/* Replace the constant term of "aff" by "v".
 
675
 *
 
676
 * A NaN is unaffected by this operation.
531
677
 */
532
678
__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
533
679
        __isl_take isl_val *v)
535
681
        if (!aff || !v)
536
682
                goto error;
537
683
 
 
684
        if (isl_aff_is_nan(aff)) {
 
685
                isl_val_free(v);
 
686
                return aff;
 
687
        }
 
688
 
538
689
        if (!isl_val_is_rat(v))
539
690
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
540
691
                        "expecting rational value", goto error);
574
725
        return NULL;
575
726
}
576
727
 
 
728
/* Add "v" to the constant term of "aff".
 
729
 *
 
730
 * A NaN is unaffected by this operation.
 
731
 */
577
732
__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
578
733
{
579
734
        if (isl_int_is_zero(v))
580
735
                return aff;
581
736
 
 
737
        if (!aff)
 
738
                return NULL;
 
739
        if (isl_aff_is_nan(aff))
 
740
                return aff;
582
741
        aff = isl_aff_cow(aff);
583
742
        if (!aff)
584
743
                return NULL;
593
752
}
594
753
 
595
754
/* Add "v" to the constant term of "aff".
 
755
 *
 
756
 * A NaN is unaffected by this operation.
596
757
 */
597
758
__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
598
759
        __isl_take isl_val *v)
600
761
        if (!aff || !v)
601
762
                goto error;
602
763
 
603
 
        if (isl_val_is_zero(v)) {
 
764
        if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) {
604
765
                isl_val_free(v);
605
766
                return aff;
606
767
        }
655
816
}
656
817
 
657
818
/* Add "v" to the numerator of the constant term of "aff".
 
819
 *
 
820
 * A NaN is unaffected by this operation.
658
821
 */
659
822
__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
660
823
{
661
824
        if (isl_int_is_zero(v))
662
825
                return aff;
663
826
 
 
827
        if (!aff)
 
828
                return NULL;
 
829
        if (isl_aff_is_nan(aff))
 
830
                return aff;
664
831
        aff = isl_aff_cow(aff);
665
832
        if (!aff)
666
833
                return NULL;
675
842
}
676
843
 
677
844
/* Add "v" to the numerator of the constant term of "aff".
 
845
 *
 
846
 * A NaN is unaffected by this operation.
678
847
 */
679
848
__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
680
849
{
691
860
        return aff;
692
861
}
693
862
 
 
863
/* Replace the numerator of the constant term of "aff" by "v".
 
864
 *
 
865
 * A NaN is unaffected by this operation.
 
866
 */
694
867
__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
695
868
{
 
869
        if (!aff)
 
870
                return NULL;
 
871
        if (isl_aff_is_nan(aff))
 
872
                return aff;
696
873
        aff = isl_aff_cow(aff);
697
874
        if (!aff)
698
875
                return NULL;
706
883
        return aff;
707
884
}
708
885
 
 
886
/* Replace the numerator of the coefficient of the variable of type "type"
 
887
 * at position "pos" of "aff" by "v".
 
888
 *
 
889
 * A NaN is unaffected by this operation.
 
890
 */
709
891
__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
710
892
        enum isl_dim_type type, int pos, isl_int v)
711
893
{
723
905
                isl_die(aff->v->ctx, isl_error_invalid,
724
906
                        "position out of bounds", return isl_aff_free(aff));
725
907
 
 
908
        if (isl_aff_is_nan(aff))
 
909
                return aff;
726
910
        aff = isl_aff_cow(aff);
727
911
        if (!aff)
728
912
                return NULL;
737
921
        return aff;
738
922
}
739
923
 
 
924
/* Replace the numerator of the coefficient of the variable of type "type"
 
925
 * at position "pos" of "aff" by "v".
 
926
 *
 
927
 * A NaN is unaffected by this operation.
 
928
 */
740
929
__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
741
930
        enum isl_dim_type type, int pos, int v)
742
931
{
750
939
        if (type == isl_dim_in)
751
940
                type = isl_dim_set;
752
941
 
753
 
        if (pos >= isl_local_space_dim(aff->ls, type))
 
942
        if (pos < 0 || pos >= isl_local_space_dim(aff->ls, type))
754
943
                isl_die(aff->v->ctx, isl_error_invalid,
755
944
                        "position out of bounds", return isl_aff_free(aff));
756
945
 
 
946
        if (isl_aff_is_nan(aff))
 
947
                return aff;
 
948
        pos += isl_local_space_offset(aff->ls, type);
 
949
        if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0)
 
950
                return aff;
 
951
 
757
952
        aff = isl_aff_cow(aff);
758
953
        if (!aff)
759
954
                return NULL;
762
957
        if (!aff->v)
763
958
                return isl_aff_free(aff);
764
959
 
765
 
        pos += isl_local_space_offset(aff->ls, type);
766
960
        isl_int_set_si(aff->v->el[1 + pos], v);
767
961
 
768
962
        return aff;
770
964
 
771
965
/* Replace the coefficient of the variable of type "type" at position "pos"
772
966
 * of "aff" by "v".
 
967
 *
 
968
 * A NaN is unaffected by this operation.
773
969
 */
774
970
__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
775
971
        enum isl_dim_type type, int pos, __isl_take isl_val *v)
788
984
                isl_die(aff->v->ctx, isl_error_invalid,
789
985
                        "position out of bounds", goto error);
790
986
 
 
987
        if (isl_aff_is_nan(aff)) {
 
988
                isl_val_free(v);
 
989
                return aff;
 
990
        }
791
991
        if (!isl_val_is_rat(v))
792
992
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
793
993
                        "expecting rational value", goto error);
828
1028
        return NULL;
829
1029
}
830
1030
 
 
1031
/* Add "v" to the coefficient of the variable of type "type"
 
1032
 * at position "pos" of "aff".
 
1033
 *
 
1034
 * A NaN is unaffected by this operation.
 
1035
 */
831
1036
__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
832
1037
        enum isl_dim_type type, int pos, isl_int v)
833
1038
{
845
1050
                isl_die(aff->v->ctx, isl_error_invalid,
846
1051
                        "position out of bounds", return isl_aff_free(aff));
847
1052
 
 
1053
        if (isl_aff_is_nan(aff))
 
1054
                return aff;
848
1055
        aff = isl_aff_cow(aff);
849
1056
        if (!aff)
850
1057
                return NULL;
861
1068
 
862
1069
/* Add "v" to the coefficient of the variable of type "type"
863
1070
 * at position "pos" of "aff".
 
1071
 *
 
1072
 * A NaN is unaffected by this operation.
864
1073
 */
865
1074
__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
866
1075
        enum isl_dim_type type, int pos, __isl_take isl_val *v)
884
1093
                isl_die(aff->v->ctx, isl_error_invalid,
885
1094
                        "position out of bounds", goto error);
886
1095
 
 
1096
        if (isl_aff_is_nan(aff)) {
 
1097
                isl_val_free(v);
 
1098
                return aff;
 
1099
        }
887
1100
        if (!isl_val_is_rat(v))
888
1101
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
889
1102
                        "expecting rational value", goto error);
943
1156
        return isl_local_space_get_div(aff->ls, pos);
944
1157
}
945
1158
 
 
1159
/* Return the negation of "aff".
 
1160
 *
 
1161
 * As a special case, -NaN = NaN.
 
1162
 */
946
1163
__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
947
1164
{
 
1165
        if (!aff)
 
1166
                return NULL;
 
1167
        if (isl_aff_is_nan(aff))
 
1168
                return aff;
948
1169
        aff = isl_aff_cow(aff);
949
1170
        if (!aff)
950
1171
                return NULL;
1232
1453
 * Otherwise, if f = g/m, write g = q m + r,
1233
1454
 * create a new div d = [r/m] and return the expression q + d.
1234
1455
 * The coefficients in r are taken to lie between -m/2 and m/2.
 
1456
 *
 
1457
 * As a special case, floor(NaN) = NaN.
1235
1458
 */
1236
1459
__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
1237
1460
{
1243
1466
        if (!aff)
1244
1467
                return NULL;
1245
1468
 
 
1469
        if (isl_aff_is_nan(aff))
 
1470
                return aff;
1246
1471
        if (isl_int_is_one(aff->v->el[0]))
1247
1472
                return aff;
1248
1473
 
1389
1614
 * then return
1390
1615
 *
1391
1616
 *      floor((e + m - 1)/m)
 
1617
 *
 
1618
 * As a special case, ceil(NaN) = NaN.
1392
1619
 */
1393
1620
__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1394
1621
{
1395
1622
        if (!aff)
1396
1623
                return NULL;
1397
1624
 
 
1625
        if (isl_aff_is_nan(aff))
 
1626
                return aff;
1398
1627
        if (isl_int_is_one(aff->v->el[0]))
1399
1628
                return aff;
1400
1629
 
1496
1725
        return NULL;
1497
1726
}
1498
1727
 
 
1728
/* Return the sum of "aff1" and "aff2".
 
1729
 *
 
1730
 * If either of the two is NaN, then the result is NaN.
 
1731
 */
1499
1732
__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1500
1733
        __isl_take isl_aff *aff2)
1501
1734
{
1513
1746
                isl_die(ctx, isl_error_invalid,
1514
1747
                        "spaces don't match", goto error);
1515
1748
 
 
1749
        if (isl_aff_is_nan(aff1)) {
 
1750
                isl_aff_free(aff2);
 
1751
                return aff1;
 
1752
        }
 
1753
        if (isl_aff_is_nan(aff2)) {
 
1754
                isl_aff_free(aff1);
 
1755
                return aff2;
 
1756
        }
 
1757
 
1516
1758
        n_div1 = isl_aff_dim(aff1, isl_dim_div);
1517
1759
        n_div2 = isl_aff_dim(aff2, isl_dim_div);
1518
1760
        if (n_div1 == 0 && n_div2 == 0)
1544
1786
        return isl_aff_add(aff1, isl_aff_neg(aff2));
1545
1787
}
1546
1788
 
 
1789
/* Return the result of scaling "aff" by a factor of "f".
 
1790
 *
 
1791
 * As a special case, f * NaN = NaN.
 
1792
 */
1547
1793
__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
1548
1794
{
1549
1795
        isl_int gcd;
1550
1796
 
 
1797
        if (!aff)
 
1798
                return NULL;
 
1799
        if (isl_aff_is_nan(aff))
 
1800
                return aff;
 
1801
 
1551
1802
        if (isl_int_is_one(f))
1552
1803
                return aff;
1553
1804
 
1601
1852
        return NULL;
1602
1853
}
1603
1854
 
 
1855
/* Return the result of scaling "aff" down by a factor of "f".
 
1856
 *
 
1857
 * As a special case, NaN/f = NaN.
 
1858
 */
1604
1859
__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
1605
1860
{
1606
1861
        isl_int gcd;
1607
1862
 
 
1863
        if (!aff)
 
1864
                return NULL;
 
1865
        if (isl_aff_is_nan(aff))
 
1866
                return aff;
 
1867
 
1608
1868
        if (isl_int_is_one(f))
1609
1869
                return aff;
1610
1870
 
1701
1961
{
1702
1962
        aff = isl_aff_cow(aff);
1703
1963
        if (!aff)
1704
 
                return isl_id_free(id);
 
1964
                goto error;
1705
1965
        if (type == isl_dim_out)
1706
1966
                isl_die(aff->v->ctx, isl_error_invalid,
1707
1967
                        "cannot set name of output/set dimension",
1719
1979
        return NULL;
1720
1980
}
1721
1981
 
 
1982
/* Replace the identifier of the input tuple of "aff" by "id".
 
1983
 * type is currently required to be equal to isl_dim_in
 
1984
 */
 
1985
__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
 
1986
        enum isl_dim_type type, __isl_take isl_id *id)
 
1987
{
 
1988
        aff = isl_aff_cow(aff);
 
1989
        if (!aff)
 
1990
                goto error;
 
1991
        if (type != isl_dim_out)
 
1992
                isl_die(aff->v->ctx, isl_error_invalid,
 
1993
                        "cannot only set id of input tuple", goto error);
 
1994
        aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
 
1995
        if (!aff->ls)
 
1996
                return isl_aff_free(aff);
 
1997
 
 
1998
        return aff;
 
1999
error:
 
2000
        isl_id_free(id);
 
2001
        isl_aff_free(aff);
 
2002
        return NULL;
 
2003
}
 
2004
 
1722
2005
/* Exploit the equalities in "eq" to simplify the affine expression
1723
2006
 * and the expressions of the integer divisions in the local space.
1724
2007
 * The integer divisions in this local space are assumed to appear
1833
2116
/* Return a basic set containing those elements in the space
1834
2117
 * of aff where it is non-negative.
1835
2118
 * If "rational" is set, then return a rational basic set.
 
2119
 *
 
2120
 * If "aff" is NaN, then it is not non-negative (it's not negative either).
1836
2121
 */
1837
2122
static __isl_give isl_basic_set *aff_nonneg_basic_set(
1838
2123
        __isl_take isl_aff *aff, int rational)
1840
2125
        isl_constraint *ineq;
1841
2126
        isl_basic_set *bset;
1842
2127
 
 
2128
        if (!aff)
 
2129
                return NULL;
 
2130
        if (isl_aff_is_nan(aff)) {
 
2131
                isl_space *space = isl_aff_get_domain_space(aff);
 
2132
                isl_aff_free(aff);
 
2133
                return isl_basic_set_empty(space);
 
2134
        }
 
2135
 
1843
2136
        ineq = isl_inequality_from_aff(aff);
1844
2137
 
1845
2138
        bset = isl_basic_set_from_constraint(ineq);
1870
2163
/* Return a basic set containing those elements in the space
1871
2164
 * of aff where it is zero.
1872
2165
 * If "rational" is set, then return a rational basic set.
 
2166
 *
 
2167
 * If "aff" is NaN, then it is not zero.
1873
2168
 */
1874
2169
static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
1875
2170
        int rational)
1877
2172
        isl_constraint *ineq;
1878
2173
        isl_basic_set *bset;
1879
2174
 
 
2175
        if (!aff)
 
2176
                return NULL;
 
2177
        if (isl_aff_is_nan(aff)) {
 
2178
                isl_space *space = isl_aff_get_domain_space(aff);
 
2179
                isl_aff_free(aff);
 
2180
                return isl_basic_set_empty(space);
 
2181
        }
 
2182
 
1880
2183
        ineq = isl_equality_from_aff(aff);
1881
2184
 
1882
2185
        bset = isl_basic_set_from_constraint(ineq);
2090
2393
        return isl_pw_aff_insert_dims(pwaff, type, pos, n);
2091
2394
}
2092
2395
 
 
2396
/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
 
2397
 * to dimensions of "dst_type" at "dst_pos".
 
2398
 *
 
2399
 * We only support moving input dimensions to parameters and vice versa.
 
2400
 */
 
2401
__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
 
2402
        enum isl_dim_type dst_type, unsigned dst_pos,
 
2403
        enum isl_dim_type src_type, unsigned src_pos, unsigned n)
 
2404
{
 
2405
        unsigned g_dst_pos;
 
2406
        unsigned g_src_pos;
 
2407
 
 
2408
        if (!aff)
 
2409
                return NULL;
 
2410
        if (n == 0 &&
 
2411
            !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
 
2412
            !isl_local_space_is_named_or_nested(aff->ls, dst_type))
 
2413
                return aff;
 
2414
 
 
2415
        if (dst_type == isl_dim_out || src_type == isl_dim_out)
 
2416
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
2417
                        "cannot move output/set dimension", isl_aff_free(aff));
 
2418
        if (dst_type == isl_dim_div || src_type == isl_dim_div)
 
2419
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
2420
                        "cannot move divs", isl_aff_free(aff));
 
2421
        if (dst_type == isl_dim_in)
 
2422
                dst_type = isl_dim_set;
 
2423
        if (src_type == isl_dim_in)
 
2424
                src_type = isl_dim_set;
 
2425
 
 
2426
        if (src_pos + n > isl_local_space_dim(aff->ls, src_type))
 
2427
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
 
2428
                        "range out of bounds", isl_aff_free(aff));
 
2429
        if (dst_type == src_type)
 
2430
                isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
 
2431
                        "moving dims within the same type not supported",
 
2432
                        isl_aff_free(aff));
 
2433
 
 
2434
        aff = isl_aff_cow(aff);
 
2435
        if (!aff)
 
2436
                return NULL;
 
2437
 
 
2438
        g_src_pos = 1 + isl_local_space_offset(aff->ls, src_type) + src_pos;
 
2439
        g_dst_pos = 1 + isl_local_space_offset(aff->ls, dst_type) + dst_pos;
 
2440
        if (dst_type > src_type)
 
2441
                g_dst_pos -= n;
 
2442
 
 
2443
        aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
 
2444
        aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
 
2445
                                                src_type, src_pos, n);
 
2446
        if (!aff->v || !aff->ls)
 
2447
                return isl_aff_free(aff);
 
2448
 
 
2449
        aff = sort_divs(aff);
 
2450
 
 
2451
        return aff;
 
2452
}
 
2453
 
2093
2454
__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
2094
2455
{
2095
2456
        isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
2113
2474
 
2114
2475
#define NO_EVAL
2115
2476
#define NO_OPT
2116
 
#define NO_MOVE_DIMS
2117
2477
#define NO_LIFT
2118
2478
#define NO_MORPH
2119
2479
 
2312
2672
                return NULL;
2313
2673
        if (isl_space_is_set(pwaff->dim))
2314
2674
                isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2315
 
                        "space of input is not a map",
2316
 
                        return isl_pw_aff_free(pwaff));
 
2675
                        "space of input is not a map", goto error);
2317
2676
        return map_from_pw_aff(pwaff);
 
2677
error:
 
2678
        isl_pw_aff_free(pwaff);
 
2679
        return NULL;
2318
2680
}
2319
2681
 
2320
2682
/* Construct a one-dimensional set with as parameter domain
2327
2689
                return NULL;
2328
2690
        if (!isl_space_is_set(pwaff->dim))
2329
2691
                isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2330
 
                        "space of input is not a set",
2331
 
                        return isl_pw_aff_free(pwaff));
 
2692
                        "space of input is not a set", goto error);
2332
2693
        return map_from_pw_aff(pwaff);
 
2694
error:
 
2695
        isl_pw_aff_free(pwaff);
 
2696
        return NULL;
2333
2697
}
2334
2698
 
2335
2699
/* Return a set containing those elements in the domain
2366
2730
/* Return a set containing those elements in the domain
2367
2731
 * of pwaff where it is zero (if complement is 0) or not zero
2368
2732
 * (if complement is 1).
 
2733
 *
 
2734
 * The pieces with a NaN never belong to the result since
 
2735
 * NaN is neither zero nor non-zero.
2369
2736
 */
2370
2737
static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff,
2371
2738
        int complement)
2383
2750
                isl_set *set_i, *zero;
2384
2751
                int rational;
2385
2752
 
 
2753
                if (isl_aff_is_nan(pwaff->p[i].aff))
 
2754
                        continue;
 
2755
 
2386
2756
                rational = isl_set_has_rational(pwaff->p[i].set);
2387
2757
                bset = aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff),
2388
2758
                                                rational);
2738
3108
 * where "cond" is non-zero and to pwaff_false for elements where "cond"
2739
3109
 * is zero.
2740
3110
 * That is, return cond ? pwaff_true : pwaff_false;
 
3111
 *
 
3112
 * If "cond" involves and NaN, then we conservatively return a NaN
 
3113
 * on its entire domain.  In principle, we could consider the pieces
 
3114
 * where it is NaN separately from those where it is not.
2741
3115
 */
2742
3116
__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
2743
3117
        __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
2744
3118
{
2745
3119
        isl_set *cond_true, *cond_false;
2746
3120
 
 
3121
        if (!cond)
 
3122
                goto error;
 
3123
        if (isl_pw_aff_involves_nan(cond)) {
 
3124
                isl_space *space = isl_pw_aff_get_domain_space(cond);
 
3125
                isl_local_space *ls = isl_local_space_from_space(space);
 
3126
                isl_pw_aff_free(cond);
 
3127
                isl_pw_aff_free(pwaff_true);
 
3128
                isl_pw_aff_free(pwaff_false);
 
3129
                return isl_pw_aff_nan_on_domain(ls);
 
3130
        }
 
3131
 
2747
3132
        cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
2748
3133
        cond_false = isl_pw_aff_zero_set(cond);
2749
3134
        return isl_pw_aff_select(cond_true, pwaff_true,
2750
3135
                                 cond_false, pwaff_false);
 
3136
error:
 
3137
        isl_pw_aff_free(cond);
 
3138
        isl_pw_aff_free(pwaff_true);
 
3139
        isl_pw_aff_free(pwaff_false);
 
3140
        return NULL;
2751
3141
}
2752
3142
 
2753
3143
int isl_aff_is_cst(__isl_keep isl_aff *aff)
2776
3166
        return 1;
2777
3167
}
2778
3168
 
 
3169
/* Return the product of "aff1" and "aff2".
 
3170
 *
 
3171
 * If either of the two is NaN, then the result is NaN.
 
3172
 *
 
3173
 * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
 
3174
 */
2779
3175
__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
2780
3176
        __isl_take isl_aff *aff2)
2781
3177
{
 
3178
        if (!aff1 || !aff2)
 
3179
                goto error;
 
3180
 
 
3181
        if (isl_aff_is_nan(aff1)) {
 
3182
                isl_aff_free(aff2);
 
3183
                return aff1;
 
3184
        }
 
3185
        if (isl_aff_is_nan(aff2)) {
 
3186
                isl_aff_free(aff1);
 
3187
                return aff2;
 
3188
        }
 
3189
 
2782
3190
        if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
2783
3191
                return isl_aff_mul(aff2, aff1);
2784
3192
 
2802
3210
        return NULL;
2803
3211
}
2804
3212
 
2805
 
/* Divide "aff1" by "aff2", assuming "aff2" is a piecewise constant.
 
3213
/* Divide "aff1" by "aff2", assuming "aff2" is a constant.
 
3214
 *
 
3215
 * If either of the two is NaN, then the result is NaN.
2806
3216
 */
2807
3217
__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
2808
3218
        __isl_take isl_aff *aff2)
2810
3220
        int is_cst;
2811
3221
        int neg;
2812
3222
 
 
3223
        if (!aff1 || !aff2)
 
3224
                goto error;
 
3225
 
 
3226
        if (isl_aff_is_nan(aff1)) {
 
3227
                isl_aff_free(aff2);
 
3228
                return aff1;
 
3229
        }
 
3230
        if (isl_aff_is_nan(aff2)) {
 
3231
                isl_aff_free(aff1);
 
3232
                return aff2;
 
3233
        }
 
3234
 
2813
3235
        is_cst = isl_aff_is_cst(aff2);
2814
3236
        if (is_cst < 0)
2815
3237
                goto error;
3022
3444
        ctx = isl_pw_aff_list_get_ctx(list);
3023
3445
        if (list->n < 1)
3024
3446
                isl_die(ctx, isl_error_invalid,
3025
 
                        "list should contain at least one element",
3026
 
                        return isl_pw_aff_list_free(list));
 
3447
                        "list should contain at least one element", goto error);
3027
3448
 
3028
3449
        res = isl_pw_aff_copy(list->p[0]);
3029
3450
        for (i = 1; i < list->n; ++i)
3031
3452
 
3032
3453
        isl_pw_aff_list_free(list);
3033
3454
        return res;
 
3455
error:
 
3456
        isl_pw_aff_list_free(list);
 
3457
        return NULL;
3034
3458
}
3035
3459
 
3036
3460
/* Return an isl_pw_aff that maps each element in the intersection of the
3096
3520
        return list;
3097
3521
}
3098
3522
 
 
3523
/* Do the parameters of "aff" match those of "space"?
 
3524
 */
 
3525
int isl_aff_matching_params(__isl_keep isl_aff *aff,
 
3526
        __isl_keep isl_space *space)
 
3527
{
 
3528
        isl_space *aff_space;
 
3529
        int match;
 
3530
 
 
3531
        if (!aff || !space)
 
3532
                return -1;
 
3533
 
 
3534
        aff_space = isl_aff_get_domain_space(aff);
 
3535
 
 
3536
        match = isl_space_match(space, isl_dim_param, aff_space, isl_dim_param);
 
3537
 
 
3538
        isl_space_free(aff_space);
 
3539
        return match;
 
3540
}
 
3541
 
3099
3542
/* Check that the domain space of "aff" matches "space".
3100
3543
 *
3101
3544
 * Return 0 on success and -1 on error.
3117
3560
        if (!match)
3118
3561
                isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
3119
3562
                        "parameters don't match", goto error);
3120
 
        match = isl_space_tuple_match(space, isl_dim_in,
 
3563
        match = isl_space_tuple_is_equal(space, isl_dim_in,
3121
3564
                                        aff_space, isl_dim_set);
3122
3565
        if (match < 0)
3123
3566
                goto error;
3133
3576
 
3134
3577
#undef BASE
3135
3578
#define BASE aff
 
3579
#define NO_INTERSECT_DOMAIN
 
3580
#define NO_DOMAIN
3136
3581
 
3137
3582
#include <isl_multi_templ.c>
3138
3583
 
 
3584
#undef NO_DOMAIN
 
3585
#undef NO_INTERSECT_DOMAIN
 
3586
 
 
3587
/* Remove any internal structure of the domain of "ma".
 
3588
 * If there is any such internal structure in the input,
 
3589
 * then the name of the corresponding space is also removed.
 
3590
 */
 
3591
__isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
 
3592
        __isl_take isl_multi_aff *ma)
 
3593
{
 
3594
        isl_space *space;
 
3595
 
 
3596
        if (!ma)
 
3597
                return NULL;
 
3598
 
 
3599
        if (!ma->space->nested[0])
 
3600
                return ma;
 
3601
 
 
3602
        space = isl_multi_aff_get_space(ma);
 
3603
        space = isl_space_flatten_domain(space);
 
3604
        ma = isl_multi_aff_reset_space(ma, space);
 
3605
 
 
3606
        return ma;
 
3607
}
 
3608
 
 
3609
/* Given a map space, return an isl_multi_aff that maps a wrapped copy
 
3610
 * of the space to its domain.
 
3611
 */
 
3612
__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
 
3613
{
 
3614
        int i, n_in;
 
3615
        isl_local_space *ls;
 
3616
        isl_multi_aff *ma;
 
3617
 
 
3618
        if (!space)
 
3619
                return NULL;
 
3620
        if (!isl_space_is_map(space))
 
3621
                isl_die(isl_space_get_ctx(space), isl_error_invalid,
 
3622
                        "not a map space", goto error);
 
3623
 
 
3624
        n_in = isl_space_dim(space, isl_dim_in);
 
3625
        space = isl_space_domain_map(space);
 
3626
 
 
3627
        ma = isl_multi_aff_alloc(isl_space_copy(space));
 
3628
        if (n_in == 0) {
 
3629
                isl_space_free(space);
 
3630
                return ma;
 
3631
        }
 
3632
 
 
3633
        space = isl_space_domain(space);
 
3634
        ls = isl_local_space_from_space(space);
 
3635
        for (i = 0; i < n_in; ++i) {
 
3636
                isl_aff *aff;
 
3637
 
 
3638
                aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
 
3639
                                                isl_dim_set, i);
 
3640
                ma = isl_multi_aff_set_aff(ma, i, aff);
 
3641
        }
 
3642
        isl_local_space_free(ls);
 
3643
        return ma;
 
3644
error:
 
3645
        isl_space_free(space);
 
3646
        return NULL;
 
3647
}
 
3648
 
 
3649
/* Given a map space, return an isl_multi_aff that maps a wrapped copy
 
3650
 * of the space to its range.
 
3651
 */
 
3652
__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
 
3653
{
 
3654
        int i, n_in, n_out;
 
3655
        isl_local_space *ls;
 
3656
        isl_multi_aff *ma;
 
3657
 
 
3658
        if (!space)
 
3659
                return NULL;
 
3660
        if (!isl_space_is_map(space))
 
3661
                isl_die(isl_space_get_ctx(space), isl_error_invalid,
 
3662
                        "not a map space", goto error);
 
3663
 
 
3664
        n_in = isl_space_dim(space, isl_dim_in);
 
3665
        n_out = isl_space_dim(space, isl_dim_out);
 
3666
        space = isl_space_range_map(space);
 
3667
 
 
3668
        ma = isl_multi_aff_alloc(isl_space_copy(space));
 
3669
        if (n_out == 0) {
 
3670
                isl_space_free(space);
 
3671
                return ma;
 
3672
        }
 
3673
 
 
3674
        space = isl_space_domain(space);
 
3675
        ls = isl_local_space_from_space(space);
 
3676
        for (i = 0; i < n_out; ++i) {
 
3677
                isl_aff *aff;
 
3678
 
 
3679
                aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
 
3680
                                                isl_dim_set, n_in + i);
 
3681
                ma = isl_multi_aff_set_aff(ma, i, aff);
 
3682
        }
 
3683
        isl_local_space_free(ls);
 
3684
        return ma;
 
3685
error:
 
3686
        isl_space_free(space);
 
3687
        return NULL;
 
3688
}
 
3689
 
 
3690
/* Given the space of a set and a range of set dimensions,
 
3691
 * construct an isl_multi_aff that projects out those dimensions.
 
3692
 */
 
3693
__isl_give isl_multi_aff *isl_multi_aff_project_out_map(
 
3694
        __isl_take isl_space *space, enum isl_dim_type type,
 
3695
        unsigned first, unsigned n)
 
3696
{
 
3697
        int i, dim;
 
3698
        isl_local_space *ls;
 
3699
        isl_multi_aff *ma;
 
3700
 
 
3701
        if (!space)
 
3702
                return NULL;
 
3703
        if (!isl_space_is_set(space))
 
3704
                isl_die(isl_space_get_ctx(space), isl_error_unsupported,
 
3705
                        "expecting set space", goto error);
 
3706
        if (type != isl_dim_set)
 
3707
                isl_die(isl_space_get_ctx(space), isl_error_invalid,
 
3708
                        "only set dimensions can be projected out", goto error);
 
3709
 
 
3710
        dim = isl_space_dim(space, isl_dim_set);
 
3711
        if (first + n > dim)
 
3712
                isl_die(isl_space_get_ctx(space), isl_error_invalid,
 
3713
                        "range out of bounds", goto error);
 
3714
 
 
3715
        space = isl_space_from_domain(space);
 
3716
        space = isl_space_add_dims(space, isl_dim_out, dim - n);
 
3717
 
 
3718
        if (dim == n)
 
3719
                return isl_multi_aff_alloc(space);
 
3720
 
 
3721
        ma = isl_multi_aff_alloc(isl_space_copy(space));
 
3722
        space = isl_space_domain(space);
 
3723
        ls = isl_local_space_from_space(space);
 
3724
 
 
3725
        for (i = 0; i < first; ++i) {
 
3726
                isl_aff *aff;
 
3727
 
 
3728
                aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
 
3729
                                                isl_dim_set, i);
 
3730
                ma = isl_multi_aff_set_aff(ma, i, aff);
 
3731
        }
 
3732
 
 
3733
        for (i = 0; i < dim - (first + n); ++i) {
 
3734
                isl_aff *aff;
 
3735
 
 
3736
                aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
 
3737
                                                isl_dim_set, first + n + i);
 
3738
                ma = isl_multi_aff_set_aff(ma, first + i, aff);
 
3739
        }
 
3740
 
 
3741
        isl_local_space_free(ls);
 
3742
        return ma;
 
3743
error:
 
3744
        isl_space_free(space);
 
3745
        return NULL;
 
3746
}
 
3747
 
 
3748
/* Given the space of a set and a range of set dimensions,
 
3749
 * construct an isl_pw_multi_aff that projects out those dimensions.
 
3750
 */
 
3751
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
 
3752
        __isl_take isl_space *space, enum isl_dim_type type,
 
3753
        unsigned first, unsigned n)
 
3754
{
 
3755
        isl_multi_aff *ma;
 
3756
 
 
3757
        ma = isl_multi_aff_project_out_map(space, type, first, n);
 
3758
        return isl_pw_multi_aff_from_multi_aff(ma);
 
3759
}
 
3760
 
3139
3761
/* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe
3140
3762
 * domain.
3141
3763
 */
3155
3777
        return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
3156
3778
}
3157
3779
 
3158
 
__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
3159
 
        __isl_take isl_multi_aff *maff2)
 
3780
/* Add "ma2" to "ma1" and return the result.
 
3781
 *
 
3782
 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
 
3783
 */
 
3784
static __isl_give isl_multi_aff *isl_multi_aff_add_aligned(
 
3785
        __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
3160
3786
{
3161
3787
        return isl_multi_aff_bin_op(maff1, maff2, &isl_aff_add);
3162
3788
}
3163
3789
 
 
3790
/* Add "ma2" to "ma1" and return the result.
 
3791
 */
 
3792
__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *ma1,
 
3793
        __isl_take isl_multi_aff *ma2)
 
3794
{
 
3795
        return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
 
3796
                                                &isl_multi_aff_add_aligned);
 
3797
}
 
3798
 
 
3799
/* Subtract "ma2" from "ma1" and return the result.
 
3800
 *
 
3801
 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
 
3802
 */
 
3803
static __isl_give isl_multi_aff *isl_multi_aff_sub_aligned(
 
3804
        __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
 
3805
{
 
3806
        return isl_multi_aff_bin_op(ma1, ma2, &isl_aff_sub);
 
3807
}
 
3808
 
3164
3809
/* Subtract "ma2" from "ma1" and return the result.
3165
3810
 */
3166
3811
__isl_give isl_multi_aff *isl_multi_aff_sub(__isl_take isl_multi_aff *ma1,
3167
3812
        __isl_take isl_multi_aff *ma2)
3168
3813
{
3169
 
        return isl_multi_aff_bin_op(ma1, ma2, &isl_aff_sub);
3170
 
}
3171
 
 
3172
 
/* Given two multi-affine expressions A -> B and C -> D,
3173
 
 * construct a multi-affine expression [A -> C] -> [B -> D].
3174
 
 */
3175
 
__isl_give isl_multi_aff *isl_multi_aff_product(
3176
 
        __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
3177
 
{
3178
 
        int i;
3179
 
        isl_aff *aff;
3180
 
        isl_space *space;
3181
 
        isl_multi_aff *res;
3182
 
        int in1, in2, out1, out2;
3183
 
 
3184
 
        in1 = isl_multi_aff_dim(ma1, isl_dim_in);
3185
 
        in2 = isl_multi_aff_dim(ma2, isl_dim_in);
3186
 
        out1 = isl_multi_aff_dim(ma1, isl_dim_out);
3187
 
        out2 = isl_multi_aff_dim(ma2, isl_dim_out);
3188
 
        space = isl_space_product(isl_multi_aff_get_space(ma1),
3189
 
                                  isl_multi_aff_get_space(ma2));
3190
 
        res = isl_multi_aff_alloc(isl_space_copy(space));
3191
 
        space = isl_space_domain(space);
3192
 
 
3193
 
        for (i = 0; i < out1; ++i) {
3194
 
                aff = isl_multi_aff_get_aff(ma1, i);
3195
 
                aff = isl_aff_insert_dims(aff, isl_dim_in, in1, in2);
3196
 
                aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
3197
 
                res = isl_multi_aff_set_aff(res, i, aff);
3198
 
        }
3199
 
 
3200
 
        for (i = 0; i < out2; ++i) {
3201
 
                aff = isl_multi_aff_get_aff(ma2, i);
3202
 
                aff = isl_aff_insert_dims(aff, isl_dim_in, 0, in1);
3203
 
                aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
3204
 
                res = isl_multi_aff_set_aff(res, out1 + i, aff);
3205
 
        }
3206
 
 
3207
 
        isl_space_free(space);
3208
 
        isl_multi_aff_free(ma1);
3209
 
        isl_multi_aff_free(ma2);
3210
 
        return res;
 
3814
        return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
 
3815
                                                &isl_multi_aff_sub_aligned);
3211
3816
}
3212
3817
 
3213
3818
/* Exploit the equalities in "eq" to simplify the affine expressions.
3236
3841
        return NULL;
3237
3842
}
3238
3843
 
 
3844
/* Given f, return floor(f).
 
3845
 */
 
3846
__isl_give isl_multi_aff *isl_multi_aff_floor(__isl_take isl_multi_aff *ma)
 
3847
{
 
3848
        int i;
 
3849
 
 
3850
        ma = isl_multi_aff_cow(ma);
 
3851
        if (!ma)
 
3852
                return NULL;
 
3853
 
 
3854
        for (i = 0; i < ma->n; ++i) {
 
3855
                ma->p[i] = isl_aff_floor(ma->p[i]);
 
3856
                if (!ma->p[i])
 
3857
                        return isl_multi_aff_free(ma);
 
3858
        }
 
3859
 
 
3860
        return ma;
 
3861
}
 
3862
 
3239
3863
__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
3240
3864
        isl_int f)
3241
3865
{
3270
3894
        return 0;
3271
3895
}
3272
3896
 
3273
 
int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
3274
 
        __isl_keep isl_multi_aff *maff2)
3275
 
{
3276
 
        int i;
3277
 
        int equal;
3278
 
 
3279
 
        if (!maff1 || !maff2)
3280
 
                return -1;
3281
 
        if (maff1->n != maff2->n)
3282
 
                return 0;
3283
 
        equal = isl_space_is_equal(maff1->space, maff2->space);
3284
 
        if (equal < 0 || !equal)
3285
 
                return equal;
3286
 
 
3287
 
        for (i = 0; i < maff1->n; ++i) {
3288
 
                equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
3289
 
                if (equal < 0 || !equal)
3290
 
                        return equal;
3291
 
        }
3292
 
 
3293
 
        return 1;
3294
 
}
3295
 
 
3296
3897
/* Return the set of domain elements where "ma1" is lexicographically
3297
3898
 * smaller than or equal to "ma2".
3298
3899
 */
3342
3943
#define NO_EVAL
3343
3944
#define NO_OPT
3344
3945
#define NO_INVOLVES_DIMS
3345
 
#define NO_MOVE_DIMS
3346
3946
#define NO_INSERT_DIMS
3347
3947
#define NO_LIFT
3348
3948
#define NO_MORPH
3636
4236
        if (!isl_space_is_set(pma->dim))
3637
4237
                isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
3638
4238
                        "isl_pw_multi_aff cannot be converted into an isl_set",
3639
 
                        return isl_pw_multi_aff_free(pma));
 
4239
                        goto error);
3640
4240
 
3641
4241
        return isl_map_from_pw_multi_aff(pma);
 
4242
error:
 
4243
        isl_pw_multi_aff_free(pma);
 
4244
        return NULL;
3642
4245
}
3643
4246
 
3644
4247
/* Given a basic map with a single output dimension that is defined
3645
4248
 * in terms of the parameters and input dimensions using an equality,
3646
4249
 * extract an isl_aff that expresses the output dimension in terms
3647
4250
 * of the parameters and input dimensions.
3648
 
 *
3649
 
 * Since some applications expect the result of isl_pw_multi_aff_from_map
3650
 
 * to only contain integer affine expressions, we compute the floor
3651
 
 * of the expression before returning.
 
4251
 * Note that this expression may involve integer divisions defined
 
4252
 * in terms of parameters and input dimensions.
3652
4253
 *
3653
4254
 * This function shares some similarities with
3654
4255
 * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
3656
4257
static __isl_give isl_aff *extract_isl_aff_from_basic_map(
3657
4258
        __isl_take isl_basic_map *bmap)
3658
4259
{
3659
 
        int i;
 
4260
        int eq;
3660
4261
        unsigned offset;
3661
 
        unsigned total;
 
4262
        unsigned n_div;
3662
4263
        isl_local_space *ls;
3663
4264
        isl_aff *aff;
3664
4265
 
3668
4269
                isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3669
4270
                        "basic map should have a single output dimension",
3670
4271
                        goto error);
3671
 
        offset = isl_basic_map_offset(bmap, isl_dim_out);
3672
 
        total = isl_basic_map_total_dim(bmap);
3673
 
        for (i = 0; i < bmap->n_eq; ++i) {
3674
 
                if (isl_int_is_zero(bmap->eq[i][offset]))
3675
 
                        continue;
3676
 
                if (isl_seq_first_non_zero(bmap->eq[i] + offset + 1,
3677
 
                                           1 + total - (offset + 1)) != -1)
3678
 
                        continue;
3679
 
                break;
3680
 
        }
3681
 
        if (i >= bmap->n_eq)
 
4272
        eq = isl_basic_map_output_defining_equality(bmap, 0);
 
4273
        if (eq >= bmap->n_eq)
3682
4274
                isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3683
4275
                        "unable to find suitable equality", goto error);
3684
4276
        ls = isl_basic_map_get_local_space(bmap);
3685
4277
        aff = isl_aff_alloc(isl_local_space_domain(ls));
3686
4278
        if (!aff)
3687
4279
                goto error;
3688
 
        if (isl_int_is_neg(bmap->eq[i][offset]))
3689
 
                isl_seq_cpy(aff->v->el + 1, bmap->eq[i], offset);
3690
 
        else
3691
 
                isl_seq_neg(aff->v->el + 1, bmap->eq[i], offset);
3692
 
        isl_seq_clr(aff->v->el + 1 + offset, aff->v->size - (1 + offset));
3693
 
        isl_int_abs(aff->v->el[0], bmap->eq[i][offset]);
 
4280
        offset = isl_basic_map_offset(bmap, isl_dim_out);
 
4281
        n_div = isl_basic_map_dim(bmap, isl_dim_div);
 
4282
        if (isl_int_is_neg(bmap->eq[eq][offset])) {
 
4283
                isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], offset);
 
4284
                isl_seq_cpy(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1,
 
4285
                            n_div);
 
4286
        } else {
 
4287
                isl_seq_neg(aff->v->el + 1, bmap->eq[eq], offset);
 
4288
                isl_seq_neg(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1,
 
4289
                            n_div);
 
4290
        }
 
4291
        isl_int_abs(aff->v->el[0], bmap->eq[eq][offset]);
3694
4292
        isl_basic_map_free(bmap);
3695
4293
 
3696
4294
        aff = isl_aff_remove_unused_divs(aff);
3697
 
        aff = isl_aff_floor(aff);
3698
4295
        return aff;
3699
4296
error:
3700
4297
        isl_basic_map_free(bmap);
3736
4333
        return ma;
3737
4334
}
3738
4335
 
 
4336
/* Given a basic set where each set dimension is defined
 
4337
 * in terms of the parameters using an equality,
 
4338
 * extract an isl_multi_aff that expresses the set dimensions in terms
 
4339
 * of the parameters.
 
4340
 */
 
4341
__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
 
4342
        __isl_take isl_basic_set *bset)
 
4343
{
 
4344
        return extract_isl_multi_aff_from_basic_map(bset);
 
4345
}
 
4346
 
3739
4347
/* Create an isl_pw_multi_aff that is equivalent to
3740
4348
 * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
3741
4349
 * The given basic map is such that each output dimension is defined
3742
4350
 * in terms of the parameters and input dimensions using an equality.
 
4351
 *
 
4352
 * Since some applications expect the result of isl_pw_multi_aff_from_map
 
4353
 * to only contain integer affine expressions, we compute the floor
 
4354
 * of the expression before returning.
3743
4355
 */
3744
4356
static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
3745
4357
        __isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
3747
4359
        isl_multi_aff *ma;
3748
4360
 
3749
4361
        ma = extract_isl_multi_aff_from_basic_map(bmap);
 
4362
        ma = isl_multi_aff_floor(ma);
3750
4363
        return isl_pw_multi_aff_alloc(domain, ma);
3751
4364
}
3752
4365
 
4617
5230
        return NULL;
4618
5231
}
4619
5232
 
 
5233
/* Compute the pullback of "aff1" by the function represented by "aff2".
 
5234
 * In other words, plug in "aff2" in "aff1".  The result is an affine expression
 
5235
 * defined over the domain space of "aff1".
 
5236
 *
 
5237
 * The domain of "aff1" should match the range of "aff2", which means
 
5238
 * that it should be single-dimensional.
 
5239
 */
 
5240
__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
 
5241
        __isl_take isl_aff *aff2)
 
5242
{
 
5243
        isl_multi_aff *ma;
 
5244
 
 
5245
        ma = isl_multi_aff_from_aff(aff2);
 
5246
        return isl_aff_pullback_multi_aff(aff1, ma);
 
5247
}
 
5248
 
4620
5249
/* Compute the pullback of "ma1" by the function represented by "ma2".
4621
5250
 * In other words, plug in "ma2" in "ma1".
 
5251
 *
 
5252
 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
4622
5253
 */
4623
 
__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
 
5254
static __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff_aligned(
4624
5255
        __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
4625
5256
{
4626
5257
        int i;
4651
5282
        return NULL;
4652
5283
}
4653
5284
 
 
5285
/* Compute the pullback of "ma1" by the function represented by "ma2".
 
5286
 * In other words, plug in "ma2" in "ma1".
 
5287
 */
 
5288
__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
 
5289
        __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
 
5290
{
 
5291
        return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
 
5292
                                &isl_multi_aff_pullback_multi_aff_aligned);
 
5293
}
 
5294
 
4654
5295
/* Extend the local space of "dst" to include the divs
4655
5296
 * in the local space of "src".
4656
5297
 */
5043
5684
        struct isl_union_pw_multi_aff_bin_data *data = user;
5044
5685
        isl_pw_multi_aff *pma2 = *entry;
5045
5686
 
5046
 
        if (!isl_space_tuple_match(data->pma->dim, isl_dim_in,
 
5687
        if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
5047
5688
                                 pma2->dim, isl_dim_in))
5048
5689
                return 0;
5049
5690
 
5082
5723
        if (!pma || !pa)
5083
5724
                goto error;
5084
5725
 
5085
 
        if (!isl_space_tuple_match(pma->dim, isl_dim_in, pa->dim, isl_dim_in))
 
5726
        if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
 
5727
                                        pa->dim, isl_dim_in))
5086
5728
                isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
5087
5729
                        "domains don't match", goto error);
5088
5730
        if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
5150
5792
        return NULL;
5151
5793
}
5152
5794
 
 
5795
/* Do the parameters of "pa" match those of "space"?
 
5796
 */
 
5797
int isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
 
5798
        __isl_keep isl_space *space)
 
5799
{
 
5800
        isl_space *pa_space;
 
5801
        int match;
 
5802
 
 
5803
        if (!pa || !space)
 
5804
                return -1;
 
5805
 
 
5806
        pa_space = isl_pw_aff_get_space(pa);
 
5807
 
 
5808
        match = isl_space_match(space, isl_dim_param, pa_space, isl_dim_param);
 
5809
 
 
5810
        isl_space_free(pa_space);
 
5811
        return match;
 
5812
}
 
5813
 
5153
5814
/* Check that the domain space of "pa" matches "space".
5154
5815
 *
5155
5816
 * Return 0 on success and -1 on error.
5171
5832
        if (!match)
5172
5833
                isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
5173
5834
                        "parameters don't match", goto error);
5174
 
        match = isl_space_tuple_match(space, isl_dim_in, pa_space, isl_dim_in);
 
5835
        match = isl_space_tuple_is_equal(space, isl_dim_in,
 
5836
                                        pa_space, isl_dim_in);
5175
5837
        if (match < 0)
5176
5838
                goto error;
5177
5839
        if (!match)
5199
5861
        pma = isl_pw_multi_aff_cow(pma);
5200
5862
        if (!pma || !mv)
5201
5863
                goto error;
5202
 
        if (!isl_space_tuple_match(pma->dim, isl_dim_out,
 
5864
        if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
5203
5865
                                        mv->space, isl_dim_set))
5204
5866
                isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
5205
5867
                        "spaces don't match", goto error);
5249
5911
 
5250
5912
        if (!pma)
5251
5913
                return -1;
5252
 
        if (!isl_space_tuple_match(pma->dim, isl_dim_out,
 
5914
        if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
5253
5915
                                    data->mv->space, isl_dim_set))
5254
5916
                return 0;
5255
5917
 
5293
5955
        isl_union_pw_multi_aff_free(upma);
5294
5956
        return NULL;
5295
5957
}
 
5958
 
 
5959
/* Construct and return a piecewise multi affine expression
 
5960
 * in the given space with value zero in each of the output dimensions and
 
5961
 * a universe domain.
 
5962
 */
 
5963
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
 
5964
{
 
5965
        return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
 
5966
}
 
5967
 
 
5968
/* Construct and return a piecewise multi affine expression
 
5969
 * that is equal to the given piecewise affine expression.
 
5970
 */
 
5971
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
 
5972
        __isl_take isl_pw_aff *pa)
 
5973
{
 
5974
        int i;
 
5975
        isl_space *space;
 
5976
        isl_pw_multi_aff *pma;
 
5977
 
 
5978
        if (!pa)
 
5979
                return NULL;
 
5980
 
 
5981
        space = isl_pw_aff_get_space(pa);
 
5982
        pma = isl_pw_multi_aff_alloc_size(space, pa->n);
 
5983
 
 
5984
        for (i = 0; i < pa->n; ++i) {
 
5985
                isl_set *set;
 
5986
                isl_multi_aff *ma;
 
5987
 
 
5988
                set = isl_set_copy(pa->p[i].set);
 
5989
                ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
 
5990
                pma = isl_pw_multi_aff_add_piece(pma, set, ma);
 
5991
        }
 
5992
 
 
5993
        isl_pw_aff_free(pa);
 
5994
        return pma;
 
5995
}
 
5996
 
 
5997
/* Construct a set or map mapping the shared (parameter) domain
 
5998
 * of the piecewise affine expressions to the range of "mpa"
 
5999
 * with each dimension in the range equated to the
 
6000
 * corresponding piecewise affine expression.
 
6001
 */
 
6002
static __isl_give isl_map *map_from_multi_pw_aff(
 
6003
        __isl_take isl_multi_pw_aff *mpa)
 
6004
{
 
6005
        int i;
 
6006
        isl_space *space;
 
6007
        isl_map *map;
 
6008
 
 
6009
        if (!mpa)
 
6010
                return NULL;
 
6011
 
 
6012
        if (isl_space_dim(mpa->space, isl_dim_out) != mpa->n)
 
6013
                isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,
 
6014
                        "invalid space", goto error);
 
6015
 
 
6016
        space = isl_multi_pw_aff_get_domain_space(mpa);
 
6017
        map = isl_map_universe(isl_space_from_domain(space));
 
6018
 
 
6019
        for (i = 0; i < mpa->n; ++i) {
 
6020
                isl_pw_aff *pa;
 
6021
                isl_map *map_i;
 
6022
 
 
6023
                pa = isl_pw_aff_copy(mpa->p[i]);
 
6024
                map_i = map_from_pw_aff(pa);
 
6025
 
 
6026
                map = isl_map_flat_range_product(map, map_i);
 
6027
        }
 
6028
 
 
6029
        map = isl_map_reset_space(map, isl_multi_pw_aff_get_space(mpa));
 
6030
 
 
6031
        isl_multi_pw_aff_free(mpa);
 
6032
        return map;
 
6033
error:
 
6034
        isl_multi_pw_aff_free(mpa);
 
6035
        return NULL;
 
6036
}
 
6037
 
 
6038
/* Construct a map mapping the shared domain
 
6039
 * of the piecewise affine expressions to the range of "mpa"
 
6040
 * with each dimension in the range equated to the
 
6041
 * corresponding piecewise affine expression.
 
6042
 */
 
6043
__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
 
6044
{
 
6045
        if (!mpa)
 
6046
                return NULL;
 
6047
        if (isl_space_is_set(mpa->space))
 
6048
                isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,
 
6049
                        "space of input is not a map", goto error);
 
6050
 
 
6051
        return map_from_multi_pw_aff(mpa);
 
6052
error:
 
6053
        isl_multi_pw_aff_free(mpa);
 
6054
        return NULL;
 
6055
}
 
6056
 
 
6057
/* Construct a set mapping the shared parameter domain
 
6058
 * of the piecewise affine expressions to the space of "mpa"
 
6059
 * with each dimension in the range equated to the
 
6060
 * corresponding piecewise affine expression.
 
6061
 */
 
6062
__isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
 
6063
{
 
6064
        if (!mpa)
 
6065
                return NULL;
 
6066
        if (!isl_space_is_set(mpa->space))
 
6067
                isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,
 
6068
                        "space of input is not a set", goto error);
 
6069
 
 
6070
        return map_from_multi_pw_aff(mpa);
 
6071
error:
 
6072
        isl_multi_pw_aff_free(mpa);
 
6073
        return NULL;
 
6074
}
 
6075
 
 
6076
/* Construct and return a piecewise multi affine expression
 
6077
 * that is equal to the given multi piecewise affine expression
 
6078
 * on the shared domain of the piecewise affine expressions.
 
6079
 */
 
6080
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
 
6081
        __isl_take isl_multi_pw_aff *mpa)
 
6082
{
 
6083
        int i;
 
6084
        isl_space *space;
 
6085
        isl_pw_aff *pa;
 
6086
        isl_pw_multi_aff *pma;
 
6087
 
 
6088
        if (!mpa)
 
6089
                return NULL;
 
6090
 
 
6091
        space = isl_multi_pw_aff_get_space(mpa);
 
6092
 
 
6093
        if (mpa->n == 0) {
 
6094
                isl_multi_pw_aff_free(mpa);
 
6095
                return isl_pw_multi_aff_zero(space);
 
6096
        }
 
6097
 
 
6098
        pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
 
6099
        pma = isl_pw_multi_aff_from_pw_aff(pa);
 
6100
 
 
6101
        for (i = 1; i < mpa->n; ++i) {
 
6102
                isl_pw_multi_aff *pma_i;
 
6103
 
 
6104
                pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
 
6105
                pma_i = isl_pw_multi_aff_from_pw_aff(pa);
 
6106
                pma = isl_pw_multi_aff_range_product(pma, pma_i);
 
6107
        }
 
6108
 
 
6109
        pma = isl_pw_multi_aff_reset_space(pma, space);
 
6110
 
 
6111
        isl_multi_pw_aff_free(mpa);
 
6112
        return pma;
 
6113
}
 
6114
 
 
6115
/* Construct and return a multi piecewise affine expression
 
6116
 * that is equal to the given multi affine expression.
 
6117
 */
 
6118
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
 
6119
        __isl_take isl_multi_aff *ma)
 
6120
{
 
6121
        int i, n;
 
6122
        isl_multi_pw_aff *mpa;
 
6123
 
 
6124
        if (!ma)
 
6125
                return NULL;
 
6126
 
 
6127
        n = isl_multi_aff_dim(ma, isl_dim_out);
 
6128
        mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
 
6129
 
 
6130
        for (i = 0; i < n; ++i) {
 
6131
                isl_pw_aff *pa;
 
6132
 
 
6133
                pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
 
6134
                mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
 
6135
        }
 
6136
 
 
6137
        isl_multi_aff_free(ma);
 
6138
        return mpa;
 
6139
}
 
6140
 
 
6141
/* Construct and return a multi piecewise affine expression
 
6142
 * that is equal to the given piecewise multi affine expression.
 
6143
 */
 
6144
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
 
6145
        __isl_take isl_pw_multi_aff *pma)
 
6146
{
 
6147
        int i, n;
 
6148
        isl_space *space;
 
6149
        isl_multi_pw_aff *mpa;
 
6150
 
 
6151
        if (!pma)
 
6152
                return NULL;
 
6153
 
 
6154
        n = isl_pw_multi_aff_dim(pma, isl_dim_out);
 
6155
        space = isl_pw_multi_aff_get_space(pma);
 
6156
        mpa = isl_multi_pw_aff_alloc(space);
 
6157
 
 
6158
        for (i = 0; i < n; ++i) {
 
6159
                isl_pw_aff *pa;
 
6160
 
 
6161
                pa = isl_pw_multi_aff_get_pw_aff(pma, i);
 
6162
                mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
 
6163
        }
 
6164
 
 
6165
        isl_pw_multi_aff_free(pma);
 
6166
        return mpa;
 
6167
}
 
6168
 
 
6169
/* Do "pa1" and "pa2" represent the same function?
 
6170
 *
 
6171
 * We first check if they are obviously equal.
 
6172
 * If not, we convert them to maps and check if those are equal.
 
6173
 */
 
6174
int isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, __isl_keep isl_pw_aff *pa2)
 
6175
{
 
6176
        int equal;
 
6177
        isl_map *map1, *map2;
 
6178
 
 
6179
        if (!pa1 || !pa2)
 
6180
                return -1;
 
6181
 
 
6182
        equal = isl_pw_aff_plain_is_equal(pa1, pa2);
 
6183
        if (equal < 0 || equal)
 
6184
                return equal;
 
6185
 
 
6186
        map1 = map_from_pw_aff(isl_pw_aff_copy(pa1));
 
6187
        map2 = map_from_pw_aff(isl_pw_aff_copy(pa2));
 
6188
        equal = isl_map_is_equal(map1, map2);
 
6189
        isl_map_free(map1);
 
6190
        isl_map_free(map2);
 
6191
 
 
6192
        return equal;
 
6193
}
 
6194
 
 
6195
/* Do "mpa1" and "mpa2" represent the same function?
 
6196
 *
 
6197
 * Note that we cannot convert the entire isl_multi_pw_aff
 
6198
 * to a map because the domains of the piecewise affine expressions
 
6199
 * may not be the same.
 
6200
 */
 
6201
int isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
 
6202
        __isl_keep isl_multi_pw_aff *mpa2)
 
6203
{
 
6204
        int i;
 
6205
        int equal;
 
6206
 
 
6207
        if (!mpa1 || !mpa2)
 
6208
                return -1;
 
6209
 
 
6210
        if (!isl_space_match(mpa1->space, isl_dim_param,
 
6211
                             mpa2->space, isl_dim_param)) {
 
6212
                if (!isl_space_has_named_params(mpa1->space))
 
6213
                        return 0;
 
6214
                if (!isl_space_has_named_params(mpa2->space))
 
6215
                        return 0;
 
6216
                mpa1 = isl_multi_pw_aff_copy(mpa1);
 
6217
                mpa2 = isl_multi_pw_aff_copy(mpa2);
 
6218
                mpa1 = isl_multi_pw_aff_align_params(mpa1,
 
6219
                                            isl_multi_pw_aff_get_space(mpa2));
 
6220
                mpa2 = isl_multi_pw_aff_align_params(mpa2,
 
6221
                                            isl_multi_pw_aff_get_space(mpa1));
 
6222
                equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
 
6223
                isl_multi_pw_aff_free(mpa1);
 
6224
                isl_multi_pw_aff_free(mpa2);
 
6225
                return equal;
 
6226
        }
 
6227
 
 
6228
        equal = isl_space_is_equal(mpa1->space, mpa2->space);
 
6229
        if (equal < 0 || !equal)
 
6230
                return equal;
 
6231
 
 
6232
        for (i = 0; i < mpa1->n; ++i) {
 
6233
                equal = isl_pw_aff_is_equal(mpa1->p[i], mpa2->p[i]);
 
6234
                if (equal < 0 || !equal)
 
6235
                        return equal;
 
6236
        }
 
6237
 
 
6238
        return 1;
 
6239
}
 
6240
 
 
6241
/* Coalesce the elements of "mpa".
 
6242
 *
 
6243
 * Note that such coalescing does not change the meaning of "mpa"
 
6244
 * so there is no need to cow.  We do need to be careful not to
 
6245
 * destroy any other copies of "mpa" in case of failure.
 
6246
 */
 
6247
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce(
 
6248
        __isl_take isl_multi_pw_aff *mpa)
 
6249
{
 
6250
        int i;
 
6251
 
 
6252
        if (!mpa)
 
6253
                return NULL;
 
6254
 
 
6255
        for (i = 0; i < mpa->n; ++i) {
 
6256
                isl_pw_aff *pa = isl_pw_aff_copy(mpa->p[i]);
 
6257
                pa = isl_pw_aff_coalesce(pa);
 
6258
                if (!pa)
 
6259
                        return isl_multi_pw_aff_free(mpa);
 
6260
                isl_pw_aff_free(mpa->p[i]);
 
6261
                mpa->p[i] = pa;
 
6262
        }
 
6263
 
 
6264
        return mpa;
 
6265
}
 
6266
 
 
6267
/* Compute the pullback of "mpa" by the function represented by "ma".
 
6268
 * In other words, plug in "ma" in "mpa".
 
6269
 *
 
6270
 * The parameters of "mpa" and "ma" are assumed to have been aligned.
 
6271
 */
 
6272
static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff_aligned(
 
6273
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
 
6274
{
 
6275
        int i;
 
6276
        isl_space *space = NULL;
 
6277
 
 
6278
        mpa = isl_multi_pw_aff_cow(mpa);
 
6279
        if (!mpa || !ma)
 
6280
                goto error;
 
6281
 
 
6282
        space = isl_space_join(isl_multi_aff_get_space(ma),
 
6283
                                isl_multi_pw_aff_get_space(mpa));
 
6284
        if (!space)
 
6285
                goto error;
 
6286
 
 
6287
        for (i = 0; i < mpa->n; ++i) {
 
6288
                mpa->p[i] = isl_pw_aff_pullback_multi_aff(mpa->p[i],
 
6289
                                                    isl_multi_aff_copy(ma));
 
6290
                if (!mpa->p[i])
 
6291
                        goto error;
 
6292
        }
 
6293
 
 
6294
        isl_multi_aff_free(ma);
 
6295
        isl_space_free(mpa->space);
 
6296
        mpa->space = space;
 
6297
        return mpa;
 
6298
error:
 
6299
        isl_space_free(space);
 
6300
        isl_multi_pw_aff_free(mpa);
 
6301
        isl_multi_aff_free(ma);
 
6302
        return NULL;
 
6303
}
 
6304
 
 
6305
/* Compute the pullback of "mpa" by the function represented by "ma".
 
6306
 * In other words, plug in "ma" in "mpa".
 
6307
 */
 
6308
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff(
 
6309
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
 
6310
{
 
6311
        if (!mpa || !ma)
 
6312
                goto error;
 
6313
        if (isl_space_match(mpa->space, isl_dim_param,
 
6314
                            ma->space, isl_dim_param))
 
6315
                return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
 
6316
        mpa = isl_multi_pw_aff_align_params(mpa, isl_multi_aff_get_space(ma));
 
6317
        ma = isl_multi_aff_align_params(ma, isl_multi_pw_aff_get_space(mpa));
 
6318
        return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
 
6319
error:
 
6320
        isl_multi_pw_aff_free(mpa);
 
6321
        isl_multi_aff_free(ma);
 
6322
        return NULL;
 
6323
}
 
6324
 
 
6325
/* Compute the pullback of "mpa" by the function represented by "pma".
 
6326
 * In other words, plug in "pma" in "mpa".
 
6327
 *
 
6328
 * The parameters of "mpa" and "mpa" are assumed to have been aligned.
 
6329
 */
 
6330
static __isl_give isl_multi_pw_aff *
 
6331
isl_multi_pw_aff_pullback_pw_multi_aff_aligned(
 
6332
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
 
6333
{
 
6334
        int i;
 
6335
        isl_space *space = NULL;
 
6336
 
 
6337
        mpa = isl_multi_pw_aff_cow(mpa);
 
6338
        if (!mpa || !pma)
 
6339
                goto error;
 
6340
 
 
6341
        space = isl_space_join(isl_pw_multi_aff_get_space(pma),
 
6342
                                isl_multi_pw_aff_get_space(mpa));
 
6343
 
 
6344
        for (i = 0; i < mpa->n; ++i) {
 
6345
                mpa->p[i] = isl_pw_aff_pullback_pw_multi_aff_aligned(mpa->p[i],
 
6346
                                                    isl_pw_multi_aff_copy(pma));
 
6347
                if (!mpa->p[i])
 
6348
                        goto error;
 
6349
        }
 
6350
 
 
6351
        isl_pw_multi_aff_free(pma);
 
6352
        isl_space_free(mpa->space);
 
6353
        mpa->space = space;
 
6354
        return mpa;
 
6355
error:
 
6356
        isl_space_free(space);
 
6357
        isl_multi_pw_aff_free(mpa);
 
6358
        isl_pw_multi_aff_free(pma);
 
6359
        return NULL;
 
6360
}
 
6361
 
 
6362
/* Compute the pullback of "mpa" by the function represented by "pma".
 
6363
 * In other words, plug in "pma" in "mpa".
 
6364
 */
 
6365
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff(
 
6366
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
 
6367
{
 
6368
        if (!mpa || !pma)
 
6369
                goto error;
 
6370
        if (isl_space_match(mpa->space, isl_dim_param, pma->dim, isl_dim_param))
 
6371
                return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
 
6372
        mpa = isl_multi_pw_aff_align_params(mpa,
 
6373
                                            isl_pw_multi_aff_get_space(pma));
 
6374
        pma = isl_pw_multi_aff_align_params(pma,
 
6375
                                            isl_multi_pw_aff_get_space(mpa));
 
6376
        return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
 
6377
error:
 
6378
        isl_multi_pw_aff_free(mpa);
 
6379
        isl_pw_multi_aff_free(pma);
 
6380
        return NULL;
 
6381
}
 
6382
 
 
6383
/* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
 
6384
 * with the domain of "aff".  The domain of the result is the same
 
6385
 * as that of "mpa".
 
6386
 * "mpa" and "aff" are assumed to have been aligned.
 
6387
 *
 
6388
 * We first extract the parametric constant from "aff", defined
 
6389
 * over the correct domain.
 
6390
 * Then we add the appropriate combinations of the members of "mpa".
 
6391
 * Finally, we add the integer divisions through recursive calls.
 
6392
 */
 
6393
static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
 
6394
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
 
6395
{
 
6396
        int i, n_param, n_in, n_div;
 
6397
        isl_space *space;
 
6398
        isl_val *v;
 
6399
        isl_pw_aff *pa;
 
6400
        isl_aff *tmp;
 
6401
 
 
6402
        n_param = isl_aff_dim(aff, isl_dim_param);
 
6403
        n_in = isl_aff_dim(aff, isl_dim_in);
 
6404
        n_div = isl_aff_dim(aff, isl_dim_div);
 
6405
 
 
6406
        space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
 
6407
        tmp = isl_aff_copy(aff);
 
6408
        tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
 
6409
        tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
 
6410
        tmp = isl_aff_add_dims(tmp, isl_dim_in,
 
6411
                                isl_space_dim(space, isl_dim_set));
 
6412
        tmp = isl_aff_reset_domain_space(tmp, space);
 
6413
        pa = isl_pw_aff_from_aff(tmp);
 
6414
 
 
6415
        for (i = 0; i < n_in; ++i) {
 
6416
                isl_pw_aff *pa_i;
 
6417
 
 
6418
                if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
 
6419
                        continue;
 
6420
                v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
 
6421
                pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
 
6422
                pa_i = isl_pw_aff_scale_val(pa_i, v);
 
6423
                pa = isl_pw_aff_add(pa, pa_i);
 
6424
        }
 
6425
 
 
6426
        for (i = 0; i < n_div; ++i) {
 
6427
                isl_aff *div;
 
6428
                isl_pw_aff *pa_i;
 
6429
 
 
6430
                if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
 
6431
                        continue;
 
6432
                div = isl_aff_get_div(aff, i);
 
6433
                pa_i = isl_multi_pw_aff_apply_aff_aligned(
 
6434
                                            isl_multi_pw_aff_copy(mpa), div);
 
6435
                pa_i = isl_pw_aff_floor(pa_i);
 
6436
                v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
 
6437
                pa_i = isl_pw_aff_scale_val(pa_i, v);
 
6438
                pa = isl_pw_aff_add(pa, pa_i);
 
6439
        }
 
6440
 
 
6441
        isl_multi_pw_aff_free(mpa);
 
6442
        isl_aff_free(aff);
 
6443
 
 
6444
        return pa;
 
6445
}
 
6446
 
 
6447
/* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
 
6448
 * with the domain of "aff".  The domain of the result is the same
 
6449
 * as that of "mpa".
 
6450
 */
 
6451
__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
 
6452
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
 
6453
{
 
6454
        if (!aff || !mpa)
 
6455
                goto error;
 
6456
        if (isl_space_match(aff->ls->dim, isl_dim_param,
 
6457
                                mpa->space, isl_dim_param))
 
6458
                return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
 
6459
 
 
6460
        aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
 
6461
        mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
 
6462
 
 
6463
        return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
 
6464
error:
 
6465
        isl_aff_free(aff);
 
6466
        isl_multi_pw_aff_free(mpa);
 
6467
        return NULL;
 
6468
}
 
6469
 
 
6470
/* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
 
6471
 * with the domain of "pa".  The domain of the result is the same
 
6472
 * as that of "mpa".
 
6473
 * "mpa" and "pa" are assumed to have been aligned.
 
6474
 *
 
6475
 * We consider each piece in turn.  Note that the domains of the
 
6476
 * pieces are assumed to be disjoint and they remain disjoint
 
6477
 * after taking the preimage (over the same function).
 
6478
 */
 
6479
static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
 
6480
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
 
6481
{
 
6482
        isl_space *space;
 
6483
        isl_pw_aff *res;
 
6484
        int i;
 
6485
 
 
6486
        if (!mpa || !pa)
 
6487
                goto error;
 
6488
 
 
6489
        space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
 
6490
                                isl_pw_aff_get_space(pa));
 
6491
        res = isl_pw_aff_empty(space);
 
6492
 
 
6493
        for (i = 0; i < pa->n; ++i) {
 
6494
                isl_pw_aff *pa_i;
 
6495
                isl_set *domain;
 
6496
 
 
6497
                pa_i = isl_multi_pw_aff_apply_aff_aligned(
 
6498
                                        isl_multi_pw_aff_copy(mpa),
 
6499
                                        isl_aff_copy(pa->p[i].aff));
 
6500
                domain = isl_set_copy(pa->p[i].set);
 
6501
                domain = isl_set_preimage_multi_pw_aff(domain,
 
6502
                                        isl_multi_pw_aff_copy(mpa));
 
6503
                pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
 
6504
                res = isl_pw_aff_add_disjoint(res, pa_i);
 
6505
        }
 
6506
 
 
6507
        isl_pw_aff_free(pa);
 
6508
        isl_multi_pw_aff_free(mpa);
 
6509
        return res;
 
6510
error:
 
6511
        isl_pw_aff_free(pa);
 
6512
        isl_multi_pw_aff_free(mpa);
 
6513
        return NULL;
 
6514
}
 
6515
 
 
6516
/* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
 
6517
 * with the domain of "pa".  The domain of the result is the same
 
6518
 * as that of "mpa".
 
6519
 */
 
6520
__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
 
6521
        __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
 
6522
{
 
6523
        if (!pa || !mpa)
 
6524
                goto error;
 
6525
        if (isl_space_match(pa->dim, isl_dim_param, mpa->space, isl_dim_param))
 
6526
                return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
 
6527
 
 
6528
        pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
 
6529
        mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
 
6530
 
 
6531
        return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
 
6532
error:
 
6533
        isl_pw_aff_free(pa);
 
6534
        isl_multi_pw_aff_free(mpa);
 
6535
        return NULL;
 
6536
}
 
6537
 
 
6538
/* Compute the pullback of "pa" by the function represented by "mpa".
 
6539
 * In other words, plug in "mpa" in "pa".
 
6540
 * "pa" and "mpa" are assumed to have been aligned.
 
6541
 *
 
6542
 * The pullback is computed by applying "pa" to "mpa".
 
6543
 */
 
6544
static __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff_aligned(
 
6545
        __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
 
6546
{
 
6547
        return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
 
6548
}
 
6549
 
 
6550
/* Compute the pullback of "pa" by the function represented by "mpa".
 
6551
 * In other words, plug in "mpa" in "pa".
 
6552
 *
 
6553
 * The pullback is computed by applying "pa" to "mpa".
 
6554
 */
 
6555
__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
 
6556
        __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
 
6557
{
 
6558
        return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
 
6559
}
 
6560
 
 
6561
/* Compute the pullback of "mpa1" by the function represented by "mpa2".
 
6562
 * In other words, plug in "mpa2" in "mpa1".
 
6563
 *
 
6564
 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
 
6565
 *
 
6566
 * We pullback each member of "mpa1" in turn.
 
6567
 */
 
6568
static __isl_give isl_multi_pw_aff *
 
6569
isl_multi_pw_aff_pullback_multi_pw_aff_aligned(
 
6570
        __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
 
6571
{
 
6572
        int i;
 
6573
        isl_space *space = NULL;
 
6574
 
 
6575
        mpa1 = isl_multi_pw_aff_cow(mpa1);
 
6576
        if (!mpa1 || !mpa2)
 
6577
                goto error;
 
6578
 
 
6579
        space = isl_space_join(isl_multi_pw_aff_get_space(mpa2),
 
6580
                                isl_multi_pw_aff_get_space(mpa1));
 
6581
 
 
6582
        for (i = 0; i < mpa1->n; ++i) {
 
6583
                mpa1->p[i] = isl_pw_aff_pullback_multi_pw_aff_aligned(
 
6584
                                mpa1->p[i], isl_multi_pw_aff_copy(mpa2));
 
6585
                if (!mpa1->p[i])
 
6586
                        goto error;
 
6587
        }
 
6588
 
 
6589
        mpa1 = isl_multi_pw_aff_reset_space(mpa1, space);
 
6590
 
 
6591
        isl_multi_pw_aff_free(mpa2);
 
6592
        return mpa1;
 
6593
error:
 
6594
        isl_space_free(space);
 
6595
        isl_multi_pw_aff_free(mpa1);
 
6596
        isl_multi_pw_aff_free(mpa2);
 
6597
        return NULL;
 
6598
}
 
6599
 
 
6600
/* Compute the pullback of "mpa1" by the function represented by "mpa2".
 
6601
 * In other words, plug in "mpa2" in "mpa1".
 
6602
 */
 
6603
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff(
 
6604
        __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
 
6605
{
 
6606
        return isl_multi_pw_aff_align_params_multi_multi_and(mpa1, mpa2,
 
6607
                        &isl_multi_pw_aff_pullback_multi_pw_aff_aligned);
 
6608
}
 
6609
 
 
6610
/* Compare two isl_affs.
 
6611
 *
 
6612
 * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
 
6613
 * than "aff2" and 0 if they are equal.
 
6614
 *
 
6615
 * The order is fairly arbitrary.  We do consider expressions that only involve
 
6616
 * earlier dimensions as "smaller".
 
6617
 */
 
6618
int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
 
6619
{
 
6620
        int cmp;
 
6621
        int last1, last2;
 
6622
 
 
6623
        if (aff1 == aff2)
 
6624
                return 0;
 
6625
 
 
6626
        if (!aff1)
 
6627
                return -1;
 
6628
        if (!aff2)
 
6629
                return 1;
 
6630
 
 
6631
        cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
 
6632
        if (cmp != 0)
 
6633
                return cmp;
 
6634
 
 
6635
        last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
 
6636
        last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
 
6637
        if (last1 != last2)
 
6638
                return last1 - last2;
 
6639
 
 
6640
        return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
 
6641
}
 
6642
 
 
6643
/* Compare two isl_pw_affs.
 
6644
 *
 
6645
 * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
 
6646
 * than "pa2" and 0 if they are equal.
 
6647
 *
 
6648
 * The order is fairly arbitrary.  We do consider expressions that only involve
 
6649
 * earlier dimensions as "smaller".
 
6650
 */
 
6651
int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
 
6652
        __isl_keep isl_pw_aff *pa2)
 
6653
{
 
6654
        int i;
 
6655
        int cmp;
 
6656
 
 
6657
        if (pa1 == pa2)
 
6658
                return 0;
 
6659
 
 
6660
        if (!pa1)
 
6661
                return -1;
 
6662
        if (!pa2)
 
6663
                return 1;
 
6664
 
 
6665
        cmp = isl_space_cmp(pa1->dim, pa2->dim);
 
6666
        if (cmp != 0)
 
6667
                return cmp;
 
6668
 
 
6669
        if (pa1->n != pa2->n)
 
6670
                return pa1->n - pa2->n;
 
6671
 
 
6672
        for (i = 0; i < pa1->n; ++i) {
 
6673
                cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
 
6674
                if (cmp != 0)
 
6675
                        return cmp;
 
6676
                cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
 
6677
                if (cmp != 0)
 
6678
                        return cmp;
 
6679
        }
 
6680
 
 
6681
        return 0;
 
6682
}