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#include "nv50_ir.h" 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_cinamespace nv50_ir { 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ciFunction::Function(Program *p, const char *fnName, uint32_t label) 28bf215546Sopenharmony_ci : call(this), 29bf215546Sopenharmony_ci label(label), 30bf215546Sopenharmony_ci name(fnName), 31bf215546Sopenharmony_ci prog(p) 32bf215546Sopenharmony_ci{ 33bf215546Sopenharmony_ci cfgExit = NULL; 34bf215546Sopenharmony_ci domTree = NULL; 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci bbArray = NULL; 37bf215546Sopenharmony_ci bbCount = 0; 38bf215546Sopenharmony_ci loopNestingBound = 0; 39bf215546Sopenharmony_ci regClobberMax = 0; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci binPos = 0; 42bf215546Sopenharmony_ci binSize = 0; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci stackPtr = NULL; 45bf215546Sopenharmony_ci tlsBase = 0; 46bf215546Sopenharmony_ci tlsSize = 0; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci prog->add(this, id); 49bf215546Sopenharmony_ci} 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ciFunction::~Function() 52bf215546Sopenharmony_ci{ 53bf215546Sopenharmony_ci prog->del(this, id); 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci if (domTree) 56bf215546Sopenharmony_ci delete domTree; 57bf215546Sopenharmony_ci if (bbArray) 58bf215546Sopenharmony_ci delete[] bbArray; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci // clear value refs and defs 61bf215546Sopenharmony_ci ins.clear(); 62bf215546Sopenharmony_ci outs.clear(); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci for (ArrayList::Iterator it = allInsns.iterator(); !it.end(); it.next()) 65bf215546Sopenharmony_ci delete_Instruction(prog, reinterpret_cast<Instruction *>(it.get())); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next()) 68bf215546Sopenharmony_ci delete_Value(prog, reinterpret_cast<LValue *>(it.get())); 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci for (ArrayList::Iterator BBs = allBBlocks.iterator(); !BBs.end(); BBs.next()) 71bf215546Sopenharmony_ci delete reinterpret_cast<BasicBlock *>(BBs.get()); 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ciBasicBlock::BasicBlock(Function *fn) : cfg(this), dom(this), func(fn) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci program = func->getProgram(); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci joinAt = phi = entry = exit = NULL; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci numInsns = 0; 81bf215546Sopenharmony_ci binPos = 0; 82bf215546Sopenharmony_ci binSize = 0; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci explicitCont = false; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci func->add(this, this->id); 87bf215546Sopenharmony_ci} 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ciBasicBlock::~BasicBlock() 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci // nothing yet 92bf215546Sopenharmony_ci} 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ciBasicBlock * 95bf215546Sopenharmony_ciBasicBlock::clone(ClonePolicy<Function>& pol) const 96bf215546Sopenharmony_ci{ 97bf215546Sopenharmony_ci BasicBlock *bb = new BasicBlock(pol.context()); 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci pol.set(this, bb); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci for (Instruction *i = getFirst(); i; i = i->next) 102bf215546Sopenharmony_ci bb->insertTail(i->clone(pol)); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci pol.context()->cfg.insert(&bb->cfg); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci for (Graph::EdgeIterator it = cfg.outgoing(); !it.end(); it.next()) { 107bf215546Sopenharmony_ci BasicBlock *obb = BasicBlock::get(it.getNode()); 108bf215546Sopenharmony_ci bb->cfg.attach(&pol.get(obb)->cfg, it.getType()); 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci return bb; 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ciBasicBlock * 115bf215546Sopenharmony_ciBasicBlock::idom() const 116bf215546Sopenharmony_ci{ 117bf215546Sopenharmony_ci Graph::Node *dn = dom.parent(); 118bf215546Sopenharmony_ci return dn ? BasicBlock::get(dn) : NULL; 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_civoid 122bf215546Sopenharmony_ciBasicBlock::insertHead(Instruction *inst) 123bf215546Sopenharmony_ci{ 124bf215546Sopenharmony_ci assert(inst->next == 0 && inst->prev == 0); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci if (inst->op == OP_PHI) { 127bf215546Sopenharmony_ci if (phi) { 128bf215546Sopenharmony_ci insertBefore(phi, inst); 129bf215546Sopenharmony_ci } else { 130bf215546Sopenharmony_ci if (entry) { 131bf215546Sopenharmony_ci insertBefore(entry, inst); 132bf215546Sopenharmony_ci } else { 133bf215546Sopenharmony_ci assert(!exit); 134bf215546Sopenharmony_ci phi = exit = inst; 135bf215546Sopenharmony_ci inst->bb = this; 136bf215546Sopenharmony_ci ++numInsns; 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci } else { 140bf215546Sopenharmony_ci if (entry) { 141bf215546Sopenharmony_ci insertBefore(entry, inst); 142bf215546Sopenharmony_ci } else { 143bf215546Sopenharmony_ci if (phi) { 144bf215546Sopenharmony_ci insertAfter(exit, inst); // after last phi 145bf215546Sopenharmony_ci } else { 146bf215546Sopenharmony_ci assert(!exit); 147bf215546Sopenharmony_ci entry = exit = inst; 148bf215546Sopenharmony_ci inst->bb = this; 149bf215546Sopenharmony_ci ++numInsns; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci} 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_civoid 156bf215546Sopenharmony_ciBasicBlock::insertTail(Instruction *inst) 157bf215546Sopenharmony_ci{ 158bf215546Sopenharmony_ci assert(inst->next == 0 && inst->prev == 0); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci if (inst->op == OP_PHI) { 161bf215546Sopenharmony_ci if (entry) { 162bf215546Sopenharmony_ci insertBefore(entry, inst); 163bf215546Sopenharmony_ci } else 164bf215546Sopenharmony_ci if (exit) { 165bf215546Sopenharmony_ci assert(phi); 166bf215546Sopenharmony_ci insertAfter(exit, inst); 167bf215546Sopenharmony_ci } else { 168bf215546Sopenharmony_ci assert(!phi); 169bf215546Sopenharmony_ci phi = exit = inst; 170bf215546Sopenharmony_ci inst->bb = this; 171bf215546Sopenharmony_ci ++numInsns; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci } else { 174bf215546Sopenharmony_ci if (exit) { 175bf215546Sopenharmony_ci insertAfter(exit, inst); 176bf215546Sopenharmony_ci } else { 177bf215546Sopenharmony_ci assert(!phi); 178bf215546Sopenharmony_ci entry = exit = inst; 179bf215546Sopenharmony_ci inst->bb = this; 180bf215546Sopenharmony_ci ++numInsns; 181bf215546Sopenharmony_ci } 182bf215546Sopenharmony_ci } 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_civoid 186bf215546Sopenharmony_ciBasicBlock::insertBefore(Instruction *q, Instruction *p) 187bf215546Sopenharmony_ci{ 188bf215546Sopenharmony_ci assert(p && q); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci assert(p->next == 0 && p->prev == 0); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (q == entry) { 193bf215546Sopenharmony_ci if (p->op == OP_PHI) { 194bf215546Sopenharmony_ci if (!phi) 195bf215546Sopenharmony_ci phi = p; 196bf215546Sopenharmony_ci } else { 197bf215546Sopenharmony_ci entry = p; 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci } else 200bf215546Sopenharmony_ci if (q == phi) { 201bf215546Sopenharmony_ci assert(p->op == OP_PHI); 202bf215546Sopenharmony_ci phi = p; 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci p->next = q; 206bf215546Sopenharmony_ci p->prev = q->prev; 207bf215546Sopenharmony_ci if (p->prev) 208bf215546Sopenharmony_ci p->prev->next = p; 209bf215546Sopenharmony_ci q->prev = p; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci p->bb = this; 212bf215546Sopenharmony_ci ++numInsns; 213bf215546Sopenharmony_ci} 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_civoid 216bf215546Sopenharmony_ciBasicBlock::insertAfter(Instruction *p, Instruction *q) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci assert(p && q); 219bf215546Sopenharmony_ci assert(q->op != OP_PHI || p->op == OP_PHI); 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci assert(q->next == 0 && q->prev == 0); 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (p == exit) 224bf215546Sopenharmony_ci exit = q; 225bf215546Sopenharmony_ci if (p->op == OP_PHI && q->op != OP_PHI) 226bf215546Sopenharmony_ci entry = q; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci q->prev = p; 229bf215546Sopenharmony_ci q->next = p->next; 230bf215546Sopenharmony_ci if (q->next) 231bf215546Sopenharmony_ci q->next->prev = q; 232bf215546Sopenharmony_ci p->next = q; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci q->bb = this; 235bf215546Sopenharmony_ci ++numInsns; 236bf215546Sopenharmony_ci} 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_civoid 239bf215546Sopenharmony_ciBasicBlock::remove(Instruction *insn) 240bf215546Sopenharmony_ci{ 241bf215546Sopenharmony_ci assert(insn->bb == this); 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci if (insn->prev) 244bf215546Sopenharmony_ci insn->prev->next = insn->next; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci if (insn->next) 247bf215546Sopenharmony_ci insn->next->prev = insn->prev; 248bf215546Sopenharmony_ci else 249bf215546Sopenharmony_ci exit = insn->prev; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (insn == entry) { 252bf215546Sopenharmony_ci if (insn->next) 253bf215546Sopenharmony_ci entry = insn->next; 254bf215546Sopenharmony_ci else 255bf215546Sopenharmony_ci if (insn->prev && insn->prev->op != OP_PHI) 256bf215546Sopenharmony_ci entry = insn->prev; 257bf215546Sopenharmony_ci else 258bf215546Sopenharmony_ci entry = NULL; 259bf215546Sopenharmony_ci } 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci if (insn == phi) 262bf215546Sopenharmony_ci phi = (insn->next && insn->next->op == OP_PHI) ? insn->next : 0; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci --numInsns; 265bf215546Sopenharmony_ci insn->bb = NULL; 266bf215546Sopenharmony_ci insn->next = 267bf215546Sopenharmony_ci insn->prev = NULL; 268bf215546Sopenharmony_ci} 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_civoid BasicBlock::permuteAdjacent(Instruction *a, Instruction *b) 271bf215546Sopenharmony_ci{ 272bf215546Sopenharmony_ci assert(a->bb == b->bb); 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci if (a->next != b) { 275bf215546Sopenharmony_ci Instruction *i = a; 276bf215546Sopenharmony_ci a = b; 277bf215546Sopenharmony_ci b = i; 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci assert(a->next == b); 280bf215546Sopenharmony_ci assert(a->op != OP_PHI && b->op != OP_PHI); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci if (b == exit) 283bf215546Sopenharmony_ci exit = a; 284bf215546Sopenharmony_ci if (a == entry) 285bf215546Sopenharmony_ci entry = b; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci b->prev = a->prev; 288bf215546Sopenharmony_ci a->next = b->next; 289bf215546Sopenharmony_ci b->next = a; 290bf215546Sopenharmony_ci a->prev = b; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci if (b->prev) 293bf215546Sopenharmony_ci b->prev->next = b; 294bf215546Sopenharmony_ci if (a->next) 295bf215546Sopenharmony_ci a->next->prev = a; 296bf215546Sopenharmony_ci} 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_civoid 299bf215546Sopenharmony_ciBasicBlock::splitCommon(Instruction *insn, BasicBlock *bb, bool attach) 300bf215546Sopenharmony_ci{ 301bf215546Sopenharmony_ci bb->entry = insn; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if (insn) { 304bf215546Sopenharmony_ci exit = insn->prev; 305bf215546Sopenharmony_ci insn->prev = NULL; 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci if (exit) 309bf215546Sopenharmony_ci exit->next = NULL; 310bf215546Sopenharmony_ci else 311bf215546Sopenharmony_ci entry = NULL; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci while (!cfg.outgoing(true).end()) { 314bf215546Sopenharmony_ci Graph::Edge *e = cfg.outgoing(true).getEdge(); 315bf215546Sopenharmony_ci bb->cfg.attach(e->getTarget(), e->getType()); 316bf215546Sopenharmony_ci this->cfg.detach(e->getTarget()); 317bf215546Sopenharmony_ci } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci for (; insn; insn = insn->next) { 320bf215546Sopenharmony_ci this->numInsns--; 321bf215546Sopenharmony_ci bb->numInsns++; 322bf215546Sopenharmony_ci insn->bb = bb; 323bf215546Sopenharmony_ci bb->exit = insn; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci if (attach) 326bf215546Sopenharmony_ci this->cfg.attach(&bb->cfg, Graph::Edge::TREE); 327bf215546Sopenharmony_ci} 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ciBasicBlock * 330bf215546Sopenharmony_ciBasicBlock::splitBefore(Instruction *insn, bool attach) 331bf215546Sopenharmony_ci{ 332bf215546Sopenharmony_ci BasicBlock *bb = new BasicBlock(func); 333bf215546Sopenharmony_ci assert(!insn || insn->op != OP_PHI); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci bb->joinAt = joinAt; 336bf215546Sopenharmony_ci joinAt = NULL; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci splitCommon(insn, bb, attach); 339bf215546Sopenharmony_ci return bb; 340bf215546Sopenharmony_ci} 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ciBasicBlock * 343bf215546Sopenharmony_ciBasicBlock::splitAfter(Instruction *insn, bool attach) 344bf215546Sopenharmony_ci{ 345bf215546Sopenharmony_ci BasicBlock *bb = new BasicBlock(func); 346bf215546Sopenharmony_ci assert(!insn || insn->op != OP_PHI); 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci bb->joinAt = joinAt; 349bf215546Sopenharmony_ci joinAt = NULL; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci splitCommon(insn ? insn->next : NULL, bb, attach); 352bf215546Sopenharmony_ci return bb; 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_cibool 356bf215546Sopenharmony_ciBasicBlock::dominatedBy(BasicBlock *that) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci Graph::Node *bn = &that->dom; 359bf215546Sopenharmony_ci Graph::Node *dn = &this->dom; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci while (dn && dn != bn) 362bf215546Sopenharmony_ci dn = dn->parent(); 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci return dn != NULL; 365bf215546Sopenharmony_ci} 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ciunsigned int 368bf215546Sopenharmony_ciBasicBlock::initiatesSimpleConditional() const 369bf215546Sopenharmony_ci{ 370bf215546Sopenharmony_ci Graph::Node *out[2]; 371bf215546Sopenharmony_ci int n; 372bf215546Sopenharmony_ci Graph::Edge::Type eR; 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (cfg.outgoingCount() != 2) // -> if and -> else/endif 375bf215546Sopenharmony_ci return false; 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci n = 0; 378bf215546Sopenharmony_ci for (Graph::EdgeIterator ei = cfg.outgoing(); !ei.end(); ei.next()) 379bf215546Sopenharmony_ci out[n++] = ei.getNode(); 380bf215546Sopenharmony_ci eR = out[1]->outgoing().getType(); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci // IF block is out edge to the right 383bf215546Sopenharmony_ci if (eR == Graph::Edge::CROSS || eR == Graph::Edge::BACK) 384bf215546Sopenharmony_ci return 0x2; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if (out[1]->outgoingCount() != 1) // 0 is IF { RET; }, >1 is more divergence 387bf215546Sopenharmony_ci return 0x0; 388bf215546Sopenharmony_ci // do they reconverge immediately ? 389bf215546Sopenharmony_ci if (out[1]->outgoing().getNode() == out[0]) 390bf215546Sopenharmony_ci return 0x1; 391bf215546Sopenharmony_ci if (out[0]->outgoingCount() == 1) 392bf215546Sopenharmony_ci if (out[0]->outgoing().getNode() == out[1]->outgoing().getNode()) 393bf215546Sopenharmony_ci return 0x3; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci return 0x0; 396bf215546Sopenharmony_ci} 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_cibool 399bf215546Sopenharmony_ciFunction::setEntry(BasicBlock *bb) 400bf215546Sopenharmony_ci{ 401bf215546Sopenharmony_ci if (cfg.getRoot()) 402bf215546Sopenharmony_ci return false; 403bf215546Sopenharmony_ci cfg.insert(&bb->cfg); 404bf215546Sopenharmony_ci return true; 405bf215546Sopenharmony_ci} 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_cibool 408bf215546Sopenharmony_ciFunction::setExit(BasicBlock *bb) 409bf215546Sopenharmony_ci{ 410bf215546Sopenharmony_ci if (cfgExit) 411bf215546Sopenharmony_ci return false; 412bf215546Sopenharmony_ci cfgExit = &bb->cfg; 413bf215546Sopenharmony_ci return true; 414bf215546Sopenharmony_ci} 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ciunsigned int 417bf215546Sopenharmony_ciFunction::orderInstructions(ArrayList &result) 418bf215546Sopenharmony_ci{ 419bf215546Sopenharmony_ci result.clear(); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci for (IteratorRef it = cfg.iteratorCFG(); !it->end(); it->next()) { 422bf215546Sopenharmony_ci BasicBlock *bb = 423bf215546Sopenharmony_ci BasicBlock::get(reinterpret_cast<Graph::Node *>(it->get())); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci for (Instruction *insn = bb->getFirst(); insn; insn = insn->next) 426bf215546Sopenharmony_ci result.insert(insn, insn->serial); 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci return result.getSize(); 430bf215546Sopenharmony_ci} 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_civoid 433bf215546Sopenharmony_ciFunction::buildLiveSets() 434bf215546Sopenharmony_ci{ 435bf215546Sopenharmony_ci for (unsigned i = 0; i <= loopNestingBound; ++i) 436bf215546Sopenharmony_ci buildLiveSetsPreSSA(BasicBlock::get(cfg.getRoot()), cfg.nextSequence()); 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci for (ArrayList::Iterator bi = allBBlocks.iterator(); !bi.end(); bi.next()) 439bf215546Sopenharmony_ci BasicBlock::get(bi)->liveSet.marker = false; 440bf215546Sopenharmony_ci} 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_civoid 443bf215546Sopenharmony_ciFunction::buildDefSets() 444bf215546Sopenharmony_ci{ 445bf215546Sopenharmony_ci for (unsigned i = 0; i <= loopNestingBound; ++i) 446bf215546Sopenharmony_ci buildDefSetsPreSSA(BasicBlock::get(cfgExit), cfg.nextSequence()); 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci for (ArrayList::Iterator bi = allBBlocks.iterator(); !bi.end(); bi.next()) 449bf215546Sopenharmony_ci BasicBlock::get(bi)->liveSet.marker = false; 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cibool 453bf215546Sopenharmony_ciPass::run(Program *prog, bool ordered, bool skipPhi) 454bf215546Sopenharmony_ci{ 455bf215546Sopenharmony_ci this->prog = prog; 456bf215546Sopenharmony_ci err = false; 457bf215546Sopenharmony_ci return doRun(prog, ordered, skipPhi); 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_cibool 461bf215546Sopenharmony_ciPass::doRun(Program *prog, bool ordered, bool skipPhi) 462bf215546Sopenharmony_ci{ 463bf215546Sopenharmony_ci for (IteratorRef it = prog->calls.iteratorDFS(false); 464bf215546Sopenharmony_ci !it->end(); it->next()) { 465bf215546Sopenharmony_ci Graph::Node *n = reinterpret_cast<Graph::Node *>(it->get()); 466bf215546Sopenharmony_ci if (!doRun(Function::get(n), ordered, skipPhi)) 467bf215546Sopenharmony_ci return false; 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci return !err; 470bf215546Sopenharmony_ci} 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_cibool 473bf215546Sopenharmony_ciPass::run(Function *func, bool ordered, bool skipPhi) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci prog = func->getProgram(); 476bf215546Sopenharmony_ci err = false; 477bf215546Sopenharmony_ci return doRun(func, ordered, skipPhi); 478bf215546Sopenharmony_ci} 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_cibool 481bf215546Sopenharmony_ciPass::doRun(Function *func, bool ordered, bool skipPhi) 482bf215546Sopenharmony_ci{ 483bf215546Sopenharmony_ci IteratorRef bbIter; 484bf215546Sopenharmony_ci BasicBlock *bb; 485bf215546Sopenharmony_ci Instruction *insn, *next; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci this->func = func; 488bf215546Sopenharmony_ci if (!visit(func)) 489bf215546Sopenharmony_ci return false; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci bbIter = ordered ? func->cfg.iteratorCFG() : func->cfg.iteratorDFS(); 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci for (; !bbIter->end(); bbIter->next()) { 494bf215546Sopenharmony_ci bb = BasicBlock::get(reinterpret_cast<Graph::Node *>(bbIter->get())); 495bf215546Sopenharmony_ci if (!visit(bb)) 496bf215546Sopenharmony_ci break; 497bf215546Sopenharmony_ci for (insn = skipPhi ? bb->getEntry() : bb->getFirst(); insn != NULL; 498bf215546Sopenharmony_ci insn = next) { 499bf215546Sopenharmony_ci next = insn->next; 500bf215546Sopenharmony_ci if (!visit(insn)) 501bf215546Sopenharmony_ci break; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci } 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci return !err; 506bf215546Sopenharmony_ci} 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_civoid 509bf215546Sopenharmony_ciFunction::printCFGraph(const char *filePath) 510bf215546Sopenharmony_ci{ 511bf215546Sopenharmony_ci FILE *out = fopen(filePath, "a"); 512bf215546Sopenharmony_ci if (!out) { 513bf215546Sopenharmony_ci ERROR("failed to open file: %s\n", filePath); 514bf215546Sopenharmony_ci return; 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci INFO("printing control flow graph to: %s\n", filePath); 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci fprintf(out, "digraph G {\n"); 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci for (IteratorRef it = cfg.iteratorDFS(); !it->end(); it->next()) { 521bf215546Sopenharmony_ci BasicBlock *bb = BasicBlock::get( 522bf215546Sopenharmony_ci reinterpret_cast<Graph::Node *>(it->get())); 523bf215546Sopenharmony_ci int idA = bb->getId(); 524bf215546Sopenharmony_ci for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) { 525bf215546Sopenharmony_ci int idB = BasicBlock::get(ei.getNode())->getId(); 526bf215546Sopenharmony_ci switch (ei.getType()) { 527bf215546Sopenharmony_ci case Graph::Edge::TREE: 528bf215546Sopenharmony_ci fprintf(out, "\t%i -> %i;\n", idA, idB); 529bf215546Sopenharmony_ci break; 530bf215546Sopenharmony_ci case Graph::Edge::FORWARD: 531bf215546Sopenharmony_ci fprintf(out, "\t%i -> %i [color=green];\n", idA, idB); 532bf215546Sopenharmony_ci break; 533bf215546Sopenharmony_ci case Graph::Edge::CROSS: 534bf215546Sopenharmony_ci fprintf(out, "\t%i -> %i [color=red];\n", idA, idB); 535bf215546Sopenharmony_ci break; 536bf215546Sopenharmony_ci case Graph::Edge::BACK: 537bf215546Sopenharmony_ci fprintf(out, "\t%i -> %i;\n", idA, idB); 538bf215546Sopenharmony_ci break; 539bf215546Sopenharmony_ci default: 540bf215546Sopenharmony_ci assert(0); 541bf215546Sopenharmony_ci break; 542bf215546Sopenharmony_ci } 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci fprintf(out, "}\n"); 547bf215546Sopenharmony_ci fclose(out); 548bf215546Sopenharmony_ci} 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci} // namespace nv50_ir 551