isl_stream_read_map: use affine expressions during parsing
[isl.git] / isl_reordering.c
blobc284bc383c5c7c9107a1fcef16b07ef99c55ebb7
1 /*
2 * Copyright 2010 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
8 * 91893 Orsay, France
9 */
11 #include <isl_ctx_private.h>
12 #include <isl_dim_private.h>
13 #include <isl_reordering.h>
15 __isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int len)
17 isl_reordering *exp;
19 exp = isl_alloc(ctx, struct isl_reordering,
20 sizeof(struct isl_reordering) + (len - 1) * sizeof(int));
21 if (!exp)
22 return NULL;
24 exp->ref = 1;
25 exp->len = len;
26 exp->dim = NULL;
28 return exp;
31 __isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp)
33 if (!exp)
34 return NULL;
36 exp->ref++;
37 return exp;
40 __isl_give isl_reordering *isl_reordering_dup(__isl_keep isl_reordering *r)
42 int i;
43 isl_reordering *dup;
45 if (!r)
46 return NULL;
48 dup = isl_reordering_alloc(r->dim->ctx, r->len);
49 if (!dup)
50 return NULL;
52 dup->dim = isl_dim_copy(r->dim);
53 if (!dup->dim)
54 return isl_reordering_free(dup);
55 for (i = 0; i < dup->len; ++i)
56 dup->pos[i] = r->pos[i];
58 return dup;
61 __isl_give isl_reordering *isl_reordering_cow(__isl_take isl_reordering *r)
63 if (!r)
64 return NULL;
66 if (r->ref == 1)
67 return r;
68 r->ref--;
69 return isl_reordering_dup(r);
72 void *isl_reordering_free(__isl_take isl_reordering *exp)
74 if (!exp)
75 return NULL;
77 if (--exp->ref > 0)
78 return NULL;
80 isl_dim_free(exp->dim);
81 free(exp);
82 return NULL;
85 /* Construct a reordering that maps the parameters of "alignee"
86 * to the corresponding parameters in a new dimension specification
87 * that has the parameters of "aligner" first, followed by
88 * any remaining parameters of "alignee" that do not occur in "aligner".
90 __isl_give isl_reordering *isl_parameter_alignment_reordering(
91 __isl_keep isl_dim *alignee, __isl_keep isl_dim *aligner)
93 int i, j;
94 isl_reordering *exp;
96 if (!alignee || !aligner)
97 return NULL;
99 exp = isl_reordering_alloc(alignee->ctx, alignee->nparam);
100 if (!exp)
101 return NULL;
103 exp->dim = isl_dim_copy(aligner);
105 for (i = 0; i < alignee->nparam; ++i) {
106 isl_id *id_i;
107 id_i = isl_dim_get_dim_id(alignee, isl_dim_param, i);
108 if (!id_i)
109 isl_die(alignee->ctx, isl_error_invalid,
110 "cannot align unnamed parameters", goto error);
111 for (j = 0; j < aligner->nparam; ++j) {
112 isl_id *id_j;
113 id_j = isl_dim_get_dim_id(aligner, isl_dim_param, j);
114 isl_id_free(id_j);
115 if (id_i == id_j)
116 break;
118 if (j < aligner->nparam) {
119 exp->pos[i] = j;
120 isl_id_free(id_i);
121 } else {
122 int pos;
123 pos = isl_dim_size(exp->dim, isl_dim_param);
124 exp->dim = isl_dim_add(exp->dim, isl_dim_param, 1);
125 exp->dim = isl_dim_set_dim_id(exp->dim,
126 isl_dim_param, pos, id_i);
127 exp->pos[i] = pos;
131 return exp;
132 error:
133 isl_reordering_free(exp);
134 return NULL;
137 __isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
138 unsigned extra)
140 int i;
141 isl_reordering *res;
142 int offset;
144 if (!exp)
145 return NULL;
146 if (extra == 0)
147 return exp;
149 offset = isl_dim_total(exp->dim) - exp->len;
150 res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra);
151 if (!res)
152 goto error;
153 res->dim = isl_dim_copy(exp->dim);
154 for (i = 0; i < exp->len; ++i)
155 res->pos[i] = exp->pos[i];
156 for (i = exp->len; i < res->len; ++i)
157 res->pos[i] = offset + i;
159 isl_reordering_free(exp);
161 return res;
162 error:
163 isl_reordering_free(exp);
164 return NULL;
167 __isl_give isl_reordering *isl_reordering_extend_dim(
168 __isl_take isl_reordering *exp, __isl_take isl_dim *dim)
170 isl_reordering *res;
172 if (!exp || !dim)
173 goto error;
175 res = isl_reordering_extend(isl_reordering_copy(exp),
176 isl_dim_total(dim) - exp->len);
177 res = isl_reordering_cow(res);
178 if (!res)
179 goto error;
180 isl_dim_free(res->dim);
181 res->dim = isl_dim_replace(dim, isl_dim_param, exp->dim);
183 isl_reordering_free(exp);
185 return res;
186 error:
187 isl_reordering_free(exp);
188 isl_dim_free(dim);
189 return NULL;
192 void isl_reordering_dump(__isl_keep isl_reordering *exp)
194 int i;
196 for (i = 0; i < exp->len; ++i)
197 fprintf(stderr, "%d -> %d; ", i, exp->pos[i]);
198 fprintf(stderr, "\n");