nv50_ir_util.cpp revision f0a7ec9a2fad56eeb70c76202c21c97a33915d0b
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 25namespace nv50_ir { 26 27void 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 36void 37DLList::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 49void 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 62bool 63DLList::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 78void 79Stack::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 91Interval::~Interval() 92{ 93 clear(); 94} 95 96void 97Interval::clear() 98{ 99 for (Range *next, *r = head; r; r = next) { 100 next = r->next; 101 delete r; 102 } 103 head = tail = NULL; 104} 105 106bool 107Interval::extend(int a, int b) 108{ 109 Range *r, **nextp = &head; 110 111 // NOTE: we need empty intervals for fixed registers 112 // if (a == b) 113 // return false; 114 assert(a <= b); 115 116 for (r = head; r; r = r->next) { 117 if (b < r->bgn) 118 break; // insert before 119 if (a > r->end) { 120 // insert after 121 nextp = &r->next; 122 continue; 123 } 124 125 // overlap 126 if (a < r->bgn) { 127 r->bgn = a; 128 if (b > r->end) 129 r->end = b; 130 r->coalesce(&tail); 131 return true; 132 } 133 if (b > r->end) { 134 r->end = b; 135 r->coalesce(&tail); 136 return true; 137 } 138 assert(a >= r->bgn); 139 assert(b <= r->end); 140 return true; 141 } 142 143 (*nextp) = new Range(a, b); 144 (*nextp)->next = r; 145 146 for (r = (*nextp); r->next; r = r->next); 147 tail = r; 148 return true; 149} 150 151bool Interval::contains(int pos) 152{ 153 for (Range *r = head; r && r->bgn <= pos; r = r->next) 154 if (r->end > pos) 155 return true; 156 return false; 157} 158 159bool Interval::overlaps(const Interval &iv) const 160{ 161 for (Range *rA = this->head; rA; rA = rA->next) 162 for (Range *rB = iv.head; rB; rB = rB->next) 163 if (rB->bgn < rA->end && 164 rB->end > rA->bgn) 165 return true; 166 return false; 167} 168 169void Interval::unify(Interval &that) 170{ 171 assert(this != &that); 172 for (Range *next, *r = that.head; r; r = next) { 173 next = r->next; 174 this->extend(r->bgn, r->end); 175 delete r; 176 } 177 that.head = NULL; 178} 179 180void Interval::print() const 181{ 182 if (!head) 183 return; 184 INFO("[%i %i)", head->bgn, head->end); 185 for (const Range *r = head->next; r; r = r->next) 186 INFO(" [%i %i)", r->bgn, r->end); 187 INFO("\n"); 188} 189 190void 191BitSet::andNot(const BitSet &set) 192{ 193 assert(data && set.data); 194 assert(size >= set.size); 195 for (unsigned int i = 0; i < (set.size + 31) / 32; ++i) 196 data[i] &= ~set.data[i]; 197} 198 199BitSet& BitSet::operator|=(const BitSet &set) 200{ 201 assert(data && set.data); 202 assert(size >= set.size); 203 for (unsigned int i = 0; i < (set.size + 31) / 32; ++i) 204 data[i] |= set.data[i]; 205 return *this; 206} 207 208bool BitSet::allocate(unsigned int nBits, bool zero) 209{ 210 if (data && size < nBits) { 211 FREE(data); 212 data = NULL; 213 } 214 size = nBits; 215 216 if (!data) 217 data = reinterpret_cast<uint32_t *>(CALLOC((size + 31) / 32, 4)); 218 219 if (zero) 220 memset(data, 0, (size + 7) / 8); 221 else 222 data[(size + 31) / 32 - 1] = 0; // clear unused bits (e.g. for popCount) 223 224 return data; 225} 226 227unsigned int BitSet::popCount() const 228{ 229 unsigned int count = 0; 230 231 for (unsigned int i = 0; i < (size + 31) / 32; ++i) 232 if (data[i]) 233 count += util_bitcount(data[i]); 234 return count; 235} 236 237void BitSet::fill(uint32_t val) 238{ 239 unsigned int i; 240 for (i = 0; i < (size + 31) / 32; ++i) 241 data[i] = val; 242 if (val) 243 data[i] &= ~(0xffffffff << (size % 32)); // BE ? 244} 245 246void BitSet::setOr(BitSet *pA, BitSet *pB) 247{ 248 if (!pB) { 249 *this = *pA; 250 } else { 251 for (unsigned int i = 0; i < (size + 31) / 32; ++i) 252 data[i] = pA->data[i] | pB->data[i]; 253 } 254} 255 256void BitSet::print() const 257{ 258 unsigned int n = 0; 259 INFO("BitSet of size %u:\n", size); 260 for (unsigned int i = 0; i < (size + 31) / 32; ++i) { 261 uint32_t bits = data[i]; 262 while (bits) { 263 int pos = ffs(bits) - 1; 264 bits &= ~(1 << pos); 265 INFO(" %i", i * 32 + pos); 266 ++n; 267 if ((n % 16) == 0) 268 INFO("\n"); 269 } 270 } 271 if (n % 16) 272 INFO("\n"); 273} 274 275} // namespace nv50_ir 276