isl 0.05.1
[platform/upstream/isl.git] / isl_reordering.c
1 /*
2  * Copyright 2010      INRIA Saclay
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
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  */
10
11 #include <isl_dim_private.h>
12 #include <isl_reordering.h>
13
14 __isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int len)
15 {
16         isl_reordering *exp;
17
18         exp = isl_alloc(ctx, struct isl_reordering,
19                         sizeof(struct isl_reordering) + (len - 1) * sizeof(int));
20         if (!exp)
21                 return NULL;
22
23         exp->ref = 1;
24         exp->len = len;
25         exp->dim = NULL;
26
27         return exp;
28 }
29
30 __isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp)
31 {
32         if (!exp)
33                 return NULL;
34
35         exp->ref++;
36         return exp;
37 }
38
39 void isl_reordering_free(__isl_take isl_reordering *exp)
40 {
41         if (!exp)
42                 return;
43
44         if (--exp->ref > 0)
45                 return;
46
47         isl_dim_free(exp->dim);
48         free(exp);
49 }
50
51 /* Construct a reordering that maps the parameters of "alignee"
52  * to the corresponding parameters in a new dimension specification
53  * that has the parameters of "aligner" first, followed by
54  * any remaining parameters of "alignee" that do not occur in "aligner".
55  */
56 __isl_give isl_reordering *isl_parameter_alignment_reordering(
57         __isl_keep isl_dim *alignee, __isl_keep isl_dim *aligner)
58 {
59         int i, j;
60         isl_reordering *exp;
61
62         if (!alignee || !aligner)
63                 return NULL;
64
65         exp = isl_reordering_alloc(alignee->ctx, alignee->nparam);
66         if (!exp)
67                 return NULL;
68
69         exp->dim = isl_dim_copy(aligner);
70
71         for (i = 0; i < alignee->nparam; ++i) {
72                 const char *name_i;
73                 name_i = isl_dim_get_name(alignee, isl_dim_param, i);
74                 if (!name_i)
75                         isl_die(alignee->ctx, isl_error_invalid,
76                                 "cannot align unnamed parameters", goto error);
77                 for (j = 0; j < aligner->nparam; ++j) {
78                         const char *name_j;
79                         name_j = isl_dim_get_name(aligner, isl_dim_param, j);
80                         if (name_i == name_j)
81                                 break;
82                 }
83                 if (j < aligner->nparam)
84                         exp->pos[i] = j;
85                 else {
86                         int pos;
87                         pos = isl_dim_size(exp->dim, isl_dim_param);
88                         exp->dim = isl_dim_add(exp->dim, isl_dim_param, 1);
89                         exp->dim = isl_dim_set_name(exp->dim,
90                                                 isl_dim_param, pos, name_i);
91                         exp->pos[i] = pos;
92                 }
93         }
94
95         return exp;
96 error:
97         isl_reordering_free(exp);
98         return NULL;
99 }
100
101 __isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
102         unsigned extra)
103 {
104         int i;
105         isl_reordering *res;
106         int offset;
107
108         if (!exp)
109                 return NULL;
110         if (extra == 0)
111                 return exp;
112
113         offset = isl_dim_total(exp->dim) - exp->len;
114         res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra);
115         if (!res)
116                 goto error;
117         res->dim = isl_dim_copy(exp->dim);
118         for (i = 0; i < exp->len; ++i)
119                 res->pos[i] = exp->pos[i];
120         for (i = exp->len; i < res->len; ++i)
121                 res->pos[i] = offset + i;
122
123         isl_reordering_free(exp);
124
125         return res;
126 error:
127         isl_reordering_free(exp);
128         return NULL;
129 }
130
131 __isl_give isl_reordering *isl_reordering_extend_dim(
132         __isl_take isl_reordering *exp, __isl_take isl_dim *dim)
133 {
134         int i;
135         isl_reordering *res;
136         int offset;
137
138         if (!exp || !dim)
139                 goto error;
140
141         res = isl_reordering_extend(isl_reordering_copy(exp),
142                                             isl_dim_total(dim) - exp->len);
143         if (!res)
144                 goto error;
145         isl_dim_free(res->dim);
146         res->dim = isl_dim_replace(dim, isl_dim_param, exp->dim);
147
148         isl_reordering_free(exp);
149
150         return res;
151 error:
152         isl_reordering_free(exp);
153         isl_dim_free(dim);
154         return NULL;
155 }
156
157 void isl_reordering_dump(__isl_keep isl_reordering *exp)
158 {
159         int i;
160
161         for (i = 0; i < exp->len; ++i)
162                 fprintf(stderr, "%d -> %d; ", i, exp->pos[i]);
163         fprintf(stderr, "\n");
164 }