Пример #1
0
Файл: cfg.cpp Проект: Yermo/hhvm
bool splitCriticalEdges(IRUnit& unit) {
  FTRACE(2, "splitting critical edges\n");
  auto modified = removeUnreachable(unit);
  auto const startBlocks = unit.numBlocks();

  for (auto* block : unit.main()->blocks()) {
    splitCriticalEdge(unit, block->takenEdge());
    splitCriticalEdge(unit, block->nextEdge());
  }

  return modified || unit.numBlocks() != startBlocks;
}
Пример #2
0
bool splitCriticalEdges(IRUnit& unit) {
  FTRACE(2, "splitting critical edges\n");
  auto modified = removeUnreachable(unit);
  if (modified) reflowTypes(unit);
  auto const startBlocks = unit.numBlocks();

  // Try to split outgoing edges of each reachable block.  This is safe in
  // a postorder walk since we visit blocks after visiting successors.
  postorderWalk(unit, [&](Block* b) {
    splitCriticalEdge(unit, b->takenEdge());
    splitCriticalEdge(unit, b->nextEdge());
  });

  return modified || unit.numBlocks() != startBlocks;
}
Пример #3
0
bool splitCriticalEdges(IRUnit& unit) {
  FTRACE(2, "splitting critical edges\n");
  auto modified = removeUnreachable(unit);
  if (modified) reflowTypes(unit);
  auto const startBlocks = unit.numBlocks();

  std::unordered_set<Block*> newCatches;
  std::unordered_set<Block*> oldCatches;

  // Try to split outgoing edges of each reachable block.  This is safe in
  // a postorder walk since we visit blocks after visiting successors.
  postorderWalk(unit, [&](Block* b) {
    auto bnew = splitCriticalEdge(unit, b->takenEdge());
    splitCriticalEdge(unit, b->nextEdge());

    assertx(!b->next() || !b->next()->isCatch());
    if (bnew && b->taken()->isCatch()) {
      newCatches.emplace(bnew);
      oldCatches.emplace(b->taken());
    }
  });

  for (auto b : newCatches) {
    auto bc = b->next()->begin();
    assertx(bc->is(BeginCatch));
    b->prepend(unit.gen(BeginCatch, bc->bcctx()));
  }

  for (auto b : oldCatches) {
    auto bc = b->begin();
    assertx(bc->is(BeginCatch));
    b->erase(bc);
  }

  return modified || unit.numBlocks() != startBlocks;
}
Пример #4
0
	bool PhiElimination::eliminatePhiNodes(
		IRFunction *function, BasicBlock *block)
	{
		if (!block->numOfInstrs() || !block->front()->is_phi_node())
			return false;

		splitCriticalEdge(function, block);

		for (auto iter = block->instr_begin();
			iter != block->instr_end();
			++iter) {
			Instruction *instr = *iter;
			if (!instr->is_phi_node())
				break;
			
			unsigned to = instr->getOutputReg().getRegisterNum();
			// Now loop over all of the incoming arguments,
			// changing them to copy into the destReg register 
			// in the corresponding predecessor basic block.
			for (auto op = instr->op_begin(); op != instr->op_end(); ++op) {
				Value *OPV = op->get_value();
				if (OPV->is_undef())
					continue;
				assert(!OPV->is_value());
				Instruction *opI = static_cast<Instruction*>(OPV);
				BasicBlock *opBlock = findEdge(opI->get_parent(), block);
				assert(opBlock);

				// Figure out where to insert the copy, which is at the end of the
				// predecessor basic block, but before any terminator/branch
				// instructions...
				BasicBlock::instr_iterator I = opBlock->instr_end();
				if (I == opBlock->instr_begin())
					assert(0 && "Not allow empty block.");
				--I;

				// because split ensure use this reg must be safe.
				IRContext::insertAfter<Assign>(
					I, to, opI->getOutputReg().getRegisterNum());
			}

			// Unlink the Phi node from the basic block.
			// instr->erase_from_parent();
			// jump at CodeGen
		}
		return true;
	}