Bug Summary

File:tools/polly/lib/External/isl/isl_mat.c
Warning:line 1370, column 2
Use of memory after it is freed

Annotated Source Code

1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2014 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_map_private.h>
14#include <isl/space.h>
15#include <isl_seq.h>
16#include <isl_mat_private.h>
17#include <isl_vec_private.h>
18#include <isl_space_private.h>
19#include <isl_val_private.h>
20#include <isl/deprecated/mat_int.h>
21
22isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat)
23{
24 return mat ? mat->ctx : NULL((void*)0);
25}
26
27/* Return a hash value that digests "mat".
28 */
29uint32_t isl_mat_get_hash(__isl_keep isl_mat *mat)
30{
31 int i;
32 uint32_t hash;
33
34 if (!mat)
35 return 0;
36
37 hash = isl_hash_init()(2166136261u);
38 isl_hash_byte(hash, mat->n_row & 0xFF)do { hash *= 16777619; hash ^= mat->n_row & 0xFF; } while
(0)
;
39 isl_hash_byte(hash, mat->n_col & 0xFF)do { hash *= 16777619; hash ^= mat->n_col & 0xFF; } while
(0)
;
40 for (i = 0; i < mat->n_row; ++i) {
41 uint32_t row_hash;
42
43 row_hash = isl_seq_get_hash(mat->row[i], mat->n_col);
44 isl_hash_hash(hash, row_hash)do { do { hash *= 16777619; hash ^= (row_hash) & 0xFF; } while
(0); do { hash *= 16777619; hash ^= ((row_hash) >> 8) &
0xFF; } while(0); do { hash *= 16777619; hash ^= ((row_hash)
>> 16) & 0xFF; } while(0); do { hash *= 16777619; hash
^= ((row_hash) >> 24) & 0xFF; } while(0); } while(
0)
;
45 }
46
47 return hash;
48}
49
50struct isl_mat *isl_mat_alloc(struct isl_ctx *ctx,
51 unsigned n_row, unsigned n_col)
52{
53 int i;
54 struct isl_mat *mat;
55
56 mat = isl_alloc_type(ctx, struct isl_mat)((struct isl_mat *)isl_malloc_or_die(ctx, sizeof(struct isl_mat
)))
;
57 if (!mat)
58 return NULL((void*)0);
59
60 mat->row = NULL((void*)0);
61 mat->block = isl_blk_alloc(ctx, n_row * n_col);
62 if (isl_blk_is_error(mat->block))
63 goto error;
64 mat->row = isl_alloc_array(ctx, isl_int *, n_row)((isl_int * *)isl_malloc_or_die(ctx, (n_row)*sizeof(isl_int *
)))
;
65 if (n_row && !mat->row)
66 goto error;
67
68 for (i = 0; i < n_row; ++i)
69 mat->row[i] = mat->block.data + i * n_col;
70
71 mat->ctx = ctx;
72 isl_ctx_ref(ctx);
73 mat->ref = 1;
74 mat->n_row = n_row;
75 mat->n_col = n_col;
76 mat->max_col = n_col;
77 mat->flags = 0;
78
79 return mat;
80error:
81 isl_blk_free(ctx, mat->block);
82 free(mat);
83 return NULL((void*)0);
84}
85
86struct isl_mat *isl_mat_extend(struct isl_mat *mat,
87 unsigned n_row, unsigned n_col)
88{
89 int i;
90 isl_int *old;
91 isl_int **row;
92
93 if (!mat)
94 return NULL((void*)0);
95
96 if (mat->max_col >= n_col && mat->n_row >= n_row) {
97 if (mat->n_col < n_col)
98 mat->n_col = n_col;
99 return mat;
100 }
101
102 if (mat->max_col < n_col) {
103 struct isl_mat *new_mat;
104
105 if (n_row < mat->n_row)
106 n_row = mat->n_row;
107 new_mat = isl_mat_alloc(mat->ctx, n_row, n_col);
108 if (!new_mat)
109 goto error;
110 for (i = 0; i < mat->n_row; ++i)
111 isl_seq_cpy(new_mat->row[i], mat->row[i], mat->n_col);
112 isl_mat_free(mat);
113 return new_mat;
114 }
115
116 mat = isl_mat_cow(mat);
117 if (!mat)
118 goto error;
119
120 old = mat->block.data;
121 mat->block = isl_blk_extend(mat->ctx, mat->block, n_row * mat->max_col);
122 if (isl_blk_is_error(mat->block))
123 goto error;
124 row = isl_realloc_array(mat->ctx, mat->row, isl_int *, n_row)((isl_int * *)isl_realloc_or_die(mat->ctx, mat->row, (n_row
)*sizeof(isl_int *)))
;
125 if (n_row && !row)
126 goto error;
127 mat->row = row;
128
129 for (i = 0; i < mat->n_row; ++i)
130 mat->row[i] = mat->block.data + (mat->row[i] - old);
131 for (i = mat->n_row; i < n_row; ++i)
132 mat->row[i] = mat->block.data + i * mat->max_col;
133 mat->n_row = n_row;
134 if (mat->n_col < n_col)
135 mat->n_col = n_col;
136
137 return mat;
138error:
139 isl_mat_free(mat);
140 return NULL((void*)0);
141}
142
143__isl_give isl_mat *isl_mat_sub_alloc6(isl_ctx *ctx, isl_int **row,
144 unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col)
145{
146 int i;
147 struct isl_mat *mat;
148
149 mat = isl_alloc_type(ctx, struct isl_mat)((struct isl_mat *)isl_malloc_or_die(ctx, sizeof(struct isl_mat
)))
;
150 if (!mat)
151 return NULL((void*)0);
152 mat->row = isl_alloc_array(ctx, isl_int *, n_row)((isl_int * *)isl_malloc_or_die(ctx, (n_row)*sizeof(isl_int *
)))
;
153 if (n_row && !mat->row)
154 goto error;
155 for (i = 0; i < n_row; ++i)
156 mat->row[i] = row[first_row+i] + first_col;
157 mat->ctx = ctx;
158 isl_ctx_ref(ctx);
159 mat->ref = 1;
160 mat->n_row = n_row;
161 mat->n_col = n_col;
162 mat->block = isl_blk_empty();
163 mat->flags = ISL_MAT_BORROWED(1 << 0);
164 return mat;
165error:
166 free(mat);
167 return NULL((void*)0);
168}
169
170__isl_give isl_mat *isl_mat_sub_alloc(__isl_keep isl_mat *mat,
171 unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col)
172{
173 if (!mat)
174 return NULL((void*)0);
175 return isl_mat_sub_alloc6(mat->ctx, mat->row, first_row, n_row,
176 first_col, n_col);
177}
178
179void isl_mat_sub_copy(struct isl_ctx *ctx, isl_int **dst, isl_int **src,
180 unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col)
181{
182 int i;
183
184 for (i = 0; i < n_row; ++i)
185 isl_seq_cpy(dst[i]+dst_col, src[i]+src_col, n_col);
186}
187
188void isl_mat_sub_neg(struct isl_ctx *ctx, isl_int **dst, isl_int **src,
189 unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col)
190{
191 int i;
192
193 for (i = 0; i < n_row; ++i)
194 isl_seq_neg(dst[i]+dst_col, src[i]+src_col, n_col);
195}
196
197__isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat)
198{
199 if (!mat)
6
Assuming 'mat' is non-null
7
Taking false branch
200 return NULL((void*)0);
201
202 mat->ref++;
203 return mat;
204}
205
206__isl_give isl_mat *isl_mat_dup(__isl_keep isl_mat *mat)
207{
208 int i;
209 struct isl_mat *mat2;
210
211 if (!mat)
212 return NULL((void*)0);
213 mat2 = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col);
214 if (!mat2)
215 return NULL((void*)0);
216 for (i = 0; i < mat->n_row; ++i)
217 isl_seq_cpy(mat2->row[i], mat->row[i], mat->n_col);
218 return mat2;
219}
220
221__isl_give isl_mat *isl_mat_cow(__isl_take isl_mat *mat)
222{
223 struct isl_mat *mat2;
224 if (!mat)
225 return NULL((void*)0);
226
227 if (mat->ref == 1 && !ISL_F_ISSET(mat, ISL_MAT_BORROWED)(!!(((mat)->flags) & ((1 << 0)))))
228 return mat;
229
230 mat2 = isl_mat_dup(mat);
231 isl_mat_free(mat);
232 return mat2;
233}
234
235__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat)
236{
237 if (!mat)
15
Taking false branch
238 return NULL((void*)0);
239
240 if (--mat->ref > 0)
16
Assuming the condition is false
17
Taking false branch
241 return NULL((void*)0);
242
243 if (!ISL_F_ISSET(mat, ISL_MAT_BORROWED)(!!(((mat)->flags) & ((1 << 0)))))
18
Taking false branch
244 isl_blk_free(mat->ctx, mat->block);
245 isl_ctx_deref(mat->ctx);
246 free(mat->row);
247 free(mat);
19
Memory is released
248
249 return NULL((void*)0);
250}
251
252int isl_mat_rows(__isl_keep isl_mat *mat)
253{
254 return mat ? mat->n_row : -1;
255}
256
257int isl_mat_cols(__isl_keep isl_mat *mat)
258{
259 return mat ? mat->n_col : -1;
260}
261
262/* Check that "col" is a valid column position for "mat".
263 */
264static isl_stat check_col(__isl_keep isl_mat *mat, int col)
265{
266 if (!mat)
267 return isl_stat_error;
268 if (col < 0 || col >= mat->n_col)
269 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(mat), isl_error_invalid
, "column out of range", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 270); return isl_stat_error; } while (0)
270 "column out of range", return isl_stat_error)do { isl_handle_error(isl_mat_get_ctx(mat), isl_error_invalid
, "column out of range", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 270); return isl_stat_error; } while (0)
;
271 return isl_stat_ok;
272}
273
274/* Check that "row" is a valid row position for "mat".
275 */
276static isl_stat check_row(__isl_keep isl_mat *mat, int row)
277{
278 if (!mat)
279 return isl_stat_error;
280 if (row < 0 || row >= mat->n_row)
281 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(mat), isl_error_invalid
, "row out of range", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 282); return isl_stat_error; } while (0)
282 "row out of range", return isl_stat_error)do { isl_handle_error(isl_mat_get_ctx(mat), isl_error_invalid
, "row out of range", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 282); return isl_stat_error; } while (0)
;
283 return isl_stat_ok;
284}
285
286int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v)
287{
288 if (check_row(mat, row) < 0)
289 return -1;
290 if (check_col(mat, col) < 0)
291 return -1;
292 isl_int_set(*v, mat->row[row][col])isl_sioimath_set((*v), *(mat->row[row][col]));
293 return 0;
294}
295
296/* Extract the element at row "row", oolumn "col" of "mat".
297 */
298__isl_give isl_val *isl_mat_get_element_val(__isl_keep isl_mat *mat,
299 int row, int col)
300{
301 isl_ctx *ctx;
302
303 if (check_row(mat, row) < 0)
304 return NULL((void*)0);
305 if (check_col(mat, col) < 0)
306 return NULL((void*)0);
307 ctx = isl_mat_get_ctx(mat);
308 return isl_val_int_from_isl_int(ctx, mat->row[row][col]);
309}
310
311__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat,
312 int row, int col, isl_int v)
313{
314 mat = isl_mat_cow(mat);
315 if (check_row(mat, row) < 0)
316 return isl_mat_free(mat);
317 if (check_col(mat, col) < 0)
318 return isl_mat_free(mat);
319 isl_int_set(mat->row[row][col], v)isl_sioimath_set((mat->row[row][col]), *(v));
320 return mat;
321}
322
323__isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat,
324 int row, int col, int v)
325{
326 mat = isl_mat_cow(mat);
327 if (check_row(mat, row) < 0)
328 return isl_mat_free(mat);
329 if (check_col(mat, col) < 0)
330 return isl_mat_free(mat);
331 isl_int_set_si(mat->row[row][col], v)isl_sioimath_set_si((mat->row[row][col]), v);
332 return mat;
333}
334
335/* Replace the element at row "row", column "col" of "mat" by "v".
336 */
337__isl_give isl_mat *isl_mat_set_element_val(__isl_take isl_mat *mat,
338 int row, int col, __isl_take isl_val *v)
339{
340 if (!v)
341 return isl_mat_free(mat);
342 if (!isl_val_is_int(v))
343 isl_die(isl_val_get_ctx(v), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting integer value"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 344); goto error; } while (0)
344 "expecting integer value", goto error)do { isl_handle_error(isl_val_get_ctx(v), isl_error_invalid, "expecting integer value"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 344); goto error; } while (0)
;
345 mat = isl_mat_set_element(mat, row, col, v->n);
346 isl_val_free(v);
347 return mat;
348error:
349 isl_val_free(v);
350 return isl_mat_free(mat);
351}
352
353__isl_give isl_mat *isl_mat_diag(isl_ctx *ctx, unsigned n_row, isl_int d)
354{
355 int i;
356 struct isl_mat *mat;
357
358 mat = isl_mat_alloc(ctx, n_row, n_row);
359 if (!mat)
360 return NULL((void*)0);
361 for (i = 0; i < n_row; ++i) {
362 isl_seq_clr(mat->row[i], i);
363 isl_int_set(mat->row[i][i], d)isl_sioimath_set((mat->row[i][i]), *(d));
364 isl_seq_clr(mat->row[i]+i+1, n_row-(i+1));
365 }
366
367 return mat;
368}
369
370/* Create an "n_row" by "n_col" matrix with zero elements.
371 */
372__isl_give isl_mat *isl_mat_zero(isl_ctx *ctx, unsigned n_row, unsigned n_col)
373{
374 int i;
375 isl_mat *mat;
376
377 mat = isl_mat_alloc(ctx, n_row, n_col);
378 if (!mat)
379 return NULL((void*)0);
380 for (i = 0; i < n_row; ++i)
381 isl_seq_clr(mat->row[i], n_col);
382
383 return mat;
384}
385
386__isl_give isl_mat *isl_mat_identity(isl_ctx *ctx, unsigned n_row)
387{
388 if (!ctx)
389 return NULL((void*)0);
390 return isl_mat_diag(ctx, n_row, ctx->one);
391}
392
393/* Is "mat" a (possibly scaled) identity matrix?
394 */
395int isl_mat_is_scaled_identity(__isl_keep isl_mat *mat)
396{
397 int i;
398
399 if (!mat)
400 return -1;
401 if (mat->n_row != mat->n_col)
402 return 0;
403
404 for (i = 0; i < mat->n_row; ++i) {
405 if (isl_seq_first_non_zero(mat->row[i], i) != -1)
406 return 0;
407 if (isl_int_ne(mat->row[0][0], mat->row[i][i])(isl_sioimath_cmp(*(mat->row[0][0]), *(mat->row[i][i]))
!= 0)
)
408 return 0;
409 if (isl_seq_first_non_zero(mat->row[i] + i + 1,
410 mat->n_col - (i + 1)) != -1)
411 return 0;
412 }
413
414 return 1;
415}
416
417__isl_give isl_vec *isl_mat_vec_product(__isl_take isl_mat *mat,
418 __isl_take isl_vec *vec)
419{
420 int i;
421 struct isl_vec *prod;
422
423 if (!mat || !vec)
424 goto error;
425
426 isl_assert(mat->ctx, mat->n_col == vec->size, goto error)do { if (mat->n_col == vec->size) break; do { isl_handle_error
(mat->ctx, isl_error_unknown, "Assertion \"" "mat->n_col == vec->size"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 426); goto error; } while (0); } while (0)
;
427
428 prod = isl_vec_alloc(mat->ctx, mat->n_row);
429 if (!prod)
430 goto error;
431
432 for (i = 0; i < prod->size; ++i)
433 isl_seq_inner_product(mat->row[i], vec->el, vec->size,
434 &prod->block.data[i]);
435 isl_mat_free(mat);
436 isl_vec_free(vec);
437 return prod;
438error:
439 isl_mat_free(mat);
440 isl_vec_free(vec);
441 return NULL((void*)0);
442}
443
444__isl_give isl_vec *isl_mat_vec_inverse_product(__isl_take isl_mat *mat,
445 __isl_take isl_vec *vec)
446{
447 struct isl_mat *vec_mat;
448 int i;
449
450 if (!mat || !vec)
451 goto error;
452 vec_mat = isl_mat_alloc(vec->ctx, vec->size, 1);
453 if (!vec_mat)
454 goto error;
455 for (i = 0; i < vec->size; ++i)
456 isl_int_set(vec_mat->row[i][0], vec->el[i])isl_sioimath_set((vec_mat->row[i][0]), *(vec->el[i]));
457 vec_mat = isl_mat_inverse_product(mat, vec_mat);
458 isl_vec_free(vec);
459 if (!vec_mat)
460 return NULL((void*)0);
461 vec = isl_vec_alloc(vec_mat->ctx, vec_mat->n_row);
462 if (vec)
463 for (i = 0; i < vec->size; ++i)
464 isl_int_set(vec->el[i], vec_mat->row[i][0])isl_sioimath_set((vec->el[i]), *(vec_mat->row[i][0]));
465 isl_mat_free(vec_mat);
466 return vec;
467error:
468 isl_mat_free(mat);
469 isl_vec_free(vec);
470 return NULL((void*)0);
471}
472
473__isl_give isl_vec *isl_vec_mat_product(__isl_take isl_vec *vec,
474 __isl_take isl_mat *mat)
475{
476 int i, j;
477 struct isl_vec *prod;
478
479 if (!mat || !vec)
480 goto error;
481
482 isl_assert(mat->ctx, mat->n_row == vec->size, goto error)do { if (mat->n_row == vec->size) break; do { isl_handle_error
(mat->ctx, isl_error_unknown, "Assertion \"" "mat->n_row == vec->size"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 482); goto error; } while (0); } while (0)
;
483
484 prod = isl_vec_alloc(mat->ctx, mat->n_col);
485 if (!prod)
486 goto error;
487
488 for (i = 0; i < prod->size; ++i) {
489 isl_int_set_si(prod->el[i], 0)isl_sioimath_set_si((prod->el[i]), 0);
490 for (j = 0; j < vec->size; ++j)
491 isl_int_addmul(prod->el[i], vec->el[j], mat->row[j][i])isl_sioimath_addmul((prod->el[i]), *(vec->el[j]), *(mat
->row[j][i]))
;
492 }
493 isl_mat_free(mat);
494 isl_vec_free(vec);
495 return prod;
496error:
497 isl_mat_free(mat);
498 isl_vec_free(vec);
499 return NULL((void*)0);
500}
501
502__isl_give isl_mat *isl_mat_aff_direct_sum(__isl_take isl_mat *left,
503 __isl_take isl_mat *right)
504{
505 int i;
506 struct isl_mat *sum;
507
508 if (!left || !right)
509 goto error;
510
511 isl_assert(left->ctx, left->n_row == right->n_row, goto error)do { if (left->n_row == right->n_row) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_row == right->n_row"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 511); goto error; } while (0); } while (0)
;
512 isl_assert(left->ctx, left->n_row >= 1, goto error)do { if (left->n_row >= 1) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_row >= 1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 512); goto error; } while (0); } while (0)
;
513 isl_assert(left->ctx, left->n_col >= 1, goto error)do { if (left->n_col >= 1) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_col >= 1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 513); goto error; } while (0); } while (0)
;
514 isl_assert(left->ctx, right->n_col >= 1, goto error)do { if (right->n_col >= 1) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "right->n_col >= 1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 514); goto error; } while (0); } while (0)
;
515 isl_assert(left->ctx,do { if (isl_seq_first_non_zero(left->row[0]+1, left->n_col
-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 517); goto error; } while (0); } while (0)
516 isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1,do { if (isl_seq_first_non_zero(left->row[0]+1, left->n_col
-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 517); goto error; } while (0); } while (0)
517 goto error)do { if (isl_seq_first_non_zero(left->row[0]+1, left->n_col
-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 517); goto error; } while (0); } while (0)
;
518 isl_assert(left->ctx,do { if (isl_seq_first_non_zero(right->row[0]+1, right->
n_col-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 520); goto error; } while (0); } while (0)
519 isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1,do { if (isl_seq_first_non_zero(right->row[0]+1, right->
n_col-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 520); goto error; } while (0); } while (0)
520 goto error)do { if (isl_seq_first_non_zero(right->row[0]+1, right->
n_col-1) == -1) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 520); goto error; } while (0); } while (0)
;
521
522 sum = isl_mat_alloc(left->ctx, left->n_row, left->n_col + right->n_col - 1);
523 if (!sum)
524 goto error;
525 isl_int_lcm(sum->row[0][0], left->row[0][0], right->row[0][0])isl_sioimath_lcm((sum->row[0][0]), *(left->row[0][0]), *
(right->row[0][0]))
;
526 isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0])isl_sioimath_tdiv_q((left->row[0][0]), *(sum->row[0][0]
), *(left->row[0][0]))
;
527 isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0])isl_sioimath_tdiv_q((right->row[0][0]), *(sum->row[0][0
]), *(right->row[0][0]))
;
528
529 isl_seq_clr(sum->row[0]+1, sum->n_col-1);
530 for (i = 1; i < sum->n_row; ++i) {
531 isl_int_mul(sum->row[i][0], left->row[0][0], left->row[i][0])isl_sioimath_mul((sum->row[i][0]), *(left->row[0][0]), *
(left->row[i][0]))
;
532 isl_int_addmul(sum->row[i][0],isl_sioimath_addmul((sum->row[i][0]), *(right->row[0][0
]), *(right->row[i][0]))
533 right->row[0][0], right->row[i][0])isl_sioimath_addmul((sum->row[i][0]), *(right->row[0][0
]), *(right->row[i][0]))
;
534 isl_seq_scale(sum->row[i]+1, left->row[i]+1, left->row[0][0],
535 left->n_col-1);
536 isl_seq_scale(sum->row[i]+left->n_col,
537 right->row[i]+1, right->row[0][0],
538 right->n_col-1);
539 }
540
541 isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0])isl_sioimath_tdiv_q((left->row[0][0]), *(sum->row[0][0]
), *(left->row[0][0]))
;
542 isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0])isl_sioimath_tdiv_q((right->row[0][0]), *(sum->row[0][0
]), *(right->row[0][0]))
;
543 isl_mat_free(left);
544 isl_mat_free(right);
545 return sum;
546error:
547 isl_mat_free(left);
548 isl_mat_free(right);
549 return NULL((void*)0);
550}
551
552static void exchange(struct isl_mat *M, struct isl_mat **U,
553 struct isl_mat **Q, unsigned row, unsigned i, unsigned j)
554{
555 int r;
556 for (r = row; r < M->n_row; ++r)
557 isl_int_swap(M->row[r][i], M->row[r][j])isl_sioimath_swap((M->row[r][i]), (M->row[r][j]));
558 if (U) {
559 for (r = 0; r < (*U)->n_row; ++r)
560 isl_int_swap((*U)->row[r][i], (*U)->row[r][j])isl_sioimath_swap(((*U)->row[r][i]), ((*U)->row[r][j]));
561 }
562 if (Q)
563 isl_mat_swap_rows(*Q, i, j);
564}
565
566static void subtract(struct isl_mat *M, struct isl_mat **U,
567 struct isl_mat **Q, unsigned row, unsigned i, unsigned j, isl_int m)
568{
569 int r;
570 for (r = row; r < M->n_row; ++r)
571 isl_int_submul(M->row[r][j], m, M->row[r][i])isl_sioimath_submul((M->row[r][j]), *(m), *(M->row[r][i
]))
;
572 if (U) {
573 for (r = 0; r < (*U)->n_row; ++r)
574 isl_int_submul((*U)->row[r][j], m, (*U)->row[r][i])isl_sioimath_submul(((*U)->row[r][j]), *(m), *((*U)->row
[r][i]))
;
575 }
576 if (Q) {
577 for (r = 0; r < (*Q)->n_col; ++r)
578 isl_int_addmul((*Q)->row[i][r], m, (*Q)->row[j][r])isl_sioimath_addmul(((*Q)->row[i][r]), *(m), *((*Q)->row
[j][r]))
;
579 }
580}
581
582static void oppose(struct isl_mat *M, struct isl_mat **U,
583 struct isl_mat **Q, unsigned row, unsigned col)
584{
585 int r;
586 for (r = row; r < M->n_row; ++r)
587 isl_int_neg(M->row[r][col], M->row[r][col])isl_sioimath_neg((M->row[r][col]), *(M->row[r][col]));
588 if (U) {
589 for (r = 0; r < (*U)->n_row; ++r)
590 isl_int_neg((*U)->row[r][col], (*U)->row[r][col])isl_sioimath_neg(((*U)->row[r][col]), *((*U)->row[r][col
]))
;
591 }
592 if (Q)
593 isl_seq_neg((*Q)->row[col], (*Q)->row[col], (*Q)->n_col);
594}
595
596/* Given matrix M, compute
597 *
598 * M U = H
599 * M = H Q
600 *
601 * with U and Q unimodular matrices and H a matrix in column echelon form
602 * such that on each echelon row the entries in the non-echelon column
603 * are non-negative (if neg == 0) or non-positive (if neg == 1)
604 * and strictly smaller (in absolute value) than the entries in the echelon
605 * column.
606 * If U or Q are NULL, then these matrices are not computed.
607 */
608__isl_give isl_mat *isl_mat_left_hermite(__isl_take isl_mat *M, int neg,
609 __isl_give isl_mat **U, __isl_give isl_mat **Q)
610{
611 isl_int c;
612 int row, col;
613
614 if (U)
615 *U = NULL((void*)0);
616 if (Q)
617 *Q = NULL((void*)0);
618 if (!M)
619 goto error;
620 M = isl_mat_cow(M);
621 if (!M)
622 goto error;
623 if (U) {
624 *U = isl_mat_identity(M->ctx, M->n_col);
625 if (!*U)
626 goto error;
627 }
628 if (Q) {
629 *Q = isl_mat_identity(M->ctx, M->n_col);
630 if (!*Q)
631 goto error;
632 }
633
634 col = 0;
635 isl_int_init(c)isl_sioimath_init((c));
636 for (row = 0; row < M->n_row; ++row) {
637 int first, i, off;
638 first = isl_seq_abs_min_non_zero(M->row[row]+col, M->n_col-col);
639 if (first == -1)
640 continue;
641 first += col;
642 if (first != col)
643 exchange(M, U, Q, row, first, col);
644 if (isl_int_is_neg(M->row[row][col])(isl_sioimath_sgn(*(M->row[row][col])) < 0))
645 oppose(M, U, Q, row, col);
646 first = col+1;
647 while ((off = isl_seq_first_non_zero(M->row[row]+first,
648 M->n_col-first)) != -1) {
649 first += off;
650 isl_int_fdiv_q(c, M->row[row][first], M->row[row][col])isl_sioimath_fdiv_q((c), *(M->row[row][first]), *(M->row
[row][col]))
;
651 subtract(M, U, Q, row, col, first, c);
652 if (!isl_int_is_zero(M->row[row][first])(isl_sioimath_sgn(*(M->row[row][first])) == 0))
653 exchange(M, U, Q, row, first, col);
654 else
655 ++first;
656 }
657 for (i = 0; i < col; ++i) {
658 if (isl_int_is_zero(M->row[row][i])(isl_sioimath_sgn(*(M->row[row][i])) == 0))
659 continue;
660 if (neg)
661 isl_int_cdiv_q(c, M->row[row][i], M->row[row][col])isl_sioimath_cdiv_q((c), *(M->row[row][i]), *(M->row[row
][col]))
;
662 else
663 isl_int_fdiv_q(c, M->row[row][i], M->row[row][col])isl_sioimath_fdiv_q((c), *(M->row[row][i]), *(M->row[row
][col]))
;
664 if (isl_int_is_zero(c)(isl_sioimath_sgn(*(c)) == 0))
665 continue;
666 subtract(M, U, Q, row, col, i, c);
667 }
668 ++col;
669 }
670 isl_int_clear(c)isl_sioimath_clear((c));
671
672 return M;
673error:
674 if (Q) {
675 isl_mat_free(*Q);
676 *Q = NULL((void*)0);
677 }
678 if (U) {
679 isl_mat_free(*U);
680 *U = NULL((void*)0);
681 }
682 isl_mat_free(M);
683 return NULL((void*)0);
684}
685
686/* Use row "row" of "mat" to eliminate column "col" from all other rows.
687 */
688static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col)
689{
690 int k, nr, nc;
691 isl_ctx *ctx;
692
693 if (!mat)
694 return NULL((void*)0);
695
696 ctx = isl_mat_get_ctx(mat);
697 nr = isl_mat_rows(mat);
698 nc = isl_mat_cols(mat);
699
700 for (k = 0; k < nr; ++k) {
701 if (k == row)
702 continue;
703 if (isl_int_is_zero(mat->row[k][col])(isl_sioimath_sgn(*(mat->row[k][col])) == 0))
704 continue;
705 mat = isl_mat_cow(mat);
706 if (!mat)
707 return NULL((void*)0);
708 isl_seq_elim(mat->row[k], mat->row[row], col, nc, NULL((void*)0));
709 isl_seq_normalize(ctx, mat->row[k], nc);
710 }
711
712 return mat;
713}
714
715/* Perform Gaussian elimination on the rows of "mat", but start
716 * from the final row and the final column.
717 * Any zero rows that result from the elimination are removed.
718 *
719 * In particular, for each column from last to first,
720 * look for the last row with a non-zero coefficient in that column,
721 * move it last (but before other rows moved last in previous steps) and
722 * use it to eliminate the column from the other rows.
723 */
724__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat)
725{
726 int k, row, last, nr, nc;
727
728 if (!mat)
729 return NULL((void*)0);
730
731 nr = isl_mat_rows(mat);
732 nc = isl_mat_cols(mat);
733
734 last = nc - 1;
735 for (row = nr - 1; row >= 0; --row) {
736 for (; last >= 0; --last) {
737 for (k = row; k >= 0; --k)
738 if (!isl_int_is_zero(mat->row[k][last])(isl_sioimath_sgn(*(mat->row[k][last])) == 0))
739 break;
740 if (k >= 0)
741 break;
742 }
743 if (last < 0)
744 break;
745 if (k != row)
746 mat = isl_mat_swap_rows(mat, k, row);
747 if (!mat)
748 return NULL((void*)0);
749 if (isl_int_is_neg(mat->row[row][last])(isl_sioimath_sgn(*(mat->row[row][last])) < 0))
750 mat = isl_mat_row_neg(mat, row);
751 mat = eliminate(mat, row, last);
752 if (!mat)
753 return NULL((void*)0);
754 }
755 mat = isl_mat_drop_rows(mat, 0, row + 1);
756
757 return mat;
758}
759
760/* Negate the lexicographically negative rows of "mat" such that
761 * all rows in the result are lexicographically non-negative.
762 */
763__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat)
764{
765 int i, nr, nc;
766
767 if (!mat)
768 return NULL((void*)0);
769
770 nr = isl_mat_rows(mat);
771 nc = isl_mat_cols(mat);
772
773 for (i = 0; i < nr; ++i) {
774 int pos;
775
776 pos = isl_seq_first_non_zero(mat->row[i], nc);
777 if (pos < 0)
778 continue;
779 if (isl_int_is_nonneg(mat->row[i][pos])(isl_sioimath_sgn(*(mat->row[i][pos])) >= 0))
780 continue;
781 mat = isl_mat_row_neg(mat, i);
782 if (!mat)
783 return NULL((void*)0);
784 }
785
786 return mat;
787}
788
789struct isl_mat *isl_mat_right_kernel(struct isl_mat *mat)
790{
791 int i, rank;
792 struct isl_mat *U = NULL((void*)0);
793 struct isl_mat *K;
794
795 mat = isl_mat_left_hermite(mat, 0, &U, NULL((void*)0));
796 if (!mat || !U)
797 goto error;
798
799 for (i = 0, rank = 0; rank < mat->n_col; ++rank) {
800 while (i < mat->n_row && isl_int_is_zero(mat->row[i][rank])(isl_sioimath_sgn(*(mat->row[i][rank])) == 0))
801 ++i;
802 if (i >= mat->n_row)
803 break;
804 }
805 K = isl_mat_alloc(U->ctx, U->n_row, U->n_col - rank);
806 if (!K)
807 goto error;
808 isl_mat_sub_copy(K->ctx, K->row, U->row, U->n_row, 0, rank, U->n_col-rank);
809 isl_mat_free(mat);
810 isl_mat_free(U);
811 return K;
812error:
813 isl_mat_free(mat);
814 isl_mat_free(U);
815 return NULL((void*)0);
816}
817
818__isl_give isl_mat *isl_mat_lin_to_aff(__isl_take isl_mat *mat)
819{
820 int i;
821 struct isl_mat *mat2;
822
823 if (!mat)
824 return NULL((void*)0);
825 mat2 = isl_mat_alloc(mat->ctx, 1+mat->n_row, 1+mat->n_col);
826 if (!mat2)
827 goto error;
828 isl_int_set_si(mat2->row[0][0], 1)isl_sioimath_set_si((mat2->row[0][0]), 1);
829 isl_seq_clr(mat2->row[0]+1, mat->n_col);
830 for (i = 0; i < mat->n_row; ++i) {
831 isl_int_set_si(mat2->row[1+i][0], 0)isl_sioimath_set_si((mat2->row[1+i][0]), 0);
832 isl_seq_cpy(mat2->row[1+i]+1, mat->row[i], mat->n_col);
833 }
834 isl_mat_free(mat);
835 return mat2;
836error:
837 isl_mat_free(mat);
838 return NULL((void*)0);
839}
840
841/* Given two matrices M1 and M2, return the block matrix
842 *
843 * [ M1 0 ]
844 * [ 0 M2 ]
845 */
846__isl_give isl_mat *isl_mat_diagonal(__isl_take isl_mat *mat1,
847 __isl_take isl_mat *mat2)
848{
849 int i;
850 isl_mat *mat;
851
852 if (!mat1 || !mat2)
853 goto error;
854
855 mat = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row,
856 mat1->n_col + mat2->n_col);
857 if (!mat)
858 goto error;
859 for (i = 0; i < mat1->n_row; ++i) {
860 isl_seq_cpy(mat->row[i], mat1->row[i], mat1->n_col);
861 isl_seq_clr(mat->row[i] + mat1->n_col, mat2->n_col);
862 }
863 for (i = 0; i < mat2->n_row; ++i) {
864 isl_seq_clr(mat->row[mat1->n_row + i], mat1->n_col);
865 isl_seq_cpy(mat->row[mat1->n_row + i] + mat1->n_col,
866 mat2->row[i], mat2->n_col);
867 }
868 isl_mat_free(mat1);
869 isl_mat_free(mat2);
870 return mat;
871error:
872 isl_mat_free(mat1);
873 isl_mat_free(mat2);
874 return NULL((void*)0);
875}
876
877static int row_first_non_zero(isl_int **row, unsigned n_row, unsigned col)
878{
879 int i;
880
881 for (i = 0; i < n_row; ++i)
882 if (!isl_int_is_zero(row[i][col])(isl_sioimath_sgn(*(row[i][col])) == 0))
883 return i;
884 return -1;
885}
886
887static int row_abs_min_non_zero(isl_int **row, unsigned n_row, unsigned col)
888{
889 int i, min = row_first_non_zero(row, n_row, col);
890 if (min < 0)
891 return -1;
892 for (i = min + 1; i < n_row; ++i) {
893 if (isl_int_is_zero(row[i][col])(isl_sioimath_sgn(*(row[i][col])) == 0))
894 continue;
895 if (isl_int_abs_lt(row[i][col], row[min][col])(isl_sioimath_abs_cmp(*(row[i][col]), *(row[min][col])) < 0
)
)
896 min = i;
897 }
898 return min;
899}
900
901static isl_stat inv_exchange(__isl_keep isl_mat **left,
902 __isl_keep isl_mat **right, unsigned i, unsigned j)
903{
904 *left = isl_mat_swap_rows(*left, i, j);
905 *right = isl_mat_swap_rows(*right, i, j);
906
907 if (!*left || !*right)
908 return isl_stat_error;
909 return isl_stat_ok;
910}
911
912static void inv_oppose(
913 struct isl_mat *left, struct isl_mat *right, unsigned row)
914{
915 isl_seq_neg(left->row[row]+row, left->row[row]+row, left->n_col-row);
916 isl_seq_neg(right->row[row], right->row[row], right->n_col);
917}
918
919static void inv_subtract(struct isl_mat *left, struct isl_mat *right,
920 unsigned row, unsigned i, isl_int m)
921{
922 isl_int_neg(m, m)isl_sioimath_neg((m), *(m));
923 isl_seq_combine(left->row[i]+row,
924 left->ctx->one, left->row[i]+row,
925 m, left->row[row]+row,
926 left->n_col-row);
927 isl_seq_combine(right->row[i], right->ctx->one, right->row[i],
928 m, right->row[row], right->n_col);
929}
930
931/* Compute inv(left)*right
932 */
933__isl_give isl_mat *isl_mat_inverse_product(__isl_take isl_mat *left,
934 __isl_take isl_mat *right)
935{
936 int row;
937 isl_int a, b;
938
939 if (!left || !right)
940 goto error;
941
942 isl_assert(left->ctx, left->n_row == left->n_col, goto error)do { if (left->n_row == left->n_col) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_row == left->n_col"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 942); goto error; } while (0); } while (0)
;
943 isl_assert(left->ctx, left->n_row == right->n_row, goto error)do { if (left->n_row == right->n_row) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_row == right->n_row"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 943); goto error; } while (0); } while (0)
;
944
945 if (left->n_row == 0) {
946 isl_mat_free(left);
947 return right;
948 }
949
950 left = isl_mat_cow(left);
951 right = isl_mat_cow(right);
952 if (!left || !right)
953 goto error;
954
955 isl_int_init(a)isl_sioimath_init((a));
956 isl_int_init(b)isl_sioimath_init((b));
957 for (row = 0; row < left->n_row; ++row) {
958 int pivot, first, i, off;
959 pivot = row_abs_min_non_zero(left->row+row, left->n_row-row, row);
960 if (pivot < 0) {
961 isl_int_clear(a)isl_sioimath_clear((a));
962 isl_int_clear(b)isl_sioimath_clear((b));
963 isl_assert(left->ctx, pivot >= 0, goto error)do { if (pivot >= 0) break; do { isl_handle_error(left->
ctx, isl_error_unknown, "Assertion \"" "pivot >= 0" "\" failed"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 963); goto error; } while (0); } while (0)
;
964 }
965 pivot += row;
966 if (pivot != row)
967 if (inv_exchange(&left, &right, pivot, row) < 0)
968 goto error;
969 if (isl_int_is_neg(left->row[row][row])(isl_sioimath_sgn(*(left->row[row][row])) < 0))
970 inv_oppose(left, right, row);
971 first = row+1;
972 while ((off = row_first_non_zero(left->row+first,
973 left->n_row-first, row)) != -1) {
974 first += off;
975 isl_int_fdiv_q(a, left->row[first][row],isl_sioimath_fdiv_q((a), *(left->row[first][row]), *(left->
row[row][row]))
976 left->row[row][row])isl_sioimath_fdiv_q((a), *(left->row[first][row]), *(left->
row[row][row]))
;
977 inv_subtract(left, right, row, first, a);
978 if (!isl_int_is_zero(left->row[first][row])(isl_sioimath_sgn(*(left->row[first][row])) == 0)) {
979 if (inv_exchange(&left, &right, row, first) < 0)
980 goto error;
981 } else {
982 ++first;
983 }
984 }
985 for (i = 0; i < row; ++i) {
986 if (isl_int_is_zero(left->row[i][row])(isl_sioimath_sgn(*(left->row[i][row])) == 0))
987 continue;
988 isl_int_gcd(a, left->row[row][row], left->row[i][row])isl_sioimath_gcd((a), *(left->row[row][row]), *(left->row
[i][row]))
;
989 isl_int_divexact(b, left->row[i][row], a)isl_sioimath_tdiv_q((b), *(left->row[i][row]), *(a));
990 isl_int_divexact(a, left->row[row][row], a)isl_sioimath_tdiv_q((a), *(left->row[row][row]), *(a));
991 isl_int_neg(b, b)isl_sioimath_neg((b), *(b));
992 isl_seq_combine(left->row[i] + i,
993 a, left->row[i] + i,
994 b, left->row[row] + i,
995 left->n_col - i);
996 isl_seq_combine(right->row[i], a, right->row[i],
997 b, right->row[row], right->n_col);
998 }
999 }
1000 isl_int_clear(b)isl_sioimath_clear((b));
1001
1002 isl_int_set(a, left->row[0][0])isl_sioimath_set((a), *(left->row[0][0]));
1003 for (row = 1; row < left->n_row; ++row)
1004 isl_int_lcm(a, a, left->row[row][row])isl_sioimath_lcm((a), *(a), *(left->row[row][row]));
1005 if (isl_int_is_zero(a)(isl_sioimath_sgn(*(a)) == 0)){
1006 isl_int_clear(a)isl_sioimath_clear((a));
1007 isl_assert(left->ctx, 0, goto error)do { if (0) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "0" "\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1007); goto error; } while (0); } while (0)
;
1008 }
1009 for (row = 0; row < left->n_row; ++row) {
1010 isl_int_divexact(left->row[row][row], a, left->row[row][row])isl_sioimath_tdiv_q((left->row[row][row]), *(a), *(left->
row[row][row]))
;
1011 if (isl_int_is_one(left->row[row][row])(isl_sioimath_cmp_si(*(left->row[row][row]), 1) == 0))
1012 continue;
1013 isl_seq_scale(right->row[row], right->row[row],
1014 left->row[row][row], right->n_col);
1015 }
1016 isl_int_clear(a)isl_sioimath_clear((a));
1017
1018 isl_mat_free(left);
1019 return right;
1020error:
1021 isl_mat_free(left);
1022 isl_mat_free(right);
1023 return NULL((void*)0);
1024}
1025
1026void isl_mat_col_scale(struct isl_mat *mat, unsigned col, isl_int m)
1027{
1028 int i;
1029
1030 for (i = 0; i < mat->n_row; ++i)
1031 isl_int_mul(mat->row[i][col], mat->row[i][col], m)isl_sioimath_mul((mat->row[i][col]), *(mat->row[i][col]
), *(m))
;
1032}
1033
1034void isl_mat_col_combine(struct isl_mat *mat, unsigned dst,
1035 isl_int m1, unsigned src1, isl_int m2, unsigned src2)
1036{
1037 int i;
1038 isl_int tmp;
1039
1040 isl_int_init(tmp)isl_sioimath_init((tmp));
1041 for (i = 0; i < mat->n_row; ++i) {
1042 isl_int_mul(tmp, m1, mat->row[i][src1])isl_sioimath_mul((tmp), *(m1), *(mat->row[i][src1]));
1043 isl_int_addmul(tmp, m2, mat->row[i][src2])isl_sioimath_addmul((tmp), *(m2), *(mat->row[i][src2]));
1044 isl_int_set(mat->row[i][dst], tmp)isl_sioimath_set((mat->row[i][dst]), *(tmp));
1045 }
1046 isl_int_clear(tmp)isl_sioimath_clear((tmp));
1047}
1048
1049__isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat)
1050{
1051 struct isl_mat *inv;
1052 int row;
1053 isl_int a, b;
1054
1055 mat = isl_mat_cow(mat);
1056 if (!mat)
1057 return NULL((void*)0);
1058
1059 inv = isl_mat_identity(mat->ctx, mat->n_col);
1060 inv = isl_mat_cow(inv);
1061 if (!inv)
1062 goto error;
1063
1064 isl_int_init(a)isl_sioimath_init((a));
1065 isl_int_init(b)isl_sioimath_init((b));
1066 for (row = 0; row < mat->n_row; ++row) {
1067 int pivot, first, i, off;
1068 pivot = isl_seq_abs_min_non_zero(mat->row[row]+row, mat->n_col-row);
1069 if (pivot < 0) {
1070 isl_int_clear(a)isl_sioimath_clear((a));
1071 isl_int_clear(b)isl_sioimath_clear((b));
1072 isl_assert(mat->ctx, pivot >= 0, goto error)do { if (pivot >= 0) break; do { isl_handle_error(mat->
ctx, isl_error_unknown, "Assertion \"" "pivot >= 0" "\" failed"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1072); goto error; } while (0); } while (0)
;
1073 }
1074 pivot += row;
1075 if (pivot != row)
1076 exchange(mat, &inv, NULL((void*)0), row, pivot, row);
1077 if (isl_int_is_neg(mat->row[row][row])(isl_sioimath_sgn(*(mat->row[row][row])) < 0))
1078 oppose(mat, &inv, NULL((void*)0), row, row);
1079 first = row+1;
1080 while ((off = isl_seq_first_non_zero(mat->row[row]+first,
1081 mat->n_col-first)) != -1) {
1082 first += off;
1083 isl_int_fdiv_q(a, mat->row[row][first],isl_sioimath_fdiv_q((a), *(mat->row[row][first]), *(mat->
row[row][row]))
1084 mat->row[row][row])isl_sioimath_fdiv_q((a), *(mat->row[row][first]), *(mat->
row[row][row]))
;
1085 subtract(mat, &inv, NULL((void*)0), row, row, first, a);
1086 if (!isl_int_is_zero(mat->row[row][first])(isl_sioimath_sgn(*(mat->row[row][first])) == 0))
1087 exchange(mat, &inv, NULL((void*)0), row, row, first);
1088 else
1089 ++first;
1090 }
1091 for (i = 0; i < row; ++i) {
1092 if (isl_int_is_zero(mat->row[row][i])(isl_sioimath_sgn(*(mat->row[row][i])) == 0))
1093 continue;
1094 isl_int_gcd(a, mat->row[row][row], mat->row[row][i])isl_sioimath_gcd((a), *(mat->row[row][row]), *(mat->row
[row][i]))
;
1095 isl_int_divexact(b, mat->row[row][i], a)isl_sioimath_tdiv_q((b), *(mat->row[row][i]), *(a));
1096 isl_int_divexact(a, mat->row[row][row], a)isl_sioimath_tdiv_q((a), *(mat->row[row][row]), *(a));
1097 isl_int_neg(a, a)isl_sioimath_neg((a), *(a));
1098 isl_mat_col_combine(mat, i, a, i, b, row);
1099 isl_mat_col_combine(inv, i, a, i, b, row);
1100 }
1101 }
1102 isl_int_clear(b)isl_sioimath_clear((b));
1103
1104 isl_int_set(a, mat->row[0][0])isl_sioimath_set((a), *(mat->row[0][0]));
1105 for (row = 1; row < mat->n_row; ++row)
1106 isl_int_lcm(a, a, mat->row[row][row])isl_sioimath_lcm((a), *(a), *(mat->row[row][row]));
1107 if (isl_int_is_zero(a)(isl_sioimath_sgn(*(a)) == 0)){
1108 isl_int_clear(a)isl_sioimath_clear((a));
1109 goto error;
1110 }
1111 for (row = 0; row < mat->n_row; ++row) {
1112 isl_int_divexact(mat->row[row][row], a, mat->row[row][row])isl_sioimath_tdiv_q((mat->row[row][row]), *(a), *(mat->
row[row][row]))
;
1113 if (isl_int_is_one(mat->row[row][row])(isl_sioimath_cmp_si(*(mat->row[row][row]), 1) == 0))
1114 continue;
1115 isl_mat_col_scale(inv, row, mat->row[row][row]);
1116 }
1117 isl_int_clear(a)isl_sioimath_clear((a));
1118
1119 isl_mat_free(mat);
1120
1121 return inv;
1122error:
1123 isl_mat_free(mat);
1124 isl_mat_free(inv);
1125 return NULL((void*)0);
1126}
1127
1128__isl_give isl_mat *isl_mat_transpose(__isl_take isl_mat *mat)
1129{
1130 struct isl_mat *transpose = NULL((void*)0);
1131 int i, j;
1132
1133 if (!mat)
1134 return NULL((void*)0);
1135
1136 if (mat->n_col == mat->n_row) {
1137 mat = isl_mat_cow(mat);
1138 if (!mat)
1139 return NULL((void*)0);
1140 for (i = 0; i < mat->n_row; ++i)
1141 for (j = i + 1; j < mat->n_col; ++j)
1142 isl_int_swap(mat->row[i][j], mat->row[j][i])isl_sioimath_swap((mat->row[i][j]), (mat->row[j][i]));
1143 return mat;
1144 }
1145 transpose = isl_mat_alloc(mat->ctx, mat->n_col, mat->n_row);
1146 if (!transpose)
1147 goto error;
1148 for (i = 0; i < mat->n_row; ++i)
1149 for (j = 0; j < mat->n_col; ++j)
1150 isl_int_set(transpose->row[j][i], mat->row[i][j])isl_sioimath_set((transpose->row[j][i]), *(mat->row[i][
j]))
;
1151 isl_mat_free(mat);
1152 return transpose;
1153error:
1154 isl_mat_free(mat);
1155 return NULL((void*)0);
1156}
1157
1158__isl_give isl_mat *isl_mat_swap_cols(__isl_take isl_mat *mat,
1159 unsigned i, unsigned j)
1160{
1161 int r;
1162
1163 mat = isl_mat_cow(mat);
1164 if (!mat)
1165 return NULL((void*)0);
1166 isl_assert(mat->ctx, i < mat->n_col, goto error)do { if (i < mat->n_col) break; do { isl_handle_error(mat
->ctx, isl_error_unknown, "Assertion \"" "i < mat->n_col"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1166); goto error; } while (0); } while (0)
;
1167 isl_assert(mat->ctx, j < mat->n_col, goto error)do { if (j < mat->n_col) break; do { isl_handle_error(mat
->ctx, isl_error_unknown, "Assertion \"" "j < mat->n_col"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1167); goto error; } while (0); } while (0)
;
1168
1169 for (r = 0; r < mat->n_row; ++r)
1170 isl_int_swap(mat->row[r][i], mat->row[r][j])isl_sioimath_swap((mat->row[r][i]), (mat->row[r][j]));
1171 return mat;
1172error:
1173 isl_mat_free(mat);
1174 return NULL((void*)0);
1175}
1176
1177__isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat,
1178 unsigned i, unsigned j)
1179{
1180 isl_int *t;
1181
1182 if (!mat)
1183 return NULL((void*)0);
1184 mat = isl_mat_cow(mat);
1185 if (!mat)
1186 return NULL((void*)0);
1187 t = mat->row[i];
1188 mat->row[i] = mat->row[j];
1189 mat->row[j] = t;
1190 return mat;
1191}
1192
1193/* Calculate the product of two matrices.
1194 *
1195 * This function is optimized for operand matrices that contain many zeros and
1196 * skips multiplications where we know one of the operands is zero.
1197 */
1198__isl_give isl_mat *isl_mat_product(__isl_take isl_mat *left,
1199 __isl_take isl_mat *right)
1200{
1201 int i, j, k;
1202 struct isl_mat *prod;
1203
1204 if (!left || !right)
1205 goto error;
1206 isl_assert(left->ctx, left->n_col == right->n_row, goto error)do { if (left->n_col == right->n_row) break; do { isl_handle_error
(left->ctx, isl_error_unknown, "Assertion \"" "left->n_col == right->n_row"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1206); goto error; } while (0); } while (0)
;
1207 prod = isl_mat_alloc(left->ctx, left->n_row, right->n_col);
1208 if (!prod)
1209 goto error;
1210 if (left->n_col == 0) {
1211 for (i = 0; i < prod->n_row; ++i)
1212 isl_seq_clr(prod->row[i], prod->n_col);
1213 isl_mat_free(left);
1214 isl_mat_free(right);
1215 return prod;
1216 }
1217 for (i = 0; i < prod->n_row; ++i) {
1218 for (j = 0; j < prod->n_col; ++j)
1219 isl_int_mul(prod->row[i][j],isl_sioimath_mul((prod->row[i][j]), *(left->row[i][0]),
*(right->row[0][j]))
1220 left->row[i][0], right->row[0][j])isl_sioimath_mul((prod->row[i][j]), *(left->row[i][0]),
*(right->row[0][j]))
;
1221 for (k = 1; k < left->n_col; ++k) {
1222 if (isl_int_is_zero(left->row[i][k])(isl_sioimath_sgn(*(left->row[i][k])) == 0))
1223 continue;
1224 for (j = 0; j < prod->n_col; ++j)
1225 isl_int_addmul(prod->row[i][j],isl_sioimath_addmul((prod->row[i][j]), *(left->row[i][k
]), *(right->row[k][j]))
1226 left->row[i][k], right->row[k][j])isl_sioimath_addmul((prod->row[i][j]), *(left->row[i][k
]), *(right->row[k][j]))
;
1227 }
1228 }
1229 isl_mat_free(left);
1230 isl_mat_free(right);
1231 return prod;
1232error:
1233 isl_mat_free(left);
1234 isl_mat_free(right);
1235 return NULL((void*)0);
1236}
1237
1238/* Replace the variables x in the rows q by x' given by x = M x',
1239 * with M the matrix mat.
1240 *
1241 * If the number of new variables is greater than the original
1242 * number of variables, then the rows q have already been
1243 * preextended. If the new number is smaller, then the coefficients
1244 * of the divs, which are not changed, need to be shifted down.
1245 * The row q may be the equalities, the inequalities or the
1246 * div expressions. In the latter case, has_div is true and
1247 * we need to take into account the extra denominator column.
1248 */
1249static int preimage(struct isl_ctx *ctx, isl_int **q, unsigned n,
1250 unsigned n_div, int has_div, struct isl_mat *mat)
1251{
1252 int i;
1253 struct isl_mat *t;
1254 int e;
1255
1256 if (mat->n_col >= mat->n_row)
1257 e = 0;
1258 else
1259 e = mat->n_row - mat->n_col;
1260 if (has_div)
1261 for (i = 0; i < n; ++i)
1262 isl_int_mul(q[i][0], q[i][0], mat->row[0][0])isl_sioimath_mul((q[i][0]), *(q[i][0]), *(mat->row[0][0]));
1263 t = isl_mat_sub_alloc6(mat->ctx, q, 0, n, has_div, mat->n_row);
1264 t = isl_mat_product(t, mat);
1265 if (!t)
1266 return -1;
1267 for (i = 0; i < n; ++i) {
1268 isl_seq_swp_or_cpy(q[i] + has_div, t->row[i], t->n_col);
1269 isl_seq_cpy(q[i] + has_div + t->n_col,
1270 q[i] + has_div + t->n_col + e, n_div);
1271 isl_seq_clr(q[i] + has_div + t->n_col + n_div, e);
1272 }
1273 isl_mat_free(t);
1274 return 0;
1275}
1276
1277/* Replace the variables x in bset by x' given by x = M x', with
1278 * M the matrix mat.
1279 *
1280 * If there are fewer variables x' then there are x, then we perform
1281 * the transformation in place, which means that, in principle,
1282 * this frees up some extra variables as the number
1283 * of columns remains constant, but we would have to extend
1284 * the div array too as the number of rows in this array is assumed
1285 * to be equal to extra.
1286 */
1287__isl_give isl_basic_setisl_basic_map *isl_basic_set_preimage(
1288 __isl_take isl_basic_setisl_basic_map *bset, __isl_take isl_mat *mat)
1289{
1290 struct isl_ctx *ctx;
1291
1292 if (!bset || !mat)
10
Assuming 'bset' is non-null
11
Taking false branch
1293 goto error;
1294
1295 ctx = bset->ctx;
1296 bset = isl_basic_set_cow(bset);
1297 if (!bset)
12
Assuming 'bset' is non-null
13
Taking false branch
1298 goto error;
1299
1300 isl_assert(ctx, bset->dim->nparam == 0, goto error)do { if (bset->dim->nparam == 0) break; do { isl_handle_error
(ctx, isl_error_unknown, "Assertion \"" "bset->dim->nparam == 0"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1300); goto error; } while (0); } while (0)
;
1301 isl_assert(ctx, 1+bset->dim->n_out == mat->n_row, goto error)do { if (1+bset->dim->n_out == mat->n_row) break; do
{ isl_handle_error(ctx, isl_error_unknown, "Assertion \"" "1+bset->dim->n_out == mat->n_row"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1301); goto error; } while (0); } while (0)
;
1302 isl_assert(ctx, mat->n_col > 0, goto error)do { if (mat->n_col > 0) break; do { isl_handle_error(ctx
, isl_error_unknown, "Assertion \"" "mat->n_col > 0" "\" failed"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1302); goto error; } while (0); } while (0)
;
1303
1304 if (mat->n_col > mat->n_row) {
1305 bset = isl_basic_set_extend(bset, 0, mat->n_col-1, 0, 0, 0);
1306 if (!bset)
1307 goto error;
1308 } else if (mat->n_col < mat->n_row) {
1309 bset->dim = isl_space_cow(bset->dim);
1310 if (!bset->dim)
1311 goto error;
1312 bset->dim->n_out -= mat->n_row - mat->n_col;
1313 }
1314
1315 if (preimage(ctx, bset->eq, bset->n_eq, bset->n_div, 0,
1316 isl_mat_copy(mat)) < 0)
1317 goto error;
1318
1319 if (preimage(ctx, bset->ineq, bset->n_ineq, bset->n_div, 0,
1320 isl_mat_copy(mat)) < 0)
1321 goto error;
1322
1323 if (preimage(ctx, bset->div, bset->n_div, bset->n_div, 1, mat) < 0)
1324 goto error2;
1325
1326 ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT)(((bset)->flags) &= ~((1 << 2)));
1327 ISL_F_CLR(bset, ISL_BASIC_SET_NO_REDUNDANT)(((bset)->flags) &= ~((1 << 3)));
1328 ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED)(((bset)->flags) &= ~((1 << 5)));
1329 ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED_DIVS)(((bset)->flags) &= ~((1 << 6)));
1330 ISL_F_CLR(bset, ISL_BASIC_SET_ALL_EQUALITIES)(((bset)->flags) &= ~((1 << 7)));
1331
1332 bset = isl_basic_set_simplify(bset);
1333 bset = isl_basic_set_finalize(bset);
1334
1335 return bset;
1336error:
1337 isl_mat_free(mat);
14
Calling 'isl_mat_free'
20
Returning; memory was released via 1st parameter
1338error2:
1339 isl_basic_set_free(bset);
1340 return NULL((void*)0);
1341}
1342
1343__isl_give isl_setisl_map *isl_set_preimage(
1344 __isl_take isl_setisl_map *set, __isl_take isl_mat *mat)
1345{
1346 int i;
1347
1348 set = isl_set_cow(set);
1349 if (!set)
1
Assuming 'set' is non-null
2
Taking false branch
1350 goto error;
1351
1352 for (i = 0; i < set->n; ++i) {
3
Assuming the condition is true
4
Loop condition is true. Entering loop body
1353 set->p[i] = isl_basic_set_preimage(set->p[i],
9
Calling 'isl_basic_set_preimage'
21
Returning; memory was released via 2nd parameter
1354 isl_mat_copy(mat));
5
Calling 'isl_mat_copy'
8
Returning from 'isl_mat_copy'
1355 if (!set->p[i])
22
Taking true branch
1356 goto error;
23
Control jumps to line 1369
1357 }
1358 if (mat->n_col != mat->n_row) {
1359 set->dim = isl_space_cow(set->dim);
1360 if (!set->dim)
1361 goto error;
1362 set->dim->n_out += mat->n_col;
1363 set->dim->n_out -= mat->n_row;
1364 }
1365 isl_mat_free(mat);
1366 ISL_F_CLR(set, ISL_SET_NORMALIZED)(((set)->flags) &= ~((1 << 1)));
1367 return set;
1368error:
1369 isl_set_free(set);
1370 isl_mat_free(mat);
24
Use of memory after it is freed
1371 return NULL((void*)0);
1372}
1373
1374/* Replace the variables x starting at "first_col" in the rows "rows"
1375 * of some coefficient matrix by x' with x = M x' with M the matrix mat.
1376 * That is, replace the corresponding coefficients c by c M.
1377 */
1378isl_stat isl_mat_sub_transform(isl_int **row, unsigned n_row,
1379 unsigned first_col, __isl_take isl_mat *mat)
1380{
1381 int i;
1382 isl_ctx *ctx;
1383 isl_mat *t;
1384
1385 if (!mat)
1386 return isl_stat_error;
1387 ctx = isl_mat_get_ctx(mat);
1388 t = isl_mat_sub_alloc6(ctx, row, 0, n_row, first_col, mat->n_row);
1389 t = isl_mat_product(t, mat);
1390 if (!t)
1391 return isl_stat_error;
1392 for (i = 0; i < n_row; ++i)
1393 isl_seq_swp_or_cpy(row[i] + first_col, t->row[i], t->n_col);
1394 isl_mat_free(t);
1395 return isl_stat_ok;
1396}
1397
1398void isl_mat_print_internal(__isl_keep isl_mat *mat, FILE *out, int indent)
1399{
1400 int i, j;
1401
1402 if (!mat) {
1403 fprintf(out, "%*snull mat\n", indent, "");
1404 return;
1405 }
1406
1407 if (mat->n_row == 0)
1408 fprintf(out, "%*s[]\n", indent, "");
1409
1410 for (i = 0; i < mat->n_row; ++i) {
1411 if (!i)
1412 fprintf(out, "%*s[[", indent, "");
1413 else
1414 fprintf(out, "%*s[", indent+1, "");
1415 for (j = 0; j < mat->n_col; ++j) {
1416 if (j)
1417 fprintf(out, ",");
1418 isl_int_print(out, mat->row[i][j], 0)isl_sioimath_print(out, *(mat->row[i][j]), 0);
1419 }
1420 if (i == mat->n_row-1)
1421 fprintf(out, "]]\n");
1422 else
1423 fprintf(out, "]\n");
1424 }
1425}
1426
1427void isl_mat_dump(__isl_keep isl_mat *mat)
1428{
1429 isl_mat_print_internal(mat, stderrstderr, 0);
1430}
1431
1432__isl_give isl_mat *isl_mat_drop_cols(__isl_take isl_mat *mat,
1433 unsigned col, unsigned n)
1434{
1435 int r;
1436
1437 if (n == 0)
1438 return mat;
1439
1440 mat = isl_mat_cow(mat);
1441 if (!mat)
1442 return NULL((void*)0);
1443
1444 if (col != mat->n_col-n) {
1445 for (r = 0; r < mat->n_row; ++r)
1446 isl_seq_cpy(mat->row[r]+col, mat->row[r]+col+n,
1447 mat->n_col - col - n);
1448 }
1449 mat->n_col -= n;
1450 return mat;
1451}
1452
1453__isl_give isl_mat *isl_mat_drop_rows(__isl_take isl_mat *mat,
1454 unsigned row, unsigned n)
1455{
1456 int r;
1457
1458 mat = isl_mat_cow(mat);
1459 if (!mat)
1460 return NULL((void*)0);
1461
1462 for (r = row; r+n < mat->n_row; ++r)
1463 mat->row[r] = mat->row[r+n];
1464
1465 mat->n_row -= n;
1466 return mat;
1467}
1468
1469__isl_give isl_mat *isl_mat_insert_cols(__isl_take isl_mat *mat,
1470 unsigned col, unsigned n)
1471{
1472 isl_mat *ext;
1473
1474 if (!mat)
1475 return NULL((void*)0);
1476 if (n == 0)
1477 return mat;
1478
1479 ext = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col + n);
1480 if (!ext)
1481 goto error;
1482
1483 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row, 0, 0, col);
1484 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row,
1485 col + n, col, mat->n_col - col);
1486
1487 isl_mat_free(mat);
1488 return ext;
1489error:
1490 isl_mat_free(mat);
1491 return NULL((void*)0);
1492}
1493
1494__isl_give isl_mat *isl_mat_insert_zero_cols(__isl_take isl_mat *mat,
1495 unsigned first, unsigned n)
1496{
1497 int i;
1498
1499 if (!mat)
1500 return NULL((void*)0);
1501 mat = isl_mat_insert_cols(mat, first, n);
1502 if (!mat)
1503 return NULL((void*)0);
1504
1505 for (i = 0; i < mat->n_row; ++i)
1506 isl_seq_clr(mat->row[i] + first, n);
1507
1508 return mat;
1509}
1510
1511__isl_give isl_mat *isl_mat_add_zero_cols(__isl_take isl_mat *mat, unsigned n)
1512{
1513 if (!mat)
1514 return NULL((void*)0);
1515
1516 return isl_mat_insert_zero_cols(mat, mat->n_col, n);
1517}
1518
1519__isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat,
1520 unsigned row, unsigned n)
1521{
1522 isl_mat *ext;
1523
1524 if (!mat)
1525 return NULL((void*)0);
1526 if (n == 0)
1527 return mat;
1528
1529 ext = isl_mat_alloc(mat->ctx, mat->n_row + n, mat->n_col);
1530 if (!ext)
1531 goto error;
1532
1533 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, row, 0, 0, mat->n_col);
1534 isl_mat_sub_copy(mat->ctx, ext->row + row + n, mat->row + row,
1535 mat->n_row - row, 0, 0, mat->n_col);
1536
1537 isl_mat_free(mat);
1538 return ext;
1539error:
1540 isl_mat_free(mat);
1541 return NULL((void*)0);
1542}
1543
1544__isl_give isl_mat *isl_mat_add_rows(__isl_take isl_mat *mat, unsigned n)
1545{
1546 if (!mat)
1547 return NULL((void*)0);
1548
1549 return isl_mat_insert_rows(mat, mat->n_row, n);
1550}
1551
1552__isl_give isl_mat *isl_mat_insert_zero_rows(__isl_take isl_mat *mat,
1553 unsigned row, unsigned n)
1554{
1555 int i;
1556
1557 mat = isl_mat_insert_rows(mat, row, n);
1558 if (!mat)
1559 return NULL((void*)0);
1560
1561 for (i = 0; i < n; ++i)
1562 isl_seq_clr(mat->row[row + i], mat->n_col);
1563
1564 return mat;
1565}
1566
1567__isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n)
1568{
1569 if (!mat)
1570 return NULL((void*)0);
1571
1572 return isl_mat_insert_zero_rows(mat, mat->n_row, n);
1573}
1574
1575void isl_mat_col_submul(struct isl_mat *mat,
1576 int dst_col, isl_int f, int src_col)
1577{
1578 int i;
1579
1580 for (i = 0; i < mat->n_row; ++i)
1581 isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col])isl_sioimath_submul((mat->row[i][dst_col]), *(f), *(mat->
row[i][src_col]))
;
1582}
1583
1584void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col)
1585{
1586 int i;
1587
1588 if (!mat)
1589 return;
1590
1591 for (i = 0; i < mat->n_row; ++i)
1592 isl_int_add(mat->row[i][dst_col],isl_sioimath_add((mat->row[i][dst_col]), *(mat->row[i][
dst_col]), *(mat->row[i][src_col]))
1593 mat->row[i][dst_col], mat->row[i][src_col])isl_sioimath_add((mat->row[i][dst_col]), *(mat->row[i][
dst_col]), *(mat->row[i][src_col]))
;
1594}
1595
1596void isl_mat_col_mul(struct isl_mat *mat, int dst_col, isl_int f, int src_col)
1597{
1598 int i;
1599
1600 for (i = 0; i < mat->n_row; ++i)
1601 isl_int_mul(mat->row[i][dst_col], f, mat->row[i][src_col])isl_sioimath_mul((mat->row[i][dst_col]), *(f), *(mat->row
[i][src_col]))
;
1602}
1603
1604/* Add "f" times column "src_col" to column "dst_col" of "mat" and
1605 * return the result.
1606 */
1607__isl_give isl_mat *isl_mat_col_addmul(__isl_take isl_mat *mat, int dst_col,
1608 isl_int f, int src_col)
1609{
1610 int i;
1611
1612 if (check_col(mat, dst_col) < 0 || check_col(mat, src_col) < 0)
1613 return isl_mat_free(mat);
1614
1615 for (i = 0; i < mat->n_row; ++i) {
1616 if (isl_int_is_zero(mat->row[i][src_col])(isl_sioimath_sgn(*(mat->row[i][src_col])) == 0))
1617 continue;
1618 mat = isl_mat_cow(mat);
1619 if (!mat)
1620 return NULL((void*)0);
1621 isl_int_addmul(mat->row[i][dst_col], f, mat->row[i][src_col])isl_sioimath_addmul((mat->row[i][dst_col]), *(f), *(mat->
row[i][src_col]))
;
1622 }
1623
1624 return mat;
1625}
1626
1627/* Negate column "col" of "mat" and return the result.
1628 */
1629__isl_give isl_mat *isl_mat_col_neg(__isl_take isl_mat *mat, int col)
1630{
1631 int i;
1632
1633 if (check_col(mat, col) < 0)
1634 return isl_mat_free(mat);
1635
1636 for (i = 0; i < mat->n_row; ++i) {
1637 if (isl_int_is_zero(mat->row[i][col])(isl_sioimath_sgn(*(mat->row[i][col])) == 0))
1638 continue;
1639 mat = isl_mat_cow(mat);
1640 if (!mat)
1641 return NULL((void*)0);
1642 isl_int_neg(mat->row[i][col], mat->row[i][col])isl_sioimath_neg((mat->row[i][col]), *(mat->row[i][col]
))
;
1643 }
1644
1645 return mat;
1646}
1647
1648/* Negate row "row" of "mat" and return the result.
1649 */
1650__isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row)
1651{
1652 if (check_row(mat, row) < 0)
1653 return isl_mat_free(mat);
1654 if (isl_seq_first_non_zero(mat->row[row], mat->n_col) == -1)
1655 return mat;
1656 mat = isl_mat_cow(mat);
1657 if (!mat)
1658 return NULL((void*)0);
1659 isl_seq_neg(mat->row[row], mat->row[row], mat->n_col);
1660 return mat;
1661}
1662
1663__isl_give isl_mat *isl_mat_unimodular_complete(__isl_take isl_mat *M, int row)
1664{
1665 int r;
1666 struct isl_mat *H = NULL((void*)0), *Q = NULL((void*)0);
1667
1668 if (!M)
1669 return NULL((void*)0);
1670
1671 isl_assert(M->ctx, M->n_row == M->n_col, goto error)do { if (M->n_row == M->n_col) break; do { isl_handle_error
(M->ctx, isl_error_unknown, "Assertion \"" "M->n_row == M->n_col"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1671); goto error; } while (0); } while (0)
;
1672 M->n_row = row;
1673 H = isl_mat_left_hermite(isl_mat_copy(M), 0, NULL((void*)0), &Q);
1674 M->n_row = M->n_col;
1675 if (!H)
1676 goto error;
1677 for (r = 0; r < row; ++r)
1678 isl_assert(M->ctx, isl_int_is_one(H->row[r][r]), goto error)do { if ((isl_sioimath_cmp_si(*(H->row[r][r]), 1) == 0)) break
; do { isl_handle_error(M->ctx, isl_error_unknown, "Assertion \""
"(isl_sioimath_cmp_si(*(H->row[r][r]), 1) == 0)" "\" failed"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1678); goto error; } while (0); } while (0)
;
1679 for (r = row; r < M->n_row; ++r)
1680 isl_seq_cpy(M->row[r], Q->row[r], M->n_col);
1681 isl_mat_free(H);
1682 isl_mat_free(Q);
1683 return M;
1684error:
1685 isl_mat_free(H);
1686 isl_mat_free(Q);
1687 isl_mat_free(M);
1688 return NULL((void*)0);
1689}
1690
1691__isl_give isl_mat *isl_mat_concat(__isl_take isl_mat *top,
1692 __isl_take isl_mat *bot)
1693{
1694 struct isl_mat *mat;
1695
1696 if (!top || !bot)
1697 goto error;
1698
1699 isl_assert(top->ctx, top->n_col == bot->n_col, goto error)do { if (top->n_col == bot->n_col) break; do { isl_handle_error
(top->ctx, isl_error_unknown, "Assertion \"" "top->n_col == bot->n_col"
"\" failed", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1699); goto error; } while (0); } while (0)
;
1700 if (top->n_row == 0) {
1701 isl_mat_free(top);
1702 return bot;
1703 }
1704 if (bot->n_row == 0) {
1705 isl_mat_free(bot);
1706 return top;
1707 }
1708
1709 mat = isl_mat_alloc(top->ctx, top->n_row + bot->n_row, top->n_col);
1710 if (!mat)
1711 goto error;
1712 isl_mat_sub_copy(mat->ctx, mat->row, top->row, top->n_row,
1713 0, 0, mat->n_col);
1714 isl_mat_sub_copy(mat->ctx, mat->row + top->n_row, bot->row, bot->n_row,
1715 0, 0, mat->n_col);
1716 isl_mat_free(top);
1717 isl_mat_free(bot);
1718 return mat;
1719error:
1720 isl_mat_free(top);
1721 isl_mat_free(bot);
1722 return NULL((void*)0);
1723}
1724
1725isl_bool isl_mat_is_equal(__isl_keep isl_mat *mat1, __isl_keep isl_mat *mat2)
1726{
1727 int i;
1728
1729 if (!mat1 || !mat2)
1730 return isl_bool_error;
1731
1732 if (mat1->n_row != mat2->n_row)
1733 return isl_bool_false;
1734
1735 if (mat1->n_col != mat2->n_col)
1736 return isl_bool_false;
1737
1738 for (i = 0; i < mat1->n_row; ++i)
1739 if (!isl_seq_eq(mat1->row[i], mat2->row[i], mat1->n_col))
1740 return isl_bool_false;
1741
1742 return isl_bool_true;
1743}
1744
1745__isl_give isl_mat *isl_mat_from_row_vec(__isl_take isl_vec *vec)
1746{
1747 struct isl_mat *mat;
1748
1749 if (!vec)
1750 return NULL((void*)0);
1751 mat = isl_mat_alloc(vec->ctx, 1, vec->size);
1752 if (!mat)
1753 goto error;
1754
1755 isl_seq_cpy(mat->row[0], vec->el, vec->size);
1756
1757 isl_vec_free(vec);
1758 return mat;
1759error:
1760 isl_vec_free(vec);
1761 return NULL((void*)0);
1762}
1763
1764/* Return a copy of row "row" of "mat" as an isl_vec.
1765 */
1766__isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row)
1767{
1768 isl_vec *v;
1769
1770 if (!mat)
1771 return NULL((void*)0);
1772 if (row >= mat->n_row)
1773 isl_die(mat->ctx, isl_error_invalid, "row out of range",do { isl_handle_error(mat->ctx, isl_error_invalid, "row out of range"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1774); return ((void*)0); } while (0)
1774 return NULL)do { isl_handle_error(mat->ctx, isl_error_invalid, "row out of range"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/polly/lib/External/isl/isl_mat.c"
, 1774); return ((void*)0); } while (0)
;
1775
1776 v = isl_vec_alloc(isl_mat_get_ctx(mat), mat->n_col);
1777 if (!v)
1778 return NULL((void*)0);
1779 isl_seq_cpy(v->el, mat->row[row], mat->n_col);
1780
1781 return v;
1782}
1783
1784__isl_give isl_mat *isl_mat_vec_concat(__isl_take isl_mat *top,
1785 __isl_take isl_vec *bot)
1786{
1787 return isl_mat_concat(top, isl_mat_from_row_vec(bot));
1788}
1789
1790__isl_give isl_mat *isl_mat_move_cols(__isl_take isl_mat *mat,
1791 unsigned dst_col, unsigned src_col, unsigned n)
1792{
1793 isl_mat *res;
1794
1795 if (!mat)
1796 return NULL((void*)0);
1797 if (n == 0 || dst_col == src_col)
1798 return mat;
1799
1800 res = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col);
1801 if (!res)
1802 goto error;
1803
1804 if (dst_col < src_col) {
1805 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1806 0, 0, dst_col);
1807 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1808 dst_col, src_col, n);
1809 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1810 dst_col + n, dst_col, src_col - dst_col);
1811 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1812 src_col + n, src_col + n,
1813 res->n_col - src_col - n);
1814 } else {
1815 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1816 0, 0, src_col);
1817 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1818 src_col, src_col + n, dst_col - src_col);
1819 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1820 dst_col, src_col, n);
1821 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1822 dst_col + n, dst_col + n,
1823 res->n_col - dst_col - n);
1824 }
1825 isl_mat_free(mat);
1826
1827 return res;
1828error:
1829 isl_mat_free(mat);
1830 return NULL((void*)0);
1831}
1832
1833/* Return the gcd of the elements in row "row" of "mat" in *gcd.
1834 * Return isl_stat_ok on success and isl_stat_error on failure.
1835 */
1836isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd)
1837{
1838 if (check_row(mat, row) < 0)
1839 return isl_stat_error;
1840
1841 isl_seq_gcd(mat->row[row], mat->n_col, gcd);
1842
1843 return isl_stat_ok;
1844}
1845
1846void isl_mat_gcd(__isl_keep isl_mat *mat, isl_int *gcd)
1847{
1848 int i;
1849 isl_int g;
1850
1851 isl_int_set_si(*gcd, 0)isl_sioimath_set_si((*gcd), 0);
1852 if (!mat)
1853 return;
1854
1855 isl_int_init(g)isl_sioimath_init((g));
1856 for (i = 0; i < mat->n_row; ++i) {
1857 isl_seq_gcd(mat->row[i], mat->n_col, &g);
1858 isl_int_gcd(*gcd, *gcd, g)isl_sioimath_gcd((*gcd), *(*gcd), *(g));
1859 }
1860 isl_int_clear(g)isl_sioimath_clear((g));
1861}
1862
1863/* Return the result of scaling "mat" by a factor of "m".
1864 */
1865__isl_give isl_mat *isl_mat_scale(__isl_take isl_mat *mat, isl_int m)
1866{
1867 int i;
1868
1869 if (isl_int_is_one(m)(isl_sioimath_cmp_si(*(m), 1) == 0))
1870 return mat;
1871
1872 mat = isl_mat_cow(mat);
1873 if (!mat)
1874 return NULL((void*)0);
1875
1876 for (i = 0; i < mat->n_row; ++i)
1877 isl_seq_scale(mat->row[i], mat->row[i], m, mat->n_col);
1878
1879 return mat;
1880}
1881
1882__isl_give isl_mat *isl_mat_scale_down(__isl_take isl_mat *mat, isl_int m)
1883{
1884 int i;
1885
1886 if (isl_int_is_one(m)(isl_sioimath_cmp_si(*(m), 1) == 0))
1887 return mat;
1888
1889 mat = isl_mat_cow(mat);
1890 if (!mat)
1891 return NULL((void*)0);
1892
1893 for (i = 0; i < mat->n_row; ++i)
1894 isl_seq_scale_down(mat->row[i], mat->row[i], m, mat->n_col);
1895
1896 return mat;
1897}
1898
1899__isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row,
1900 isl_int m)
1901{
1902 if (isl_int_is_one(m)(isl_sioimath_cmp_si(*(m), 1) == 0))
1903 return mat;
1904
1905 mat = isl_mat_cow(mat);
1906 if (!mat)
1907 return NULL((void*)0);
1908
1909 isl_seq_scale_down(mat->row[row], mat->row[row], m, mat->n_col);
1910
1911 return mat;
1912}
1913
1914__isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat)
1915{
1916 isl_int gcd;
1917
1918 if (!mat)
1919 return NULL((void*)0);
1920
1921 isl_int_init(gcd)isl_sioimath_init((gcd));
1922 isl_mat_gcd(mat, &gcd);
1923 mat = isl_mat_scale_down(mat, gcd);
1924 isl_int_clear(gcd)isl_sioimath_clear((gcd));
1925
1926 return mat;
1927}
1928
1929__isl_give isl_mat *isl_mat_normalize_row(__isl_take isl_mat *mat, int row)
1930{
1931 mat = isl_mat_cow(mat);
1932 if (!mat)
1933 return NULL((void*)0);
1934
1935 isl_seq_normalize(mat->ctx, mat->row[row], mat->n_col);
1936
1937 return mat;
1938}
1939
1940/* Number of initial non-zero columns.
1941 */
1942int isl_mat_initial_non_zero_cols(__isl_keep isl_mat *mat)
1943{
1944 int i;
1945
1946 if (!mat)
1947 return -1;
1948
1949 for (i = 0; i < mat->n_col; ++i)
1950 if (row_first_non_zero(mat->row, mat->n_row, i) < 0)
1951 break;
1952
1953 return i;
1954}