Exemple #1
0
LValue *
RenamePass::mkUndefined(Value *val)
{
   LValue *lval = val->asLValue();
   assert(lval);
   LValue *ud = new_LValue(func, lval);
   Instruction *nop = new_Instruction(func, OP_NOP, typeOfSize(lval->reg.size));
   nop->setDef(0, ud);
   BasicBlock::get(func->cfg.getRoot())->insertHead(nop);
   return ud;
}
Exemple #2
0
LValue *
LValue::clone(ClonePolicy<Function>& pol) const
{
   LValue *that = new_LValue(pol.context(), reg.file);

   pol.set<Value>(this, that);

   that->reg.size = this->reg.size;
   that->reg.type = this->reg.type;
   that->reg.data = this->reg.data;

   return that;
}
Exemple #3
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();
   }
}