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 "src/compiler/generic-algorithm.h" | 7 #include "src/compiler/generic-algorithm.h" |
8 #include "src/compiler/generic-node.h" | 8 #include "src/compiler/generic-node.h" |
9 #include "src/compiler/generic-node-inl.h" | 9 #include "src/compiler/generic-node-inl.h" |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 public: | 26 public: |
27 GraphVisualizer(OStream& os, Zone* zone, const Graph* graph); // NOLINT | 27 GraphVisualizer(OStream& os, Zone* zone, const Graph* graph); // NOLINT |
28 | 28 |
29 void Print(); | 29 void Print(); |
30 | 30 |
31 GenericGraphVisit::Control Pre(Node* node); | 31 GenericGraphVisit::Control Pre(Node* node); |
32 GenericGraphVisit::Control PreEdge(Node* from, int index, Node* to); | 32 GenericGraphVisit::Control PreEdge(Node* from, int index, Node* to); |
33 | 33 |
34 private: | 34 private: |
35 void AnnotateNode(Node* node); | 35 void AnnotateNode(Node* node); |
36 void PrintEdge(Node* from, int index, Node* to); | 36 void PrintEdge(Node::Edge edge); |
37 | 37 |
38 Zone* zone_; | 38 Zone* zone_; |
39 NodeSet all_nodes_; | 39 NodeSet all_nodes_; |
40 NodeSet white_nodes_; | 40 NodeSet white_nodes_; |
41 bool use_to_def_; | 41 bool use_to_def_; |
42 OStream& os_; | 42 OStream& os_; |
43 const Graph* const graph_; | 43 const Graph* const graph_; |
44 | 44 |
45 DISALLOW_COPY_AND_ASSIGN(GraphVisualizer); | 45 DISALLOW_COPY_AND_ASSIGN(GraphVisualizer); |
46 }; | 46 }; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0; | 161 for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0; |
162 ++i, j--) { | 162 ++i, j--) { |
163 os_ << "|<I" << i.index() << ">#" << (*i)->id(); | 163 os_ << "|<I" << i.index() << ">#" << (*i)->id(); |
164 } | 164 } |
165 for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0; | 165 for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0; |
166 ++i, j--) { | 166 ++i, j--) { |
167 os_ << "|<I" << i.index() << ">X #" << (*i)->id(); | 167 os_ << "|<I" << i.index() << ">X #" << (*i)->id(); |
168 } | 168 } |
169 for (int j = OperatorProperties::GetFrameStateInputCount(node->op()); j > 0; | 169 for (int j = OperatorProperties::GetFrameStateInputCount(node->op()); j > 0; |
170 ++i, j--) { | 170 ++i, j--) { |
171 os_ << "|<I" << i.index() << ">X #" << (*i)->id(); | 171 os_ << "|<I" << i.index() << ">F #" << (*i)->id(); |
172 } | 172 } |
173 for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0; | 173 for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0; |
174 ++i, j--) { | 174 ++i, j--) { |
175 os_ << "|<I" << i.index() << ">E #" << (*i)->id(); | 175 os_ << "|<I" << i.index() << ">E #" << (*i)->id(); |
176 } | 176 } |
177 | 177 |
178 if (!use_to_def_ || OperatorProperties::IsBasicBlockBegin(node->op()) || | 178 if (!use_to_def_ || OperatorProperties::IsBasicBlockBegin(node->op()) || |
179 GetControlCluster(node) == NULL) { | 179 GetControlCluster(node) == NULL) { |
180 for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0; | 180 for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0; |
181 ++i, j--) { | 181 ++i, j--) { |
182 os_ << "|<I" << i.index() << ">C #" << (*i)->id(); | 182 os_ << "|<I" << i.index() << ">C #" << (*i)->id(); |
183 } | 183 } |
184 } | 184 } |
185 os_ << "}"; | 185 os_ << "}"; |
186 | 186 |
187 if (FLAG_trace_turbo_types && !NodeProperties::IsControl(node)) { | 187 if (FLAG_trace_turbo_types && !NodeProperties::IsControl(node)) { |
188 Bounds bounds = NodeProperties::GetBounds(node); | 188 Bounds bounds = NodeProperties::GetBounds(node); |
189 OStringStream upper; | 189 OStringStream upper; |
190 bounds.upper->PrintTo(upper); | 190 bounds.upper->PrintTo(upper); |
191 OStringStream lower; | 191 OStringStream lower; |
192 bounds.lower->PrintTo(lower); | 192 bounds.lower->PrintTo(lower); |
193 os_ << "|" << Escaped(upper) << "|" << Escaped(lower); | 193 os_ << "|" << Escaped(upper) << "|" << Escaped(lower); |
194 } | 194 } |
195 os_ << "}\"\n"; | 195 os_ << "}\"\n"; |
196 } | 196 } |
197 | 197 |
198 | 198 |
199 void GraphVisualizer::PrintEdge(Node* from, int index, Node* to) { | 199 void GraphVisualizer::PrintEdge(Node::Edge edge) { |
| 200 Node* from = edge.from(); |
| 201 int index = edge.index(); |
| 202 Node* to = edge.to(); |
200 bool unconstrained = IsLikelyBackEdge(from, index, to); | 203 bool unconstrained = IsLikelyBackEdge(from, index, to); |
201 os_ << " ID" << from->id(); | 204 os_ << " ID" << from->id(); |
202 if (all_nodes_.count(to) == 0) { | 205 if (all_nodes_.count(to) == 0) { |
203 os_ << ":I" << index << ":n -> DEAD_INPUT"; | 206 os_ << ":I" << index << ":n -> DEAD_INPUT"; |
204 } else if (OperatorProperties::IsBasicBlockBegin(from->op()) || | 207 } else if (OperatorProperties::IsBasicBlockBegin(from->op()) || |
205 GetControlCluster(from) == NULL || | 208 GetControlCluster(from) == NULL || |
206 (OperatorProperties::GetControlInputCount(from->op()) > 0 && | 209 (OperatorProperties::GetControlInputCount(from->op()) > 0 && |
207 NodeProperties::GetControlInput(from) != to)) { | 210 NodeProperties::GetControlInput(from) != to)) { |
208 os_ << ":I" << index << ":n -> ID" << to->id() << ":s"; | 211 os_ << ":I" << index << ":n -> ID" << to->id() << ":s" |
209 if (unconstrained) os_ << " [constraint=false,style=dotted]"; | 212 << "[" << (unconstrained ? "constraint=false" : "") |
| 213 << (NodeProperties::IsControlEdge(edge) ? "style=bold" : "") |
| 214 << (NodeProperties::IsEffectEdge(edge) ? "style=dotted" : "") |
| 215 << (NodeProperties::IsContextEdge(edge) ? "style=dashed" : "") << "]"; |
210 } else { | 216 } else { |
211 os_ << " -> ID" << to->id() << ":s [color=transparent" | 217 os_ << " -> ID" << to->id() << ":s [color=transparent" |
212 << (unconstrained ? ", constraint=false" : "") << "]"; | 218 << (unconstrained ? ", constraint=false" : "") |
| 219 << (NodeProperties::IsControlEdge(edge) ? ", style=dashed" : "") << "]"; |
213 } | 220 } |
214 os_ << "\n"; | 221 os_ << "\n"; |
215 } | 222 } |
216 | 223 |
217 | 224 |
218 void GraphVisualizer::Print() { | 225 void GraphVisualizer::Print() { |
219 os_ << "digraph D {\n" | 226 os_ << "digraph D {\n" |
220 << " node [fontsize=8,height=0.25]\n" | 227 << " node [fontsize=8,height=0.25]\n" |
221 << " rankdir=\"BT\"\n" | 228 << " rankdir=\"BT\"\n" |
| 229 << " ranksep=\"1.2 equally\"\n" |
| 230 << " overlap=\"false\"\n" |
| 231 << " splines=\"true\"\n" |
| 232 << " concentrate=\"true\"\n" |
222 << " \n"; | 233 << " \n"; |
223 | 234 |
224 // Make sure all nodes have been output before writing out the edges. | 235 // Make sure all nodes have been output before writing out the edges. |
225 use_to_def_ = true; | 236 use_to_def_ = true; |
226 // TODO(svenpanne) Remove the need for the const_casts. | 237 // TODO(svenpanne) Remove the need for the const_casts. |
227 const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); | 238 const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); |
228 white_nodes_.insert(const_cast<Graph*>(graph_)->start()); | 239 white_nodes_.insert(const_cast<Graph*>(graph_)->start()); |
229 | 240 |
230 // Visit all uses of white nodes. | 241 // Visit all uses of white nodes. |
231 use_to_def_ = false; | 242 use_to_def_ = false; |
232 GenericGraphVisit::Visit<GraphVisualizer, NodeUseIterationTraits<Node> >( | 243 GenericGraphVisit::Visit<GraphVisualizer, NodeUseIterationTraits<Node> >( |
233 const_cast<Graph*>(graph_), zone_, white_nodes_.begin(), | 244 const_cast<Graph*>(graph_), zone_, white_nodes_.begin(), |
234 white_nodes_.end(), this); | 245 white_nodes_.end(), this); |
235 | 246 |
236 os_ << " DEAD_INPUT [\n" | 247 os_ << " DEAD_INPUT [\n" |
237 << " style=\"filled\" \n" | 248 << " style=\"filled\" \n" |
238 << " fillcolor=\"" DEAD_COLOR "\"\n" | 249 << " fillcolor=\"" DEAD_COLOR "\"\n" |
239 << " ]\n" | 250 << " ]\n" |
240 << "\n"; | 251 << "\n"; |
241 | 252 |
242 // With all the nodes written, add the edges. | 253 // With all the nodes written, add the edges. |
243 for (NodeSetIter i = all_nodes_.begin(); i != all_nodes_.end(); ++i) { | 254 for (NodeSetIter i = all_nodes_.begin(); i != all_nodes_.end(); ++i) { |
244 Node::Inputs inputs = (*i)->inputs(); | 255 Node::Inputs inputs = (*i)->inputs(); |
245 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 256 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
246 ++iter) { | 257 ++iter) { |
247 PrintEdge(iter.edge().from(), iter.edge().index(), iter.edge().to()); | 258 PrintEdge(iter.edge()); |
248 } | 259 } |
249 } | 260 } |
250 os_ << "}\n"; | 261 os_ << "}\n"; |
251 } | 262 } |
252 | 263 |
253 | 264 |
254 GraphVisualizer::GraphVisualizer(OStream& os, Zone* zone, | 265 GraphVisualizer::GraphVisualizer(OStream& os, Zone* zone, |
255 const Graph* graph) // NOLINT | 266 const Graph* graph) // NOLINT |
256 : zone_(zone), | 267 : zone_(zone), |
257 all_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)), | 268 all_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)), |
258 white_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)), | 269 white_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)), |
259 use_to_def_(true), | 270 use_to_def_(true), |
260 os_(os), | 271 os_(os), |
261 graph_(graph) {} | 272 graph_(graph) {} |
262 | 273 |
263 | 274 |
264 OStream& operator<<(OStream& os, const AsDOT& ad) { | 275 OStream& operator<<(OStream& os, const AsDOT& ad) { |
265 Zone tmp_zone(ad.graph.zone()->isolate()); | 276 Zone tmp_zone(ad.graph.zone()->isolate()); |
266 GraphVisualizer(os, &tmp_zone, &ad.graph).Print(); | 277 GraphVisualizer(os, &tmp_zone, &ad.graph).Print(); |
267 return os; | 278 return os; |
268 } | 279 } |
269 } | 280 } |
270 } | 281 } |
271 } // namespace v8::internal::compiler | 282 } // namespace v8::internal::compiler |
OLD | NEW |