OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/graph-visualizer.h" | 5 #include "src/compiler/graph-visualizer.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 class JSONGraphNodeWriter : public NullNodeVisitor { | 59 class JSONGraphNodeWriter : public NullNodeVisitor { |
60 public: | 60 public: |
61 JSONGraphNodeWriter(std::ostream& os, Zone* zone, | 61 JSONGraphNodeWriter(std::ostream& os, Zone* zone, |
62 const Graph* graph) // NOLINT | 62 const Graph* graph) // NOLINT |
63 : os_(os), | 63 : os_(os), |
64 graph_(graph), | 64 graph_(graph), |
65 first_node_(true) {} | 65 first_node_(true) {} |
66 | 66 |
67 void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); } | 67 void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); } |
68 | 68 |
69 GenericGraphVisit::Control Pre(Node* node); | 69 void Pre(Node* node); |
70 | 70 |
71 private: | 71 private: |
72 std::ostream& os_; | 72 std::ostream& os_; |
73 const Graph* const graph_; | 73 const Graph* const graph_; |
74 bool first_node_; | 74 bool first_node_; |
75 | 75 |
76 DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter); | 76 DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter); |
77 }; | 77 }; |
78 | 78 |
79 | 79 |
80 GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) { | 80 void JSONGraphNodeWriter::Pre(Node* node) { |
81 if (first_node_) { | 81 if (first_node_) { |
82 first_node_ = false; | 82 first_node_ = false; |
83 } else { | 83 } else { |
84 os_ << ","; | 84 os_ << ","; |
85 } | 85 } |
86 std::ostringstream label; | 86 std::ostringstream label; |
87 label << *node->op(); | 87 label << *node->op(); |
88 os_ << "{\"id\":" << node->id() << ",\"label\":\"" << Escaped(label, "\"") | 88 os_ << "{\"id\":" << node->id() << ",\"label\":\"" << Escaped(label, "\"") |
89 << "\""; | 89 << "\""; |
90 IrOpcode::Value opcode = node->opcode(); | 90 IrOpcode::Value opcode = node->opcode(); |
91 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) { | 91 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) { |
92 os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node) | 92 os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node) |
93 << "]"; | 93 << "]"; |
94 os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node) | 94 os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node) |
95 << "]"; | 95 << "]"; |
96 } else if (opcode == IrOpcode::kIfTrue || opcode == IrOpcode::kIfFalse || | 96 } else if (opcode == IrOpcode::kIfTrue || opcode == IrOpcode::kIfFalse || |
97 opcode == IrOpcode::kLoop) { | 97 opcode == IrOpcode::kLoop) { |
98 os_ << ",\"rankInputs\":[" << NodeProperties::FirstControlIndex(node) | 98 os_ << ",\"rankInputs\":[" << NodeProperties::FirstControlIndex(node) |
99 << "]"; | 99 << "]"; |
100 } | 100 } |
101 if (opcode == IrOpcode::kBranch) { | 101 if (opcode == IrOpcode::kBranch) { |
102 os_ << ",\"rankInputs\":[0]"; | 102 os_ << ",\"rankInputs\":[0]"; |
103 } | 103 } |
104 os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\""; | 104 os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\""; |
105 os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true" | 105 os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true" |
106 : "false"); | 106 : "false"); |
107 os_ << "}"; | 107 os_ << "}"; |
108 return GenericGraphVisit::CONTINUE; | |
109 } | 108 } |
110 | 109 |
111 | 110 |
112 class JSONGraphEdgeWriter : public NullNodeVisitor { | 111 class JSONGraphEdgeWriter : public NullNodeVisitor { |
113 public: | 112 public: |
114 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, | 113 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, |
115 const Graph* graph) // NOLINT | 114 const Graph* graph) // NOLINT |
116 : os_(os), | 115 : os_(os), |
117 graph_(graph), | 116 graph_(graph), |
118 first_edge_(true) {} | 117 first_edge_(true) {} |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 return os; | 164 return os; |
166 } | 165 } |
167 | 166 |
168 | 167 |
169 class GraphVisualizer : public NullNodeVisitor { | 168 class GraphVisualizer : public NullNodeVisitor { |
170 public: | 169 public: |
171 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph); // NOLINT | 170 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph); // NOLINT |
172 | 171 |
173 void Print(); | 172 void Print(); |
174 | 173 |
175 GenericGraphVisit::Control Pre(Node* node); | 174 void Pre(Node* node); |
176 | 175 |
177 private: | 176 private: |
178 void AnnotateNode(Node* node); | 177 void AnnotateNode(Node* node); |
179 void PrintEdge(Node::Edge edge); | 178 void PrintEdge(Node::Edge edge); |
180 | 179 |
181 Zone* zone_; | 180 Zone* zone_; |
182 NodeSet all_nodes_; | 181 NodeSet all_nodes_; |
183 NodeSet white_nodes_; | 182 NodeSet white_nodes_; |
184 bool use_to_def_; | 183 bool use_to_def_; |
185 std::ostream& os_; | 184 std::ostream& os_; |
186 const Graph* const graph_; | 185 const Graph* const graph_; |
187 | 186 |
188 DISALLOW_COPY_AND_ASSIGN(GraphVisualizer); | 187 DISALLOW_COPY_AND_ASSIGN(GraphVisualizer); |
189 }; | 188 }; |
190 | 189 |
191 | 190 |
192 static Node* GetControlCluster(Node* node) { | 191 static Node* GetControlCluster(Node* node) { |
193 if (OperatorProperties::IsBasicBlockBegin(node->op())) { | 192 if (OperatorProperties::IsBasicBlockBegin(node->op())) { |
194 return node; | 193 return node; |
195 } else if (node->op()->ControlInputCount() == 1) { | 194 } else if (node->op()->ControlInputCount() == 1) { |
196 Node* control = NodeProperties::GetControlInput(node, 0); | 195 Node* control = NodeProperties::GetControlInput(node, 0); |
197 return OperatorProperties::IsBasicBlockBegin(control->op()) ? control | 196 return OperatorProperties::IsBasicBlockBegin(control->op()) ? control |
198 : NULL; | 197 : NULL; |
199 } else { | 198 } else { |
200 return NULL; | 199 return NULL; |
201 } | 200 } |
202 } | 201 } |
203 | 202 |
204 | 203 |
205 GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) { | 204 void GraphVisualizer::Pre(Node* node) { |
206 if (all_nodes_.count(node) == 0) { | 205 if (all_nodes_.count(node) == 0) { |
207 Node* control_cluster = GetControlCluster(node); | 206 Node* control_cluster = GetControlCluster(node); |
208 if (control_cluster != NULL) { | 207 if (control_cluster != NULL) { |
209 os_ << " subgraph cluster_BasicBlock" << control_cluster->id() << " {\n"; | 208 os_ << " subgraph cluster_BasicBlock" << control_cluster->id() << " {\n"; |
210 } | 209 } |
211 os_ << " ID" << node->id() << " [\n"; | 210 os_ << " ID" << node->id() << " [\n"; |
212 AnnotateNode(node); | 211 AnnotateNode(node); |
213 os_ << " ]\n"; | 212 os_ << " ]\n"; |
214 if (control_cluster != NULL) os_ << " }\n"; | 213 if (control_cluster != NULL) os_ << " }\n"; |
215 all_nodes_.insert(node); | 214 all_nodes_.insert(node); |
216 if (use_to_def_) white_nodes_.insert(node); | 215 if (use_to_def_) white_nodes_.insert(node); |
217 } | 216 } |
218 return GenericGraphVisit::CONTINUE; | |
219 } | 217 } |
220 | 218 |
221 | 219 |
222 static bool IsLikelyBackEdge(Node* from, int index, Node* to) { | 220 static bool IsLikelyBackEdge(Node* from, int index, Node* to) { |
223 if (from->opcode() == IrOpcode::kPhi || | 221 if (from->opcode() == IrOpcode::kPhi || |
224 from->opcode() == IrOpcode::kEffectPhi) { | 222 from->opcode() == IrOpcode::kEffectPhi) { |
225 Node* control = NodeProperties::GetControlInput(from, 0); | 223 Node* control = NodeProperties::GetControlInput(from, 0); |
226 return control->opcode() != IrOpcode::kMerge && control != to && index != 0; | 224 return control->opcode() != IrOpcode::kMerge && control != to && index != 0; |
227 } else if (from->opcode() == IrOpcode::kLoop) { | 225 } else if (from->opcode() == IrOpcode::kLoop) { |
228 return index != 0; | 226 return index != 0; |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 759 |
762 | 760 |
763 std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) { | 761 std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) { |
764 Zone tmp_zone(ac.allocator_->code()->zone()->isolate()); | 762 Zone tmp_zone(ac.allocator_->code()->zone()->isolate()); |
765 GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_); | 763 GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_); |
766 return os; | 764 return os; |
767 } | 765 } |
768 } | 766 } |
769 } | 767 } |
770 } // namespace v8::internal::compiler | 768 } // namespace v8::internal::compiler |
OLD | NEW |