Beispiel #1
0
bool
PrintPass::visit(BasicBlock *bb)
{
#if 0
   INFO("---\n");
   for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next())
      INFO(" <- BB:%i (%s)\n",
           BasicBlock::get(ei.getNode())->getId(),
           ei.getEdge()->typeStr());
#endif
   INFO("BB:%i (%u instructions) - ", bb->getId(), bb->getInsnCount());

   if (bb->idom())
      INFO("idom = BB:%i, ", bb->idom()->getId());

   INFO("df = { ");
   for (DLList::Iterator df = bb->getDF().iterator(); !df.end(); df.next())
      INFO("BB:%i ", BasicBlock::get(df)->getId());

   INFO("}\n");

   for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next())
      INFO(" -> BB:%i (%s)\n",
           BasicBlock::get(ei.getNode())->getId(),
           ei.getEdge()->typeStr());

   return true;
}
Beispiel #2
0
void DominatorTree::buildDFS(Graph::Node *node)
{
   SEMI(node->tag) = node->tag;

   for (Graph::EdgeIterator ei = node->outgoing(); !ei.end(); ei.next()) {
      if (SEMI(ei.getNode()->tag) < 0) {
         buildDFS(ei.getNode());
         PARENT(ei.getNode()->tag) = node->tag;
      }
   }
}
Beispiel #3
0
   void search(Graph::Node *node, const bool preorder, const int sequence)
   {
      if (preorder)
         nodes[count++] = node;

      for (Graph::EdgeIterator ei = node->outgoing(); !ei.end(); ei.next())
         if (ei.getNode()->visit(sequence))
            search(ei.getNode(), preorder, sequence);

      if (!preorder)
         nodes[count++] = node;
   }
Beispiel #4
0
unsigned int
BasicBlock::initiatesSimpleConditional() const
{
   Graph::Node *out[2];
   int n;
   Graph::Edge::Type eR;

   if (cfg.outgoingCount() != 2) // -> if and -> else/endif
      return false;

   n = 0;
   for (Graph::EdgeIterator ei = cfg.outgoing(); !ei.end(); ei.next())
      out[n++] = ei.getNode();
   eR = out[1]->outgoing().getType();

   // IF block is out edge to the right
   if (eR == Graph::Edge::CROSS || eR == Graph::Edge::BACK)
      return 0x2;

   if (out[1]->outgoingCount() != 1) // 0 is IF { RET; }, >1 is more divergence
      return 0x0;
   // do they reconverge immediately ?
   if (out[1]->outgoing().getNode() == out[0])
      return 0x1;
   if (out[0]->outgoingCount() == 1)
      if (out[0]->outgoing().getNode() == out[1]->outgoing().getNode())
         return 0x3;

   return 0x0;
}
Beispiel #5
0
   void search(Graph::Node *node, const int sequence)
   {
      Stack bb, cross;

      bb.push(node);

      while (bb.getSize()) {
         node = reinterpret_cast<Graph::Node *>(bb.pop().u.p);
         assert(node);
         if (!node->visit(sequence))
            continue;
         node->tag = 0;

         for (Graph::EdgeIterator ei = node->outgoing(); !ei.end(); ei.next()) {
            switch (ei.getType()) {
            case Graph::Edge::TREE:
            case Graph::Edge::FORWARD:
            case Graph::Edge::DUMMY:
               if (++(ei.getNode()->tag) == ei.getNode()->incidentCountFwd())
                  bb.push(ei.getNode());
               break;
            case Graph::Edge::BACK:
               continue;
            case Graph::Edge::CROSS:
               if (++(ei.getNode()->tag) == 1)
                  cross.push(ei.getNode());
               break;
            default:
               assert(!"unknown edge kind in CFG");
               break;
            }
         }
         nodes[count++] = node;

         if (bb.getSize() == 0)
            cross.moveTo(bb);
      }
   }
Beispiel #6
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;
}
Beispiel #7
0
// liveIn(bb) = usedBeforeAssigned(bb) U (liveOut(bb) - assigned(bb))
void
Function::buildLiveSetsPreSSA(BasicBlock *bb, const int seq)
{
   Function *f = bb->getFunction();
   BitSet usedBeforeAssigned(allLValues.getSize(), true);
   BitSet assigned(allLValues.getSize(), true);

   bb->liveSet.allocate(allLValues.getSize(), false);

   int n = 0;
   for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
      BasicBlock *out = BasicBlock::get(ei.getNode());
      if (out == bb)
         continue;
      if (out->cfg.visit(seq))
         buildLiveSetsPreSSA(out, seq);
      if (!n++)
         bb->liveSet = out->liveSet;
      else
         bb->liveSet |= out->liveSet;
   }
   if (!n && !bb->liveSet.marker)
      bb->liveSet.fill(0);
   bb->liveSet.marker = true;

   for (Instruction *i = bb->getEntry(); i; i = i->next) {
      for (int s = 0; i->srcExists(s); ++s)
         if (i->getSrc(s)->asLValue() && !assigned.test(i->getSrc(s)->id))
            usedBeforeAssigned.set(i->getSrc(s)->id);
      for (int d = 0; i->defExists(d); ++d)
         assigned.set(i->getDef(d)->id);
   }

   if (bb == BasicBlock::get(f->cfgExit)) {
      for (std::deque<ValueRef>::iterator it = f->outs.begin();
           it != f->outs.end(); ++it) {
         if (!assigned.test(it->get()->id))
            usedBeforeAssigned.set(it->get()->id);
      }
   }

   bb->liveSet.andNot(assigned);
   bb->liveSet |= usedBeforeAssigned;
}
Beispiel #8
0
void
Function::printCFGraph(const char *filePath)
{
   FILE *out = fopen(filePath, "a");
   if (!out) {
      ERROR("failed to open file: %s\n", filePath);
      return;
   }
   INFO("printing control flow graph to: %s\n", filePath);

   fprintf(out, "digraph G {\n");

   for (IteratorRef it = cfg.iteratorDFS(); !it->end(); it->next()) {
      BasicBlock *bb = BasicBlock::get(
         reinterpret_cast<Graph::Node *>(it->get()));
      int idA = bb->getId();
      for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
         int idB = BasicBlock::get(ei.getNode())->getId();
         switch (ei.getType()) {
         case Graph::Edge::TREE:
            fprintf(out, "\t%i -> %i;\n", idA, idB);
            break;
         case Graph::Edge::FORWARD:
            fprintf(out, "\t%i -> %i [color=green];\n", idA, idB);
            break;
         case Graph::Edge::CROSS:
            fprintf(out, "\t%i -> %i [color=red];\n", idA, idB);
            break;
         case Graph::Edge::BACK:
            fprintf(out, "\t%i -> %i;\n", idA, idB);
            break;
         case Graph::Edge::DUMMY:
            fprintf(out, "\t%i -> %i [style=dotted];\n", idA, idB);
            break;
         default:
            assert(0);
            break;
         }
      }
   }

   fprintf(out, "}\n");
   fclose(out);
}
Beispiel #9
0
BasicBlock *
BasicBlock::clone(ClonePolicy<Function>& pol) const
{
   BasicBlock *bb = new BasicBlock(pol.context());

   pol.set(this, bb);

   for (Instruction *i = getFirst(); i; i = i->next)
      bb->insertTail(i->clone(pol));

   pol.context()->cfg.insert(&bb->cfg);

   for (Graph::EdgeIterator it = cfg.outgoing(); !it.end(); it.next()) {
      BasicBlock *obb = BasicBlock::get(it.getNode());
      bb->cfg.attach(&pol.get(obb)->cfg, it.getType());
   }

   return bb;
}
Beispiel #10
0
void
Function::buildDefSetsPreSSA(BasicBlock *bb, const int seq)
{
   bb->defSet.allocate(allLValues.getSize(), !bb->liveSet.marker);
   bb->liveSet.marker = true;

   for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
      BasicBlock *in = BasicBlock::get(ei.getNode());

      if (in->cfg.visit(seq))
         buildDefSetsPreSSA(in, seq);

      bb->defSet |= in->defSet;
   }

   for (Instruction *i = bb->getEntry(); i; i = i->next) {
      for (int d = 0; i->defExists(d); ++d)
         bb->defSet.set(i->getDef(d)->id);
   }
}
Beispiel #11
0
// Go through BBs in dominance order, create new values for each definition,
// and replace all sources with their current new values.
//
// NOTE: The values generated for function inputs/outputs have no connection
// to their corresponding outputs/inputs in other functions. Only allocation
// of physical registers will establish this connection.
//
void RenamePass::search(BasicBlock *bb)
{
   LValue *lval, *ssa;
   int d, s;
   const Target *targ = prog->getTarget();

   // Put current definitions for function inputs values on the stack.
   // They can be used before any redefinitions are pushed.
   if (bb == BasicBlock::get(func->cfg.getRoot())) {
      for (std::deque<ValueDef>::iterator it = func->ins.begin();
           it != func->ins.end(); ++it) {
         lval = it->get()->asLValue();
         assert(lval);

         ssa = new_LValue(func, targ->nativeFile(lval->reg.file));
         ssa->reg.size = lval->reg.size;
         ssa->reg.data.id = lval->reg.data.id;

         it->setSSA(ssa);
         stack[lval->id].push(ssa);
      }
   }

   for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
      // PHI sources get definitions from the passes through the incident BBs,
      // so skip them here.
      if (stmt->op != OP_PHI) {
         for (s = 0; stmt->srcExists(s); ++s) {
            lval = stmt->getSrc(s)->asLValue();
            if (!lval)
               continue;
            // Values on the stack created in previously visited blocks, and
            // function inputs, will be valid because they dominate this one.
            lval = getStackTop(lval);
            if (!lval)
               lval = mkUndefined(stmt->getSrc(s));
            stmt->setSrc(s, lval);
         }
      }
      for (d = 0; stmt->defExists(d); ++d) {
         lval = stmt->def(d).get()->asLValue();
         assert(lval);
         stmt->def(d).setSSA(
            new_LValue(func, targ->nativeFile(lval->reg.file)));
         stmt->def(d).get()->reg.size = lval->reg.size;
         stmt->def(d).get()->reg.data.id = lval->reg.data.id;
         stack[lval->id].push(stmt->def(d).get());
      }
   }

   // Update sources of PHI ops corresponding to this BB in outgoing BBs.
   for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
      Instruction *phi;
      int p = 0;
      BasicBlock *sb = BasicBlock::get(ei.getNode());

      // which predecessor of sb is bb ?
      for (Graph::EdgeIterator ei = sb->cfg.incident(); !ei.end(); ei.next()) {
         if (ei.getNode() == &bb->cfg)
            break;
         ++p;
      }
      assert(p < sb->cfg.incidentCount());

      for (phi = sb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
         lval = getStackTop(phi->getSrc(p));
         if (!lval)
            lval = mkUndefined(phi->getSrc(p));
         phi->setSrc(p, lval);
      }
   }

   // Visit the BBs we dominate.
   for (Graph::EdgeIterator ei = bb->dom.outgoing(); !ei.end(); ei.next())
      search(BasicBlock::get(ei.getNode()));

   // Update function outputs to the last definitions of their pre-SSA values.
   // I hope they're unique, i.e. that we get PHIs for all of them ...
   if (bb == BasicBlock::get(func->cfgExit)) {
      for (std::deque<ValueRef>::iterator it = func->outs.begin();
           it != func->outs.end(); ++it) {
         lval = it->get()->asLValue();
         if (!lval)
            continue;
         lval = getStackTop(lval);
         if (!lval)
            lval = mkUndefined(it->get());
         it->set(lval);
      }
   }

   // Pop the values we created in this block from the stack because we will
   // return to blocks that we do not dominate.
   for (Instruction *stmt = bb->getFirst(); stmt; stmt = stmt->next) {
      if (stmt->op == OP_NOP)
         continue;
      for (d = 0; stmt->defExists(d); ++d)
         stack[stmt->def(d).preSSA()->id].pop();
   }
}