| 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/compiler/generic-algorithm.h" | 10 #include "src/compiler/generic-algorithm.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 class JSONGraphEdgeWriter : public NullNodeVisitor { | 111 class JSONGraphEdgeWriter : public NullNodeVisitor { |
| 112 public: | 112 public: |
| 113 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, | 113 JSONGraphEdgeWriter(std::ostream& os, Zone* zone, |
| 114 const Graph* graph) // NOLINT | 114 const Graph* graph) // NOLINT |
| 115 : os_(os), | 115 : os_(os), |
| 116 graph_(graph), | 116 graph_(graph), |
| 117 first_edge_(true) {} | 117 first_edge_(true) {} |
| 118 | 118 |
| 119 void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); } | 119 void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); } |
| 120 | 120 |
| 121 GenericGraphVisit::Control PreEdge(Node* from, int index, Node* to); | 121 void PreEdge(Node* from, int index, Node* to); |
| 122 | 122 |
| 123 private: | 123 private: |
| 124 std::ostream& os_; | 124 std::ostream& os_; |
| 125 const Graph* const graph_; | 125 const Graph* const graph_; |
| 126 bool first_edge_; | 126 bool first_edge_; |
| 127 | 127 |
| 128 DISALLOW_COPY_AND_ASSIGN(JSONGraphEdgeWriter); | 128 DISALLOW_COPY_AND_ASSIGN(JSONGraphEdgeWriter); |
| 129 }; | 129 }; |
| 130 | 130 |
| 131 | 131 |
| 132 GenericGraphVisit::Control JSONGraphEdgeWriter::PreEdge(Node* from, int index, | 132 void JSONGraphEdgeWriter::PreEdge(Node* from, int index, Node* to) { |
| 133 Node* to) { | |
| 134 if (first_edge_) { | 133 if (first_edge_) { |
| 135 first_edge_ = false; | 134 first_edge_ = false; |
| 136 } else { | 135 } else { |
| 137 os_ << ","; | 136 os_ << ","; |
| 138 } | 137 } |
| 139 const char* edge_type = NULL; | 138 const char* edge_type = NULL; |
| 140 if (index < NodeProperties::FirstValueIndex(from)) { | 139 if (index < NodeProperties::FirstValueIndex(from)) { |
| 141 edge_type = "unknown"; | 140 edge_type = "unknown"; |
| 142 } else if (index < NodeProperties::FirstContextIndex(from)) { | 141 } else if (index < NodeProperties::FirstContextIndex(from)) { |
| 143 edge_type = "value"; | 142 edge_type = "value"; |
| 144 } else if (index < NodeProperties::FirstFrameStateIndex(from)) { | 143 } else if (index < NodeProperties::FirstFrameStateIndex(from)) { |
| 145 edge_type = "context"; | 144 edge_type = "context"; |
| 146 } else if (index < NodeProperties::FirstEffectIndex(from)) { | 145 } else if (index < NodeProperties::FirstEffectIndex(from)) { |
| 147 edge_type = "frame-state"; | 146 edge_type = "frame-state"; |
| 148 } else if (index < NodeProperties::FirstControlIndex(from)) { | 147 } else if (index < NodeProperties::FirstControlIndex(from)) { |
| 149 edge_type = "effect"; | 148 edge_type = "effect"; |
| 150 } else { | 149 } else { |
| 151 edge_type = "control"; | 150 edge_type = "control"; |
| 152 } | 151 } |
| 153 os_ << "{\"source\":" << to->id() << ",\"target\":" << from->id() | 152 os_ << "{\"source\":" << to->id() << ",\"target\":" << from->id() |
| 154 << ",\"index\":" << index << ",\"type\":\"" << edge_type << "\"}"; | 153 << ",\"index\":" << index << ",\"type\":\"" << edge_type << "\"}"; |
| 155 return GenericGraphVisit::CONTINUE; | |
| 156 } | 154 } |
| 157 | 155 |
| 158 | 156 |
| 159 std::ostream& operator<<(std::ostream& os, const AsJSON& ad) { | 157 std::ostream& operator<<(std::ostream& os, const AsJSON& ad) { |
| 160 Zone tmp_zone(ad.graph.zone()->isolate()); | 158 Zone tmp_zone(ad.graph.zone()->isolate()); |
| 161 os << "{\"nodes\":["; | 159 os << "{\"nodes\":["; |
| 162 JSONGraphNodeWriter(os, &tmp_zone, &ad.graph).Print(); | 160 JSONGraphNodeWriter(os, &tmp_zone, &ad.graph).Print(); |
| 163 os << "],\"edges\":["; | 161 os << "],\"edges\":["; |
| 164 JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print(); | 162 JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print(); |
| 165 os << "]}"; | 163 os << "]}"; |
| 166 return os; | 164 return os; |
| 167 } | 165 } |
| 168 | 166 |
| 169 | 167 |
| 170 class GraphVisualizer : public NullNodeVisitor { | 168 class GraphVisualizer : public NullNodeVisitor { |
| 171 public: | 169 public: |
| 172 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph); // NOLINT | 170 GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph); // NOLINT |
| 173 | 171 |
| 174 void Print(); | 172 void Print(); |
| 175 | 173 |
| 176 GenericGraphVisit::Control Pre(Node* node); | 174 GenericGraphVisit::Control Pre(Node* node); |
| 177 GenericGraphVisit::Control PreEdge(Node* from, int index, Node* to); | |
| 178 | 175 |
| 179 private: | 176 private: |
| 180 void AnnotateNode(Node* node); | 177 void AnnotateNode(Node* node); |
| 181 void PrintEdge(Node::Edge edge); | 178 void PrintEdge(Node::Edge edge); |
| 182 | 179 |
| 183 Zone* zone_; | 180 Zone* zone_; |
| 184 NodeSet all_nodes_; | 181 NodeSet all_nodes_; |
| 185 NodeSet white_nodes_; | 182 NodeSet white_nodes_; |
| 186 bool use_to_def_; | 183 bool use_to_def_; |
| 187 std::ostream& os_; | 184 std::ostream& os_; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 214 AnnotateNode(node); | 211 AnnotateNode(node); |
| 215 os_ << " ]\n"; | 212 os_ << " ]\n"; |
| 216 if (control_cluster != NULL) os_ << " }\n"; | 213 if (control_cluster != NULL) os_ << " }\n"; |
| 217 all_nodes_.insert(node); | 214 all_nodes_.insert(node); |
| 218 if (use_to_def_) white_nodes_.insert(node); | 215 if (use_to_def_) white_nodes_.insert(node); |
| 219 } | 216 } |
| 220 return GenericGraphVisit::CONTINUE; | 217 return GenericGraphVisit::CONTINUE; |
| 221 } | 218 } |
| 222 | 219 |
| 223 | 220 |
| 224 GenericGraphVisit::Control GraphVisualizer::PreEdge(Node* from, int index, | |
| 225 Node* to) { | |
| 226 if (use_to_def_) return GenericGraphVisit::CONTINUE; | |
| 227 // When going from def to use, only consider white -> other edges, which are | |
| 228 // the dead nodes that use live nodes. We're probably not interested in | |
| 229 // dead nodes that only use other dead nodes. | |
| 230 if (white_nodes_.count(from) > 0) return GenericGraphVisit::CONTINUE; | |
| 231 return GenericGraphVisit::SKIP; | |
| 232 } | |
| 233 | |
| 234 | |
| 235 static bool IsLikelyBackEdge(Node* from, int index, Node* to) { | 221 static bool IsLikelyBackEdge(Node* from, int index, Node* to) { |
| 236 if (from->opcode() == IrOpcode::kPhi || | 222 if (from->opcode() == IrOpcode::kPhi || |
| 237 from->opcode() == IrOpcode::kEffectPhi) { | 223 from->opcode() == IrOpcode::kEffectPhi) { |
| 238 Node* control = NodeProperties::GetControlInput(from, 0); | 224 Node* control = NodeProperties::GetControlInput(from, 0); |
| 239 return control->opcode() != IrOpcode::kMerge && control != to && index != 0; | 225 return control->opcode() != IrOpcode::kMerge && control != to && index != 0; |
| 240 } else if (from->opcode() == IrOpcode::kLoop) { | 226 } else if (from->opcode() == IrOpcode::kLoop) { |
| 241 return index != 0; | 227 return index != 0; |
| 242 } else { | 228 } else { |
| 243 return false; | 229 return false; |
| 244 } | 230 } |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 | 767 |
| 782 | 768 |
| 783 std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) { | 769 std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) { |
| 784 Zone tmp_zone(ac.allocator_->code()->zone()->isolate()); | 770 Zone tmp_zone(ac.allocator_->code()->zone()->isolate()); |
| 785 GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_); | 771 GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_); |
| 786 return os; | 772 return os; |
| 787 } | 773 } |
| 788 } | 774 } |
| 789 } | 775 } |
| 790 } // namespace v8::internal::compiler | 776 } // namespace v8::internal::compiler |
| OLD | NEW |