2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * @author Sebastian Buchwald
36 pbqp_matrix_t *pbqp_matrix_alloc(pbqp_t *pbqp, unsigned rows, unsigned cols)
41 unsigned length = rows * cols;
43 pbqp_matrix_t *mat = (pbqp_matrix_t*)obstack_alloc(&pbqp->obstack, sizeof(*mat) + sizeof(*mat->entries) * length);
47 memset(mat->entries, 0, sizeof(*mat->entries) * length);
52 pbqp_matrix_t *pbqp_matrix_copy(pbqp_t *pbqp, pbqp_matrix_t *m)
54 unsigned len = m->rows * m->cols;
55 pbqp_matrix_t *copy = (pbqp_matrix_t*)obstack_copy(&pbqp->obstack, m, sizeof(*copy) + sizeof(*copy->entries) * len);
61 pbqp_matrix_t *pbqp_matrix_copy_and_transpose(pbqp_t *pbqp, pbqp_matrix_t *m)
65 unsigned cols = m->cols;
66 unsigned rows = m->rows;
67 unsigned len = rows * cols;
68 pbqp_matrix_t *copy = (pbqp_matrix_t*)obstack_alloc(&pbqp->obstack, sizeof(*copy) + sizeof(*copy->entries) * len);
70 for (i = 0; i < rows; ++i) {
71 for (j = 0; j < cols; ++j) {
72 copy->entries[j*rows+i] = m->entries[i*cols+j];
82 void pbqp_matrix_transpose(pbqp_t *pbqp, pbqp_matrix_t *mat)
86 len = mat->rows * mat->cols;
88 pbqp_matrix_t *tmp = pbqp_matrix_copy_and_transpose(pbqp, mat);
90 memcpy(mat, tmp, sizeof(*mat) + sizeof(*mat->entries) * len);
92 obstack_free(&pbqp->obstack, tmp);
95 void pbqp_matrix_add(pbqp_matrix_t *sum, pbqp_matrix_t *summand)
100 assert(sum->cols == summand->cols);
101 assert(sum->rows == summand->rows);
103 len = sum->rows * sum->cols;
105 for (i = 0; i < len; ++i) {
106 sum->entries[i] = pbqp_add(sum->entries[i], summand->entries[i]);
110 void pbqp_matrix_set_col_value(pbqp_matrix_t *mat, unsigned col, num value)
115 assert(col < mat->cols);
119 for (row_index = 0; row_index < row_len; ++row_index) {
120 mat->entries[row_index * mat->cols + col] = value;
124 void pbqp_matrix_set_row_value(pbqp_matrix_t *mat, unsigned row, num value)
129 assert(row < mat->rows);
133 for (col_index = 0; col_index < col_len; ++col_index) {
134 mat->entries[row * mat->cols + col_index] = value;
138 void pbqp_matrix_set(pbqp_matrix_t *mat, unsigned row, unsigned col, num value)
140 assert(col < mat->cols);
141 assert(row < mat->rows);
143 mat->entries[row * mat->cols + col] = value;
146 num pbqp_matrix_get_col_min(pbqp_matrix_t *matrix, unsigned col_index, vector_t *flags)
151 assert(matrix->rows == flags->len);
153 unsigned col_len = matrix->cols;
154 unsigned row_len = matrix->rows;
156 for (row_index = 0; row_index < row_len; ++row_index) {
157 /* Ignore virtual deleted columns. */
158 if (flags->entries[row_index].data == INF_COSTS) continue;
160 num elem = matrix->entries[row_index * col_len + col_index];
170 unsigned pbqp_matrix_get_col_min_index(pbqp_matrix_t *matrix, unsigned col_index, vector_t *flags)
173 unsigned min_index = 0;
176 assert(matrix->rows == flags->len);
178 unsigned col_len = matrix->cols;
179 unsigned row_len = matrix->rows;
181 for (row_index = 0; row_index < row_len; ++row_index) {
182 /* Ignore virtual deleted columns. */
183 if (flags->entries[row_index].data == INF_COSTS) continue;
185 num elem = matrix->entries[row_index * col_len + col_index];
189 min_index = row_index;
196 void pbqp_matrix_sub_col_value(pbqp_matrix_t *matrix, unsigned col_index,
197 vector_t *flags, num value)
203 assert(matrix->rows == flags->len);
205 col_len = matrix->cols;
206 row_len = matrix->rows;
208 for (row_index = 0; row_index < row_len; ++row_index) {
209 if (flags->entries[row_index].data == INF_COSTS) {
210 matrix->entries[row_index * col_len + col_index] = 0;
213 /* inf - x = inf if x < inf */
214 if (matrix->entries[row_index * col_len + col_index] == INF_COSTS && value
217 matrix->entries[row_index * col_len + col_index] -= value;
221 num pbqp_matrix_get_row_min(pbqp_matrix_t *matrix, unsigned row_index, vector_t *flags)
226 assert(matrix->cols == flags->len);
228 unsigned len = flags->len;
230 for (col_index = 0; col_index < len; ++col_index) {
231 /* Ignore virtual deleted columns. */
232 if (flags->entries[col_index].data == INF_COSTS) continue;
234 num elem = matrix->entries[row_index * len + col_index];
244 unsigned pbqp_matrix_get_row_min_index(pbqp_matrix_t *matrix, unsigned row_index, vector_t *flags)
247 unsigned min_index = 0;
250 assert(matrix->cols == flags->len);
252 unsigned len = flags->len;
254 for (col_index = 0; col_index < len; ++col_index) {
255 /* Ignore virtual deleted columns. */
256 if (flags->entries[col_index].data == INF_COSTS) continue;
258 num elem = matrix->entries[row_index * len + col_index];
262 min_index = col_index;
269 void pbqp_matrix_sub_row_value(pbqp_matrix_t *matrix, unsigned row_index,
270 vector_t *flags, num value)
275 assert(matrix->cols == flags->len);
277 col_len = matrix->cols;
279 for (col_index = 0; col_index < col_len; ++col_index) {
280 if (flags->entries[col_index].data == INF_COSTS) {
281 matrix->entries[row_index * col_len + col_index] = 0;
284 /* inf - x = inf if x < inf */
285 if (matrix->entries[row_index * col_len + col_index] == INF_COSTS && value
288 matrix->entries[row_index * col_len + col_index] -= value;
292 int pbqp_matrix_is_zero(pbqp_matrix_t *mat, vector_t *src_vec, vector_t *tgt_vec)
299 assert(mat->cols = tgt_vec->len);
300 assert(mat->rows = src_vec->len);
305 for (row_index = 0; row_index < row_len; ++row_index) {
306 if (src_vec->entries[row_index].data == INF_COSTS) continue;
307 for (col_index = 0; col_index < col_len; ++col_index) {
308 if (tgt_vec->entries[col_index].data == INF_COSTS) continue;
310 if (mat->entries[row_index * col_len + col_index] != 0) {
319 void pbqp_matrix_add_to_all_cols(pbqp_matrix_t *mat, vector_t *vec)
326 assert(mat->rows == vec->len);
331 for (row_index = 0; row_index < row_len; ++row_index) {
332 num value = vec->entries[row_index].data;
333 for (col_index = 0; col_index < col_len; ++col_index) {
334 mat->entries[row_index * col_len + col_index] = pbqp_add(
335 mat->entries[row_index * col_len + col_index], value);
340 void pbqp_matrix_add_to_all_rows(pbqp_matrix_t *mat, vector_t *vec)
347 assert(mat->cols == vec->len);
352 for (row_index = 0; row_index < row_len; ++row_index) {
353 for (col_index = 0; col_index < col_len; ++col_index) {
354 num value = vec->entries[col_index].data;
356 mat->entries[row_index * col_len + col_index] = pbqp_add(mat->entries[row_index * col_len + col_index], value);