doc: add some implementation details on parametric integer programming
[isl.git] / isl_reordering.c
blob6a5b014a39470c5f9fdaa5f83196dc0a7d850f49
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 void isl_reordering_free(__isl_take isl_reordering *exp)
42 if (!exp)
43 return;
45 if (--exp->ref > 0)
46 return;
48 isl_dim_free(exp->dim);
49 free(exp);
52 /* Construct a reordering that maps the parameters of "alignee"
53 * to the corresponding parameters in a new dimension specification
54 * that has the parameters of "aligner" first, followed by
55 * any remaining parameters of "alignee" that do not occur in "aligner".
57 __isl_give isl_reordering *isl_parameter_alignment_reordering(
58 __isl_keep isl_dim *alignee, __isl_keep isl_dim *aligner)
60 int i, j;
61 isl_reordering *exp;
63 if (!alignee || !aligner)
64 return NULL;
66 exp = isl_reordering_alloc(alignee->ctx, alignee->nparam);
67 if (!exp)
68 return NULL;
70 exp->dim = isl_dim_copy(aligner);
72 for (i = 0; i < alignee->nparam; ++i) {
73 const char *name_i;
74 name_i = isl_dim_get_name(alignee, isl_dim_param, i);
75 if (!name_i)
76 isl_die(alignee->ctx, isl_error_invalid,
77 "cannot align unnamed parameters", goto error);
78 for (j = 0; j < aligner->nparam; ++j) {
79 const char *name_j;
80 name_j = isl_dim_get_name(aligner, isl_dim_param, j);
81 if (name_i == name_j)
82 break;
84 if (j < aligner->nparam)
85 exp->pos[i] = j;
86 else {
87 int pos;
88 pos = isl_dim_size(exp->dim, isl_dim_param);
89 exp->dim = isl_dim_add(exp->dim, isl_dim_param, 1);
90 exp->dim = isl_dim_set_name(exp->dim,
91 isl_dim_param, pos, name_i);
92 exp->pos[i] = pos;
96 return exp;
97 error:
98 isl_reordering_free(exp);
99 return NULL;
102 __isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
103 unsigned extra)
105 int i;
106 isl_reordering *res;
107 int offset;
109 if (!exp)
110 return NULL;
111 if (extra == 0)
112 return exp;
114 offset = isl_dim_total(exp->dim) - exp->len;
115 res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra);
116 if (!res)
117 goto error;
118 res->dim = isl_dim_copy(exp->dim);
119 for (i = 0; i < exp->len; ++i)
120 res->pos[i] = exp->pos[i];
121 for (i = exp->len; i < res->len; ++i)
122 res->pos[i] = offset + i;
124 isl_reordering_free(exp);
126 return res;
127 error:
128 isl_reordering_free(exp);
129 return NULL;
132 __isl_give isl_reordering *isl_reordering_extend_dim(
133 __isl_take isl_reordering *exp, __isl_take isl_dim *dim)
135 int i;
136 isl_reordering *res;
137 int offset;
139 if (!exp || !dim)
140 goto error;
142 res = isl_reordering_extend(isl_reordering_copy(exp),
143 isl_dim_total(dim) - exp->len);
144 if (!res)
145 goto error;
146 isl_dim_free(res->dim);
147 res->dim = isl_dim_replace(dim, isl_dim_param, exp->dim);
149 isl_reordering_free(exp);
151 return res;
152 error:
153 isl_reordering_free(exp);
154 isl_dim_free(dim);
155 return NULL;
158 void isl_reordering_dump(__isl_keep isl_reordering *exp)
160 int i;
162 for (i = 0; i < exp->len; ++i)
163 fprintf(stderr, "%d -> %d; ", i, exp->pos[i]);
164 fprintf(stderr, "\n");