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 |