Home | History | Annotate | Download | only in codegen
      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.h"
     24 #include "nv50_ir_target.h"
     25 
     26 namespace nv50_ir {
     27 
     28 // Converts nv50 IR generated from TGSI to SSA form.
     29 
     30 // DominatorTree implements an algorithm for finding immediate dominators,
     31 // as described by T. Lengauer & R. Tarjan.
     32 class DominatorTree : public Graph
     33 {
     34 public:
     35    DominatorTree(Graph *cfg);
     36    ~DominatorTree() { }
     37 
     38    bool dominates(BasicBlock *, BasicBlock *);
     39 
     40    void findDominanceFrontiers();
     41 
     42 private:
     43    void build();
     44    void buildDFS(Node *);
     45 
     46    void squash(int);
     47    inline void link(int, int);
     48    inline int eval(int);
     49 
     50    void debugPrint();
     51 
     52    Graph *cfg;
     53 
     54    Node **vert;
     55    int *data;
     56    const int count;
     57 
     58    #define SEMI(i)     (data[(i) + 0 * count])
     59    #define ANCESTOR(i) (data[(i) + 1 * count])
     60    #define PARENT(i)   (data[(i) + 2 * count])
     61    #define LABEL(i)    (data[(i) + 3 * count])
     62    #define DOM(i)      (data[(i) + 4 * count])
     63 };
     64 
     65 void DominatorTree::debugPrint()
     66 {
     67    for (int i = 0; i < count; ++i) {
     68       INFO("SEMI(%i) = %i\n", i, SEMI(i));
     69       INFO("ANCESTOR(%i) = %i\n", i, ANCESTOR(i));
     70       INFO("PARENT(%i) = %i\n", i, PARENT(i));
     71       INFO("LABEL(%i) = %i\n", i, LABEL(i));
     72       INFO("DOM(%i) = %i\n", i, DOM(i));
     73    }
     74 }
     75 
     76 DominatorTree::DominatorTree(Graph *cfgraph) : cfg(cfgraph),
     77                                                count(cfg->getSize())
     78 {
     79    int i = 0;
     80 
     81    vert = new Node * [count];
     82    data = new int[5 * count];
     83 
     84    for (IteratorRef it = cfg->iteratorDFS(true); !it->end(); it->next(), ++i) {
     85       vert[i] = reinterpret_cast<Node *>(it->get());
     86       vert[i]->tag = i;
     87       LABEL(i) = i;
     88       SEMI(i) = ANCESTOR(i) = -1;
     89    }
     90 
     91    build();
     92 
     93    delete[] vert;
     94    delete[] data;
     95 }
     96 
     97 void DominatorTree::buildDFS(Graph::Node *node)
     98 {
     99    SEMI(node->tag) = node->tag;
    100 
    101    for (Graph::EdgeIterator ei = node->outgoing(); !ei.end(); ei.next()) {
    102       if (SEMI(ei.getNode()->tag) < 0) {
    103          buildDFS(ei.getNode());
    104          PARENT(ei.getNode()->tag) = node->tag;
    105       }
    106    }
    107 }
    108 
    109 void DominatorTree::squash(int v)
    110 {
    111    if (ANCESTOR(ANCESTOR(v)) >= 0) {
    112       squash(ANCESTOR(v));
    113 
    114       if (SEMI(LABEL(ANCESTOR(v))) < SEMI(LABEL(v)))
    115          LABEL(v) = LABEL(ANCESTOR(v));
    116       ANCESTOR(v) = ANCESTOR(ANCESTOR(v));
    117    }
    118 }
    119 
    120 int DominatorTree::eval(int v)
    121 {
    122    if (ANCESTOR(v) < 0)
    123       return v;
    124    squash(v);
    125    return LABEL(v);
    126 }
    127 
    128 void DominatorTree::link(int v, int w)
    129 {
    130    ANCESTOR(w) = v;
    131 }
    132 
    133 void DominatorTree::build()
    134 {
    135    DLList *bucket = new DLList[count];
    136    Node *nv, *nw;
    137    int p, u, v, w;
    138 
    139    buildDFS(cfg->getRoot());
    140 
    141    for (w = count - 1; w >= 1; --w) {
    142       nw = vert[w];
    143       assert(nw->tag == w);
    144       for (Graph::EdgeIterator ei = nw->incident(); !ei.end(); ei.next()) {
    145          nv = ei.getNode();
    146          v = nv->tag;
    147          u = eval(v);
    148          if (SEMI(u) < SEMI(w))
    149             SEMI(w) = SEMI(u);
    150       }
    151       p = PARENT(w);
    152       bucket[SEMI(w)].insert(nw);
    153       link(p, w);
    154 
    155       for (DLList::Iterator it = bucket[p].iterator(); !it.end(); it.erase()) {
    156          v = reinterpret_cast<Node *>(it.get())->tag;
    157          u = eval(v);
    158          DOM(v) = (SEMI(u) < SEMI(v)) ? u : p;
    159       }
    160    }
    161    for (w = 1; w < count; ++w) {
    162       if (DOM(w) != SEMI(w))
    163          DOM(w) = DOM(DOM(w));
    164    }
    165    DOM(0) = 0;
    166 
    167    insert(&BasicBlock::get(cfg->getRoot())->dom);
    168    do {
    169       p = 0;
    170       for (v = 1; v < count; ++v) {
    171          nw = &BasicBlock::get(vert[DOM(v)])->dom;;
    172          nv = &BasicBlock::get(vert[v])->dom;
    173          if (nw->getGraph() && !nv->getGraph()) {
    174             ++p;
    175             nw->attach(nv, Graph::Edge::TREE);
    176          }
    177       }
    178    } while (p);
    179 
    180    delete[] bucket;
    181 }
    182 
    183 #undef SEMI
    184 #undef ANCESTOR
    185 #undef PARENT
    186 #undef LABEL
    187 #undef DOM
    188 
    189 void DominatorTree::findDominanceFrontiers()
    190 {
    191    BasicBlock *bb;
    192 
    193    for (IteratorRef dtIt = iteratorDFS(false); !dtIt->end(); dtIt->next()) {
    194       EdgeIterator succIt, chldIt;
    195 
    196       bb = BasicBlock::get(reinterpret_cast<Node *>(dtIt->get()));
    197       bb->getDF().clear();
    198 
    199       for (succIt = bb->cfg.outgoing(); !succIt.end(); succIt.next()) {
    200          BasicBlock *dfLocal = BasicBlock::get(succIt.getNode());
    201          if (dfLocal->idom() != bb)
    202             bb->getDF().insert(dfLocal);
    203       }
    204 
    205       for (chldIt = bb->dom.outgoing(); !chldIt.end(); chldIt.next()) {
    206          BasicBlock *cb = BasicBlock::get(chldIt.getNode());
    207 
    208          DLList::Iterator dfIt = cb->getDF().iterator();
    209          for (; !dfIt.end(); dfIt.next()) {
    210             BasicBlock *dfUp = BasicBlock::get(dfIt);
    211             if (dfUp->idom() != bb)
    212                bb->getDF().insert(dfUp);
    213          }
    214       }
    215    }
    216 }
    217 
    218 // liveIn(bb) = usedBeforeAssigned(bb) U (liveOut(bb) - assigned(bb))
    219 void
    220 Function::buildLiveSetsPreSSA(BasicBlock *bb, const int seq)
    221 {
    222    Function *f = bb->getFunction();
    223    BitSet usedBeforeAssigned(allLValues.getSize(), true);
    224    BitSet assigned(allLValues.getSize(), true);
    225 
    226    bb->liveSet.allocate(allLValues.getSize(), false);
    227 
    228    int n = 0;
    229    for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
    230       BasicBlock *out = BasicBlock::get(ei.getNode());
    231       if (out == bb)
    232          continue;
    233       if (out->cfg.visit(seq))
    234          buildLiveSetsPreSSA(out, seq);
    235       if (!n++)
    236          bb->liveSet = out->liveSet;
    237       else
    238          bb->liveSet |= out->liveSet;
    239    }
    240    if (!n && !bb->liveSet.marker)
    241       bb->liveSet.fill(0);
    242    bb->liveSet.marker = true;
    243 
    244    for (Instruction *i = bb->getEntry(); i; i = i->next) {
    245       for (int s = 0; i->srcExists(s); ++s)
    246          if (i->getSrc(s)->asLValue() && !assigned.test(i->getSrc(s)->id))
    247             usedBeforeAssigned.set(i->getSrc(s)->id);
    248       for (int d = 0; i->defExists(d); ++d)
    249          assigned.set(i->getDef(d)->id);
    250    }
    251 
    252    if (bb == BasicBlock::get(f->cfgExit)) {
    253       for (std::deque<ValueRef>::iterator it = f->outs.begin();
    254            it != f->outs.end(); ++it) {
    255          if (!assigned.test(it->get()->id))
    256             usedBeforeAssigned.set(it->get()->id);
    257       }
    258    }
    259 
    260    bb->liveSet.andNot(assigned);
    261    bb->liveSet |= usedBeforeAssigned;
    262 }
    263 
    264 void
    265 Function::buildDefSetsPreSSA(BasicBlock *bb, const int seq)
    266 {
    267    bb->defSet.allocate(allLValues.getSize(), !bb->liveSet.marker);
    268    bb->liveSet.marker = true;
    269 
    270    for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
    271       BasicBlock *in = BasicBlock::get(ei.getNode());
    272 
    273       if (in->cfg.visit(seq))
    274          buildDefSetsPreSSA(in, seq);
    275 
    276       bb->defSet |= in->defSet;
    277    }
    278 
    279    for (Instruction *i = bb->getEntry(); i; i = i->next) {
    280       for (int d = 0; i->defExists(d); ++d)
    281          bb->defSet.set(i->getDef(d)->id);
    282    }
    283 }
    284 
    285 class RenamePass
    286 {
    287 public:
    288    RenamePass(Function *);
    289    ~RenamePass();
    290 
    291    bool run();
    292    void search(BasicBlock *);
    293 
    294    inline LValue *getStackTop(Value *);
    295 
    296    LValue *mkUndefined(Value *);
    297 
    298 private:
    299    Stack *stack;
    300    Function *func;
    301    Program *prog;
    302 };
    303 
    304 bool
    305 Program::convertToSSA()
    306 {
    307    for (ArrayList::Iterator fi = allFuncs.iterator(); !fi.end(); fi.next()) {
    308       Function *fn = reinterpret_cast<Function *>(fi.get());
    309       if (!fn->convertToSSA())
    310          return false;
    311    }
    312    return true;
    313 }
    314 
    315 // XXX: add edge from entry to exit ?
    316 
    317 // Efficiently Computing Static Single Assignment Form and
    318 //  the Control Dependence Graph,
    319 // R. Cytron, J. Ferrante, B. K. Rosen, M. N. Wegman, F. K. Zadeck
    320 bool
    321 Function::convertToSSA()
    322 {
    323    // 0. calculate live in variables (for pruned SSA)
    324    buildLiveSets();
    325 
    326    // 1. create the dominator tree
    327    domTree = new DominatorTree(&cfg);
    328    reinterpret_cast<DominatorTree *>(domTree)->findDominanceFrontiers();
    329 
    330    // 2. insert PHI functions
    331    DLList workList;
    332    LValue *lval;
    333    BasicBlock *bb;
    334    int var;
    335    int iterCount = 0;
    336    int *hasAlready = new int[allBBlocks.getSize() * 2];
    337    int *work = &hasAlready[allBBlocks.getSize()];
    338 
    339    memset(hasAlready, 0, allBBlocks.getSize() * 2 * sizeof(int));
    340 
    341    // for each variable
    342    for (var = 0; var < allLValues.getSize(); ++var) {
    343       if (!allLValues.get(var))
    344          continue;
    345       lval = reinterpret_cast<Value *>(allLValues.get(var))->asLValue();
    346       if (!lval || lval->defs.empty())
    347          continue;
    348       ++iterCount;
    349 
    350       // TODO: don't add phi functions for values that aren't used outside
    351       //  the BB they're defined in
    352 
    353       // gather blocks with assignments to lval in workList
    354       for (Value::DefIterator d = lval->defs.begin();
    355            d != lval->defs.end(); ++d) {
    356          bb = ((*d)->getInsn() ? (*d)->getInsn()->bb : NULL);
    357          if (!bb)
    358             continue; // instruction likely been removed but not XXX deleted
    359 
    360          if (work[bb->getId()] == iterCount)
    361             continue;
    362          work[bb->getId()] = iterCount;
    363          workList.insert(bb);
    364       }
    365 
    366       // for each block in workList, insert a phi for lval in the block's
    367       //  dominance frontier (if we haven't already done so)
    368       for (DLList::Iterator wI = workList.iterator(); !wI.end(); wI.erase()) {
    369          bb = BasicBlock::get(wI);
    370 
    371          DLList::Iterator dfIter = bb->getDF().iterator();
    372          for (; !dfIter.end(); dfIter.next()) {
    373             Instruction *phi;
    374             BasicBlock *dfBB = BasicBlock::get(dfIter);
    375 
    376             if (hasAlready[dfBB->getId()] >= iterCount)
    377                continue;
    378             hasAlready[dfBB->getId()] = iterCount;
    379 
    380             // pruned SSA: don't need a phi if the value is not live-in
    381             if (!dfBB->liveSet.test(lval->id))
    382                continue;
    383 
    384             phi = new_Instruction(this, OP_PHI, typeOfSize(lval->reg.size));
    385             dfBB->insertTail(phi);
    386 
    387             phi->setDef(0, lval);
    388             for (int s = 0; s < dfBB->cfg.incidentCount(); ++s)
    389                phi->setSrc(s, lval);
    390 
    391             if (work[dfBB->getId()] < iterCount) {
    392                work[dfBB->getId()] = iterCount;
    393                wI.insert(dfBB);
    394             }
    395          }
    396       }
    397    }
    398    delete[] hasAlready;
    399 
    400    RenamePass rename(this);
    401    return rename.run();
    402 }
    403 
    404 RenamePass::RenamePass(Function *fn) : func(fn), prog(fn->getProgram())
    405 {
    406    stack = new Stack[func->allLValues.getSize()];
    407 }
    408 
    409 RenamePass::~RenamePass()
    410 {
    411    if (stack)
    412       delete[] stack;
    413 }
    414 
    415 LValue *
    416 RenamePass::getStackTop(Value *val)
    417 {
    418    if (!stack[val->id].getSize())
    419       return 0;
    420    return reinterpret_cast<LValue *>(stack[val->id].peek().u.p);
    421 }
    422 
    423 LValue *
    424 RenamePass::mkUndefined(Value *val)
    425 {
    426    LValue *lval = val->asLValue();
    427    assert(lval);
    428    LValue *ud = new_LValue(func, lval);
    429    Instruction *nop = new_Instruction(func, OP_NOP, typeOfSize(lval->reg.size));
    430    nop->setDef(0, ud);
    431    BasicBlock::get(func->cfg.getRoot())->insertHead(nop);
    432    return ud;
    433 }
    434 
    435 bool RenamePass::run()
    436 {
    437    if (!stack)
    438       return false;
    439    search(BasicBlock::get(func->domTree->getRoot()));
    440 
    441    return true;
    442 }
    443 
    444 void RenamePass::search(BasicBlock *bb)
    445 {
    446    LValue *lval, *ssa;
    447    int d, s;
    448    const Target *targ = prog->getTarget();
    449 
    450    if (bb == BasicBlock::get(func->cfg.getRoot())) {
    451       for (std::deque<ValueDef>::iterator it = func->ins.begin();
    452            it != func->ins.end(); ++it) {
    453          lval = it->get()->asLValue();
    454          assert(lval);
    455 
    456          ssa = new_LValue(func, targ->nativeFile(lval->reg.file));
    457          ssa->reg.size = lval->reg.size;
    458          ssa->reg.data.id = lval->reg.data.id;
    459 
    460          it->setSSA(ssa);
    461          stack[lval->id].push(ssa);
    462       }
    463    }
    464 
    465    for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
    466       if (stmt->op != OP_PHI) {
    467          for (s = 0; stmt->srcExists(s); ++s) {
    468             lval = stmt->getSrc(s)->asLValue();
    469             if (!lval)
    470                continue;
    471             lval = getStackTop(lval);
    472             if (!lval)
    473                lval = mkUndefined(stmt->getSrc(s));
    474             stmt->setSrc(s, lval);
    475          }
    476       }
    477       for (d = 0; stmt->defExists(d); ++d) {
    478          lval = stmt->def(d).get()->asLValue();
    479          assert(lval);
    480          stmt->def(d).setSSA(
    481             new_LValue(func, targ->nativeFile(lval->reg.file)));
    482          stmt->def(d).get()->reg.size = lval->reg.size;
    483          stmt->def(d).get()->reg.data.id = lval->reg.data.id;
    484          stack[lval->id].push(stmt->def(d).get());
    485       }
    486    }
    487 
    488    for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
    489       Instruction *phi;
    490       int p = 0;
    491       BasicBlock *sb = BasicBlock::get(ei.getNode());
    492 
    493       // which predecessor of sb is bb ?
    494       for (Graph::EdgeIterator ei = sb->cfg.incident(); !ei.end(); ei.next()) {
    495          if (ei.getNode() == &bb->cfg)
    496             break;
    497          ++p;
    498       }
    499       assert(p < sb->cfg.incidentCount());
    500 
    501       for (phi = sb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
    502          lval = getStackTop(phi->getSrc(p));
    503          if (!lval)
    504             lval = mkUndefined(phi->getSrc(p));
    505          phi->setSrc(p, lval);
    506       }
    507    }
    508 
    509    for (Graph::EdgeIterator ei = bb->dom.outgoing(); !ei.end(); ei.next())
    510       search(BasicBlock::get(ei.getNode()));
    511 
    512    if (bb == BasicBlock::get(func->cfgExit)) {
    513       for (std::deque<ValueRef>::iterator it = func->outs.begin();
    514            it != func->outs.end(); ++it) {
    515          lval = it->get()->asLValue();
    516          if (!lval)
    517             continue;
    518          lval = getStackTop(lval);
    519          if (!lval)
    520             lval = mkUndefined(it->get());
    521          it->set(lval);
    522       }
    523    }
    524 
    525    for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
    526       if (stmt->op == OP_NOP)
    527          continue;
    528       for (d = 0; stmt->defExists(d); ++d)
    529          stack[stmt->def(d).preSSA()->id].pop();
    530    }
    531 }
    532 
    533 } // namespace nv50_ir
    534