1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2011 Christoph Bumiller 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 12bf215546Sopenharmony_ci * all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#ifndef __NV50_IR_UTIL_H__ 24bf215546Sopenharmony_ci#define __NV50_IR_UTIL_H__ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <new> 27bf215546Sopenharmony_ci#include <assert.h> 28bf215546Sopenharmony_ci#include <stdio.h> 29bf215546Sopenharmony_ci#include <memory> 30bf215546Sopenharmony_ci#include <map> 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#ifndef NDEBUG 33bf215546Sopenharmony_ci# include <typeinfo> 34bf215546Sopenharmony_ci#endif 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "util/u_inlines.h" 37bf215546Sopenharmony_ci#include "util/u_memory.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#define ERROR(args...) _debug_printf("ERROR: " args) 40bf215546Sopenharmony_ci#define WARN(args...) _debug_printf("WARNING: " args) 41bf215546Sopenharmony_ci#define INFO(args...) _debug_printf(args) 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#define INFO_DBG(m, f, args...) \ 44bf215546Sopenharmony_ci do { \ 45bf215546Sopenharmony_ci if (m & NV50_IR_DEBUG_##f) \ 46bf215546Sopenharmony_ci _debug_printf(args); \ 47bf215546Sopenharmony_ci } while(0) 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci#define FATAL(args...) \ 50bf215546Sopenharmony_ci do { \ 51bf215546Sopenharmony_ci fprintf(stderr, args); \ 52bf215546Sopenharmony_ci abort(); \ 53bf215546Sopenharmony_ci } while(0) 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#define NV50_IR_FUNC_ALLOC_OBJ_DEF(obj, f, args...) \ 57bf215546Sopenharmony_ci new ((f)->getProgram()->mem_##obj.allocate()) obj(f, args) 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci#define new_Instruction(f, args...) \ 60bf215546Sopenharmony_ci NV50_IR_FUNC_ALLOC_OBJ_DEF(Instruction, f, args) 61bf215546Sopenharmony_ci#define new_CmpInstruction(f, args...) \ 62bf215546Sopenharmony_ci NV50_IR_FUNC_ALLOC_OBJ_DEF(CmpInstruction, f, args) 63bf215546Sopenharmony_ci#define new_TexInstruction(f, args...) \ 64bf215546Sopenharmony_ci NV50_IR_FUNC_ALLOC_OBJ_DEF(TexInstruction, f, args) 65bf215546Sopenharmony_ci#define new_FlowInstruction(f, args...) \ 66bf215546Sopenharmony_ci NV50_IR_FUNC_ALLOC_OBJ_DEF(FlowInstruction, f, args) 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci#define new_LValue(f, args...) \ 69bf215546Sopenharmony_ci NV50_IR_FUNC_ALLOC_OBJ_DEF(LValue, f, args) 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci#define NV50_IR_PROG_ALLOC_OBJ_DEF(obj, p, args...) \ 73bf215546Sopenharmony_ci new ((p)->mem_##obj.allocate()) obj(p, args) 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci#define new_Symbol(p, args...) \ 76bf215546Sopenharmony_ci NV50_IR_PROG_ALLOC_OBJ_DEF(Symbol, p, args) 77bf215546Sopenharmony_ci#define new_ImmediateValue(p, args...) \ 78bf215546Sopenharmony_ci NV50_IR_PROG_ALLOC_OBJ_DEF(ImmediateValue, p, args) 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci#define delete_Instruction(p, insn) (p)->releaseInstruction(insn) 82bf215546Sopenharmony_ci#define delete_Value(p, val) (p)->releaseValue(val) 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_cinamespace nv50_ir { 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ciclass Iterator 88bf215546Sopenharmony_ci{ 89bf215546Sopenharmony_cipublic: 90bf215546Sopenharmony_ci virtual ~Iterator() { }; 91bf215546Sopenharmony_ci virtual void next() = 0; 92bf215546Sopenharmony_ci virtual void *get() const = 0; 93bf215546Sopenharmony_ci virtual bool end() const = 0; // if true, get will return 0 94bf215546Sopenharmony_ci virtual void reset() { assert(0); } // only for graph iterators 95bf215546Sopenharmony_ci}; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_citypedef std::unique_ptr<Iterator> IteratorRef; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ciclass ManipIterator : public Iterator 100bf215546Sopenharmony_ci{ 101bf215546Sopenharmony_cipublic: 102bf215546Sopenharmony_ci virtual bool insert(void *) = 0; // insert after current position 103bf215546Sopenharmony_ci virtual void erase() = 0; 104bf215546Sopenharmony_ci}; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci// WARNING: do not use a->prev/next for __item or __list 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci#define DLLIST_DEL(__item) \ 109bf215546Sopenharmony_ci do { \ 110bf215546Sopenharmony_ci (__item)->prev->next = (__item)->next; \ 111bf215546Sopenharmony_ci (__item)->next->prev = (__item)->prev; \ 112bf215546Sopenharmony_ci (__item)->next = (__item); \ 113bf215546Sopenharmony_ci (__item)->prev = (__item); \ 114bf215546Sopenharmony_ci } while(0) 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci#define DLLIST_ADDTAIL(__list, __item) \ 117bf215546Sopenharmony_ci do { \ 118bf215546Sopenharmony_ci (__item)->next = (__list); \ 119bf215546Sopenharmony_ci (__item)->prev = (__list)->prev; \ 120bf215546Sopenharmony_ci (__list)->prev->next = (__item); \ 121bf215546Sopenharmony_ci (__list)->prev = (__item); \ 122bf215546Sopenharmony_ci } while(0) 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci#define DLLIST_ADDHEAD(__list, __item) \ 125bf215546Sopenharmony_ci do { \ 126bf215546Sopenharmony_ci (__item)->prev = (__list); \ 127bf215546Sopenharmony_ci (__item)->next = (__list)->next; \ 128bf215546Sopenharmony_ci (__list)->next->prev = (__item); \ 129bf215546Sopenharmony_ci (__list)->next = (__item); \ 130bf215546Sopenharmony_ci } while(0) 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci#define DLLIST_MERGE(__listA, __listB, ty) \ 133bf215546Sopenharmony_ci do { \ 134bf215546Sopenharmony_ci ty prevB = (__listB)->prev; \ 135bf215546Sopenharmony_ci (__listA)->prev->next = (__listB); \ 136bf215546Sopenharmony_ci (__listB)->prev->next = (__listA); \ 137bf215546Sopenharmony_ci (__listB)->prev = (__listA)->prev; \ 138bf215546Sopenharmony_ci (__listA)->prev = prevB; \ 139bf215546Sopenharmony_ci } while(0) 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci#define DLLIST_EMPTY(__list) ((__list)->next == (__list)) 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci#define DLLIST_FOR_EACH(list, it) \ 144bf215546Sopenharmony_ci for (DLList::Iterator it = (list)->iterator(); !(it).end(); (it).next()) 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ciclass DLList 147bf215546Sopenharmony_ci{ 148bf215546Sopenharmony_cipublic: 149bf215546Sopenharmony_ci class Item 150bf215546Sopenharmony_ci { 151bf215546Sopenharmony_ci public: 152bf215546Sopenharmony_ci Item(void *priv) : next(this), prev(this), data(priv) { } 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci public: 155bf215546Sopenharmony_ci Item *next; 156bf215546Sopenharmony_ci Item *prev; 157bf215546Sopenharmony_ci void *data; 158bf215546Sopenharmony_ci }; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci DLList() : head(0) { } 161bf215546Sopenharmony_ci ~DLList() { clear(); } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci inline void insertHead(void *data) 164bf215546Sopenharmony_ci { 165bf215546Sopenharmony_ci Item *item = new Item(data); 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci assert(data); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci item->prev = &head; 170bf215546Sopenharmony_ci item->next = head.next; 171bf215546Sopenharmony_ci head.next->prev = item; 172bf215546Sopenharmony_ci head.next = item; 173bf215546Sopenharmony_ci } 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci inline void insertTail(void *data) 176bf215546Sopenharmony_ci { 177bf215546Sopenharmony_ci Item *item = new Item(data); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci assert(data); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci DLLIST_ADDTAIL(&head, item); 182bf215546Sopenharmony_ci } 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci inline void insert(void *data) { insertTail(data); } 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci void clear(); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci class Iterator : public ManipIterator 189bf215546Sopenharmony_ci { 190bf215546Sopenharmony_ci public: 191bf215546Sopenharmony_ci Iterator(Item *head, bool r) : rev(r), pos(r ? head->prev : head->next), 192bf215546Sopenharmony_ci term(head) { } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci virtual void next() { if (!end()) pos = rev ? pos->prev : pos->next; } 195bf215546Sopenharmony_ci virtual void *get() const { return pos->data; } 196bf215546Sopenharmony_ci virtual bool end() const { return pos == term; } 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci // caution: if you're at end-2 and erase it, then do next, you're at end 199bf215546Sopenharmony_ci virtual void erase(); 200bf215546Sopenharmony_ci virtual bool insert(void *data); 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci // move item to another list, no consistency with its iterators though 203bf215546Sopenharmony_ci void moveToList(DLList&); 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci private: 206bf215546Sopenharmony_ci const bool rev; 207bf215546Sopenharmony_ci Item *pos; 208bf215546Sopenharmony_ci Item *term; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci friend class DLList; 211bf215546Sopenharmony_ci }; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci inline void erase(Iterator& pos) 214bf215546Sopenharmony_ci { 215bf215546Sopenharmony_ci pos.erase(); 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci Iterator iterator() 219bf215546Sopenharmony_ci { 220bf215546Sopenharmony_ci return Iterator(&head, false); 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci Iterator revIterator() 224bf215546Sopenharmony_ci { 225bf215546Sopenharmony_ci return Iterator(&head, true); 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ciprivate: 229bf215546Sopenharmony_ci Item head; 230bf215546Sopenharmony_ci}; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ciclass Stack 233bf215546Sopenharmony_ci{ 234bf215546Sopenharmony_cipublic: 235bf215546Sopenharmony_ci class Item { 236bf215546Sopenharmony_ci public: 237bf215546Sopenharmony_ci union { 238bf215546Sopenharmony_ci void *p; 239bf215546Sopenharmony_ci int i; 240bf215546Sopenharmony_ci unsigned int u; 241bf215546Sopenharmony_ci float f; 242bf215546Sopenharmony_ci double d; 243bf215546Sopenharmony_ci } u; 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci Item() { memset(&u, 0, sizeof(u)); } 246bf215546Sopenharmony_ci }; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci Stack() : size(0), limit(0), array(0) { } 249bf215546Sopenharmony_ci ~Stack() { if (array) FREE(array); } 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci inline void push(int i) { Item data; data.u.i = i; push(data); } 252bf215546Sopenharmony_ci inline void push(unsigned int u) { Item data; data.u.u = u; push(data); } 253bf215546Sopenharmony_ci inline void push(void *p) { Item data; data.u.p = p; push(data); } 254bf215546Sopenharmony_ci inline void push(float f) { Item data; data.u.f = f; push(data); } 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci inline void push(Item data) 257bf215546Sopenharmony_ci { 258bf215546Sopenharmony_ci if (size == limit) 259bf215546Sopenharmony_ci resize(); 260bf215546Sopenharmony_ci array[size++] = data; 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci inline Item pop() 264bf215546Sopenharmony_ci { 265bf215546Sopenharmony_ci if (!size) { 266bf215546Sopenharmony_ci Item data; 267bf215546Sopenharmony_ci assert(0); 268bf215546Sopenharmony_ci return data; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci return array[--size]; 271bf215546Sopenharmony_ci } 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci inline unsigned int getSize() { return size; } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci inline Item& peek() { assert(size); return array[size - 1]; } 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci void clear(bool releaseStorage = false) 278bf215546Sopenharmony_ci { 279bf215546Sopenharmony_ci if (releaseStorage && array) 280bf215546Sopenharmony_ci FREE(array); 281bf215546Sopenharmony_ci size = limit = 0; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci void moveTo(Stack&); // move all items to target (not like push(pop())) 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ciprivate: 287bf215546Sopenharmony_ci void resize() 288bf215546Sopenharmony_ci { 289bf215546Sopenharmony_ci unsigned int sizeOld, sizeNew; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci sizeOld = limit * sizeof(Item); 292bf215546Sopenharmony_ci limit = MAX2(4, limit + limit); 293bf215546Sopenharmony_ci sizeNew = limit * sizeof(Item); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci array = (Item *)REALLOC(array, sizeOld, sizeNew); 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci unsigned int size; 299bf215546Sopenharmony_ci unsigned int limit; 300bf215546Sopenharmony_ci Item *array; 301bf215546Sopenharmony_ci}; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ciclass DynArray 304bf215546Sopenharmony_ci{ 305bf215546Sopenharmony_cipublic: 306bf215546Sopenharmony_ci class Item 307bf215546Sopenharmony_ci { 308bf215546Sopenharmony_ci public: 309bf215546Sopenharmony_ci union { 310bf215546Sopenharmony_ci uint32_t u32; 311bf215546Sopenharmony_ci void *p; 312bf215546Sopenharmony_ci }; 313bf215546Sopenharmony_ci }; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci DynArray() : data(NULL), size(0) { } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci ~DynArray() { if (data) FREE(data); } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci inline Item& operator[](unsigned int i) 320bf215546Sopenharmony_ci { 321bf215546Sopenharmony_ci if (i >= size) 322bf215546Sopenharmony_ci resize(i); 323bf215546Sopenharmony_ci return data[i]; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci inline const Item operator[](unsigned int i) const 327bf215546Sopenharmony_ci { 328bf215546Sopenharmony_ci return data[i]; 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci void resize(unsigned int index) 332bf215546Sopenharmony_ci { 333bf215546Sopenharmony_ci const unsigned int oldSize = size * sizeof(Item); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci if (!size) 336bf215546Sopenharmony_ci size = 8; 337bf215546Sopenharmony_ci while (size <= index) 338bf215546Sopenharmony_ci size <<= 1; 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci data = (Item *)REALLOC(data, oldSize, size * sizeof(Item)); 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci void clear() 344bf215546Sopenharmony_ci { 345bf215546Sopenharmony_ci FREE(data); 346bf215546Sopenharmony_ci data = NULL; 347bf215546Sopenharmony_ci size = 0; 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ciprivate: 351bf215546Sopenharmony_ci Item *data; 352bf215546Sopenharmony_ci unsigned int size; 353bf215546Sopenharmony_ci}; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ciclass ArrayList 356bf215546Sopenharmony_ci{ 357bf215546Sopenharmony_cipublic: 358bf215546Sopenharmony_ci ArrayList() : size(0) { } 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci void insert(void *item, int& id) 361bf215546Sopenharmony_ci { 362bf215546Sopenharmony_ci id = ids.getSize() ? ids.pop().u.i : size++; 363bf215546Sopenharmony_ci data[id].p = item; 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci void remove(int& id) 367bf215546Sopenharmony_ci { 368bf215546Sopenharmony_ci const unsigned int uid = id; 369bf215546Sopenharmony_ci assert(uid < size && data[id].p); 370bf215546Sopenharmony_ci ids.push(uid); 371bf215546Sopenharmony_ci data[uid].p = NULL; 372bf215546Sopenharmony_ci id = -1; 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci inline int getSize() const { return size; } 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci inline void *get(unsigned int id) { assert(id < size); return data[id].p; } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci class Iterator : public nv50_ir::Iterator 380bf215546Sopenharmony_ci { 381bf215546Sopenharmony_ci public: 382bf215546Sopenharmony_ci Iterator(const ArrayList *array) : pos(0), data(array->data) 383bf215546Sopenharmony_ci { 384bf215546Sopenharmony_ci size = array->getSize(); 385bf215546Sopenharmony_ci if (size) 386bf215546Sopenharmony_ci nextValid(); 387bf215546Sopenharmony_ci } 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci void nextValid() { while ((pos < size) && !data[pos].p) ++pos; } 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci void next() { if (pos < size) { ++pos; nextValid(); } } 392bf215546Sopenharmony_ci void *get() const { assert(pos < size); return data[pos].p; } 393bf215546Sopenharmony_ci bool end() const { return pos >= size; } 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci private: 396bf215546Sopenharmony_ci unsigned int pos; 397bf215546Sopenharmony_ci unsigned int size; 398bf215546Sopenharmony_ci const DynArray& data; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci friend class ArrayList; 401bf215546Sopenharmony_ci }; 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci Iterator iterator() const { return Iterator(this); } 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci void clear() 406bf215546Sopenharmony_ci { 407bf215546Sopenharmony_ci data.clear(); 408bf215546Sopenharmony_ci ids.clear(true); 409bf215546Sopenharmony_ci size = 0; 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ciprivate: 413bf215546Sopenharmony_ci DynArray data; 414bf215546Sopenharmony_ci Stack ids; 415bf215546Sopenharmony_ci unsigned int size; 416bf215546Sopenharmony_ci}; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ciclass Interval 419bf215546Sopenharmony_ci{ 420bf215546Sopenharmony_cipublic: 421bf215546Sopenharmony_ci Interval() : head(0), tail(0) { } 422bf215546Sopenharmony_ci Interval(const Interval&); 423bf215546Sopenharmony_ci ~Interval(); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci bool extend(int, int); 426bf215546Sopenharmony_ci void insert(const Interval&); 427bf215546Sopenharmony_ci void unify(Interval&); // clears source interval 428bf215546Sopenharmony_ci void clear(); 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci inline int begin() const { return head ? head->bgn : -1; } 431bf215546Sopenharmony_ci inline int end() const { checkTail(); return tail ? tail->end : -1; } 432bf215546Sopenharmony_ci inline bool isEmpty() const { return !head; } 433bf215546Sopenharmony_ci bool overlaps(const Interval&) const; 434bf215546Sopenharmony_ci bool contains(int pos) const; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci inline int extent() const { return end() - begin(); } 437bf215546Sopenharmony_ci int length() const; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci void print() const; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci inline void checkTail() const; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ciprivate: 444bf215546Sopenharmony_ci class Range 445bf215546Sopenharmony_ci { 446bf215546Sopenharmony_ci public: 447bf215546Sopenharmony_ci Range(int a, int b) : next(0), bgn(a), end(b) { } 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci Range *next; 450bf215546Sopenharmony_ci int bgn; 451bf215546Sopenharmony_ci int end; 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci void coalesce(Range **ptail) 454bf215546Sopenharmony_ci { 455bf215546Sopenharmony_ci Range *rnn; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci while (next && end >= next->bgn) { 458bf215546Sopenharmony_ci assert(bgn <= next->bgn); 459bf215546Sopenharmony_ci rnn = next->next; 460bf215546Sopenharmony_ci end = MAX2(end, next->end); 461bf215546Sopenharmony_ci delete next; 462bf215546Sopenharmony_ci next = rnn; 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci if (!next) 465bf215546Sopenharmony_ci *ptail = this; 466bf215546Sopenharmony_ci } 467bf215546Sopenharmony_ci }; 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci Range *head; 470bf215546Sopenharmony_ci Range *tail; 471bf215546Sopenharmony_ci}; 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ciclass BitSet 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_cipublic: 476bf215546Sopenharmony_ci BitSet() : marker(false), data(0), size(0) { } 477bf215546Sopenharmony_ci BitSet(unsigned int nBits, bool zero) : marker(false), data(0), size(0) 478bf215546Sopenharmony_ci { 479bf215546Sopenharmony_ci allocate(nBits, zero); 480bf215546Sopenharmony_ci } 481bf215546Sopenharmony_ci ~BitSet() 482bf215546Sopenharmony_ci { 483bf215546Sopenharmony_ci if (data) 484bf215546Sopenharmony_ci FREE(data); 485bf215546Sopenharmony_ci } 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci // allocate will keep old data iff size is unchanged 488bf215546Sopenharmony_ci bool allocate(unsigned int nBits, bool zero); 489bf215546Sopenharmony_ci bool resize(unsigned int nBits); // keep old data, zero additional bits 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci inline unsigned int getSize() const { return size; } 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci void fill(uint32_t val); 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci void setOr(BitSet *, BitSet *); // second BitSet may be NULL 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci inline void set(unsigned int i) 498bf215546Sopenharmony_ci { 499bf215546Sopenharmony_ci assert(i < size); 500bf215546Sopenharmony_ci data[i / 32] |= 1 << (i % 32); 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci // NOTE: range may not cross 32 bit boundary (implies n <= 32) 503bf215546Sopenharmony_ci inline void setRange(unsigned int i, unsigned int n) 504bf215546Sopenharmony_ci { 505bf215546Sopenharmony_ci assert((i + n) <= size && (((i % 32) + n) <= 32)); 506bf215546Sopenharmony_ci data[i / 32] |= ((1 << n) - 1) << (i % 32); 507bf215546Sopenharmony_ci } 508bf215546Sopenharmony_ci inline void setMask(unsigned int i, uint32_t m) 509bf215546Sopenharmony_ci { 510bf215546Sopenharmony_ci assert(i < size); 511bf215546Sopenharmony_ci data[i / 32] |= m; 512bf215546Sopenharmony_ci } 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci inline void clr(unsigned int i) 515bf215546Sopenharmony_ci { 516bf215546Sopenharmony_ci assert(i < size); 517bf215546Sopenharmony_ci data[i / 32] &= ~(1 << (i % 32)); 518bf215546Sopenharmony_ci } 519bf215546Sopenharmony_ci // NOTE: range may not cross 32 bit boundary (implies n <= 32) 520bf215546Sopenharmony_ci inline void clrRange(unsigned int i, unsigned int n) 521bf215546Sopenharmony_ci { 522bf215546Sopenharmony_ci assert((i + n) <= size && (((i % 32) + n) <= 32)); 523bf215546Sopenharmony_ci data[i / 32] &= ~(((1 << n) - 1) << (i % 32)); 524bf215546Sopenharmony_ci } 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci inline bool test(unsigned int i) const 527bf215546Sopenharmony_ci { 528bf215546Sopenharmony_ci assert(i < size); 529bf215546Sopenharmony_ci return data[i / 32] & (1 << (i % 32)); 530bf215546Sopenharmony_ci } 531bf215546Sopenharmony_ci // NOTE: range may not cross 32 bit boundary (implies n <= 32) 532bf215546Sopenharmony_ci inline bool testRange(unsigned int i, unsigned int n) const 533bf215546Sopenharmony_ci { 534bf215546Sopenharmony_ci assert((i + n) <= size && (((i % 32) + n) <= 32)); 535bf215546Sopenharmony_ci return data[i / 32] & (((1 << n) - 1) << (i % 32)); 536bf215546Sopenharmony_ci } 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci // Find a range of count (<= 32) clear bits aligned to roundup_pow2(count). 539bf215546Sopenharmony_ci int findFreeRange(unsigned int count, unsigned int max) const; 540bf215546Sopenharmony_ci inline int findFreeRange(unsigned int count) const { 541bf215546Sopenharmony_ci return findFreeRange(count, size); 542bf215546Sopenharmony_ci } 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci BitSet& operator|=(const BitSet&); 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci BitSet& operator=(const BitSet& set) 547bf215546Sopenharmony_ci { 548bf215546Sopenharmony_ci assert(data && set.data); 549bf215546Sopenharmony_ci assert(size == set.size); 550bf215546Sopenharmony_ci memcpy(data, set.data, (set.size + 7) / 8); 551bf215546Sopenharmony_ci return *this; 552bf215546Sopenharmony_ci } 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci void andNot(const BitSet&); 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci // bits = (bits | setMask) & ~clrMask 557bf215546Sopenharmony_ci inline void periodicMask32(uint32_t setMask, uint32_t clrMask) 558bf215546Sopenharmony_ci { 559bf215546Sopenharmony_ci for (unsigned int i = 0; i < (size + 31) / 32; ++i) 560bf215546Sopenharmony_ci data[i] = (data[i] | setMask) & ~clrMask; 561bf215546Sopenharmony_ci } 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci unsigned int popCount() const; 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci void print() const; 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_cipublic: 568bf215546Sopenharmony_ci bool marker; // for user 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_ciprivate: 571bf215546Sopenharmony_ci uint32_t *data; 572bf215546Sopenharmony_ci unsigned int size; 573bf215546Sopenharmony_ci}; 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_civoid Interval::checkTail() const 576bf215546Sopenharmony_ci{ 577bf215546Sopenharmony_ci#if NV50_DEBUG & NV50_DEBUG_PROG_RA 578bf215546Sopenharmony_ci Range *r = head; 579bf215546Sopenharmony_ci while (r->next) 580bf215546Sopenharmony_ci r = r->next; 581bf215546Sopenharmony_ci assert(tail == r); 582bf215546Sopenharmony_ci#endif 583bf215546Sopenharmony_ci} 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ciclass MemoryPool 586bf215546Sopenharmony_ci{ 587bf215546Sopenharmony_ciprivate: 588bf215546Sopenharmony_ci inline bool enlargeAllocationsArray(const unsigned int id, unsigned int nr) 589bf215546Sopenharmony_ci { 590bf215546Sopenharmony_ci const unsigned int size = sizeof(uint8_t *) * id; 591bf215546Sopenharmony_ci const unsigned int incr = sizeof(uint8_t *) * nr; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci uint8_t **alloc = (uint8_t **)REALLOC(allocArray, size, size + incr); 594bf215546Sopenharmony_ci if (!alloc) 595bf215546Sopenharmony_ci return false; 596bf215546Sopenharmony_ci allocArray = alloc; 597bf215546Sopenharmony_ci return true; 598bf215546Sopenharmony_ci } 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci inline bool enlargeCapacity() 601bf215546Sopenharmony_ci { 602bf215546Sopenharmony_ci const unsigned int id = count >> objStepLog2; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci uint8_t *const mem = (uint8_t *)MALLOC(objSize << objStepLog2); 605bf215546Sopenharmony_ci if (!mem) 606bf215546Sopenharmony_ci return false; 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci if (!(id % 32)) { 609bf215546Sopenharmony_ci if (!enlargeAllocationsArray(id, 32)) { 610bf215546Sopenharmony_ci FREE(mem); 611bf215546Sopenharmony_ci return false; 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci } 614bf215546Sopenharmony_ci allocArray[id] = mem; 615bf215546Sopenharmony_ci return true; 616bf215546Sopenharmony_ci } 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_cipublic: 619bf215546Sopenharmony_ci MemoryPool(unsigned int size, unsigned int incr) : objSize(size), 620bf215546Sopenharmony_ci objStepLog2(incr) 621bf215546Sopenharmony_ci { 622bf215546Sopenharmony_ci allocArray = NULL; 623bf215546Sopenharmony_ci released = NULL; 624bf215546Sopenharmony_ci count = 0; 625bf215546Sopenharmony_ci } 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci ~MemoryPool() 628bf215546Sopenharmony_ci { 629bf215546Sopenharmony_ci unsigned int allocCount = (count + (1 << objStepLog2) - 1) >> objStepLog2; 630bf215546Sopenharmony_ci for (unsigned int i = 0; i < allocCount && allocArray[i]; ++i) 631bf215546Sopenharmony_ci FREE(allocArray[i]); 632bf215546Sopenharmony_ci if (allocArray) 633bf215546Sopenharmony_ci FREE(allocArray); 634bf215546Sopenharmony_ci } 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci void *allocate() 637bf215546Sopenharmony_ci { 638bf215546Sopenharmony_ci void *ret; 639bf215546Sopenharmony_ci const unsigned int mask = (1 << objStepLog2) - 1; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci if (released) { 642bf215546Sopenharmony_ci ret = released; 643bf215546Sopenharmony_ci released = *(void **)released; 644bf215546Sopenharmony_ci return ret; 645bf215546Sopenharmony_ci } 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci if (!(count & mask)) 648bf215546Sopenharmony_ci if (!enlargeCapacity()) 649bf215546Sopenharmony_ci return NULL; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci ret = allocArray[count >> objStepLog2] + (count & mask) * objSize; 652bf215546Sopenharmony_ci ++count; 653bf215546Sopenharmony_ci return ret; 654bf215546Sopenharmony_ci } 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci void release(void *ptr) 657bf215546Sopenharmony_ci { 658bf215546Sopenharmony_ci *(void **)ptr = released; 659bf215546Sopenharmony_ci released = ptr; 660bf215546Sopenharmony_ci } 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ciprivate: 663bf215546Sopenharmony_ci uint8_t **allocArray; // array (list) of MALLOC allocations 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci void *released; // list of released objects 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_ci unsigned int count; // highest allocated object 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci const unsigned int objSize; 670bf215546Sopenharmony_ci const unsigned int objStepLog2; 671bf215546Sopenharmony_ci}; 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci/** 674bf215546Sopenharmony_ci * Composite object cloning policy. 675bf215546Sopenharmony_ci * 676bf215546Sopenharmony_ci * Encapsulates how sub-objects are to be handled (if at all) when a 677bf215546Sopenharmony_ci * composite object is being cloned. 678bf215546Sopenharmony_ci */ 679bf215546Sopenharmony_citemplate<typename C> 680bf215546Sopenharmony_ciclass ClonePolicy 681bf215546Sopenharmony_ci{ 682bf215546Sopenharmony_ciprotected: 683bf215546Sopenharmony_ci C *c; 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_cipublic: 686bf215546Sopenharmony_ci ClonePolicy(C *c) : c(c) {} 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci C *context() { return c; } 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci template<typename T> T *get(T *obj) 691bf215546Sopenharmony_ci { 692bf215546Sopenharmony_ci void *clone = lookup(obj); 693bf215546Sopenharmony_ci if (!clone) 694bf215546Sopenharmony_ci clone = obj->clone(*this); 695bf215546Sopenharmony_ci return reinterpret_cast<T *>(clone); 696bf215546Sopenharmony_ci } 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ci template<typename T> void set(const T *obj, T *clone) 699bf215546Sopenharmony_ci { 700bf215546Sopenharmony_ci insert(obj, clone); 701bf215546Sopenharmony_ci } 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ciprotected: 704bf215546Sopenharmony_ci virtual void *lookup(void *obj) = 0; 705bf215546Sopenharmony_ci virtual void insert(const void *obj, void *clone) = 0; 706bf215546Sopenharmony_ci}; 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci/** 709bf215546Sopenharmony_ci * Shallow non-recursive cloning policy. 710bf215546Sopenharmony_ci * 711bf215546Sopenharmony_ci * Objects cloned with the "shallow" policy don't clone their 712bf215546Sopenharmony_ci * children recursively, instead, the new copy shares its children 713bf215546Sopenharmony_ci * with the original object. 714bf215546Sopenharmony_ci */ 715bf215546Sopenharmony_citemplate<typename C> 716bf215546Sopenharmony_ciclass ShallowClonePolicy : public ClonePolicy<C> 717bf215546Sopenharmony_ci{ 718bf215546Sopenharmony_cipublic: 719bf215546Sopenharmony_ci ShallowClonePolicy(C *c) : ClonePolicy<C>(c) {} 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ciprotected: 722bf215546Sopenharmony_ci virtual void *lookup(void *obj) 723bf215546Sopenharmony_ci { 724bf215546Sopenharmony_ci return obj; 725bf215546Sopenharmony_ci } 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci virtual void insert(const void *obj, void *clone) 728bf215546Sopenharmony_ci { 729bf215546Sopenharmony_ci } 730bf215546Sopenharmony_ci}; 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_citemplate<typename C, typename T> 733bf215546Sopenharmony_ciinline T *cloneShallow(C *c, T *obj) 734bf215546Sopenharmony_ci{ 735bf215546Sopenharmony_ci ShallowClonePolicy<C> pol(c); 736bf215546Sopenharmony_ci return obj->clone(pol); 737bf215546Sopenharmony_ci} 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci/** 740bf215546Sopenharmony_ci * Recursive cloning policy. 741bf215546Sopenharmony_ci * 742bf215546Sopenharmony_ci * Objects cloned with the "deep" policy clone their children 743bf215546Sopenharmony_ci * recursively, keeping track of what has already been cloned to 744bf215546Sopenharmony_ci * avoid making several new copies of the same object. 745bf215546Sopenharmony_ci */ 746bf215546Sopenharmony_citemplate<typename C> 747bf215546Sopenharmony_ciclass DeepClonePolicy : public ClonePolicy<C> 748bf215546Sopenharmony_ci{ 749bf215546Sopenharmony_cipublic: 750bf215546Sopenharmony_ci DeepClonePolicy(C *c) : ClonePolicy<C>(c) {} 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ciprivate: 753bf215546Sopenharmony_ci std::map<const void *, void *> map; 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ciprotected: 756bf215546Sopenharmony_ci virtual void *lookup(void *obj) 757bf215546Sopenharmony_ci { 758bf215546Sopenharmony_ci return map[obj]; 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci virtual void insert(const void *obj, void *clone) 762bf215546Sopenharmony_ci { 763bf215546Sopenharmony_ci map[obj] = clone; 764bf215546Sopenharmony_ci } 765bf215546Sopenharmony_ci}; 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_citemplate<typename S, typename T> 768bf215546Sopenharmony_cistruct bimap 769bf215546Sopenharmony_ci{ 770bf215546Sopenharmony_ci std::map<S, T> forth; 771bf215546Sopenharmony_ci std::map<T, S> back; 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_cipublic: 774bf215546Sopenharmony_ci bimap() : l(back), r(forth) { } 775bf215546Sopenharmony_ci bimap(const bimap<S, T> &m) 776bf215546Sopenharmony_ci : forth(m.forth), back(m.back), l(back), r(forth) { } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci void insert(const S &s, const T &t) 779bf215546Sopenharmony_ci { 780bf215546Sopenharmony_ci forth.insert(std::make_pair(s, t)); 781bf215546Sopenharmony_ci back.insert(std::make_pair(t, s)); 782bf215546Sopenharmony_ci } 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci typedef typename std::map<T, S>::const_iterator l_iterator; 785bf215546Sopenharmony_ci const std::map<T, S> &l; 786bf215546Sopenharmony_ci typedef typename std::map<S, T>::const_iterator r_iterator; 787bf215546Sopenharmony_ci const std::map<S, T> &r; 788bf215546Sopenharmony_ci}; 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci} // namespace nv50_ir 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci#endif // __NV50_IR_UTIL_H__ 793