Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 * OTHER DEALINGS IN THE 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(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(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(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::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(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(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(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(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
// Go through BBs in dominance order, create new values for each definition,
445
// and replace all sources with their current new values.
446
//
447
// NOTE: The values generated for function inputs/outputs have no connection
448
// to their corresponding outputs/inputs in other functions. Only allocation
449
// of physical registers will establish this connection.
450
//
451
void RenamePass::search(BasicBlock *bb)
452
{
453
   LValue *lval, *ssa;
454
   int d, s;
455
   const Target *targ = prog->getTarget();
456
 
457
   // Put current definitions for function inputs values on the stack.
458
   // They can be used before any redefinitions are pushed.
459
   if (bb == BasicBlock::get(func->cfg.getRoot())) {
460
      for (std::deque::iterator it = func->ins.begin();
461
           it != func->ins.end(); ++it) {
462
         lval = it->get()->asLValue();
463
         assert(lval);
464
 
465
         ssa = new_LValue(func, targ->nativeFile(lval->reg.file));
466
         ssa->reg.size = lval->reg.size;
467
         ssa->reg.data.id = lval->reg.data.id;
468
 
469
         it->setSSA(ssa);
470
         stack[lval->id].push(ssa);
471
      }
472
   }
473
 
474
   for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
475
      // PHI sources get definitions from the passes through the incident BBs,
476
      // so skip them here.
477
      if (stmt->op != OP_PHI) {
478
         for (s = 0; stmt->srcExists(s); ++s) {
479
            lval = stmt->getSrc(s)->asLValue();
480
            if (!lval)
481
               continue;
482
            // Values on the stack created in previously visited blocks, and
483
            // function inputs, will be valid because they dominate this one.
484
            lval = getStackTop(lval);
485
            if (!lval)
486
               lval = mkUndefined(stmt->getSrc(s));
487
            stmt->setSrc(s, lval);
488
         }
489
      }
490
      for (d = 0; stmt->defExists(d); ++d) {
491
         lval = stmt->def(d).get()->asLValue();
492
         assert(lval);
493
         stmt->def(d).setSSA(
494
            new_LValue(func, targ->nativeFile(lval->reg.file)));
495
         stmt->def(d).get()->reg.size = lval->reg.size;
496
         stmt->def(d).get()->reg.data.id = lval->reg.data.id;
497
         stack[lval->id].push(stmt->def(d).get());
498
      }
499
   }
500
 
501
   // Update sources of PHI ops corresponding to this BB in outgoing BBs.
502
   for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
503
      Instruction *phi;
504
      int p = 0;
505
      BasicBlock *sb = BasicBlock::get(ei.getNode());
506
 
507
      // which predecessor of sb is bb ?
508
      for (Graph::EdgeIterator ei = sb->cfg.incident(); !ei.end(); ei.next()) {
509
         if (ei.getNode() == &bb->cfg)
510
            break;
511
         ++p;
512
      }
513
      assert(p < sb->cfg.incidentCount());
514
 
515
      for (phi = sb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
516
         lval = getStackTop(phi->getSrc(p));
517
         if (!lval)
518
            lval = mkUndefined(phi->getSrc(p));
519
         phi->setSrc(p, lval);
520
      }
521
   }
522
 
523
   // Visit the BBs we dominate.
524
   for (Graph::EdgeIterator ei = bb->dom.outgoing(); !ei.end(); ei.next())
525
      search(BasicBlock::get(ei.getNode()));
526
 
527
   // Update function outputs to the last definitions of their pre-SSA values.
528
   // I hope they're unique, i.e. that we get PHIs for all of them ...
529
   if (bb == BasicBlock::get(func->cfgExit)) {
530
      for (std::deque::iterator it = func->outs.begin();
531
           it != func->outs.end(); ++it) {
532
         lval = it->get()->asLValue();
533
         if (!lval)
534
            continue;
535
         lval = getStackTop(lval);
536
         if (!lval)
537
            lval = mkUndefined(it->get());
538
         it->set(lval);
539
      }
540
   }
541
 
542
   // Pop the values we created in this block from the stack because we will
543
   // return to blocks that we do not dominate.
544
   for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
545
      if (stmt->op == OP_NOP)
546
         continue;
547
      for (d = 0; stmt->defExists(d); ++d)
548
         stack[stmt->def(d).preSSA()->id].pop();
549
   }
550
}
551
 
552
} // namespace nv50_ir