comparison graal/GraalCompiler/src/com/sun/c1x/debug/IdealGraphPrinter.java @ 2809:b003ea36fa12

Add block structure to ideal graph visualizer
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Mon, 30 May 2011 14:55:09 +0200
parents d3fc4fe063bf
children 6fb5a1bf819f 31e0786a986c
comparison
equal deleted inserted replaced
2808:189ffb7d1d84 2809:b003ea36fa12
25 import java.io.*; 25 import java.io.*;
26 import java.util.*; 26 import java.util.*;
27 import java.util.Map.Entry; 27 import java.util.Map.Entry;
28 28
29 import com.oracle.graal.graph.*; 29 import com.oracle.graal.graph.*;
30 import com.oracle.max.graal.schedule.*;
30 31
31 /** 32 /**
32 * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the <a 33 * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the <a
33 * href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>. 34 * href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
34 */ 35 */
48 } 49 }
49 } 50 }
50 51
51 private final HashSet<Class<?>> omittedClasses = new HashSet<Class<?>>(); 52 private final HashSet<Class<?>> omittedClasses = new HashSet<Class<?>>();
52 private final PrintStream stream; 53 private final PrintStream stream;
54 private final List<Node> noBlockNodes = new LinkedList<Node>();
53 55
54 /** 56 /**
55 * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream. 57 * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
56 */ 58 */
57 public IdealGraphPrinter(OutputStream stream) { 59 public IdealGraphPrinter(OutputStream stream) {
107 * Prints an entire {@link Graph} with the specified title, optionally using short names for nodes. 109 * Prints an entire {@link Graph} with the specified title, optionally using short names for nodes.
108 */ 110 */
109 public void print(Graph graph, String title, boolean shortNames) { 111 public void print(Graph graph, String title, boolean shortNames) {
110 stream.printf(" <graph name='%s'>%n", escape(title)); 112 stream.printf(" <graph name='%s'>%n", escape(title));
111 113
114 Schedule schedule = new Schedule(graph);
115
112 stream.println(" <nodes>"); 116 stream.println(" <nodes>");
113 List<Edge> edges = printNodes(graph.getNodes(), shortNames); 117 List<Edge> edges = printNodes(graph.getNodes(), shortNames, schedule.getNodeToBlock());
114 stream.println(" </nodes>"); 118 stream.println(" </nodes>");
115 119
116 stream.println(" <edges>"); 120 stream.println(" <edges>");
117 for (Edge edge : edges) { 121 for (Edge edge : edges) {
118 printEdge(edge); 122 printEdge(edge);
119 } 123 }
120 stream.println(" </edges>"); 124 stream.println(" </edges>");
121 125
126 stream.println(" <controlFlow>");
127 for (Block block : schedule.getBlocks()) {
128 printBlock(block);
129 }
130 printNoBlock();
131 stream.println(" </controlFlow>");
132
122 stream.println(" </graph>"); 133 stream.println(" </graph>");
123 } 134 }
124 135
125 private List<Edge> printNodes(Collection<Node> nodes, boolean shortNames) { 136 private List<Edge> printNodes(Collection<Node> nodes, boolean shortNames, NodeMap<Block> nodeToBlock) {
126 ArrayList<Edge> edges = new ArrayList<Edge>(); 137 ArrayList<Edge> edges = new ArrayList<Edge>();
127 138
128 for (Node node : nodes) { 139 for (Node node : nodes) {
129 if (node == Node.Null || omittedClasses.contains(node)) { 140 if (node == Node.Null || omittedClasses.contains(node)) {
130 continue; 141 continue;
141 } else { 152 } else {
142 name = node.toString(); 153 name = node.toString();
143 } 154 }
144 stream.printf(" <p name='name'>%s</p>%n", escape(name)); 155 stream.printf(" <p name='name'>%s</p>%n", escape(name));
145 } 156 }
157 Block block = nodeToBlock.get(node);
158 if (block != null) {
159 stream.printf(" <p name='block'>%d</p>%n", block.blockID());
160 } else {
161 stream.printf(" <p name='block'>noBlock</p>%n");
162 noBlockNodes.add(node);
163 }
146 for (Entry<Object, Object> entry : props.entrySet()) { 164 for (Entry<Object, Object> entry : props.entrySet()) {
147 String key = entry.getKey().toString(); 165 String key = entry.getKey().toString();
148 String value = entry.getValue().toString(); 166 String value = entry.getValue().toString();
149 stream.printf(" <p name='%s'>%s</p>%n", escape(key), escape(value)); 167 stream.printf(" <p name='%s'>%s</p>%n", escape(key), escape(value));
150 } 168 }
175 193
176 private void printEdge(Edge edge) { 194 private void printEdge(Edge edge) {
177 stream.printf(" <edge from='%d' fromIndex='%d' to='%d' toIndex='%d'/>%n", edge.from, edge.fromIndex, edge.to, edge.toIndex); 195 stream.printf(" <edge from='%d' fromIndex='%d' to='%d' toIndex='%d'/>%n", edge.from, edge.fromIndex, edge.to, edge.toIndex);
178 } 196 }
179 197
198 private void printBlock(Block block) {
199 stream.printf(" <block name='%d'>%n", block.blockID());
200 stream.printf(" <successors>%n");
201 for (Block sux : block.getSuccessors()) {
202 stream.printf(" <successor name='%d'/>%n", sux.blockID());
203 }
204 stream.printf(" </successors>%n");
205 stream.printf(" <nodes>%n");
206 for (Node node : block.getInstructions()) {
207 stream.printf(" <node id='%d'/>%n", node.id());
208 }
209 stream.printf(" </nodes>%n");
210 stream.printf(" </block>%n", block.blockID());
211 }
212
213 private void printNoBlock() {
214 if (!noBlockNodes.isEmpty()) {
215 stream.printf(" <block name='noBlock'>%n");
216 stream.printf(" <nodes>%n");
217 for (Node node : noBlockNodes) {
218 stream.printf(" <node id='%d'/>%n", node.id());
219 }
220 stream.printf(" </nodes>%n");
221 stream.printf(" </block>%n");
222 }
223 }
224
180 private String escape(String s) { 225 private String escape(String s) {
181 s = s.replace("&", "&amp;"); 226 s = s.replace("&", "&amp;");
182 s = s.replace("<", "&lt;"); 227 s = s.replace("<", "&lt;");
183 s = s.replace(">", "&gt;"); 228 s = s.replace(">", "&gt;");
184 s = s.replace("\"", "&quot;"); 229 s = s.replace("\"", "&quot;");