2 * Copyright 2010 INRIA Saclay
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include <isl_ctx_private.h>
13 #include <isl_space_private.h>
14 #include <isl_reordering.h>
16 /* Create a new reordering description based on
17 * the number of source dimensions "src_len" and
18 * (an initial value for) the number of target dimensions "dst_len".
20 * The caller still needs to fill in the space field and
21 * possibly adjust the target dimensionality if this is not known yet
22 * when this function is called.
24 __isl_give isl_reordering
*isl_reordering_alloc(isl_ctx
*ctx
, int src_len
,
29 exp
= isl_alloc(ctx
, struct isl_reordering
,
30 sizeof(struct isl_reordering
) + (src_len
- 1) * sizeof(int));
35 exp
->src_len
= src_len
;
36 exp
->dst_len
= dst_len
;
42 /* Set r->dst_len to the total dimensionality of r->space.
44 static __isl_give isl_reordering
*isl_reordering_set_dst_len_from_space(
45 __isl_take isl_reordering
*r
)
52 n
= isl_space_dim(r
->space
, isl_dim_all
);
54 return isl_reordering_free(r
);
59 __isl_give isl_reordering
*isl_reordering_copy(__isl_keep isl_reordering
*exp
)
68 __isl_give isl_reordering
*isl_reordering_dup(__isl_keep isl_reordering
*r
)
76 dup
= isl_reordering_alloc(isl_reordering_get_ctx(r
),
77 r
->src_len
, r
->dst_len
);
81 dup
->space
= isl_reordering_get_space(r
);
83 return isl_reordering_free(dup
);
84 for (i
= 0; i
< dup
->src_len
; ++i
)
85 dup
->pos
[i
] = r
->pos
[i
];
90 __isl_give isl_reordering
*isl_reordering_cow(__isl_take isl_reordering
*r
)
98 return isl_reordering_dup(r
);
101 __isl_null isl_reordering
*isl_reordering_free(__isl_take isl_reordering
*exp
)
109 isl_space_free(exp
->space
);
114 /* Return the isl_ctx to which "r" belongs.
116 isl_ctx
*isl_reordering_get_ctx(__isl_keep isl_reordering
*r
)
118 return isl_space_get_ctx(isl_reordering_peek_space(r
));
121 /* Return the space of "r".
123 __isl_keep isl_space
*isl_reordering_peek_space(__isl_keep isl_reordering
*r
)
130 /* Return a copy of the space of "r".
132 __isl_give isl_space
*isl_reordering_get_space(__isl_keep isl_reordering
*r
)
134 return isl_space_copy(isl_reordering_peek_space(r
));
137 /* Construct a reordering that maps the parameters of "alignee"
138 * to the corresponding parameters in a new dimension specification
139 * that has the parameters of "aligner" first, followed by
140 * any remaining parameters of "alignee" that do not occur in "aligner".
141 * The other dimensions of "alignee" are mapped to subsequent positions
144 __isl_give isl_reordering
*isl_parameter_alignment_reordering(
145 __isl_keep isl_space
*alignee
, __isl_keep isl_space
*aligner
)
150 isl_size dim
, n_alignee
, n_aligner
;
152 dim
= isl_space_dim(alignee
, isl_dim_all
);
153 n_alignee
= isl_space_dim(alignee
, isl_dim_param
);
154 n_aligner
= isl_space_dim(aligner
, isl_dim_param
);
155 if (dim
< 0 || n_alignee
< 0 || n_aligner
< 0)
158 ctx
= isl_space_get_ctx(alignee
);
159 exp
= isl_reordering_alloc(ctx
, dim
, dim
);
163 exp
->space
= isl_space_replace_params(isl_space_copy(alignee
), aligner
);
165 for (i
= 0; i
< n_alignee
; ++i
) {
167 id_i
= isl_space_get_dim_id(alignee
, isl_dim_param
, i
);
169 isl_die(ctx
, isl_error_invalid
,
170 "cannot align unnamed parameters", goto error
);
171 for (j
= 0; j
< n_aligner
; ++j
) {
173 id_j
= isl_space_get_dim_id(aligner
, isl_dim_param
, j
);
183 pos
= isl_space_dim(exp
->space
, isl_dim_param
);
185 exp
->space
= isl_space_free(exp
->space
);
186 exp
->space
= isl_space_add_dims(exp
->space
,
188 exp
->space
= isl_space_set_dim_id(exp
->space
,
189 isl_dim_param
, pos
, id_i
);
194 exp
= isl_reordering_set_dst_len_from_space(exp
);
198 offset
= exp
->dst_len
- exp
->src_len
;
199 for (i
= n_alignee
; i
< dim
; ++i
)
200 exp
->pos
[i
] = offset
+ i
;
204 isl_reordering_free(exp
);
208 /* Return a reordering that moves the parameters identified by
209 * the elements of "tuple" to a domain tuple inserted into "space".
210 * The parameters that remain, are moved from their original positions
211 * in the list of parameters to their new positions in this list.
212 * The parameters that get removed, are moved to the corresponding
213 * positions in the new domain. Note that these set dimensions
214 * do not necessarily need to appear as parameters in "space".
215 * Any other dimensions are shifted by the number of extra dimensions
216 * introduced, i.e., the number of dimensions in the new domain
217 * that did not appear as parameters in "space".
219 __isl_give isl_reordering
*isl_reordering_unbind_params_insert_domain(
220 __isl_keep isl_space
*space
, __isl_keep isl_multi_id
*tuple
)
228 dim
= isl_space_dim(space
, isl_dim_all
);
229 if (dim
< 0 || !tuple
)
232 ctx
= isl_space_get_ctx(space
);
233 r
= isl_reordering_alloc(ctx
, dim
, dim
);
237 r
->space
= isl_space_copy(space
);
238 r
->space
= isl_space_unbind_params_insert_domain(r
->space
, tuple
);
240 return isl_reordering_free(r
);
242 n
= isl_space_dim(r
->space
, isl_dim_param
);
243 for (i
= 0; i
< n
; ++i
) {
247 id
= isl_space_get_dim_id(r
->space
, isl_dim_param
, i
);
249 return isl_reordering_free(r
);
250 pos
= isl_space_find_dim_by_id(space
, isl_dim_param
, id
);
255 offset
= isl_space_dim(r
->space
, isl_dim_param
);
256 n
= isl_multi_id_size(tuple
);
257 for (i
= 0; i
< n
; ++i
) {
261 id
= isl_multi_id_get_id(tuple
, i
);
263 return isl_reordering_free(r
);
264 pos
= isl_space_find_dim_by_id(space
, isl_dim_param
, id
);
268 r
->pos
[pos
] = offset
+ i
;
271 offset
= isl_space_dim(r
->space
, isl_dim_all
) - dim
;
272 first
= isl_space_dim(space
, isl_dim_param
);
274 for (i
= 0; i
< n
; ++i
)
275 r
->pos
[first
+ i
] = first
+ offset
+ i
;
277 return isl_reordering_set_dst_len_from_space(r
);
280 __isl_give isl_reordering
*isl_reordering_extend(__isl_take isl_reordering
*exp
,
293 ctx
= isl_reordering_get_ctx(exp
);
294 offset
= exp
->dst_len
- exp
->src_len
;
295 res
= isl_reordering_alloc(ctx
, exp
->src_len
+ extra
,
296 exp
->dst_len
+ extra
);
299 res
->space
= isl_reordering_get_space(exp
);
300 for (i
= 0; i
< exp
->src_len
; ++i
)
301 res
->pos
[i
] = exp
->pos
[i
];
302 for (i
= exp
->src_len
; i
< res
->src_len
; ++i
)
303 res
->pos
[i
] = offset
+ i
;
305 isl_reordering_free(exp
);
309 isl_reordering_free(exp
);
313 __isl_give isl_reordering
*isl_reordering_extend_space(
314 __isl_take isl_reordering
*exp
, __isl_take isl_space
*space
)
316 isl_space
*exp_space
;
320 dim
= isl_space_dim(space
, isl_dim_all
);
324 res
= isl_reordering_extend(isl_reordering_copy(exp
),
326 res
= isl_reordering_cow(res
);
329 isl_space_free(res
->space
);
330 exp_space
= isl_reordering_peek_space(exp
);
331 res
->space
= isl_space_replace_params(space
, exp_space
);
333 isl_reordering_free(exp
);
336 return isl_reordering_free(res
);
340 isl_reordering_free(exp
);
341 isl_space_free(space
);
345 void isl_reordering_dump(__isl_keep isl_reordering
*exp
)
349 isl_space_dump(exp
->space
);
350 for (i
= 0; i
< exp
->src_len
; ++i
)
351 fprintf(stderr
, "%d -> %d; ", i
, exp
->pos
[i
]);
352 fprintf(stderr
, "\n");