v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
graph.cc
Go to the documentation of this file.
1// Copyright 2022 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <algorithm>
8#include <iomanip>
9
10#include "src/base/logging.h"
11
13
14// PrintDominatorTree prints the dominator tree in a format that looks like:
15//
16// 0
17// ╠ 1
18// ╠ 2
19// ╠ 3
20// ║ ╠ 4
21// ║ ║ ╠ 5
22// ║ ║ ╚ 6
23// ║ ╚ 7
24// ║ ╠ 8
25// ║ ╚ 16
26// ╚ 17
27//
28// Where the numbers are the IDs of the Blocks.
29// Doing so is mostly straight forward, with the subtelty that we need to know
30// where to put "║" symbols (eg, in from of "╠ 5" above). The logic to do this
31// is basically: "if the current node is not the last of its siblings, then,
32// when going down to print its content, we add a "║" in front of each of its
33// children; otherwise (current node is the last of its siblings), we add a
34// blank space " " in front of its children". We maintain this information
35// using a stack (implemented with a std::vector).
36void Block::PrintDominatorTree(std::vector<const char*> tree_symbols,
37 bool has_next) const {
38 // Printing the current node.
39 if (tree_symbols.empty()) {
40 // This node is the root of the tree.
41 PrintF("B%d\n", index().id());
42 tree_symbols.push_back("");
43 } else {
44 // This node is not the root of the tree; we start by printing the
45 // connectors of the previous levels.
46 for (const char* s : tree_symbols) PrintF("%s", s);
47 // Then, we print the node id, preceeded by a ╠ or ╚ connector.
48 const char* tree_connector_symbol = has_next ? "╠" : "╚";
49 PrintF("%s B%d\n", tree_connector_symbol, index().id());
50 // And we add to the stack a connector to continue this path (if needed)
51 // while printing the current node's children.
52 const char* tree_cont_symbol = has_next ? "║ " : " ";
53 tree_symbols.push_back(tree_cont_symbol);
54 }
55 // Recursively printing the children of this node.
57 for (Block* child : children) {
58 child->PrintDominatorTree(tree_symbols, child != children.back());
59 }
60 // Removing from the stack the "║" or " " corresponding to this node.
61 tree_symbols.pop_back();
62}
63
64std::ostream& operator<<(std::ostream& os, PrintAsBlockHeader block_header) {
65 const Block& block = block_header.block;
66 os << block.kind() << " " << block_header.block_id;
67 if (!block.Predecessors().empty()) {
68 os << " <- ";
69 bool first = true;
70 for (const Block* pred : block.Predecessors()) {
71 if (!first) os << ", ";
72 os << pred->index();
73 first = false;
74 }
75 }
76 return os;
77}
78
79std::ostream& operator<<(std::ostream& os, const Graph& graph) {
80 for (const Block& block : graph.blocks()) {
81 os << "\n" << PrintAsBlockHeader{block} << "\n";
82 for (const Operation& op : graph.operations(block)) {
83 os << std::setw(5) << graph.Index(op).id() << ": " << op << "\n";
84 }
85 }
86 return os;
87}
88
89std::ostream& operator<<(std::ostream& os, const Block::Kind& kind) {
90 switch (kind) {
92 return os << "LOOP";
94 return os << "MERGE";
96 return os << "BLOCK";
97 }
98}
99
100} // namespace v8::internal::compiler::turboshaft
Builtins::Kind kind
Definition builtins.cc:40
base::SmallVector< Block *, 8 > Predecessors() const
Definition graph.h:328
void PrintDominatorTree(std::vector< const char * > tree_symbols=std::vector< const char * >(), bool has_next=false) const
Definition graph.cc:36
std::vector< std::unique_ptr< InstanceTypeTree > > children
std::ostream & operator<<(std::ostream &os, PaddingSpace padding)
void PrintF(const char *format,...)
Definition utils.cc:39