6ab97a239bb3487c09d8cd26e5fcc97af90d38c9
[platform/upstream/isl.git] / isl_dim_map.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
11  */
12
13 #include <isl_map_private.h>
14 #include <isl_dim_private.h>
15 #include <isl_dim_map.h>
16 #include <isl_reordering.h>
17
18 /* Maps dst positions to src positions */
19 struct isl_dim_map {
20         unsigned len;
21         int pos[1];
22 };
23
24 __isl_give isl_dim_map *isl_dim_map_alloc(isl_ctx *ctx, unsigned len)
25 {
26         int i;
27         struct isl_dim_map *dim_map;
28         dim_map = isl_alloc(ctx, struct isl_dim_map,
29                                 sizeof(struct isl_dim_map) + len * sizeof(int));
30         if (!dim_map)
31                 return NULL;
32         dim_map->len = 1 + len;
33         dim_map->pos[0] = 0;
34         for (i = 0; i < len; ++i)
35                 dim_map->pos[1 + i] = -1;
36         return dim_map;
37 }
38
39 void isl_dim_map_dim_range(__isl_keep isl_dim_map *dim_map,
40         struct isl_dim *dim, enum isl_dim_type type,
41         unsigned first, unsigned n, unsigned dst_pos)
42 {
43         int i;
44         unsigned src_pos;
45
46         if (!dim_map || !dim)
47                 return;
48         
49         src_pos = 1 + isl_dim_offset(dim, type);
50         for (i = 0; i < n; ++i)
51                 dim_map->pos[1 + dst_pos + i] = src_pos + first + i;
52 }
53
54 void isl_dim_map_dim(__isl_keep isl_dim_map *dim_map, __isl_keep isl_dim *dim,
55         enum isl_dim_type type, unsigned dst_pos)
56 {
57         isl_dim_map_dim_range(dim_map, dim, type,
58                               0, isl_dim_size(dim, type), dst_pos);
59 }
60
61 void isl_dim_map_div(__isl_keep isl_dim_map *dim_map,
62         __isl_keep isl_basic_map *bmap, unsigned dst_pos)
63 {
64         int i;
65         unsigned src_pos;
66
67         if (!dim_map || !bmap)
68                 return;
69         
70         src_pos = 1 + isl_dim_total(bmap->dim);
71         for (i = 0; i < bmap->n_div; ++i)
72                 dim_map->pos[1 + dst_pos + i] = src_pos + i;
73 }
74
75 void isl_dim_map_dump(struct isl_dim_map *dim_map)
76 {
77         int i;
78
79         for (i = 0; i < dim_map->len; ++i)
80                 fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
81         fprintf(stderr, "\n");
82 }
83
84 static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
85                                         struct isl_dim_map *dim_map)
86 {
87         int i;
88
89         for (i = 0; i < dim_map->len; ++i) {
90                 if (dim_map->pos[i] < 0)
91                         isl_int_set_si(dst[i], 0);
92                 else
93                         isl_int_set(dst[i], src[dim_map->pos[i]]);
94         }
95 }
96
97 static void copy_div_dim_map(isl_int *dst, isl_int *src,
98                                         struct isl_dim_map *dim_map)
99 {
100         isl_int_set(dst[0], src[0]);
101         copy_constraint_dim_map(dst+1, src+1, dim_map);
102 }
103
104 __isl_give isl_basic_map *isl_basic_map_add_constraints_dim_map(
105         __isl_take isl_basic_map *dst, __isl_take isl_basic_map *src,
106         __isl_take isl_dim_map *dim_map)
107 {
108         int i;
109
110         if (!src || !dst || !dim_map)
111                 goto error;
112
113         for (i = 0; i < src->n_eq; ++i) {
114                 int i1 = isl_basic_map_alloc_equality(dst);
115                 if (i1 < 0)
116                         goto error;
117                 copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
118         }
119
120         for (i = 0; i < src->n_ineq; ++i) {
121                 int i1 = isl_basic_map_alloc_inequality(dst);
122                 if (i1 < 0)
123                         goto error;
124                 copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
125         }
126
127         for (i = 0; i < src->n_div; ++i) {
128                 int i1 = isl_basic_map_alloc_div(dst);
129                 if (i1 < 0)
130                         goto error;
131                 copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
132         }
133
134         free(dim_map);
135         isl_basic_map_free(src);
136
137         return dst;
138 error:
139         free(dim_map);
140         isl_basic_map_free(src);
141         isl_basic_map_free(dst);
142         return NULL;
143 }
144
145 /* Extend the given dim_map with mappings for the divs in bmap.
146  */
147 __isl_give isl_dim_map *isl_dim_map_extend(__isl_keep isl_dim_map *dim_map,
148         __isl_keep isl_basic_map *bmap)
149 {
150         int i;
151         struct isl_dim_map *res;
152         int offset;
153
154         offset = isl_basic_map_offset(bmap, isl_dim_div);
155
156         res = isl_dim_map_alloc(bmap->ctx, dim_map->len - 1 + bmap->n_div);
157         if (!res)
158                 return NULL;
159
160         for (i = 0; i < dim_map->len; ++i)
161                 res->pos[i] = dim_map->pos[i];
162         for (i = 0; i < bmap->n_div; ++i)
163                 res->pos[dim_map->len + i] = offset + i;
164
165         return res;
166 }
167
168 /* Extract a dim_map from a reordering.
169  * We essentially need to reverse the mapping, and add an offset
170  * of 1 for the constant term.
171  */
172 __isl_give isl_dim_map *isl_dim_map_from_reordering(
173         __isl_keep isl_reordering *exp)
174 {
175         int i;
176         isl_ctx *ctx;
177         struct isl_dim_map *dim_map;
178
179         if (!exp)
180                 return NULL;
181
182         ctx = isl_dim_get_ctx(exp->dim);
183         dim_map = isl_dim_map_alloc(ctx, isl_dim_total(exp->dim));
184         if (!dim_map)
185                 return NULL;
186
187         for (i = 0; i < exp->len; ++i)
188                 dim_map->pos[1 + exp->pos[i]] = 1 + i;
189
190         return dim_map;
191 }