예제 #1
0
void reflowTypes(Block* const changed, const BlockList& blocks) {
  assert(isRPOSorted(blocks));

  auto it = rpoIteratorTo(blocks, changed);
  assert(it != blocks.end());
  for (; it != blocks.end(); ++it) {
    FTRACE(5, "reflowTypes: visiting block {}\n", (*it)->id());
    for (auto& inst : **it) visitInstruction(&inst);
  }
}
예제 #2
0
void cloneToBlock(const BlockList& rpoBlocks,
                  IRFactory& 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);
    }
  }
}
예제 #3
0
void reflowTypes(Block* const changed, const BlockList& blocks) {
  assert(isRPOSorted(blocks));

  auto retypeDst = [&] (IRInstruction* inst, int num) {
    auto ssa = inst->dst(num);

    /*
     * The type of a tmp defined by DefLabel is the union of the
     * types of the tmps at each incoming Jmp.
     */
    if (inst->op() == DefLabel) {
      Type type = Type::Bottom;
      inst->block()->forEachSrc(num, [&](IRInstruction*, SSATmp* tmp) {
        type = Type::unionOf(type, tmp->type());
      });
      ssa->setType(type);
      return;
    }

    ssa->setType(outputType(inst, num));
  };

  auto visit = [&] (IRInstruction* inst) {
    for (int i = 0; i < inst->numDsts(); ++i) {
      auto const ssa = inst->dst(i);
      auto const oldType = ssa->type();
      retypeDst(inst, i);
      if (!ssa->type().equals(oldType)) {
        FTRACE(5, "reflowTypes: retyped {} in {}\n", oldType.toString(),
               inst->toString());
      }
    }
  };

  auto it = rpoIteratorTo(blocks, changed);
  assert(it != blocks.end());
  for (; it != blocks.end(); ++it) {
    FTRACE(5, "reflowTypes: visiting block {}\n", (*it)->id());
    for (auto& inst : **it) visit(&inst);
  }
}