Beispiel #1
0
void IRInstruction::convertToMov() {
  assert(!isControlFlow());
  m_op = Mov;
  m_typeParam = Type::None;
  assert(m_numSrcs == 1);
  assert(m_numDsts == 1);
}
Beispiel #2
0
void IRInstruction::convertToMov() {
  assert(!isControlFlow());
  m_op = Mov;
  m_typeParam = Type::None;
  m_extra = nullptr;
  assert(m_numSrcs == 1);
  // Instructions in the simplifier don't have dests yet
  assert((m_numDsts == 1) != isTransient());
}
Beispiel #3
0
void IRInstruction::convertToMov() {
  assert(!isControlFlow());
  m_op = Mov;
  m_typeParam.clear();
  m_extra = nullptr;
  if (m_numDsts == 1) m_dst->setInstruction(this); // recompute type
  assert(m_numSrcs == 1);
  // Instructions in the simplifier don't have dests yet
  assert((m_numDsts == 1) != isTransient());
}
Beispiel #4
0
void IRInstruction::convertToJmp() {
  assert(isControlFlow());
  assert(IMPLIES(block(), block()->back() == this));
  m_op = Jmp_;
  m_typeParam = Type::None;
  m_numSrcs = 0;
  m_numDsts = 0;
  m_srcs = nullptr;
  m_dst = nullptr;
  // Instructions in the simplifier don't have blocks yet.
  if (block()) block()->setNext(nullptr);
}
Beispiel #5
0
void IRInstruction::convertToJmp() {
  assert(isControlFlow());
  assert(IMPLIES(block(), &block()->back() == this));
  m_op = Jmp;
  m_typeParam.clear();
  m_numSrcs = 0;
  m_numDsts = 0;
  m_srcs = nullptr;
  m_dst = nullptr;
  m_extra = nullptr;
  // Instructions in the simplifier don't have blocks yet.
  setNext(nullptr);
}
Beispiel #6
0
void cloneToBlock(const BlockList& rpoBlocks,
                  IRUnit& unit,
                  Block::iterator const first,
                  Block::iterator const last,
                  Block* const target) {
  StateVector<SSATmp,SSATmp*> rewriteMap(unit, nullptr);

  auto rewriteSources = [&] (IRInstruction* inst) {
    for (int i = 0; i < inst->numSrcs(); ++i) {
      if (auto newTmp = rewriteMap[inst->src(i)]) {
        FTRACE(5, "  rewrite: {} -> {}\n",
               inst->src(i)->toString(),
               newTmp->toString());
        inst->setSrc(i, newTmp);
      }
    }
  };

  auto targetIt = target->skipHeader();
  for (auto it = first; it != last; ++it) {
    assert(!it->isControlFlow());

    FTRACE(5, "cloneToBlock({}): {}\n", target->id(), it->toString());
    auto const newInst = unit.cloneInstruction(&*it);

    if (auto const numDests = newInst->numDsts()) {
      for (int i = 0; i < numDests; ++i) {
        FTRACE(5, "  add rewrite: {} -> {}\n",
               it->dst(i)->toString(),
               newInst->dst(i)->toString());
        rewriteMap[it->dst(i)] = newInst->dst(i);
      }
    }

    target->insert(targetIt, newInst);
    targetIt = ++target->iteratorTo(newInst);
  }

  postorderWalk(
    unit,
    [&](Block* block) {
      FTRACE(5, "cloneToBlock: rewriting block {}\n", block->id());
      for (auto& inst : *block) {
        FTRACE(5, " rewriting {}\n", inst.toString());
        rewriteSources(&inst);
      }
    },
    target
  );
}
Beispiel #7
0
void cloneToBlock(const BlockList& rpoBlocks,
                  IRFactory* const irFactory,
                  Block::iterator const first,
                  Block::iterator const last,
                  Block* const target) {
  assert(isRPOSorted(rpoBlocks));

  StateVector<SSATmp,SSATmp*> rewriteMap(irFactory, nullptr);

  auto rewriteSources = [&] (IRInstruction* inst) {
    for (int i = 0; i < inst->numSrcs(); ++i) {
      if (auto newTmp = rewriteMap[inst->src(i)]) {
        FTRACE(5, "  rewrite: {} -> {}\n",
               inst->src(i)->toString(),
               newTmp->toString());
        inst->setSrc(i, newTmp);
      }
    }
  };

  auto targetIt = target->skipHeader();
  for (auto it = first; it != last; ++it) {
    assert(!it->isControlFlow());

    FTRACE(5, "cloneToBlock({}): {}\n", target->id(), it->toString());
    auto const newInst = irFactory->cloneInstruction(&*it);

    if (auto const numDests = newInst->numDsts()) {
      for (int i = 0; i < numDests; ++i) {
        FTRACE(5, "  add rewrite: {} -> {}\n",
               it->dst(i)->toString(),
               newInst->dst(i)->toString());
        rewriteMap[it->dst(i)] = newInst->dst(i);
      }
    }

    target->insert(targetIt, newInst);
    targetIt = ++target->iteratorTo(newInst);
  }

  auto it = rpoIteratorTo(rpoBlocks, target);
  for (; it != rpoBlocks.end(); ++it) {
    FTRACE(5, "cloneToBlock: rewriting block {}\n", (*it)->id());
    for (auto& inst : **it) {
      FTRACE(5, " rewriting {}\n", inst.toString());
      rewriteSources(&inst);
    }
  }
}
Beispiel #8
0
bool IRInstruction::isEssential() const {
  Opcode opc = op();
  if (opc == DecRefNZ) {
    // If the source of a DecRefNZ is not an IncRef, mark it as essential
    // because we won't remove its source as well as itself.
    // If the ref count optimization is turned off, mark all DecRefNZ as
    // essential.
    if (!RuntimeOption::EvalHHIREnableRefCountOpt ||
        src(0)->inst()->op() != IncRef) {
      return true;
    }
  }
  return isControlFlow() ||
         opcodeHasFlags(opc, Essential) ||
         mayReenterHelper();
}
Beispiel #9
0
bool IRInstruction::mayModifyRefs() const {
  Opcode opc = op();
  // DecRefNZ does not have side effects other than decrementing the ref
  // count. Therefore, its MayModifyRefs should be false.
  if (opc == DecRef) {
    auto type = src(0)->type();
    if (isControlFlow()) {
      // If the decref has a target label, then it exits if the destructor
      // has to be called, so it does not have any side effects on the main
      // trace.
      return false;
    }
    if (!type.canRunDtor()) {
      return false;
    }
  }
  return opcodeHasFlags(opc, MayModifyRefs) || mayReenterHelper();
}
Beispiel #10
0
void moveToBlock(Block::iterator const first,
                 Block::iterator const last,
                 Block* const target) {
  if (first == last) return;

  auto const srcBlock = first->block();

  auto targetIt = target->skipHeader();
  for (auto it = first; it != last;) {
    auto const inst = &*it;
    assert(!inst->isControlFlow());

    FTRACE(5, "moveToBlock({}): {}\n",
           target->id(),
           inst->toString());

    it = srcBlock->erase(it);
    target->insert(targetIt, inst);
    targetIt = ++target->iteratorTo(inst);
  }
}
Beispiel #11
0
bool IRInstruction::isEssential() const {
  return isControlFlow() ||
         opcodeHasFlags(op(), Essential);
}