1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Martin Trapp, Christian Schaefer
6 ** irdump.h: dumping of an intermediate representation graph
18 # include "type_or_entity.h"
20 # include "typewalk.h"
22 #define DEFAULT_NODE_ATTR ""
23 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
24 #define NODE2TYPE_EDGE_ATTR ""
25 #define DEFAULT_TYPE_ATTRIBUTE ""
26 #define TYPE_EDGE_ATTR ""
32 /*******************************************************************/
33 /* routines to dump information about a single node */
34 /*******************************************************************/
39 dump_node_opcode (ir_node *n)
42 if (n->op->code == iro_Const) {
43 xfprintf (F, "%v", n->attr.con);
45 } else if (n->op->code == iro_SymConst) {
46 if (get_SymConst_kind(n) == linkage_ptr_info) {
47 xfprintf (F, "%I", get_SymConst_ptrinfo(n));
49 assert(get_kind(get_SymConst_type(n)) == k_type_class);
50 assert(get_class_ident((type_class *)get_SymConst_type(n)));
51 xfprintf (F, "%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
52 if (get_SymConst_kind == type_tag)
59 xfprintf (F, "%I", n->op->name);
64 dump_node_mode (ir_node *n)
66 switch (n->op->code) {
83 xfprintf (F, "%I", n->mode->name);
90 dump_node_nodeattr (ir_node *n)
92 switch (n->op->code) {
94 if (n->in[1]->op->code == iro_Cmp) {
95 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
97 xfprintf (F, "%ld", n->attr.proj);
101 /*assert(n->attr.s.ent->kind == k_entity);*/
102 assert(get_kind(get_Sel_entity(n)) == k_entity);
103 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
105 /* xdoesn't work for some reason.
106 fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
113 dump_node_vcgattr (ir_node *n)
115 switch (n->op->code) {
118 xfprintf (F, "color: blue");
121 xfprintf (F, "color: lightyellow");
124 xfprintf (F, "color: green");
129 xfprintf (F, "color: yellow");
132 xfprintf (F, DEFAULT_NODE_ATTR);
137 dump_node (ir_node *n) {
140 xfprintf (F, "node: {title: \"%p\" label: \"", n);
144 dump_node_nodeattr(n);
146 xfprintf (F, " %ld", get_irn_node_nr(n));
149 dump_node_vcgattr(n);
154 dump_ir_node (ir_node *n)
157 xfprintf (F, "node: {title: \"%p\" label: ", n);
159 switch (n->op->code) { /* node label */
161 xfprintf (F, "\"%I\" color: blue ", n->op->name);
162 xfprintf (F, DEFAULT_NODE_ATTR);
165 xfprintf (F, "\"%I\" color: blue ", n->op->name);
166 xfprintf (F, DEFAULT_NODE_ATTR);
169 xfprintf (F, "\"%I\" color: lightyellow ", n->op->name);
170 xfprintf (F, DEFAULT_NODE_ATTR);
173 xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name);
174 if (n->mode->code == irm_M)
175 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
177 xfprintf (F, DEFAULT_NODE_ATTR);
180 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name);
181 xfprintf (F, DEFAULT_NODE_ATTR);
184 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
185 xfprintf (F, DEFAULT_NODE_ATTR);
188 if (n->in[1]->op->code == iro_Cmp) {
189 xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name,
190 get_pnc_string(n->attr.proj));
192 xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj);
194 xfprintf (F, DEFAULT_NODE_ATTR);
197 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
198 xfprintf (F, DEFAULT_NODE_ATTR);
201 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
202 xfprintf (F, DEFAULT_NODE_ATTR);
205 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
206 xfprintf (F, DEFAULT_NODE_ATTR);
209 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
210 xfprintf (F, DEFAULT_NODE_ATTR);
213 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
214 xfprintf (F, DEFAULT_NODE_ATTR);
217 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
218 xfprintf (F, DEFAULT_NODE_ATTR);
221 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
222 xfprintf (F, DEFAULT_NODE_ATTR);
225 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
226 xfprintf (F, DEFAULT_NODE_ATTR);
229 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
230 xfprintf (F, DEFAULT_NODE_ATTR);
233 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
234 xfprintf (F, DEFAULT_NODE_ATTR);
237 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
238 xfprintf (F, DEFAULT_NODE_ATTR);
241 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
242 xfprintf (F, DEFAULT_NODE_ATTR);
245 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
246 xfprintf (F, DEFAULT_NODE_ATTR);
249 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
250 xfprintf (F, DEFAULT_NODE_ATTR);
253 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
254 xfprintf (F, DEFAULT_NODE_ATTR);
257 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
258 xfprintf (F, DEFAULT_NODE_ATTR);
261 xfprintf (F, "\"%I\"", n->op->name);
262 xfprintf (F, DEFAULT_NODE_ATTR);
265 xfprintf (F, "\"%I\"", n->op->name);
266 xfprintf (F, DEFAULT_NODE_ATTR);
269 xfprintf (F, "\"%I\"", n->op->name);
270 xfprintf (F, DEFAULT_NODE_ATTR);
273 xfprintf (F, "\"%I\"", n->op->name);
274 xfprintf (F, DEFAULT_NODE_ATTR);
277 xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
278 xfprintf (F, DEFAULT_NODE_ATTR);
282 xfprintf (F, "\"%R\"", n);
283 xfprintf (F, DEFAULT_NODE_ATTR);
286 xfprintf (F, "\"%I\" ", n->op->name);
287 xfprintf (F, DEFAULT_NODE_ATTR);
290 assert(get_kind(get_Sel_entity(n)) == k_entity);
291 /*assert(n->attr.s.ent->kind == k_entity);*/
292 xfprintf (F, "\"%I ", n->op->name);
293 /*xfprintf (F, "%s\" ", id_to_str(n->attr.s.ent->name));*/
294 xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
295 /* xdoesn't work for some reason.
296 fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
297 xfprintf (F, DEFAULT_NODE_ATTR);
300 assert(get_kind(get_SymConst_type(n)) == k_type_class);
301 /* assert(n->attr.i.type->kind == k_type_class); */
302 assert(get_class_ident((type_class *)get_SymConst_type(n)));
303 /* assert(n->attr.i.type->clss->name); */
304 xfprintf (F, "\"%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
305 /* xfprintf (F, "\"%s ", id_to_str(n->attr.i.type->name)); */
306 /* doesn't work for some reason. */
307 /* xfprintf (F, "\"%N\" ", n->attr.i.type); */
308 switch (n->attr.i.num){
310 xfprintf (F, "tag\" ");
313 xfprintf (F, "size\" ");
319 xfprintf (F, DEFAULT_NODE_ATTR);
322 xfprintf (F, "\"%I\" ", n->op->name);
323 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
326 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
327 xfprintf (F, DEFAULT_NODE_ATTR);
330 xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
332 xfprintf (F, "}\n"); /* footer */
336 /* dump the edge to the block this node belongs to */
338 dump_ir_block_edge(ir_node *n) {
340 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
341 BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
345 /* dump edges to our inputs */
347 dump_ir_data_edges(ir_node *n) {
350 for (i = 0; i < get_irn_arity(n); i++) {
351 assert(get_irn_n(n, i));
352 xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
354 fprintf (F, " label: \"%d\"", i+1);
359 /* dumps the edges between nodes and their type or entity attributes. */
360 void dump_node2type_edges (ir_node *n, void *env)
364 switch (get_irn_opcode(n)) {
366 if ( (get_SymConst_kind(n) == type_tag)
367 || (get_SymConst_kind(n) == size))
368 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
369 NODE2TYPE_EDGE_ATTR "}\n", n, get_SymConst_type(n));
372 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
373 NODE2TYPE_EDGE_ATTR "}\n", n, get_Sel_entity(n));
376 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
377 NODE2TYPE_EDGE_ATTR "}\n", n, get_Call_type(n));
380 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
381 NODE2TYPE_EDGE_ATTR "}\n", n, get_Alloc_type(n));
384 printf(" in irdum\n");
385 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
386 NODE2TYPE_EDGE_ATTR "}\n", n, get_Free_type(n));
394 /* dumps a type or entity and it's edges. */
396 dump_type_info (type_or_ent *tore, void *env) {
397 int i = 0; /* to shutup gcc */
399 /* dump this type or entity */
400 xfprintf (F, "node: {title: \"%p\" ", tore);
401 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
402 xfprintf (F, "label: ");
404 switch (get_kind(tore)) {
407 entity *ent = (entity *)tore;
408 xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
409 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
411 TYPE_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
412 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
414 TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
419 type_class *type = (type_class *)tore;
420 xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
426 type_strct *type = (type_strct *)tore;
427 xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
433 type_method *type = (type_method *)tore;
434 xfprintf (F, "\"meth %I\"}\n", get_method_ident(type));
435 for (i = 0; i < get_method_arity(type); i++)
436 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
437 " label: \"param %d\" " TYPE_EDGE_ATTR "}\n",
438 tore, get_method_param_type(type, i), i);
439 for (i = 0; i < get_method_n_res(type); i++)
440 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
441 " label: \"res %d\" " TYPE_EDGE_ATTR "}\n",
442 tore, get_method_res_type(type, i), i);
447 type_union *type = (type_union *)tore;
448 xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
454 type_array *type = (type_array *)tore;
455 xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
456 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
457 TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
460 case k_type_enumeration:
462 type_enumeration *type = (type_enumeration *)tore;
463 xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
468 type_pointer *type = (type_pointer *)tore;
469 xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
470 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
471 TYPE_EDGE_ATTR "}\n", tore,
472 get_pointer_points_to_type(type), i);
475 case k_type_primitive:
477 type_primitive *type = (type_primitive *)tore;
478 xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
479 get_mode_ident(get_primitive_mode(type)));
488 /************************************************************************/
489 /* open and close vcg file */
490 /************************************************************************/
492 void vcg_open (ir_graph *irg, char *suffix) {
493 char *fname; /* filename to put the vcg information in */
498 /** open file for vcg graph */
499 id = get_entity_ld_name (irg->ent);
501 len = id_to_strlen (id);
503 fname = malloc (len + 5 + strlen(suffix));
504 strcpy (fname, cp); /* copy the filename */
505 strcat (fname, suffix); /* append file suffix */
506 strcat (fname, ".vcg"); /* append the .vcg suffix */
508 F = fopen (fname, "w"); /* open file for writing */
510 panic ("cannot open %s for writing (%m)", fname); /* not reached */
515 "graph: { title: \"ir graph of %s\"\n"
516 "display_edge_labels: yes\n"
517 "layoutalgorithm: mindepth\n"
518 "manhattan_edges: yes\n"
520 "orientation: bottom_to_top\n"
521 "classname 1: \"Data\"\n"
522 "classname 2: \"Block\"\n", cp);
524 xfprintf (F, "\n"); /* a separator */
529 xfprintf (F, "}\n"); /* print footer */
530 fclose (F); /* close vcg file */
533 /************************************************************************/
534 /* routines to dump a graph, blocks as conventional nodes. */
535 /************************************************************************/
538 dump_whole_node (ir_node *n, void* env) {
540 dump_ir_block_edge(n);
541 dump_ir_data_edges(n);
545 dump_ir_graph (ir_graph *irg)
548 rem = current_ir_graph;
549 current_ir_graph = irg;
553 /* walk over the graph */
554 irg_walk(irg->end, dump_whole_node, NULL, NULL);
558 current_ir_graph = rem;
561 /***********************************************************************/
562 /* the following routines dump the nodes as attached to the blocks. */
563 /***********************************************************************/
566 dump_ir_blocks_nodes (ir_node *n, void *env) {
567 ir_node *block = (ir_node *)env;
569 if (is_no_Block(n) && get_nodes_Block(n) == block) {
571 dump_ir_data_edges(n);
576 dump_ir_block (ir_node *block, void *env) {
577 ir_graph *irg = (ir_graph *)env;
579 if (get_irn_opcode(block) == iro_Block) {
580 /* This is a block. So dump the vcg information to make a block. */
581 xfprintf(F, "graph: { title: \"%p\" label: \"", block);
583 xfprintf (F, "%ld", get_irn_node_nr(block));
585 xfprintf (F, "%I", block->op->name);
587 xfprintf(F, "\" status:clustered color:lightyellow \n");
588 /* dump the blocks edges */
589 dump_ir_data_edges(block);
591 /* dump the nodes that go into the block */
592 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
594 /* Close the vcg information for the block */
595 xfprintf(F, "}\n\n");
600 dump_ir_block_graph (ir_graph *irg)
603 rem = current_ir_graph;
604 current_ir_graph = irg;
608 /* walk over the blocks in the graph */
609 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
612 current_ir_graph = rem;
616 /***********************************************************************/
617 /* the following routines dump a control flow graph */
618 /***********************************************************************/
622 dump_block_to_cfg (ir_node *block, void *env) {
626 if (get_irn_opcode(block) == iro_Block) {
627 /* This is a block. Dump a node for the block. */
628 xfprintf (F, "node: {title: \"%p\" label: \"%I\"}", block,
631 for ( i = 0; i < get_Block_n_cfgpreds(block); i++) {
632 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
633 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" }\n",
640 dump_cfg (ir_graph *irg)
642 vcg_open (irg, "-cfg");
644 /* walk over the blocks in the graph */
645 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
651 /***********************************************************************/
652 /* the following routine dumps all type information */
653 /***********************************************************************/
657 dump_type_graph (ir_graph *irg)
660 rem = current_ir_graph;
661 current_ir_graph = irg;
663 vcg_open (irg, "-type");
665 /* walk over the blocks in the graph */
666 type_walk(irg, dump_type_info, NULL, NULL);
669 current_ir_graph = rem;
673 /***********************************************************************/
674 /* dumps a graph with type information */
675 /***********************************************************************/
679 dump_ir_graph_w_types (ir_graph *irg)
682 rem = current_ir_graph;
683 current_ir_graph = irg;
685 vcg_open (irg, "-all");
687 /* dump common ir graph */
688 /* irg_block_walk(irg->end, dump_ir_block, NULL, irg); */
689 irg_walk(irg->end, dump_whole_node, NULL, NULL);
691 type_walk(irg, dump_type_info, NULL, NULL);
692 /* dump edges from graph to type info */
693 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
696 current_ir_graph = rem;