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
17namespace v8 {
18namespace internal {
19
20class OptimizedCompilationInfo;
21class SharedFunctionInfo;
22class SourcePosition;
23namespace compiler {
24
25class Graph;
26class LiveRange;
27class TopLevelLiveRange;
28class Instruction;
29class InstructionBlock;
30class InstructionOperand;
31class InstructionSequence;
32class Node;
33class NodeOrigin;
34class NodeOriginTable;
35class RegisterAllocationData;
36class Schedule;
37class SourcePositionTable;
38class Type;
39
40struct TurboJsonFile : public std::ofstream {
41  TurboJsonFile(OptimizedCompilationInfo* info, std::ios_base::openmode mode);
42  ~TurboJsonFile() override;
43};
44
45struct TurboCfgFile : public std::ofstream {
46  explicit TurboCfgFile(Isolate* isolate = nullptr);
47  ~TurboCfgFile() override;
48};
49
50struct SourcePositionAsJSON {
51  explicit SourcePositionAsJSON(const SourcePosition& sp) : sp(sp) {}
52  const SourcePosition& sp;
53};
54
55V8_INLINE V8_EXPORT_PRIVATE SourcePositionAsJSON
56AsJSON(const SourcePosition& sp) {
57  return SourcePositionAsJSON(sp);
58}
59
60struct NodeOriginAsJSON {
61  explicit NodeOriginAsJSON(const NodeOrigin& no) : no(no) {}
62  const NodeOrigin& no;
63};
64
65V8_INLINE V8_EXPORT_PRIVATE NodeOriginAsJSON AsJSON(const NodeOrigin& no) {
66  return NodeOriginAsJSON(no);
67}
68
69std::ostream& operator<<(std::ostream& out, const SourcePositionAsJSON& pos);
70
71// Small helper that deduplicates SharedFunctionInfos.
72class V8_EXPORT_PRIVATE SourceIdAssigner {
73 public:
74  explicit SourceIdAssigner(size_t size) {
75    printed_.reserve(size);
76    source_ids_.reserve(size);
77  }
78  int GetIdFor(Handle<SharedFunctionInfo> shared);
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
86void JsonPrintAllSourceWithPositions(std::ostream& os,
87                                     OptimizedCompilationInfo* info,
88                                     Isolate* isolate);
89
90void 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);
95std::unique_ptr<char[]> GetVisualizerLogFileName(OptimizedCompilationInfo* info,
96                                                 const char* optional_base_dir,
97                                                 const char* phase,
98                                                 const char* suffix);
99
100class 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
128struct GraphAsJSON {
129  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
136V8_INLINE V8_EXPORT_PRIVATE GraphAsJSON AsJSON(const Graph& g,
137                                               SourcePositionTable* p,
138                                               NodeOriginTable* o) {
139  return GraphAsJSON(g, p, o);
140}
141
142V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
143                                           const GraphAsJSON& ad);
144
145struct AsRPO {
146  explicit AsRPO(const Graph& g) : graph(g) {}
147  const Graph& graph;
148};
149
150V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const AsRPO& ad);
151
152struct AsC1VCompilation {
153  explicit AsC1VCompilation(const OptimizedCompilationInfo* info)
154      : info_(info) {}
155  const OptimizedCompilationInfo* info_;
156};
157
158struct AsScheduledGraph {
159  explicit AsScheduledGraph(const Schedule* schedule) : schedule(schedule) {}
160  const Schedule* schedule;
161};
162
163std::ostream& operator<<(std::ostream& os, const AsScheduledGraph& scheduled);
164struct AsC1V {
165  AsC1V(const char* phase, const Schedule* schedule,
166        const SourcePositionTable* positions = nullptr,
167        const InstructionSequence* instructions = nullptr)
168      : 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
178struct AsC1VRegisterAllocationData {
179  explicit AsC1VRegisterAllocationData(
180      const char* phase, const RegisterAllocationData* data = nullptr)
181      : phase_(phase), data_(data) {}
182  const char* phase_;
183  const RegisterAllocationData* data_;
184};
185
186std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac);
187std::ostream& operator<<(std::ostream& os, const AsC1V& ac);
188std::ostream& operator<<(std::ostream& os,
189                         const AsC1VRegisterAllocationData& ac);
190
191struct LiveRangeAsJSON {
192  const LiveRange& range_;
193  const InstructionSequence& code_;
194};
195
196std::ostream& operator<<(std::ostream& os,
197                         const LiveRangeAsJSON& live_range_json);
198
199struct TopLevelLiveRangeAsJSON {
200  const TopLevelLiveRange& range_;
201  const InstructionSequence& code_;
202};
203
204std::ostream& operator<<(
205    std::ostream& os, const TopLevelLiveRangeAsJSON& top_level_live_range_json);
206
207struct RegisterAllocationDataAsJSON {
208  const RegisterAllocationData& data_;
209  const InstructionSequence& code_;
210};
211
212std::ostream& operator<<(std::ostream& os,
213                         const RegisterAllocationDataAsJSON& ac);
214
215struct InstructionOperandAsJSON {
216  const InstructionOperand* op_;
217  const InstructionSequence* code_;
218};
219
220std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o);
221
222struct InstructionAsJSON {
223  int index_;
224  const Instruction* instr_;
225  const InstructionSequence* code_;
226};
227std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i);
228
229struct InstructionBlockAsJSON {
230  const InstructionBlock* block_;
231  const InstructionSequence* code_;
232};
233
234std::ostream& operator<<(std::ostream& os, const InstructionBlockAsJSON& b);
235
236struct InstructionSequenceAsJSON {
237  const InstructionSequence* sequence_;
238};
239std::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