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