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); } }
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); } } }
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); } }