%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/compiler/turboshaft/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/compiler/turboshaft/graph.cc |
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/turboshaft/graph.h"
#include <algorithm>
#include <iomanip>
#include "src/base/logging.h"
namespace v8::internal::compiler::turboshaft {
// PrintDominatorTree prints the dominator tree in a format that looks like:
//
// 0
// ╠ 1
// ╠ 2
// ╠ 3
// ║ ╠ 4
// ║ ║ ╠ 5
// ║ ║ ╚ 6
// ║ ╚ 7
// ║ ╠ 8
// ║ ╚ 16
// ╚ 17
//
// Where the numbers are the IDs of the Blocks.
// Doing so is mostly straight forward, with the subtelty that we need to know
// where to put "║" symbols (eg, in from of "╠ 5" above). The logic to do this
// is basically: "if the current node is not the last of its siblings, then,
// when going down to print its content, we add a "║" in front of each of its
// children; otherwise (current node is the last of its siblings), we add a
// blank space " " in front of its children". We maintain this information
// using a stack (implemented with a std::vector).
void Block::PrintDominatorTree(std::vector<const char*> tree_symbols,
bool has_next) const {
// Printing the current node.
if (tree_symbols.empty()) {
// This node is the root of the tree.
PrintF("B%d\n", index().id());
tree_symbols.push_back("");
} else {
// This node is not the root of the tree; we start by printing the
// connectors of the previous levels.
for (const char* s : tree_symbols) PrintF("%s", s);
// Then, we print the node id, preceeded by a ╠ or ╚ connector.
const char* tree_connector_symbol = has_next ? "╠" : "╚";
PrintF("%s B%d\n", tree_connector_symbol, index().id());
// And we add to the stack a connector to continue this path (if needed)
// while printing the current node's children.
const char* tree_cont_symbol = has_next ? "║ " : " ";
tree_symbols.push_back(tree_cont_symbol);
}
// Recursively printing the children of this node.
base::SmallVector<Block*, 8> children = Children();
for (Block* child : children) {
child->PrintDominatorTree(tree_symbols, child != children.back());
}
// Removing from the stack the "║" or " " corresponding to this node.
tree_symbols.pop_back();
}
std::ostream& operator<<(std::ostream& os, PrintAsBlockHeader block_header) {
const Block& block = block_header.block;
os << block.kind() << " " << block_header.block_id;
if (!block.Predecessors().empty()) {
os << " <- ";
bool first = true;
for (const Block* pred : block.Predecessors()) {
if (!first) os << ", ";
os << pred->index();
first = false;
}
}
return os;
}
std::ostream& operator<<(std::ostream& os, const Graph& graph) {
for (const Block& block : graph.blocks()) {
os << "\n" << PrintAsBlockHeader{block} << "\n";
for (const Operation& op : graph.operations(block)) {
os << std::setw(5) << graph.Index(op).id() << ": " << op << "\n";
}
}
return os;
}
std::ostream& operator<<(std::ostream& os, const Block::Kind& kind) {
switch (kind) {
case Block::Kind::kLoopHeader:
return os << "LOOP";
case Block::Kind::kMerge:
return os << "MERGE";
case Block::Kind::kBranchTarget:
return os << "BLOCK";
}
}
} // namespace v8::internal::compiler::turboshaft