Пример #1
0
void DominatorTree::build()
{
   DLList *bucket = new DLList[count];
   Node *nv, *nw;
   int p, u, v, w;

   buildDFS(cfg->getRoot());

   for (w = count - 1; w >= 1; --w) {
      nw = vert[w];
      assert(nw->tag == w);
      for (Graph::EdgeIterator ei = nw->incident(); !ei.end(); ei.next()) {
         nv = ei.getNode();
         v = nv->tag;
         u = eval(v);
         if (SEMI(u) < SEMI(w))
            SEMI(w) = SEMI(u);
      }
      p = PARENT(w);
      bucket[SEMI(w)].insert(nw);
      link(p, w);

      for (DLList::Iterator it = bucket[p].iterator(); !it.end(); it.erase()) {
         v = reinterpret_cast<Node *>(it.get())->tag;
         u = eval(v);
         DOM(v) = (SEMI(u) < SEMI(v)) ? u : p;
      }
   }
   for (w = 1; w < count; ++w) {
      if (DOM(w) != SEMI(w))
         DOM(w) = DOM(DOM(w));
   }
   DOM(0) = 0;

   insert(&BasicBlock::get(cfg->getRoot())->dom);
   do {
      p = 0;
      for (v = 1; v < count; ++v) {
         nw = &BasicBlock::get(vert[DOM(v)])->dom;;
         nv = &BasicBlock::get(vert[v])->dom;
         if (nw->getGraph() && !nv->getGraph()) {
            ++p;
            nw->attach(nv, Graph::Edge::TREE);
         }
      }
   } while (p);

   delete[] bucket;
}
Пример #2
0
// Efficiently Computing Static Single Assignment Form and
//  the Control Dependence Graph,
// R. Cytron, J. Ferrante, B. K. Rosen, M. N. Wegman, F. K. Zadeck
bool
Function::convertToSSA()
{
   // 0. calculate live in variables (for pruned SSA)
   buildLiveSets();

   // 1. create the dominator tree
   domTree = new DominatorTree(&cfg);
   reinterpret_cast<DominatorTree *>(domTree)->findDominanceFrontiers();

   // 2. insert PHI functions
   DLList workList;
   LValue *lval;
   BasicBlock *bb;
   int var;
   int iterCount = 0;
   int *hasAlready = new int[allBBlocks.getSize() * 2];
   int *work = &hasAlready[allBBlocks.getSize()];

   memset(hasAlready, 0, allBBlocks.getSize() * 2 * sizeof(int));

   // for each variable
   for (var = 0; var < allLValues.getSize(); ++var) {
      if (!allLValues.get(var))
         continue;
      lval = reinterpret_cast<Value *>(allLValues.get(var))->asLValue();
      if (!lval || lval->defs.empty())
         continue;
      ++iterCount;

      // TODO: don't add phi functions for values that aren't used outside
      //  the BB they're defined in

      // gather blocks with assignments to lval in workList
      for (Value::DefIterator d = lval->defs.begin();
           d != lval->defs.end(); ++d) {
         bb = ((*d)->getInsn() ? (*d)->getInsn()->bb : NULL);
         if (!bb)
            continue; // instruction likely been removed but not XXX deleted

         if (work[bb->getId()] == iterCount)
            continue;
         work[bb->getId()] = iterCount;
         workList.insert(bb);
      }

      // for each block in workList, insert a phi for lval in the block's
      //  dominance frontier (if we haven't already done so)
      for (DLList::Iterator wI = workList.iterator(); !wI.end(); wI.erase()) {
         bb = BasicBlock::get(wI);

         DLList::Iterator dfIter = bb->getDF().iterator();
         for (; !dfIter.end(); dfIter.next()) {
            Instruction *phi;
            BasicBlock *dfBB = BasicBlock::get(dfIter);

            if (hasAlready[dfBB->getId()] >= iterCount)
               continue;
            hasAlready[dfBB->getId()] = iterCount;

            // pruned SSA: don't need a phi if the value is not live-in
            if (!dfBB->liveSet.test(lval->id))
               continue;

            phi = new_Instruction(this, OP_PHI, typeOfSize(lval->reg.size));
            dfBB->insertTail(phi);

            phi->setDef(0, lval);
            for (int s = 0; s < dfBB->cfg.incidentCount(); ++s)
               phi->setSrc(s, lval);

            if (work[dfBB->getId()] < iterCount) {
               work[dfBB->getId()] = iterCount;
               wI.insert(dfBB);
            }
         }
      }
   }
   delete[] hasAlready;

   RenamePass rename(this);
   return rename.run();
}