avoid new_NoMem in favor or get_irg_no_mem
[libfirm] / ir / kaps / vector.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   PBQP vector.
23  * @date    02.10.2008
24  * @author  Sebastian Buchwald
25  * @version $Id$
26  */
27 #include "config.h"
28
29 #include <string.h>
30
31 #include "adt/array.h"
32
33 #include "vector.h"
34
35 num pbqp_add(num x, num y)
36 {
37         num res;
38
39         if (x == INF_COSTS || y == INF_COSTS) return INF_COSTS;
40
41         res = x + y;
42
43 #if !KAPS_USE_UNSIGNED
44         /* No positive overflow. */
45         assert(x < 0 || y < 0 || res >= x);
46         assert(x < 0 || y < 0 || res >= y);
47 #endif
48
49         /* No negative overflow. */
50         assert(x > 0 || y > 0 || res <= x);
51         assert(x > 0 || y > 0 || res <= y);
52
53         /* Result is not infinity.*/
54         assert(res < INF_COSTS);
55
56         return res;
57 }
58
59 vector_t *vector_alloc(pbqp_t *pbqp, unsigned length)
60 {
61         vector_t *vec = (vector_t*)obstack_alloc(&pbqp->obstack, sizeof(*vec) + sizeof(*vec->entries) * length);
62         assert(length > 0);
63
64         vec->len = length;
65         memset(vec->entries, 0, sizeof(*vec->entries) * length);
66
67         return vec;
68 }
69
70 vector_t *vector_copy(pbqp_t *pbqp, vector_t *v)
71 {
72         unsigned  len  = v->len;
73         vector_t *copy = (vector_t*)obstack_copy(&pbqp->obstack, v, sizeof(*copy) + sizeof(*copy->entries) * len);
74         assert(copy);
75
76         return copy;
77 }
78
79 void vector_add(vector_t *sum, vector_t *summand)
80 {
81         int i;
82         int len;
83
84         assert(sum->len == summand->len);
85
86         len = sum->len;
87
88         for (i = 0; i < len; ++i) {
89                 sum->entries[i].data = pbqp_add(sum->entries[i].data,
90                                 summand->entries[i].data);
91         }
92 }
93
94 void vector_set(vector_t *vec, unsigned index, num value)
95 {
96         assert(index < vec->len);
97         vec->entries[index].data = value;
98 }
99
100 #if KAPS_ENABLE_VECTOR_NAMES
101 void vector_set_description(vector_t *vec, unsigned index, const char *name)
102 {
103         assert(index < vec->len);
104         vec->entries[index].name = name;
105 }
106 #endif
107
108 void vector_add_value(vector_t *vec, num value)
109 {
110         unsigned index;
111         unsigned len;
112
113         len = vec->len;
114
115         for (index = 0; index < len; ++index) {
116                 vec->entries[index].data = pbqp_add(vec->entries[index].data, value);
117         }
118 }
119
120 void vector_add_matrix_col(vector_t *vec, pbqp_matrix_t *mat, unsigned col_index)
121 {
122         unsigned index;
123         unsigned len;
124
125         assert(vec->len == mat->rows);
126         assert(col_index < mat->cols);
127
128         len = vec->len;
129
130         for (index = 0; index < len; ++index) {
131                 vec->entries[index].data = pbqp_add(vec->entries[index].data, mat->entries[index * mat->cols + col_index]);
132         }
133 }
134
135 void vector_add_matrix_row(vector_t *vec, pbqp_matrix_t *mat, unsigned row_index)
136 {
137         unsigned index;
138         unsigned len;
139
140         assert(vec->len == mat->cols);
141         assert(row_index < mat->rows);
142
143         len = vec->len;
144
145         for (index = 0; index < len; ++index) {
146                 vec->entries[index].data = pbqp_add(vec->entries[index].data,
147                                 mat->entries[row_index * mat->cols + index]);
148         }
149 }
150
151 num vector_get_min(vector_t *vec)
152 {
153         unsigned index;
154         unsigned len;
155         num      min = INF_COSTS;
156
157         len = vec->len;
158         assert(len > 0);
159
160         for (index = 0; index < len; ++index) {
161                 num elem = vec->entries[index].data;
162
163                 if (elem < min) {
164                         min = elem;
165                 }
166         }
167
168         return min;
169 }
170
171 unsigned vector_get_min_index(vector_t *vec)
172 {
173         unsigned index;
174         unsigned len;
175         unsigned min_index = 0;
176         num      min       = INF_COSTS;
177
178         len = vec->len;
179         assert(len > 0);
180
181         for (index = 0; index < len; ++index) {
182                 num elem = vec->entries[index].data;
183
184                 if (elem < min) {
185                         min = elem;
186                         min_index = index;
187                 }
188         }
189
190         return min_index;
191 }