v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
graph-visualizer.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
10
12
14 std::ostream& os, const Graph& turboshaft_graph, NodeOriginTable* origins,
15 Zone* zone)
16 : os_(os),
17 zone_(zone),
18 turboshaft_graph_(turboshaft_graph),
19 origins_(origins) {}
20
22 os_ << "{\n\"nodes\":[";
23 PrintNodes();
24 os_ << "\n],\n\"edges\":[";
25 PrintEdges();
26 os_ << "\n],\n\"blocks\":[";
28 os_ << "\n]}";
29}
30
32 bool first = true;
33 for (const Block& block : turboshaft_graph_.blocks()) {
34 for (const Operation& op : turboshaft_graph_.operations(block)) {
35 OpIndex index = turboshaft_graph_.Index(op);
36 if (!first) os_ << ",\n";
37 first = false;
38 os_ << "{\"id\":" << index.id() << ",";
39 os_ << "\"title\":\"" << OpcodeName(op.opcode) << "\",";
40 os_ << "\"block_id\":" << block.index().id() << ",";
41 os_ << "\"op_effects\":\"" << op.Effects() << "\"";
42 if (origins_) {
43 NodeOrigin origin = origins_->GetNodeOrigin(index.id());
44 if (origin.IsKnown()) {
45 os_ << ", \"origin\":" << AsJSON(origin);
46 }
47 }
48 SourcePosition position = turboshaft_graph_.source_positions()[index];
49 if (position.IsKnown()) {
50 os_ << ", \"sourcePosition\":" << compiler::AsJSON(position);
51 }
52 os_ << "}";
53 }
54 }
55}
56
58 bool first = true;
59 for (const Block& block : turboshaft_graph_.blocks()) {
60 for (const Operation& op : turboshaft_graph_.operations(block)) {
61 int target_id = turboshaft_graph_.Index(op).id();
62 base::SmallVector<OpIndex, 32> inputs{op.inputs()};
63 // Reorder the inputs to correspond to the order used in constructor and
64 // assembler functions.
65 if (auto* store = op.TryCast<StoreOp>()) {
66 if (store->index().valid()) {
67 DCHECK_EQ(store->input_count, 3);
68 inputs = {store->base(), store->index().value_or_invalid(),
69 store->value()};
70 }
71 }
72 for (OpIndex input : inputs) {
73 if (!first) os_ << ",\n";
74 first = false;
75 os_ << "{\"source\":" << input.id() << ",";
76 os_ << "\"target\":" << target_id << "}";
77 }
78 }
79 }
80}
81
83 bool first_block = true;
84 for (const Block& block : turboshaft_graph_.blocks()) {
85 if (!first_block) os_ << ",\n";
86 first_block = false;
87 os_ << "{\"id\":" << block.index().id() << ",";
88 os_ << "\"type\":\"" << block.kind() << "\",";
89 os_ << "\"predecessors\":[";
90 bool first_predecessor = true;
91 for (const Block* pred : block.Predecessors()) {
92 if (!first_predecessor) os_ << ", ";
93 first_predecessor = false;
94 os_ << pred->index().id();
95 }
96 os_ << "]}";
97 }
98}
99
100std::ostream& operator<<(std::ostream& os, const TurboshaftGraphAsJSON& ad) {
102 ad.temp_zone);
103 writer.Print();
104 return os;
105}
106
108 std::ofstream& stream, const char* data_name, const Graph& graph,
109 std::function<bool(std::ostream&, const Graph&, OpIndex)> printer) {
110 DCHECK(printer);
111 stream << "{\"name\":\"" << data_name
112 << "\", \"type\":\"turboshaft_custom_data\", "
113 "\"data_target\":\"operations\", \"data\":[";
114 bool first = true;
115 for (auto index : graph.AllOperationIndices()) {
116 std::stringstream sstream;
117 if (printer(sstream, graph, index)) {
118 stream << (first ? "\n" : ",\n") << "{\"key\":" << index.id()
119 << ", \"value\":\"" << sstream.str() << "\"}";
120 first = false;
121 }
122 }
123 stream << "]},\n";
124}
125
127 std::ofstream& stream, const char* data_name, const Graph& graph,
128 std::function<bool(std::ostream&, const Graph&, BlockIndex)> printer) {
129 DCHECK(printer);
130 stream << "{\"name\":\"" << data_name
131 << "\", \"type\":\"turboshaft_custom_data\", "
132 "\"data_target\":\"blocks\", \"data\":[";
133 bool first = true;
134 for (const Block& block : graph.blocks()) {
135 std::stringstream sstream;
136 BlockIndex index = block.index();
137 if (printer(sstream, graph, index)) {
138 stream << (first ? "\n" : ",\n") << "{\"key\":" << index.id()
139 << ", \"value\":\"" << sstream.str() << "\"}";
140 first = false;
141 }
142 }
143 stream << "]},\n";
144}
145
146} // namespace v8::internal::compiler::turboshaft
NodeOrigin GetNodeOrigin(Node *node) const
base::SmallVector< Block *, 8 > Predecessors() const
Definition graph.h:328
JSONTurboshaftGraphWriter(std::ostream &os, const Graph &turboshaft_graph, NodeOriginTable *origins, Zone *zone)
Zone * zone_
NodeOriginTable * origins
int position
Definition liveedit.cc:290
std::ostream & operator<<(std::ostream &os, PaddingSpace padding)
const char * OpcodeName(Opcode opcode)
V8_INLINE V8_EXPORT_PRIVATE TurboshaftGraphAsJSON AsJSON(const Graph &graph, NodeOriginTable *origins, Zone *temp_zone)
void PrintTurboshaftCustomDataPerBlock(std::ofstream &stream, const char *data_name, const Graph &graph, std::function< bool(std::ostream &, const Graph &, BlockIndex)> printer)
void PrintTurboshaftCustomDataPerOperation(std::ofstream &stream, const char *data_name, const Graph &graph, std::function< bool(std::ostream &, const Graph &, OpIndex)> printer)
V8_INLINE V8_EXPORT_PRIVATE SourcePositionAsJSON AsJSON(const SourcePosition &sp)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
std::ostream * os_