/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_vec.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2008-2009 Katholieke Universiteit Leuven |
3 | | * Copyright 2013 Ecole Normale Superieure |
4 | | * |
5 | | * Use of this software is governed by the MIT license |
6 | | * |
7 | | * Written by Sven Verdoolaege, K.U.Leuven, Departement |
8 | | * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium |
9 | | * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France |
10 | | */ |
11 | | |
12 | | #include <isl_ctx_private.h> |
13 | | #include <isl_seq.h> |
14 | | #include <isl_val_private.h> |
15 | | #include <isl_vec_private.h> |
16 | | |
17 | | isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec) |
18 | 181k | { |
19 | 181k | return vec ? vec->ctx : NULL; |
20 | 181k | } |
21 | | |
22 | | /* Return a hash value that digests "vec". |
23 | | */ |
24 | | uint32_t isl_vec_get_hash(__isl_keep isl_vec *vec) |
25 | 0 | { |
26 | 0 | if (!vec) |
27 | 0 | return 0; |
28 | 0 | |
29 | 0 | return isl_seq_get_hash(vec->el, vec->size); |
30 | 0 | } |
31 | | |
32 | | __isl_give isl_vec *isl_vec_alloc(struct isl_ctx *ctx, unsigned size) |
33 | 3.63M | { |
34 | 3.63M | struct isl_vec *vec; |
35 | 3.63M | |
36 | 3.63M | vec = isl_alloc_type(ctx, struct isl_vec); |
37 | 3.63M | if (!vec) |
38 | 0 | return NULL; |
39 | 3.63M | |
40 | 3.63M | vec->block = isl_blk_alloc(ctx, size); |
41 | 3.63M | if (isl_blk_is_error(vec->block)) |
42 | 0 | goto error; |
43 | 3.63M | |
44 | 3.63M | vec->ctx = ctx; |
45 | 3.63M | isl_ctx_ref(ctx); |
46 | 3.63M | vec->ref = 1; |
47 | 3.63M | vec->size = size; |
48 | 3.63M | vec->el = vec->block.data; |
49 | 3.63M | |
50 | 3.63M | return vec; |
51 | 0 | error: |
52 | 0 | isl_blk_free(ctx, vec->block); |
53 | 0 | free(vec); |
54 | 0 | return NULL; |
55 | 3.63M | } |
56 | | |
57 | | __isl_give isl_vec *isl_vec_extend(__isl_take isl_vec *vec, unsigned size) |
58 | 32.3k | { |
59 | 32.3k | if (!vec) |
60 | 0 | return NULL; |
61 | 32.3k | if (size <= vec->size) |
62 | 0 | return vec; |
63 | 32.3k | |
64 | 32.3k | vec = isl_vec_cow(vec); |
65 | 32.3k | if (!vec) |
66 | 0 | return NULL; |
67 | 32.3k | |
68 | 32.3k | vec->block = isl_blk_extend(vec->ctx, vec->block, size); |
69 | 32.3k | if (!vec->block.data) |
70 | 0 | goto error; |
71 | 32.3k | |
72 | 32.3k | vec->size = size; |
73 | 32.3k | vec->el = vec->block.data; |
74 | 32.3k | |
75 | 32.3k | return vec; |
76 | 0 | error: |
77 | 0 | isl_vec_free(vec); |
78 | 0 | return NULL; |
79 | 32.3k | } |
80 | | |
81 | | /* Apply the expansion specified by "exp" to the "n" elements starting at "pos". |
82 | | * "expanded" it the number of elements that need to replace those "n" |
83 | | * elements. The entries in "exp" have increasing values between |
84 | | * 0 and "expanded". |
85 | | */ |
86 | | __isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n, |
87 | | int *exp, int expanded) |
88 | 48.1k | { |
89 | 48.1k | int i, j; |
90 | 48.1k | int old_size, extra; |
91 | 48.1k | |
92 | 48.1k | if (!vec) |
93 | 0 | return NULL; |
94 | 48.1k | if (expanded < n) |
95 | 48.1k | isl_die0 (isl_vec_get_ctx(vec), isl_error_invalid, |
96 | 48.1k | "not an expansion", return isl_vec_free(vec)); |
97 | 48.1k | if (expanded == n) |
98 | 20.3k | return vec; |
99 | 27.7k | if (pos < 0 || n < 0 || pos + n > vec->size) |
100 | 27.7k | isl_die0 (isl_vec_get_ctx(vec), isl_error_invalid, |
101 | 27.7k | "position out of bounds", return isl_vec_free(vec)); |
102 | 27.7k | |
103 | 27.7k | old_size = vec->size; |
104 | 27.7k | extra = expanded - n; |
105 | 27.7k | vec = isl_vec_extend(vec, old_size + extra); |
106 | 27.7k | vec = isl_vec_cow(vec); |
107 | 27.7k | if (!vec) |
108 | 0 | return NULL; |
109 | 27.7k | |
110 | 27.7k | for (i = old_size - 1; i >= pos + n; --i0 ) |
111 | 27.7k | isl_int_set0 (vec->el[i + extra], vec->el[i]); |
112 | 27.7k | |
113 | 27.7k | j = n - 1; |
114 | 57.6k | for (i = expanded - 1; i >= 0; --i29.9k ) { |
115 | 29.9k | if (j >= 0 && exp[j] == i1.68k ) { |
116 | 1.10k | if (i != j) |
117 | 1.10k | isl_int_swap302 (vec->el[pos + i], |
118 | 1.10k | vec->el[pos + j]); |
119 | 1.10k | j--; |
120 | 28.8k | } else { |
121 | 28.8k | isl_int_set_si(vec->el[pos + i], 0); |
122 | 28.8k | } |
123 | 29.9k | } |
124 | 27.7k | |
125 | 27.7k | return vec; |
126 | 27.7k | } |
127 | | |
128 | | /* Create a vector of size "size" with zero-valued elements. |
129 | | */ |
130 | | __isl_give isl_vec *isl_vec_zero(isl_ctx *ctx, unsigned size) |
131 | 0 | { |
132 | 0 | isl_vec *vec; |
133 | 0 |
|
134 | 0 | vec = isl_vec_alloc(ctx, size); |
135 | 0 | if (!vec) |
136 | 0 | return NULL; |
137 | 0 | isl_seq_clr(vec->el, size); |
138 | 0 | return vec; |
139 | 0 | } |
140 | | |
141 | | __isl_give isl_vec *isl_vec_zero_extend(__isl_take isl_vec *vec, unsigned size) |
142 | 0 | { |
143 | 0 | int extra; |
144 | 0 |
|
145 | 0 | if (!vec) |
146 | 0 | return NULL; |
147 | 0 | if (size <= vec->size) |
148 | 0 | return vec; |
149 | 0 | |
150 | 0 | vec = isl_vec_cow(vec); |
151 | 0 | if (!vec) |
152 | 0 | return NULL; |
153 | 0 | |
154 | 0 | extra = size - vec->size; |
155 | 0 | vec = isl_vec_extend(vec, size); |
156 | 0 | if (!vec) |
157 | 0 | return NULL; |
158 | 0 | |
159 | 0 | isl_seq_clr(vec->el + size - extra, extra); |
160 | 0 |
|
161 | 0 | return vec; |
162 | 0 | } |
163 | | |
164 | | /* Return a vector containing the elements of "vec1" followed by |
165 | | * those of "vec2". |
166 | | */ |
167 | | __isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, |
168 | | __isl_take isl_vec *vec2) |
169 | 678 | { |
170 | 678 | if (!vec1 || !vec2) |
171 | 0 | goto error; |
172 | 678 | |
173 | 678 | if (vec2->size == 0) { |
174 | 3 | isl_vec_free(vec2); |
175 | 3 | return vec1; |
176 | 3 | } |
177 | 675 | |
178 | 675 | if (vec1->size == 0) { |
179 | 440 | isl_vec_free(vec1); |
180 | 440 | return vec2; |
181 | 440 | } |
182 | 235 | |
183 | 235 | vec1 = isl_vec_extend(vec1, vec1->size + vec2->size); |
184 | 235 | if (!vec1) |
185 | 0 | goto error; |
186 | 235 | |
187 | 235 | isl_seq_cpy(vec1->el + vec1->size - vec2->size, vec2->el, vec2->size); |
188 | 235 | |
189 | 235 | isl_vec_free(vec2); |
190 | 235 | return vec1; |
191 | 0 | error: |
192 | 0 | isl_vec_free(vec1); |
193 | 0 | isl_vec_free(vec2); |
194 | 0 | return NULL; |
195 | 235 | } |
196 | | |
197 | | struct isl_vec *isl_vec_copy(struct isl_vec *vec) |
198 | 6.45M | { |
199 | 6.45M | if (!vec) |
200 | 2.49M | return NULL; |
201 | 3.96M | |
202 | 3.96M | vec->ref++; |
203 | 3.96M | return vec; |
204 | 3.96M | } |
205 | | |
206 | | struct isl_vec *isl_vec_dup(struct isl_vec *vec) |
207 | 173k | { |
208 | 173k | struct isl_vec *vec2; |
209 | 173k | |
210 | 173k | if (!vec) |
211 | 0 | return NULL; |
212 | 173k | vec2 = isl_vec_alloc(vec->ctx, vec->size); |
213 | 173k | if (!vec2) |
214 | 0 | return NULL; |
215 | 173k | isl_seq_cpy(vec2->el, vec->el, vec->size); |
216 | 173k | return vec2; |
217 | 173k | } |
218 | | |
219 | | struct isl_vec *isl_vec_cow(struct isl_vec *vec) |
220 | 300k | { |
221 | 300k | struct isl_vec *vec2; |
222 | 300k | if (!vec) |
223 | 0 | return NULL; |
224 | 300k | |
225 | 300k | if (vec->ref == 1) |
226 | 127k | return vec; |
227 | 173k | |
228 | 173k | vec2 = isl_vec_dup(vec); |
229 | 173k | isl_vec_free(vec); |
230 | 173k | return vec2; |
231 | 173k | } |
232 | | |
233 | | __isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec) |
234 | 13.6M | { |
235 | 13.6M | if (!vec) |
236 | 6.07M | return NULL; |
237 | 7.59M | |
238 | 7.59M | if (--vec->ref > 0) |
239 | 3.96M | return NULL; |
240 | 3.63M | |
241 | 3.63M | isl_ctx_deref(vec->ctx); |
242 | 3.63M | isl_blk_free(vec->ctx, vec->block); |
243 | 3.63M | free(vec); |
244 | 3.63M | |
245 | 3.63M | return NULL; |
246 | 3.63M | } |
247 | | |
248 | | int isl_vec_size(__isl_keep isl_vec *vec) |
249 | 7.30k | { |
250 | 7.30k | return vec ? vec->size : -10 ; |
251 | 7.30k | } |
252 | | |
253 | | /* Extract the element at position "pos" of "vec". |
254 | | */ |
255 | | __isl_give isl_val *isl_vec_get_element_val(__isl_keep isl_vec *vec, int pos) |
256 | 14.3k | { |
257 | 14.3k | isl_ctx *ctx; |
258 | 14.3k | |
259 | 14.3k | if (!vec) |
260 | 0 | return NULL; |
261 | 14.3k | ctx = isl_vec_get_ctx(vec); |
262 | 14.3k | if (pos < 0 || pos >= vec->size) |
263 | 14.3k | isl_die0 (ctx, isl_error_invalid, "position out of range", |
264 | 14.3k | return NULL); |
265 | 14.3k | return isl_val_int_from_isl_int(ctx, vec->el[pos]); |
266 | 14.3k | } |
267 | | |
268 | | __isl_give isl_vec *isl_vec_set_element(__isl_take isl_vec *vec, |
269 | | int pos, isl_int v) |
270 | 1.13k | { |
271 | 1.13k | vec = isl_vec_cow(vec); |
272 | 1.13k | if (!vec) |
273 | 0 | return NULL; |
274 | 1.13k | if (pos < 0 || pos >= vec->size) |
275 | 1.13k | isl_die0 (vec->ctx, isl_error_invalid, "position out of range", |
276 | 1.13k | goto error); |
277 | 1.13k | isl_int_set(vec->el[pos], v); |
278 | 1.13k | return vec; |
279 | 0 | error: |
280 | 0 | isl_vec_free(vec); |
281 | 0 | return NULL; |
282 | 1.13k | } |
283 | | |
284 | | __isl_give isl_vec *isl_vec_set_element_si(__isl_take isl_vec *vec, |
285 | | int pos, int v) |
286 | 3 | { |
287 | 3 | vec = isl_vec_cow(vec); |
288 | 3 | if (!vec) |
289 | 0 | return NULL; |
290 | 3 | if (pos < 0 || pos >= vec->size) |
291 | 3 | isl_die0 (vec->ctx, isl_error_invalid, "position out of range", |
292 | 3 | goto error); |
293 | 3 | isl_int_set_si(vec->el[pos], v); |
294 | 3 | return vec; |
295 | 0 | error: |
296 | 0 | isl_vec_free(vec); |
297 | 0 | return NULL; |
298 | 3 | } |
299 | | |
300 | | /* Replace the element at position "pos" of "vec" by "v". |
301 | | */ |
302 | | __isl_give isl_vec *isl_vec_set_element_val(__isl_take isl_vec *vec, |
303 | | int pos, __isl_take isl_val *v) |
304 | 1.13k | { |
305 | 1.13k | if (!v) |
306 | 0 | return isl_vec_free(vec); |
307 | 1.13k | if (!isl_val_is_int(v)) |
308 | 1.13k | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
309 | 1.13k | "expecting integer value", goto error); |
310 | 1.13k | vec = isl_vec_set_element(vec, pos, v->n); |
311 | 1.13k | isl_val_free(v); |
312 | 1.13k | return vec; |
313 | 0 | error: |
314 | 0 | isl_val_free(v); |
315 | 0 | return isl_vec_free(vec); |
316 | 1.13k | } |
317 | | |
318 | | /* Compare the elements of "vec1" and "vec2" at position "pos". |
319 | | */ |
320 | | int isl_vec_cmp_element(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2, |
321 | | int pos) |
322 | 5.88k | { |
323 | 5.88k | if (!vec1 || !vec2) |
324 | 0 | return 0; |
325 | 5.88k | if (pos < 0 || pos >= vec1->size || pos >= vec2->size) |
326 | 5.88k | isl_die0 (isl_vec_get_ctx(vec1), isl_error_invalid, |
327 | 5.88k | "position out of range", return 0); |
328 | 5.88k | return isl_int_cmp(vec1->el[pos], vec2->el[pos]); |
329 | 5.88k | } |
330 | | |
331 | | /* Does "vec" contain only zero elements? |
332 | | */ |
333 | | isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec) |
334 | 789 | { |
335 | 789 | if (!vec) |
336 | 0 | return isl_bool_error; |
337 | 789 | return isl_seq_first_non_zero(vec->el, vec->size) < 0; |
338 | 789 | } |
339 | | |
340 | | isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2) |
341 | 6.51k | { |
342 | 6.51k | if (!vec1 || !vec2) |
343 | 0 | return isl_bool_error; |
344 | 6.51k | |
345 | 6.51k | if (vec1->size != vec2->size) |
346 | 0 | return isl_bool_false; |
347 | 6.51k | |
348 | 6.51k | return isl_seq_eq(vec1->el, vec2->el, vec1->size); |
349 | 6.51k | } |
350 | | |
351 | | __isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer, |
352 | | __isl_keep isl_vec *vec) |
353 | 0 | { |
354 | 0 | int i; |
355 | 0 |
|
356 | 0 | if (!printer || !vec) |
357 | 0 | goto error; |
358 | 0 | |
359 | 0 | printer = isl_printer_print_str(printer, "["); |
360 | 0 | for (i = 0; i < vec->size; ++i) { |
361 | 0 | if (i) |
362 | 0 | printer = isl_printer_print_str(printer, ","); |
363 | 0 | printer = isl_printer_print_isl_int(printer, vec->el[i]); |
364 | 0 | } |
365 | 0 | printer = isl_printer_print_str(printer, "]"); |
366 | 0 |
|
367 | 0 | return printer; |
368 | 0 | error: |
369 | 0 | isl_printer_free(printer); |
370 | 0 | return NULL; |
371 | 0 | } |
372 | | |
373 | | void isl_vec_dump(struct isl_vec *vec) |
374 | 0 | { |
375 | 0 | isl_printer *printer; |
376 | 0 |
|
377 | 0 | if (!vec) |
378 | 0 | return; |
379 | 0 | |
380 | 0 | printer = isl_printer_to_file(vec->ctx, stderr); |
381 | 0 | printer = isl_printer_print_vec(printer, vec); |
382 | 0 | printer = isl_printer_end_line(printer); |
383 | 0 |
|
384 | 0 | isl_printer_free(printer); |
385 | 0 | } |
386 | | |
387 | | __isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v) |
388 | 10 | { |
389 | 10 | vec = isl_vec_cow(vec); |
390 | 10 | if (!vec) |
391 | 0 | return NULL; |
392 | 10 | isl_seq_set(vec->el, v, vec->size); |
393 | 10 | return vec; |
394 | 10 | } |
395 | | |
396 | | __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, int v) |
397 | 1.75k | { |
398 | 1.75k | vec = isl_vec_cow(vec); |
399 | 1.75k | if (!vec) |
400 | 0 | return NULL; |
401 | 1.75k | isl_seq_set_si(vec->el, v, vec->size); |
402 | 1.75k | return vec; |
403 | 1.75k | } |
404 | | |
405 | | /* Replace all elements of "vec" by "v". |
406 | | */ |
407 | | __isl_give isl_vec *isl_vec_set_val(__isl_take isl_vec *vec, |
408 | | __isl_take isl_val *v) |
409 | 0 | { |
410 | 0 | vec = isl_vec_cow(vec); |
411 | 0 | if (!vec || !v) |
412 | 0 | goto error; |
413 | 0 | if (!isl_val_is_int(v)) |
414 | 0 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
415 | 0 | "expecting integer value", goto error); |
416 | 0 | isl_seq_set(vec->el, v->n, vec->size); |
417 | 0 | isl_val_free(v); |
418 | 0 | return vec; |
419 | 0 | error: |
420 | 0 | isl_vec_free(vec); |
421 | 0 | isl_val_free(v); |
422 | 0 | return NULL; |
423 | 0 | } |
424 | | |
425 | | __isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec) |
426 | 5.30k | { |
427 | 5.30k | vec = isl_vec_cow(vec); |
428 | 5.30k | if (!vec) |
429 | 0 | return NULL; |
430 | 5.30k | isl_seq_clr(vec->el, vec->size); |
431 | 5.30k | return vec; |
432 | 5.30k | } |
433 | | |
434 | | void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm) |
435 | 3.94k | { |
436 | 3.94k | isl_seq_lcm(vec->block.data, vec->size, lcm); |
437 | 3.94k | } |
438 | | |
439 | | /* Given a rational vector, with the denominator in the first element |
440 | | * of the vector, round up all coordinates. |
441 | | */ |
442 | | __isl_give isl_vec *isl_vec_ceil(__isl_take isl_vec *vec) |
443 | 3.96k | { |
444 | 3.96k | vec = isl_vec_cow(vec); |
445 | 3.96k | if (!vec) |
446 | 0 | return NULL; |
447 | 3.96k | |
448 | 3.96k | isl_seq_cdiv_q(vec->el + 1, vec->el + 1, vec->el[0], vec->size - 1); |
449 | 3.96k | |
450 | 3.96k | isl_int_set_si(vec->el[0], 1); |
451 | 3.96k | |
452 | 3.96k | return vec; |
453 | 3.96k | } |
454 | | |
455 | | struct isl_vec *isl_vec_normalize(struct isl_vec *vec) |
456 | 530k | { |
457 | 530k | if (!vec) |
458 | 0 | return NULL; |
459 | 530k | isl_seq_normalize(vec->ctx, vec->el, vec->size); |
460 | 530k | return vec; |
461 | 530k | } |
462 | | |
463 | | __isl_give isl_vec *isl_vec_neg(__isl_take isl_vec *vec) |
464 | 0 | { |
465 | 0 | vec = isl_vec_cow(vec); |
466 | 0 | if (!vec) |
467 | 0 | return NULL; |
468 | 0 | isl_seq_neg(vec->el, vec->el, vec->size); |
469 | 0 | return vec; |
470 | 0 | } |
471 | | |
472 | | __isl_give isl_vec *isl_vec_scale(__isl_take isl_vec *vec, isl_int m) |
473 | 0 | { |
474 | 0 | if (isl_int_is_one(m)) |
475 | 0 | return vec; |
476 | 0 | vec = isl_vec_cow(vec); |
477 | 0 | if (!vec) |
478 | 0 | return NULL; |
479 | 0 | isl_seq_scale(vec->el, vec->el, m, vec->size); |
480 | 0 | return vec; |
481 | 0 | } |
482 | | |
483 | | /* Reduce the elements of "vec" modulo "m". |
484 | | */ |
485 | | __isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, isl_int m) |
486 | 0 | { |
487 | 0 | vec = isl_vec_cow(vec); |
488 | 0 | if (!vec) |
489 | 0 | return NULL; |
490 | 0 | |
491 | 0 | isl_seq_fdiv_r(vec->el, vec->el, m, vec->size); |
492 | 0 |
|
493 | 0 | return vec; |
494 | 0 | } |
495 | | |
496 | | __isl_give isl_vec *isl_vec_add(__isl_take isl_vec *vec1, |
497 | | __isl_take isl_vec *vec2) |
498 | 0 | { |
499 | 0 | vec1 = isl_vec_cow(vec1); |
500 | 0 | if (!vec1 || !vec2) |
501 | 0 | goto error; |
502 | 0 | |
503 | 0 | isl_assert(vec1->ctx, vec1->size == vec2->size, goto error); |
504 | 0 |
|
505 | 0 | isl_seq_combine(vec1->el, vec1->ctx->one, vec1->el, |
506 | 0 | vec1->ctx->one, vec2->el, vec1->size); |
507 | 0 | |
508 | 0 | isl_vec_free(vec2); |
509 | 0 | return vec1; |
510 | 0 | error: |
511 | 0 | isl_vec_free(vec1); |
512 | 0 | isl_vec_free(vec2); |
513 | 0 | return NULL; |
514 | 0 | } |
515 | | |
516 | | static int qsort_int_cmp(const void *p1, const void *p2) |
517 | 0 | { |
518 | 0 | const isl_int *i1 = (const isl_int *) p1; |
519 | 0 | const isl_int *i2 = (const isl_int *) p2; |
520 | 0 |
|
521 | 0 | return isl_int_cmp(*i1, *i2); |
522 | 0 | } |
523 | | |
524 | | __isl_give isl_vec *isl_vec_sort(__isl_take isl_vec *vec) |
525 | 0 | { |
526 | 0 | if (!vec) |
527 | 0 | return NULL; |
528 | 0 | |
529 | 0 | qsort(vec->el, vec->size, sizeof(*vec->el), &qsort_int_cmp); |
530 | 0 |
|
531 | 0 | return vec; |
532 | 0 | } |
533 | | |
534 | | __isl_give isl_vec *isl_vec_drop_els(__isl_take isl_vec *vec, |
535 | | unsigned pos, unsigned n) |
536 | 36.0k | { |
537 | 36.0k | if (n == 0) |
538 | 20 | return vec; |
539 | 36.0k | vec = isl_vec_cow(vec); |
540 | 36.0k | if (!vec) |
541 | 0 | return NULL; |
542 | 36.0k | |
543 | 36.0k | if (pos + n > vec->size) |
544 | 36.0k | isl_die0 (vec->ctx, isl_error_invalid, |
545 | 36.0k | "range out of bounds", goto error); |
546 | 36.0k | |
547 | 36.0k | if (pos + n != vec->size) |
548 | 31.5k | isl_seq_cpy(vec->el + pos, vec->el + pos + n, |
549 | 31.5k | vec->size - pos - n); |
550 | 36.0k | |
551 | 36.0k | vec->size -= n; |
552 | 36.0k | |
553 | 36.0k | return vec; |
554 | 0 | error: |
555 | 0 | isl_vec_free(vec); |
556 | 0 | return NULL; |
557 | 36.0k | } |
558 | | |
559 | | __isl_give isl_vec *isl_vec_insert_els(__isl_take isl_vec *vec, |
560 | | unsigned pos, unsigned n) |
561 | 7.14k | { |
562 | 7.14k | isl_vec *ext = NULL; |
563 | 7.14k | |
564 | 7.14k | if (n == 0) |
565 | 4 | return vec; |
566 | 7.13k | if (!vec) |
567 | 0 | return NULL; |
568 | 7.13k | |
569 | 7.13k | if (pos > vec->size) |
570 | 7.13k | isl_die0 (vec->ctx, isl_error_invalid, |
571 | 7.13k | "position out of bounds", goto error); |
572 | 7.13k | |
573 | 7.13k | ext = isl_vec_alloc(vec->ctx, vec->size + n); |
574 | 7.13k | if (!ext) |
575 | 0 | goto error; |
576 | 7.13k | |
577 | 7.13k | isl_seq_cpy(ext->el, vec->el, pos); |
578 | 7.13k | isl_seq_cpy(ext->el + pos + n, vec->el + pos, vec->size - pos); |
579 | 7.13k | |
580 | 7.13k | isl_vec_free(vec); |
581 | 7.13k | return ext; |
582 | 0 | error: |
583 | 0 | isl_vec_free(vec); |
584 | 0 | isl_vec_free(ext); |
585 | 0 | return NULL; |
586 | 7.13k | } |
587 | | |
588 | | /* Add "n" elements at the end of "vec". |
589 | | */ |
590 | | __isl_give isl_vec *isl_vec_add_els(__isl_take isl_vec *vec, unsigned n) |
591 | 12 | { |
592 | 12 | if (!vec) |
593 | 0 | return NULL; |
594 | 12 | return isl_vec_insert_els(vec, vec->size, n); |
595 | 12 | } |
596 | | |
597 | | __isl_give isl_vec *isl_vec_insert_zero_els(__isl_take isl_vec *vec, |
598 | | unsigned pos, unsigned n) |
599 | 7.10k | { |
600 | 7.10k | vec = isl_vec_insert_els(vec, pos, n); |
601 | 7.10k | if (!vec) |
602 | 0 | return NULL; |
603 | 7.10k | |
604 | 7.10k | isl_seq_clr(vec->el + pos, n); |
605 | 7.10k | |
606 | 7.10k | return vec; |
607 | 7.10k | } |
608 | | |
609 | | /* Move the "n" elements starting as "src_pos" of "vec" |
610 | | * to "dst_pos". The elements originally at "dst_pos" are moved |
611 | | * up or down depending on whether "dst_pos" is smaller or greater |
612 | | * than "src_pos". |
613 | | */ |
614 | | __isl_give isl_vec *isl_vec_move_els(__isl_take isl_vec *vec, |
615 | | unsigned dst_pos, unsigned src_pos, unsigned n) |
616 | 0 | { |
617 | 0 | isl_vec *res; |
618 | 0 |
|
619 | 0 | if (!vec) |
620 | 0 | return NULL; |
621 | 0 | |
622 | 0 | if (src_pos + n > vec->size) |
623 | 0 | isl_die(vec->ctx, isl_error_invalid, |
624 | 0 | "source range out of bounds", return isl_vec_free(vec)); |
625 | 0 | if (dst_pos + n > vec->size) |
626 | 0 | isl_die(vec->ctx, isl_error_invalid, |
627 | 0 | "destination range out of bounds", |
628 | 0 | return isl_vec_free(vec)); |
629 | 0 |
|
630 | 0 | if (n == 0 || dst_pos == src_pos) |
631 | 0 | return vec; |
632 | 0 | |
633 | 0 | res = isl_vec_alloc(vec->ctx, vec->size); |
634 | 0 | if (!res) |
635 | 0 | return isl_vec_free(vec); |
636 | 0 | |
637 | 0 | if (dst_pos < src_pos) { |
638 | 0 | isl_seq_cpy(res->el, vec->el, dst_pos); |
639 | 0 | isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); |
640 | 0 | isl_seq_cpy(res->el + dst_pos + n, |
641 | 0 | vec->el + dst_pos, src_pos - dst_pos); |
642 | 0 | isl_seq_cpy(res->el + src_pos + n, |
643 | 0 | vec->el + src_pos + n, res->size - src_pos - n); |
644 | 0 | } else { |
645 | 0 | isl_seq_cpy(res->el, vec->el, src_pos); |
646 | 0 | isl_seq_cpy(res->el + src_pos, |
647 | 0 | vec->el + src_pos + n, dst_pos - src_pos); |
648 | 0 | isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); |
649 | 0 | isl_seq_cpy(res->el + dst_pos + n, |
650 | 0 | vec->el + dst_pos + n, res->size - dst_pos - n); |
651 | 0 | } |
652 | 0 |
|
653 | 0 | isl_vec_free(vec); |
654 | 0 | return res; |
655 | 0 | } |