isl_basic_set_sample: special case 0D and 1D sets
[platform/upstream/isl.git] / isl_sample.c
1 #include "isl_sample.h"
2 #include "isl_sample_piplib.h"
3 #include "isl_vec.h"
4 #include "isl_mat.h"
5 #include "isl_map_private.h"
6 #include "isl_equalities.h"
7
8 static struct isl_vec *point_sample(struct isl_ctx *ctx,
9         struct isl_basic_set *bset)
10 {
11         struct isl_vec *sample;
12         isl_basic_set_free(ctx, bset);
13         sample = isl_vec_alloc(ctx, 1);
14         if (!sample)
15                 return NULL;
16         isl_int_set_si(sample->block.data[0], 1);
17         return sample;
18 }
19
20 static struct isl_vec *interval_sample(struct isl_ctx *ctx,
21         struct isl_basic_set *bset)
22 {
23         struct isl_vec *sample;
24
25         bset = isl_basic_set_simplify(ctx, bset);
26         if (!bset)
27                 return NULL;
28         if (bset->n_eq > 0)
29                 return isl_basic_set_sample(ctx, bset);
30         sample = isl_vec_alloc(ctx, 2);
31         isl_int_set_si(sample->block.data[0], 1);
32         if (bset->n_ineq == 0)
33                 isl_int_set_si(sample->block.data[1], 0);
34         else {
35                 int i;
36                 isl_int t;
37                 isl_int_init(t);
38                 if (isl_int_is_one(bset->ineq[0][1]))
39                         isl_int_neg(sample->block.data[1], bset->ineq[0][0]);
40                 else
41                         isl_int_set(sample->block.data[1], bset->ineq[0][0]);
42                 for (i = 1; i < bset->n_ineq; ++i) {
43                         isl_seq_inner_product(sample->block.data,
44                                                 bset->ineq[i], 2, &t);
45                         if (isl_int_is_neg(t))
46                                 break;
47                 }
48                 isl_int_clear(t);
49                 if (i < bset->n_ineq) {
50                         isl_vec_free(ctx, sample);
51                         sample = isl_vec_alloc(ctx, 0);
52                 }
53         }
54         isl_basic_set_free(ctx, bset);
55         return sample;
56 }
57
58 struct isl_vec *isl_basic_set_sample(struct isl_ctx *ctx,
59         struct isl_basic_set *bset)
60 {
61         if (!bset)
62                 return NULL;
63
64         if (F_ISSET(bset, ISL_BASIC_SET_EMPTY)) {
65                 isl_basic_set_free(ctx, bset);
66                 return isl_vec_alloc(ctx, 0);
67         }
68
69         isl_assert(ctx, bset->nparam == 0, goto error);
70         isl_assert(ctx, bset->n_div == 0, goto error);
71
72         if (bset->n_eq > 0) {
73                 struct isl_mat *T;
74                 struct isl_vec *sample;
75
76                 bset = isl_basic_set_remove_equalities(ctx, bset, &T, NULL);
77                 sample = isl_basic_set_sample(ctx, bset);
78                 if (sample && sample->size != 0)
79                         sample = isl_mat_vec_product(ctx, T, sample);
80                 else
81                         isl_mat_free(ctx, T);
82                 return sample;
83         }
84         if (bset->dim == 0)
85                 return point_sample(ctx, bset);
86         if (bset->dim == 1)
87                 return interval_sample(ctx, bset);
88         return isl_pip_basic_set_sample(ctx, bset);
89 error:
90         isl_basic_set_free(ctx, bset);
91         return NULL;
92 }