2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010-2011 INRIA Saclay
5 * Use of this software is governed by the MIT license
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
13 #include <isl_map_private.h>
14 #include <isl_space_private.h>
15 #include <isl_dim_map.h>
16 #include <isl_reordering.h>
18 struct isl_dim_map_entry
{
23 /* Maps dst positions to src positions */
26 struct isl_dim_map_entry m
[1];
29 __isl_give isl_dim_map
*isl_dim_map_alloc(isl_ctx
*ctx
, unsigned len
)
32 struct isl_dim_map
*dim_map
;
33 dim_map
= isl_alloc(ctx
, struct isl_dim_map
,
34 sizeof(struct isl_dim_map
) + len
* sizeof(struct isl_dim_map_entry
));
37 dim_map
->len
= 1 + len
;
38 dim_map
->m
[0].pos
= 0;
39 dim_map
->m
[0].sgn
= 1;
40 for (i
= 0; i
< len
; ++i
)
41 dim_map
->m
[1 + i
].sgn
= 0;
45 /* Free "dim_map" and return NULL.
47 __isl_null isl_dim_map
*isl_dim_map_free(__isl_take isl_dim_map
*dim_map
)
53 void isl_dim_map_range(__isl_keep isl_dim_map
*dim_map
,
54 unsigned dst_pos
, int dst_stride
, unsigned src_pos
, int src_stride
,
62 for (i
= 0; i
< n
; ++i
) {
63 unsigned d
= 1 + dst_pos
+ dst_stride
* i
;
64 unsigned s
= 1 + src_pos
+ src_stride
* i
;
65 dim_map
->m
[d
].pos
= s
;
66 dim_map
->m
[d
].sgn
= sign
;
70 void isl_dim_map_dim_range(__isl_keep isl_dim_map
*dim_map
,
71 __isl_keep isl_space
*space
, enum isl_dim_type type
,
72 unsigned first
, unsigned n
, unsigned dst_pos
)
77 if (!dim_map
|| !space
)
80 src_pos
= 1 + isl_space_offset(space
, type
);
81 for (i
= 0; i
< n
; ++i
) {
82 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ first
+ i
;
83 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
87 void isl_dim_map_dim(__isl_keep isl_dim_map
*dim_map
,
88 __isl_keep isl_space
*space
, enum isl_dim_type type
, unsigned dst_pos
)
90 isl_size dim
= isl_space_dim(space
, type
);
94 isl_dim_map_dim_range(dim_map
, space
, type
, 0, dim
, dst_pos
);
97 void isl_dim_map_div(__isl_keep isl_dim_map
*dim_map
,
98 __isl_keep isl_basic_map
*bmap
, unsigned dst_pos
)
103 if (!dim_map
|| !bmap
)
106 src_pos
= isl_basic_map_offset(bmap
, isl_dim_div
);
107 for (i
= 0; i
< bmap
->n_div
; ++i
) {
108 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ i
;
109 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
113 void isl_dim_map_dump(struct isl_dim_map
*dim_map
)
117 for (i
= 0; i
< dim_map
->len
; ++i
)
118 fprintf(stderr
, "%d -> %d * %d; ", i
,
119 dim_map
->m
[i
].sgn
, dim_map
->m
[i
].pos
);
120 fprintf(stderr
, "\n");
123 static void copy_constraint_dim_map(isl_int
*dst
, isl_int
*src
,
124 struct isl_dim_map
*dim_map
)
128 for (i
= 0; i
< dim_map
->len
; ++i
) {
129 if (dim_map
->m
[i
].sgn
== 0)
130 isl_int_set_si(dst
[i
], 0);
131 else if (dim_map
->m
[i
].sgn
> 0)
132 isl_int_set(dst
[i
], src
[dim_map
->m
[i
].pos
]);
134 isl_int_neg(dst
[i
], src
[dim_map
->m
[i
].pos
]);
138 static void copy_div_dim_map(isl_int
*dst
, isl_int
*src
,
139 struct isl_dim_map
*dim_map
)
141 isl_int_set(dst
[0], src
[0]);
142 copy_constraint_dim_map(dst
+1, src
+1, dim_map
);
145 __isl_give isl_basic_map
*isl_basic_map_add_constraints_dim_map(
146 __isl_take isl_basic_map
*dst
, __isl_take isl_basic_map
*src
,
147 __isl_take isl_dim_map
*dim_map
)
151 if (!src
|| !dst
|| !dim_map
)
154 for (i
= 0; i
< src
->n_eq
; ++i
) {
155 int i1
= isl_basic_map_alloc_equality(dst
);
158 copy_constraint_dim_map(dst
->eq
[i1
], src
->eq
[i
], dim_map
);
161 for (i
= 0; i
< src
->n_ineq
; ++i
) {
162 int i1
= isl_basic_map_alloc_inequality(dst
);
165 copy_constraint_dim_map(dst
->ineq
[i1
], src
->ineq
[i
], dim_map
);
168 for (i
= 0; i
< src
->n_div
; ++i
) {
169 int i1
= isl_basic_map_alloc_div(dst
);
172 copy_div_dim_map(dst
->div
[i1
], src
->div
[i
], dim_map
);
175 isl_dim_map_free(dim_map
);
176 isl_basic_map_free(src
);
180 isl_dim_map_free(dim_map
);
181 isl_basic_map_free(src
);
182 isl_basic_map_free(dst
);
186 __isl_give isl_basic_set
*isl_basic_set_add_constraints_dim_map(
187 __isl_take isl_basic_set
*dst
, __isl_take isl_basic_set
*src
,
188 __isl_take isl_dim_map
*dim_map
)
190 return isl_basic_map_add_constraints_dim_map(dst
, src
, dim_map
);
193 /* Extend the given dim_map with mappings for the divs in bmap.
195 __isl_give isl_dim_map
*isl_dim_map_extend(__isl_keep isl_dim_map
*dim_map
,
196 __isl_keep isl_basic_map
*bmap
)
199 struct isl_dim_map
*res
;
205 offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
207 res
= isl_dim_map_alloc(bmap
->ctx
, dim_map
->len
- 1 + bmap
->n_div
);
211 for (i
= 0; i
< dim_map
->len
; ++i
)
212 res
->m
[i
] = dim_map
->m
[i
];
213 for (i
= 0; i
< bmap
->n_div
; ++i
) {
214 res
->m
[dim_map
->len
+ i
].pos
= offset
+ i
;
215 res
->m
[dim_map
->len
+ i
].sgn
= 1;
221 /* Extract a dim_map from a reordering.
222 * We essentially need to reverse the mapping, and add an offset
223 * of 1 for the constant term.
225 __isl_give isl_dim_map
*isl_dim_map_from_reordering(
226 __isl_keep isl_reordering
*exp
)
232 struct isl_dim_map
*dim_map
;
237 ctx
= isl_reordering_get_ctx(exp
);
238 space
= isl_reordering_peek_space(exp
);
239 dim
= isl_space_dim(space
, isl_dim_all
);
242 dim_map
= isl_dim_map_alloc(ctx
, dim
);
246 for (i
= 0; i
< exp
->len
; ++i
) {
247 dim_map
->m
[1 + exp
->pos
[i
]].pos
= 1 + i
;
248 dim_map
->m
[1 + exp
->pos
[i
]].sgn
= 1;