示例#1
0
void MemoryValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
{
    if (m_offset)
        out.print(comma, "offset = ", m_offset);
    if ((isLoad() && effects().reads != range())
        || (isStore() && effects().writes != range()))
        out.print(comma, "range = ", range());
}
示例#2
0
文件: lab6.c 项目: chad831/315
/* Funct m, stage 4 / Memory, assumes the em and mw Baskets */
void m(MIPS_SIM* sim, EMB* emBasket, MWB* mwBasket) /* memory write */
{
   if(emBasket->aluOut != 0)
   {
      int opc = emBasket->ir >> 26;
      printf("--- In Mem ---\n");
      if(isStore(opc))  /* For Store Word Insturctions */
      {
         printf("in m: exe store type\n");
         switch(opc)
         {
            case 0x28: /* store byte */

               mem[emBasket->aluOut] = emBasket->bReg & 0x000000FF;
               break;

            case 0x29: /* store half word */

               mem[emBasket->aluOut] = emBasket->bReg & 0x0000FFFF;
               break;

            case 0x2B: /* store word */

               mem[emBasket->aluOut] = emBasket->bReg;
               break;
         }
         printRegs(sim);
         clearem(emBasket);
      }
      else           /* For Load Word Instrustions */
      {
         if(mwBasket->wBusy)
            return;
         else
         {
            printf("in mem: exe load type\n");
            mwBasket->wBusy = 1;
            mwBasket->type = 2;
            mwBasket->mdr = mem[emBasket->aluOut]; /* write to mdr */
            clearem(emBasket);
         }
      }
   }
示例#3
0
void SimpleAliasAnalysis::analyze(ir::IRKernel& kernel)
{
	// Functions can be called
	_aStoreCanReachThisFunction = !kernel.function();
	_kernel = &kernel;
	
	if(_aStoreCanReachThisFunction) return;
	
	for(auto block = kernel.cfg()->begin();
		block != kernel.cfg()->end(); ++block)
	{
		for(auto instruction = block->instructions.begin();
			instruction != block->instructions.end(); ++instruction)
		{
			auto ptx = static_cast<ir::PTXInstruction*>(*instruction);
			
			if(ptx->isStore())
			{
				_aStoreCanReachThisFunction = true;
				return;
			}
		}
	}
}
示例#4
0
void MemMap::optimizeMemoryAccesses(Trace* trace) {
  StoreList tracking;

  for (IRInstruction* inst : trace->getInstructionList()) {
    // initialize each instruction as live
    inst->setId(LIVE);

    int offset = -1;
    Opcode op = inst->getOpcode();

    if (isLoad(op)) {
      if (op == LdProp) {
        offset = inst->getSrc(1)->getConstValAsInt();
      }

      optimizeLoad(inst, offset);
    } else if (isStore(op)) {
      if (op == StProp || op == StPropNT) {
        offset = inst->getSrc(1)->getConstValAsInt();
      }

      // if we see a store, first check if its last available access is a store
      // if it is, then the last access is a dead store
      IRInstruction* access = getLastAccess(inst->getSrc(0), offset);
      if (access != NULL && isStore(access->getOpcode())) {
        // if a dead St* is followed by a St*NT, then the second store needs to
        // now write in the type because the first store will be removed
        if (access->getOpcode() == StProp && op == StPropNT) {
          inst->setOpcode(StProp);
        } else if (access->getOpcode() == StLoc && op == StLocNT) {
          inst->setOpcode(StLoc);
        } else if (access->getOpcode() == StRef && op == StRefNT) {
          inst->setOpcode(StRef);
        }

        access->setId(DEAD);
      }

      // start tracking the current store
      tracking.push_back(std::make_pair(inst, std::vector<IRInstruction*>()));
    } else if (inst->mayRaiseError()) {
      // if the function has an exit edge that we don't know anything about
      // (raising an error), then all stores we're currently tracking need to
      // be erased. all stores already declared dead are untouched
      StoreList::iterator it, end;
      for (it = tracking.begin(), end = tracking.end(); it != end; ) {
        StoreList::iterator copy = it;
        ++it;
        if (copy->first->getId() != DEAD) {
          // XXX: t1779667
          tracking.erase(copy);
        }
      }
    }

    // if the current instruction is guarded, make sure all of our stores that
    // are not yet dead know about it
    if (inst->getLabel() != NULL) {
      for (auto& entry : tracking) {
        if (entry.first->getId() != DEAD) {
          entry.second.push_back(inst);
        }
      }
    }

    Simplifier::copyProp(inst);
    processInstruction(inst);
  }

  sinkStores(tracking);

  // kill the dead stores
  removeDeadInstructions(trace);
}
示例#5
0
void MemMap::optimizeMemoryAccesses(Trace* trace) {
  if (hasInternalFlow(trace)) {
    // This algorithm only works with linear traces.
    // TODO t2066994: reset state after each block, at least.
    return;
  }
  StoreList tracking;

  const Func* curFunc = nullptr;

  for (Block* block : trace->getBlocks()) {
    for (IRInstruction& inst : *block) {
      if (inst.getOpcode() == Marker) {
        curFunc = inst.getExtra<Marker>()->func;
      }
      // initialize each instruction as live
      setLive(inst, true);

      int offset = -1;
      Opcode op = inst.getOpcode();

      if (isLoad(op)) {
        if (op == LdProp) {
          offset = inst.getSrc(1)->getValInt();
        }
        // initialize each instruction as live
        setLive(inst, true);

        optimizeLoad(&inst, offset);
      } else if (isStore(op)) {
        if (op == StProp || op == StPropNT) {
          offset = inst.getSrc(1)->getValInt();
        }

        // if we see a store, first check if its last available access is a store
        // if it is, then the last access is a dead store
        auto access = inst.getOpcode() == StLoc || inst.getOpcode() == StLocNT
          ? lastLocalAccess(inst.getExtra<LocalId>()->locId)
          : getLastAccess(inst.getSrc(0), offset);
        if (access && isStore(access->getOpcode())) {
          // if a dead St* is followed by a St*NT, then the second store needs to
          // now write in the type because the first store will be removed
          if (access->getOpcode() == StProp && op == StPropNT) {
            inst.setOpcode(StProp);
          } else if (access->getOpcode() == StLoc && op == StLocNT) {
            inst.setOpcode(StLoc);
          } else if (access->getOpcode() == StRef && op == StRefNT) {
            inst.setOpcode(StRef);
          }

          setLive(*access, false);
        }

        // start tracking the current store
        tracking.push_back(std::make_pair(&inst, std::vector<IRInstruction*>()));
      } else if (inst.mayRaiseError()) {
        // if the function has an exit edge that we don't know anything about
        // (raising an error), then all stores we're currently tracking need to
        // be erased. all stores already declared dead are untouched
        StoreList::iterator it, end;
        for (it = tracking.begin(), end = tracking.end(); it != end; ) {
          StoreList::iterator copy = it;
          ++it;
          if (isLive(copy->first)) {
            // XXX: t1779667
            tracking.erase(copy);
          }
        }
      }

      // if the current instruction is guarded, make sure all of our stores that
      // are not yet dead know about it
      if (inst.getTaken()) {
        for (auto& entry : tracking) {
          if (isLive(entry.first)) {
            entry.second.push_back(&inst);
          }
        }
      }
      Simplifier::copyProp(&inst);
      processInstruction(&inst, curFunc && curFunc->isPseudoMain());
    }
  }

  sinkStores(tracking);

  // kill the dead stores
  removeDeadInstructions(trace, m_liveInsts);
}
示例#6
0
 bool Instruction::isMemop(){
     return (isLoad() || isStore());
 }
示例#7
0
bool Instruction::accessesMemory() const
{
	return isLoad() || isStore();
}