Beispiel #1
0
bool
PrintPass::visit(Function *fn)
{
   char str[16];

   INFO("\n%s:%i (", fn->getName(), fn->getLabel());

   if (!fn->outs.empty())
      INFO("out");
   for (std::deque<ValueRef>::iterator it = fn->outs.begin();
        it != fn->outs.end();
        ++it) {
      it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
      INFO(" %s", str);
   }

   if (!fn->ins.empty())
      INFO("%s%sin", colour[TXT_DEFAULT], fn->outs.empty() ? "" : ", ");
   for (std::deque<ValueDef>::iterator it = fn->ins.begin();
        it != fn->ins.end();
        ++it) {
      it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
      INFO(" %s", str);
   }
   INFO("%s)\n", colour[TXT_DEFAULT]);

   return true;
}
Beispiel #2
0
int Symbol::print(char *buf, size_t size,
                  Value *rel, Value *dimRel, DataType ty) const
{
   size_t pos = 0;
   char c;

   if (ty == TYPE_NONE)
      ty = typeOfSize(reg.size);

   if (reg.file == FILE_SYSTEM_VALUE) {
      PRINT("%ssv[%s%s:%i%s", colour[TXT_MEM],
            colour[TXT_REGISTER],
            SemanticStr[reg.data.sv.sv], reg.data.sv.index, colour[TXT_MEM]);
      if (rel) {
         PRINT("%s+", colour[TXT_DEFAULT]);
         pos += rel->print(&buf[pos], size - pos);
      }
      PRINT("%s]", colour[TXT_MEM]);
      return pos;
   }

   switch (reg.file) {
   case FILE_MEMORY_CONST:  c = 'c'; break;
   case FILE_SHADER_INPUT:  c = 'a'; break;
   case FILE_SHADER_OUTPUT: c = 'o'; break;
   case FILE_MEMORY_BUFFER: c = 'b'; break; // Only used before lowering
   case FILE_MEMORY_GLOBAL: c = 'g'; break;
   case FILE_MEMORY_SHARED: c = 's'; break;
   case FILE_MEMORY_LOCAL:  c = 'l'; break;
   default:
      assert(!"invalid file");
      c = '?';
      break;
   }

   if (c == 'c')
      PRINT("%s%c%i[", colour[TXT_MEM], c, reg.fileIndex);
   else
      PRINT("%s%c[", colour[TXT_MEM], c);

   if (dimRel) {
      pos += dimRel->print(&buf[pos], size - pos, TYPE_S32);
      PRINT("%s][", colour[TXT_MEM]);
   }

   if (rel) {
      pos += rel->print(&buf[pos], size - pos);
      PRINT("%s%c", colour[TXT_DEFAULT], (reg.data.offset < 0) ? '-' : '+');
   } else {
      assert(reg.data.offset >= 0);
   }
   PRINT("%s0x%x%s]", colour[TXT_IMMD], abs(reg.data.offset), colour[TXT_MEM]);

   return pos;
}
Beispiel #3
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;
}
Beispiel #4
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();
}