| 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 |