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);
~DominatorTree()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 
debugPrint()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 
DominatorTree(Graph * cfgraph)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 
buildDFS(Graph::Node * node)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 
squash(int v)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 
eval(int v)120 int DominatorTree::eval(int v)
121 {
122    if (ANCESTOR(v) < 0)
123       return v;
124    squash(v);
125    return LABEL(v);
126 }
127 
link(int v,int w)128 void DominatorTree::link(int v, int w)
129 {
130    ANCESTOR(w) = v;
131 }
132 
build()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 
findDominanceFrontiers()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
buildLiveSetsPreSSA(BasicBlock * bb,const int seq)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
buildDefSetsPreSSA(BasicBlock * bb,const int seq)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
convertToSSA()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
convertToSSA()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 
RenamePass(Function * fn)404 RenamePass::RenamePass(Function *fn) : func(fn), prog(fn->getProgram())
405 {
406    stack = new Stack[func->allLValues.getSize()];
407 }
408 
~RenamePass()409 RenamePass::~RenamePass()
410 {
411    if (stack)
412       delete[] stack;
413 }
414 
415 LValue *
getStackTop(Value * val)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 *
mkUndefined(Value * val)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 
run()435 bool RenamePass::run()
436 {
437    if (!stack)
438       return false;
439    search(BasicBlock::get(func->domTree->getRoot()));
440 
441    return true;
442 }
443 
search(BasicBlock * bb)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