1 // Copyright 2013 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
5 #ifndef V8_COMPILER_GRAPH_VISUALIZER_H_
6 #define V8_COMPILER_GRAPH_VISUALIZER_H_
7
8 #include <stdio.h>
9
10 #include <fstream>
11 #include <iosfwd>
12 #include <memory>
13
14 #include "src/common/globals.h"
15 #include "src/handles/handles.h"
16
17 namespace v8 {
18 namespace internal {
19
20 class OptimizedCompilationInfo;
21 class SharedFunctionInfo;
22 class SourcePosition;
23 namespace compiler {
24
25 class Graph;
26 class LiveRange;
27 class TopLevelLiveRange;
28 class Instruction;
29 class InstructionBlock;
30 class InstructionOperand;
31 class InstructionSequence;
32 class Node;
33 class NodeOrigin;
34 class NodeOriginTable;
35 class RegisterAllocationData;
36 class Schedule;
37 class SourcePositionTable;
38 class Type;
39
40 struct TurboJsonFile : public std::ofstream {
41 TurboJsonFile(OptimizedCompilationInfo* info, std::ios_base::openmode mode);
42 ~TurboJsonFile() override;
43 };
44
45 struct TurboCfgFile : public std::ofstream {
46 explicit TurboCfgFile(Isolate* isolate = nullptr);
47 ~TurboCfgFile() override;
48 };
49
50 struct SourcePositionAsJSON {
SourcePositionAsJSONSourcePositionAsJSON51 explicit SourcePositionAsJSON(const SourcePosition& sp) : sp(sp) {}
52 const SourcePosition& sp;
53 };
54
55 V8_INLINE V8_EXPORT_PRIVATE SourcePositionAsJSON
AsJSON(const SourcePosition & sp)56 AsJSON(const SourcePosition& sp) {
57 return SourcePositionAsJSON(sp);
58 }
59
60 struct NodeOriginAsJSON {
NodeOriginAsJSONNodeOriginAsJSON61 explicit NodeOriginAsJSON(const NodeOrigin& no) : no(no) {}
62 const NodeOrigin& no;
63 };
64
AsJSON(const NodeOrigin & no)65 V8_INLINE V8_EXPORT_PRIVATE NodeOriginAsJSON AsJSON(const NodeOrigin& no) {
66 return NodeOriginAsJSON(no);
67 }
68
69 std::ostream& operator<<(std::ostream& out, const SourcePositionAsJSON& pos);
70
71 // Small helper that deduplicates SharedFunctionInfos.
72 class V8_EXPORT_PRIVATE SourceIdAssigner {
73 public:
SourceIdAssigner(size_t size)74 explicit SourceIdAssigner(size_t size) {
75 printed_.reserve(size);
76 source_ids_.reserve(size);
77 }
78 int GetIdFor(Handle<SharedFunctionInfo> shared);
GetIdAt(size_t pos)79 int GetIdAt(size_t pos) const { return source_ids_[pos]; }
80
81 private:
82 std::vector<Handle<SharedFunctionInfo>> printed_;
83 std::vector<int> source_ids_;
84 };
85
86 void JsonPrintAllSourceWithPositions(std::ostream& os,
87 OptimizedCompilationInfo* info,
88 Isolate* isolate);
89
90 void JsonPrintFunctionSource(std::ostream& os, int source_id,
91 std::unique_ptr<char[]> function_name,
92 Handle<Script> script, Isolate* isolate,
93 Handle<SharedFunctionInfo> shared,
94 bool with_key = false);
95 std::unique_ptr<char[]> GetVisualizerLogFileName(OptimizedCompilationInfo* info,
96 const char* optional_base_dir,
97 const char* phase,
98 const char* suffix);
99
100 class JSONGraphWriter {
101 public:
102 JSONGraphWriter(std::ostream& os, const Graph* graph,
103 const SourcePositionTable* positions,
104 const NodeOriginTable* origins);
105
106 JSONGraphWriter(const JSONGraphWriter&) = delete;
107 JSONGraphWriter& operator=(const JSONGraphWriter&) = delete;
108
109 void PrintPhase(const char* phase_name);
110 void Print();
111
112 protected:
113 void PrintNode(Node* node, bool is_live);
114 void PrintEdges(Node* node);
115 void PrintEdge(Node* from, int index, Node* to);
116 virtual base::Optional<Type> GetType(Node* node);
117
118 protected:
119 std::ostream& os_;
120 Zone* zone_;
121 const Graph* graph_;
122 const SourcePositionTable* positions_;
123 const NodeOriginTable* origins_;
124 bool first_node_;
125 bool first_edge_;
126 };
127
128 struct GraphAsJSON {
GraphAsJSONGraphAsJSON129 GraphAsJSON(const Graph& g, SourcePositionTable* p, NodeOriginTable* o)
130 : graph(g), positions(p), origins(o) {}
131 const Graph& graph;
132 const SourcePositionTable* positions;
133 const NodeOriginTable* origins;
134 };
135
AsJSON(const Graph & g,SourcePositionTable * p,NodeOriginTable * o)136 V8_INLINE V8_EXPORT_PRIVATE GraphAsJSON AsJSON(const Graph& g,
137 SourcePositionTable* p,
138 NodeOriginTable* o) {
139 return GraphAsJSON(g, p, o);
140 }
141
142 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
143 const GraphAsJSON& ad);
144
145 struct AsRPO {
AsRPOAsRPO146 explicit AsRPO(const Graph& g) : graph(g) {}
147 const Graph& graph;
148 };
149
150 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const AsRPO& ad);
151
152 struct AsC1VCompilation {
AsC1VCompilationAsC1VCompilation153 explicit AsC1VCompilation(const OptimizedCompilationInfo* info)
154 : info_(info) {}
155 const OptimizedCompilationInfo* info_;
156 };
157
158 struct AsScheduledGraph {
AsScheduledGraphAsScheduledGraph159 explicit AsScheduledGraph(const Schedule* schedule) : schedule(schedule) {}
160 const Schedule* schedule;
161 };
162
163 std::ostream& operator<<(std::ostream& os, const AsScheduledGraph& scheduled);
164 struct AsC1V {
165 AsC1V(const char* phase, const Schedule* schedule,
166 const SourcePositionTable* positions = nullptr,
167 const InstructionSequence* instructions = nullptr)
schedule_AsC1V168 : schedule_(schedule),
169 instructions_(instructions),
170 positions_(positions),
171 phase_(phase) {}
172 const Schedule* schedule_;
173 const InstructionSequence* instructions_;
174 const SourcePositionTable* positions_;
175 const char* phase_;
176 };
177
178 struct AsC1VRegisterAllocationData {
179 explicit AsC1VRegisterAllocationData(
180 const char* phase, const RegisterAllocationData* data = nullptr)
phase_AsC1VRegisterAllocationData181 : phase_(phase), data_(data) {}
182 const char* phase_;
183 const RegisterAllocationData* data_;
184 };
185
186 std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac);
187 std::ostream& operator<<(std::ostream& os, const AsC1V& ac);
188 std::ostream& operator<<(std::ostream& os,
189 const AsC1VRegisterAllocationData& ac);
190
191 struct LiveRangeAsJSON {
192 const LiveRange& range_;
193 const InstructionSequence& code_;
194 };
195
196 std::ostream& operator<<(std::ostream& os,
197 const LiveRangeAsJSON& live_range_json);
198
199 struct TopLevelLiveRangeAsJSON {
200 const TopLevelLiveRange& range_;
201 const InstructionSequence& code_;
202 };
203
204 std::ostream& operator<<(
205 std::ostream& os, const TopLevelLiveRangeAsJSON& top_level_live_range_json);
206
207 struct RegisterAllocationDataAsJSON {
208 const RegisterAllocationData& data_;
209 const InstructionSequence& code_;
210 };
211
212 std::ostream& operator<<(std::ostream& os,
213 const RegisterAllocationDataAsJSON& ac);
214
215 struct InstructionOperandAsJSON {
216 const InstructionOperand* op_;
217 const InstructionSequence* code_;
218 };
219
220 std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o);
221
222 struct InstructionAsJSON {
223 int index_;
224 const Instruction* instr_;
225 const InstructionSequence* code_;
226 };
227 std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i);
228
229 struct InstructionBlockAsJSON {
230 const InstructionBlock* block_;
231 const InstructionSequence* code_;
232 };
233
234 std::ostream& operator<<(std::ostream& os, const InstructionBlockAsJSON& b);
235
236 struct InstructionSequenceAsJSON {
237 const InstructionSequence* sequence_;
238 };
239 std::ostream& operator<<(std::ostream& os, const InstructionSequenceAsJSON& s);
240
241 } // namespace compiler
242 } // namespace internal
243 } // namespace v8
244
245 #endif // V8_COMPILER_GRAPH_VISUALIZER_H_
246