1 /*
2 * Copyright 2011 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #include "nv50_ir_util.h"
24
25 namespace nv50_ir {
26
clear()27 void DLList::clear()
28 {
29 for (Item *next, *item = head.next; item != &head; item = next) {
30 next = item->next;
31 delete item;
32 }
33 head.next = head.prev = &head;
34 }
35
36 void
erase()37 DLList::Iterator::erase()
38 {
39 Item *rem = pos;
40
41 if (rem == term)
42 return;
43 pos = pos->next;
44
45 DLLIST_DEL(rem);
46 delete rem;
47 }
48
moveToList(DLList & dest)49 void DLList::Iterator::moveToList(DLList& dest)
50 {
51 Item *item = pos;
52
53 assert(term != &dest.head);
54 assert(pos != term);
55
56 pos = pos->next;
57
58 DLLIST_DEL(item);
59 DLLIST_ADDHEAD(&dest.head, item);
60 }
61
62 bool
insert(void * data)63 DLList::Iterator::insert(void *data)
64 {
65 Item *ins = new Item(data);
66
67 ins->next = pos->next;
68 ins->prev = pos;
69 pos->next->prev = ins;
70 pos->next = ins;
71
72 if (pos == term)
73 term = ins;
74
75 return true;
76 }
77
78 void
moveTo(Stack & that)79 Stack::moveTo(Stack& that)
80 {
81 unsigned int newSize = this->size + that.size;
82
83 while (newSize > that.limit)
84 that.resize();
85 memcpy(&that.array[that.size], &array[0], this->size * sizeof(Item));
86
87 that.size = newSize;
88 this->size = 0;
89 }
90
Interval(const Interval & that)91 Interval::Interval(const Interval& that) : head(NULL), tail(NULL)
92 {
93 this->insert(that);
94 }
95
~Interval()96 Interval::~Interval()
97 {
98 clear();
99 }
100
101 void
clear()102 Interval::clear()
103 {
104 for (Range *next, *r = head; r; r = next) {
105 next = r->next;
106 delete r;
107 }
108 head = tail = NULL;
109 }
110
111 bool
extend(int a,int b)112 Interval::extend(int a, int b)
113 {
114 Range *r, **nextp = &head;
115
116 // NOTE: we need empty intervals for fixed registers
117 // if (a == b)
118 // return false;
119 assert(a <= b);
120
121 for (r = head; r; r = r->next) {
122 if (b < r->bgn)
123 break; // insert before
124 if (a > r->end) {
125 // insert after
126 nextp = &r->next;
127 continue;
128 }
129
130 // overlap
131 if (a < r->bgn) {
132 r->bgn = a;
133 if (b > r->end)
134 r->end = b;
135 r->coalesce(&tail);
136 return true;
137 }
138 if (b > r->end) {
139 r->end = b;
140 r->coalesce(&tail);
141 return true;
142 }
143 assert(a >= r->bgn);
144 assert(b <= r->end);
145 return true;
146 }
147
148 (*nextp) = new Range(a, b);
149 (*nextp)->next = r;
150
151 for (r = (*nextp); r->next; r = r->next);
152 tail = r;
153 return true;
154 }
155
contains(int pos) const156 bool Interval::contains(int pos) const
157 {
158 for (Range *r = head; r && r->bgn <= pos; r = r->next)
159 if (r->end > pos)
160 return true;
161 return false;
162 }
163
overlaps(const Interval & that) const164 bool Interval::overlaps(const Interval &that) const
165 {
166 #if 1
167 Range *a = this->head;
168 Range *b = that.head;
169
170 while (a && b) {
171 if (b->bgn < a->end &&
172 b->end > a->bgn)
173 return true;
174 if (a->end <= b->bgn)
175 a = a->next;
176 else
177 b = b->next;
178 }
179 #else
180 for (Range *rA = this->head; rA; rA = rA->next)
181 for (Range *rB = iv.head; rB; rB = rB->next)
182 if (rB->bgn < rA->end &&
183 rB->end > rA->bgn)
184 return true;
185 #endif
186 return false;
187 }
188
insert(const Interval & that)189 void Interval::insert(const Interval &that)
190 {
191 for (Range *r = that.head; r; r = r->next)
192 this->extend(r->bgn, r->end);
193 }
194
unify(Interval & that)195 void Interval::unify(Interval &that)
196 {
197 assert(this != &that);
198 for (Range *next, *r = that.head; r; r = next) {
199 next = r->next;
200 this->extend(r->bgn, r->end);
201 delete r;
202 }
203 that.head = NULL;
204 }
205
length() const206 int Interval::length() const
207 {
208 int len = 0;
209 for (Range *r = head; r; r = r->next)
210 len += r->bgn - r->end;
211 return len;
212 }
213
print() const214 void Interval::print() const
215 {
216 if (!head)
217 return;
218 INFO("[%i %i)", head->bgn, head->end);
219 for (const Range *r = head->next; r; r = r->next)
220 INFO(" [%i %i)", r->bgn, r->end);
221 INFO("\n");
222 }
223
224 void
andNot(const BitSet & set)225 BitSet::andNot(const BitSet &set)
226 {
227 assert(data && set.data);
228 assert(size >= set.size);
229 for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
230 data[i] &= ~set.data[i];
231 }
232
operator |=(const BitSet & set)233 BitSet& BitSet::operator|=(const BitSet &set)
234 {
235 assert(data && set.data);
236 assert(size >= set.size);
237 for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
238 data[i] |= set.data[i];
239 return *this;
240 }
241
resize(unsigned int nBits)242 bool BitSet::resize(unsigned int nBits)
243 {
244 if (!data || !nBits)
245 return allocate(nBits, true);
246 const unsigned int p = (size + 31) / 32;
247 const unsigned int n = (nBits + 31) / 32;
248 if (n == p)
249 return true;
250
251 data = (uint32_t *)REALLOC(data, 4 * p, 4 * n);
252 if (!data) {
253 size = 0;
254 return false;
255 }
256 if (n > p)
257 memset(&data[4 * p + 4], 0, (n - p) * 4);
258
259 size = nBits;
260 return true;
261 }
262
allocate(unsigned int nBits,bool zero)263 bool BitSet::allocate(unsigned int nBits, bool zero)
264 {
265 if (data && size < nBits) {
266 FREE(data);
267 data = NULL;
268 }
269 size = nBits;
270
271 if (!data)
272 data = reinterpret_cast<uint32_t *>(CALLOC((size + 31) / 32, 4));
273
274 if (zero)
275 memset(data, 0, (size + 7) / 8);
276 else
277 if (nBits)
278 data[(size + 31) / 32 - 1] = 0; // clear unused bits (e.g. for popCount)
279
280 return data;
281 }
282
popCount() const283 unsigned int BitSet::popCount() const
284 {
285 unsigned int count = 0;
286
287 for (unsigned int i = 0; i < (size + 31) / 32; ++i)
288 if (data[i])
289 count += util_bitcount(data[i]);
290 return count;
291 }
292
fill(uint32_t val)293 void BitSet::fill(uint32_t val)
294 {
295 unsigned int i;
296 for (i = 0; i < (size + 31) / 32; ++i)
297 data[i] = val;
298 if (val)
299 data[i] &= ~(0xffffffff << (size % 32)); // BE ?
300 }
301
setOr(BitSet * pA,BitSet * pB)302 void BitSet::setOr(BitSet *pA, BitSet *pB)
303 {
304 if (!pB) {
305 *this = *pA;
306 } else {
307 for (unsigned int i = 0; i < (size + 31) / 32; ++i)
308 data[i] = pA->data[i] | pB->data[i];
309 }
310 }
311
findFreeRange(unsigned int count) const312 int BitSet::findFreeRange(unsigned int count) const
313 {
314 const uint32_t m = (1 << count) - 1;
315 int pos = size;
316 unsigned int i;
317 const unsigned int end = (size + 31) / 32;
318
319 if (count == 1) {
320 for (i = 0; i < end; ++i) {
321 pos = ffs(~data[i]) - 1;
322 if (pos >= 0)
323 break;
324 }
325 } else
326 if (count == 2) {
327 for (i = 0; i < end; ++i) {
328 if (data[i] != 0xffffffff) {
329 uint32_t b = data[i] | (data[i] >> 1) | 0xaaaaaaaa;
330 pos = ffs(~b) - 1;
331 if (pos >= 0)
332 break;
333 }
334 }
335 } else
336 if (count == 4 || count == 3) {
337 for (i = 0; i < end; ++i) {
338 if (data[i] != 0xffffffff) {
339 uint32_t b =
340 (data[i] >> 0) | (data[i] >> 1) |
341 (data[i] >> 2) | (data[i] >> 3) | 0xeeeeeeee;
342 pos = ffs(~b) - 1;
343 if (pos >= 0)
344 break;
345 }
346 }
347 } else {
348 if (count <= 8)
349 count = 8;
350 else
351 if (count <= 16)
352 count = 16;
353 else
354 count = 32;
355
356 for (i = 0; i < end; ++i) {
357 if (data[i] != 0xffffffff) {
358 for (pos = 0; pos < 32; pos += count)
359 if (!(data[i] & (m << pos)))
360 break;
361 if (pos < 32)
362 break;
363 }
364 }
365 }
366 pos += i * 32;
367
368 return ((pos + count) <= size) ? pos : -1;
369 }
370
print() const371 void BitSet::print() const
372 {
373 unsigned int n = 0;
374 INFO("BitSet of size %u:\n", size);
375 for (unsigned int i = 0; i < (size + 31) / 32; ++i) {
376 uint32_t bits = data[i];
377 while (bits) {
378 int pos = ffs(bits) - 1;
379 bits &= ~(1 << pos);
380 INFO(" %i", i * 32 + pos);
381 ++n;
382 if ((n % 16) == 0)
383 INFO("\n");
384 }
385 }
386 if (n % 16)
387 INFO("\n");
388 }
389
390 } // namespace nv50_ir
391