Exemplo n.º 1
0
static bool isMainExit(const Block* b) {
  if (b->hint() == Block::Hint::Unlikely) return false;
  if (b->next()) return false;
  auto taken = b->taken();
  if (!taken) return true;
  if (taken->isCatch()) return true;
  return false;
}
Exemplo n.º 2
0
/*
 * Whether the block appears to be the exit block of the main code
 * path of a region. This is conservative, so it may return false on
 * all blocks in a region.
 */
static bool isMainExit(const Block* b) {
  if (!isMainBlock(b)) return false;

  if (b->next()) return false;

  // The Await bytecode instruction does a RetCtrl to the scheduler,
  // which is in a likely block.  We don't want to consider this as
  // the main exit.
  auto const& back = b->back();
  if (back.op() == RetCtrl && back.marker().sk().op() == OpAwait) return false;

  auto const taken = b->taken();
  return !taken || taken->isCatch();
}
Exemplo n.º 3
0
/*
 * 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);
    }
}