/* * Unit */ void print(std::ostream& os, const IRUnit& unit, const RegAllocInfo* regs, const AsmInfo* asmInfo, const GuardConstraints* guards, bool dotBodies) { // For nice-looking dumps, we want to remember curMarker between blocks. BCMarker curMarker; auto const layout = layoutBlocks(unit); auto const& blocks = layout.blocks; if (dumpIREnabled(kExtraExtraLevel)) printOpcodeStats(os, blocks); // Print the block CFG above the actual code. os << "digraph G {\n"; for (Block* block : blocks) { if (block->empty()) continue; if (dotBodies && block->hint() != Block::Hint::Unlikely && block->hint() != Block::Hint::Unused) { // Include the IR in the body of the node std::ostringstream out; print(out, block, regs, asmInfo, guards, &curMarker); auto bodyRaw = out.str(); std::string body; body.reserve(bodyRaw.size() * 1.25); for (auto c : bodyRaw) { if (c == '\n') body += "\\n"; else if (c == '"') body += "\\\""; else if (c == '\\') body += "\\\\"; else body += c; } os << folly::format("B{} [shape=\"box\" label=\"{}\"]\n", block->id(), body); } auto* next = block->next(); auto* taken = block->taken(); if (!next && !taken) continue; if (next) { os << folly::format("B{} -> B{}", block->id(), next->id()); if (taken) os << "; "; } if (taken) os << folly::format("B{} -> B{}", block->id(), taken->id()); os << "\n"; } os << "}\n"; curMarker = BCMarker(); for (auto it = blocks.begin(); it != blocks.end(); ++it) { if (it == layout.acoldIt) { os << folly::format("\n{:-^60}", "cold blocks"); } if (it == layout.afrozenIt) { os << folly::format("\n{:-^60}", "frozen blocks"); } print(os, *it, regs, asmInfo, guards, &curMarker); } }
SSATmp* IRUnit::findConst(Type type) { assert(type.isConst()); IRInstruction inst(DefConst, BCMarker()); inst.setTypeParam(type); if (SSATmp* tmp = m_constTable.lookup(&inst)) { assert(tmp->type().equals(type)); return tmp; } return m_constTable.insert(cloneInstruction(&inst)->dst()); }
SSATmp* IRFactory::findConst(ConstData& cdata, Type ctype) { IRInstruction inst(DefConst, BCMarker()); inst.setExtra(&cdata); inst.setTypeParam(ctype); if (SSATmp* tmp = m_constTable.lookup(&inst)) { assert(tmp->type().equals(ctype)); return tmp; } return m_constTable.insert(cloneInstruction(&inst)->dst()); }
void FrameState::clear() { clearCse(); clearLocals(*this); m_frameSpansCall = false; m_spValue = m_fpValue = nullptr; m_spOffset = 0; m_thisAvailable = false; m_marker = BCMarker(); m_snapshots.clear(); assert(m_inlineSavedStates.empty()); }
void TraceBuilder::clearTrackedState() { killCse(); // clears m_cseHash clearLocals(); m_callerAvailableValues.clear(); m_spValue = m_fpValue = nullptr; m_spOffset = 0; m_thisIsAvailable = false; m_refCountedMemValue = nullptr; for (auto i = m_snapshots.begin(), end = m_snapshots.end(); i != end; ++i) { delete *i; *i = nullptr; } m_curMarker = BCMarker(); }
/* * Unit */ void print(std::ostream& os, const IRUnit& unit, const AsmInfo* asmInfo, const GuardConstraints* guards) { // For nice-looking dumps, we want to remember curMarker between blocks. BCMarker curMarker; static bool dotBodies = getenv("HHIR_DOT_BODIES"); auto blocks = rpoSortCfg(unit); // Partition into main, cold and frozen, without changing relative order. auto cold = std::stable_partition(blocks.begin(), blocks.end(), [&] (Block* b) { return b->hint() == Block::Hint::Neither || b->hint() == Block::Hint::Likely; } ); auto frozen = std::stable_partition(cold, blocks.end(), [&] (Block* b) { return b->hint() == Block::Hint::Unlikely; } ); if (dumpIREnabled(kExtraExtraLevel)) printOpcodeStats(os, blocks); // Print the block CFG above the actual code. auto const retreating_edges = findRetreatingEdges(unit); os << "digraph G {\n"; for (auto block : blocks) { if (block->empty()) continue; if (dotBodies && block->hint() != Block::Hint::Unlikely && block->hint() != Block::Hint::Unused) { // Include the IR in the body of the node std::ostringstream out; print(out, block, AreaIndex::Main, asmInfo, guards, &curMarker); auto bodyRaw = out.str(); std::string body; body.reserve(bodyRaw.size() * 1.25); for (auto c : bodyRaw) { if (c == '\n') body += "\\n"; else if (c == '"') body += "\\\""; else if (c == '\\') body += "\\\\"; else body += c; } os << folly::format("B{} [shape=\"box\" label=\"{}\"]\n", block->id(), body); } auto next = block->nextEdge(); auto taken = block->takenEdge(); if (!next && !taken) continue; auto edge_color = [&] (Edge* edge) { auto const target = edge->to(); return target->isCatch() ? " [color=blue]" : target->isExit() ? " [color=cyan]" : retreating_edges.count(edge) ? " [color=red]" : target->hint() == Block::Hint::Unlikely ? " [color=green]" : ""; }; auto show_edge = [&] (Edge* edge) { os << folly::format( "B{} -> B{}{}", block->id(), edge->to()->id(), edge_color(edge) ); }; if (next) { show_edge(next); if (taken) os << "; "; } if (taken) show_edge(taken); os << "\n"; } os << "}\n"; AreaIndex currentArea = AreaIndex::Main; curMarker = BCMarker(); for (auto it = blocks.begin(); it != blocks.end(); ++it) { if (it == cold) { os << folly::format("\n{:-^60}", "cold blocks"); currentArea = AreaIndex::Cold; } if (it == frozen) { os << folly::format("\n{:-^60}", "frozen blocks"); currentArea = AreaIndex::Frozen; } print(os, *it, currentArea, asmInfo, guards, &curMarker); } }