X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firdump.c;h=213af81f9f69450f4c460b986c0a49cba15aea33;hb=5f8ddee6b08c8040c0a304a347d65045c1141d52;hp=c37eb0e53be4a141377903d393f377b7445821f5;hpb=efbeaff549fcc6015da255ed4d453a95937ff0fd;p=libfirm diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index c37eb0e53..213af81f9 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -6,14 +6,16 @@ ** irdump.h: dumping of an intermediate representation graph */ -# include +# include "irnode_t.h" +# include "irgraph_t.h" +# include "irprog.h" # include "irdump.h" # include "panic.h" # include # include "entity.h" # include # include "array.h" -# include "irop.h" +# include "irop_t.h" # include "tv.h" # include "type_or_entity.h" # include "irgwalk.h" @@ -25,6 +27,8 @@ #define DEFAULT_TYPE_ATTRIBUTE "" #define TYPE_EDGE_ATTR "" +#define PRINT_NODEID(X) fprintf(F, "%p", X) + /* file to dump to */ static FILE *F; @@ -33,131 +37,249 @@ static FILE *F; /* routines to dump information about a single node */ /*******************************************************************/ + + +inline void +dump_node_opcode (ir_node *n) +{ + /* Const */ + if (n->op->code == iro_Const) { + xfprintf (F, "%v", n->attr.con); + /* SymConst */ + } else if (n->op->code == iro_SymConst) { + if (get_SymConst_kind(n) == linkage_ptr_info) { + xfprintf (F, "%I", get_SymConst_ptrinfo(n)); + } else { + assert(get_kind(get_SymConst_type(n)) == k_type_class); + assert(get_class_ident((type_class *)get_SymConst_type(n))); + xfprintf (F, "%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n)))); + if (get_SymConst_kind == type_tag) + xfprintf (F, "tag"); + else + xfprintf (F, "size"); + } + /* all others */ + } else { + xfprintf (F, "%I", get_irn_opident(n)); + } +} + +inline void +dump_node_mode (ir_node *n) +{ + switch (n->op->code) { + case iro_Phi: + case iro_Const: + case iro_Id: + case iro_Proj: + case iro_Conv: + case iro_Tuple: + case iro_Add: + case iro_Sub: + case iro_Mul: + case iro_And: + case iro_Or: + case iro_Eor: + case iro_Shl: + case iro_Shr: + case iro_Abs: + case iro_Cmp: + xfprintf (F, "%I", get_mode_ident(n->mode)); + break; + default: + } +} + +inline void +dump_node_nodeattr (ir_node *n) +{ + switch (n->op->code) { + case iro_Proj: + if (n->in[1]->op->code == iro_Cmp) { + xfprintf (F, "%s", get_pnc_string(n->attr.proj)); + } else { + xfprintf (F, "%ld", n->attr.proj); + } + break; + case iro_Sel: + /*assert(n->attr.s.ent->kind == k_entity);*/ + assert(get_kind(get_Sel_entity(n)) == k_entity); + xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n)))); + + /* xdoesn't work for some reason. + fprintf (F, "\"%I %I\" ", get_irn_opident(n), n->attr.s.ent); */ + break; + default: + } /* end switch */ +} + +inline void +dump_node_vcgattr (ir_node *n) +{ + switch (n->op->code) { + case iro_Start: + case iro_End: + xfprintf (F, "color: blue"); + break; + case iro_Block: + xfprintf (F, "color: lightyellow"); + break; + case iro_Phi: + xfprintf (F, "color: green"); + break; + case iro_Const: + case iro_Proj: + case iro_Tuple: + xfprintf (F, "color: yellow"); + break; + default: + xfprintf (F, DEFAULT_NODE_ATTR); + } +} + +void +dump_node (ir_node *n) { + + /* dump this node */ + xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \""); + + dump_node_opcode(n); + dump_node_mode (n); + xfprintf (F, " "); + dump_node_nodeattr(n); +#ifdef DEBUG_libfirm + xfprintf (F, " %ld", get_irn_node_nr(n)); +#endif + xfprintf (F, "\" "); + dump_node_vcgattr(n); + xfprintf (F, "}\n"); +} + void dump_ir_node (ir_node *n) { /* dump this node */ - xfprintf (F, "node: {title: \"%p\" label: ", n); + fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: "); switch (n->op->code) { /* node label */ case iro_Start: - xfprintf (F, "\"%I\" color: blue ", n->op->name); + xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_End: - xfprintf (F, "\"%I\" color: blue ", n->op->name); + xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Block: - xfprintf (F, "\"%I\" color: lightyellow ", n->op->name); + xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Phi: - xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name); - if (n->mode->code == irm_M) + xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n)); + if (get_irn_modecode(n) == irm_M) xfprintf (F, DEFAULT_NODE_ATTR " color: green"); else xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Const: - xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name); + xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Id: - xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Proj: if (n->in[1]->op->code == iro_Cmp) { - xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name, + xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n), get_pnc_string(n->attr.proj)); } else { - xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj); + xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj); } xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Conv: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Tuple: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Add: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Sub: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Mul: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Quot: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_DivMod: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Div: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Mod: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_And: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Or: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Eor: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Shl: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Shr: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Abs: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Cmp: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Jmp: - xfprintf (F, "\"%I\"", n->op->name); + xfprintf (F, "\"%I\"", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Cond: - xfprintf (F, "\"%I\"", n->op->name); + xfprintf (F, "\"%I\"", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Call: - xfprintf (F, "\"%I\"", n->op->name); + xfprintf (F, "\"%I\"", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Return: - xfprintf (F, "\"%I\"", n->op->name); + xfprintf (F, "\"%I\"", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Raise: - xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Load: @@ -166,24 +288,22 @@ dump_ir_node (ir_node *n) xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Alloc: - xfprintf (F, "\"%I\" ", n->op->name); + xfprintf (F, "\"%I\" ", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Sel: - assert(n->attr.s.ent->kind == k_entity); - xfprintf (F, "\"%I ", n->op->name); - xfprintf (F, "%s\" ", id_to_str(n->attr.s.ent->name)); - // xfprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); // GL: doesn't work for some reason. + assert(get_kind(get_Sel_entity(n)) == k_entity); + xfprintf (F, "\"%I ", get_irn_opident(n)); + xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n)))); + /* xdoesn't work for some reason. + fprintf (F, "\"%I %I\" ", get_irn_opident(n), get_entity_ident(get_Sel_entity(n))); */ xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_SymConst: assert(get_kind(get_SymConst_type(n)) == k_type_class); - //assert(n->attr.i.type->kind == k_type_class); assert(get_class_ident((type_class *)get_SymConst_type(n))); - //assert(n->attr.i.type->clss->name); - xfprintf (F, "\"%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n)))); - //xfprintf (F, "\"%s ", id_to_str(n->attr.i.type->name)); - // xfprintf (F, "\"%N\" ", n->attr.i.type); // GL: doesn't work for some reason. + xfprintf (F, "\"%s ", + id_to_str(get_class_ident((type_class *)get_SymConst_type(n)))); switch (n->attr.i.num){ case type_tag: xfprintf (F, "tag\" "); @@ -198,15 +318,15 @@ dump_ir_node (ir_node *n) xfprintf (F, DEFAULT_NODE_ATTR); break; case iro_Sync: - xfprintf (F, "\"%I\" ", n->op->name); + xfprintf (F, "\"%I\" ", get_irn_opident(n)); xfprintf (F, DEFAULT_NODE_ATTR " color: green"); break; case iro_Bad: - xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n)); xfprintf (F, DEFAULT_NODE_ATTR); break; default: - xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name); + xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n)); } xfprintf (F, "}\n"); /* footer */ } @@ -290,22 +410,21 @@ dump_type_info (type_or_ent *tore, void *env) { xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " " label: \"type\" " TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent)); - } - break; + } break; case k_type_class: { type_class *type = (type_class *)tore; xfprintf (F, "\"class %I\"}\n", get_class_ident(type)); - /* edges !!!??? */ - } - break; + for (i=0; i < get_class_n_supertype(type); i++) + xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " + " label: \"supertype\" " TYPE_EDGE_ATTR "}\n", + type, get_class_supertype(type, i)); + } break; case k_type_strct: { type_strct *type = (type_strct *)tore; xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type)); - /* edges !!!??? */ - } - break; + } break; case k_type_method: { type_method *type = (type_method *)tore; @@ -318,29 +437,25 @@ dump_type_info (type_or_ent *tore, void *env) { xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " " label: \"res %d\" " TYPE_EDGE_ATTR "}\n", tore, get_method_res_type(type, i), i); - } - break; + } break; case k_type_union: { type_union *type = (type_union *)tore; xfprintf (F, "\"union %I\"}\n", get_union_ident(type)); /* edges !!!??? */ - } - break; + } break; case k_type_array: { type_array *type = (type_array *)tore; xfprintf (F, "\"array %I\"}\n", get_array_ident(type)); xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i); - } - break; + } break; case k_type_enumeration: { type_enumeration *type = (type_enumeration *)tore; xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type)); - } - break; + } break; case k_type_pointer: { type_pointer *type = (type_pointer *)tore; @@ -348,19 +463,19 @@ dump_type_info (type_or_ent *tore, void *env) { xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" " TYPE_EDGE_ATTR "}\n", tore, get_pointer_points_to_type(type), i); - } - break; + } break; case k_type_primitive: { type_primitive *type = (type_primitive *)tore; xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type), get_mode_ident(get_primitive_mode(type))); - } - break; + } break; default: - break; + { + xfprintf (F, "\" faulty type \"}\n"); + printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__); + } break; } - } /************************************************************************/ @@ -374,16 +489,24 @@ void vcg_open (ir_graph *irg, char *suffix) { int len; /** open file for vcg graph */ - id = get_entity_ld_name (irg->ent); - + id = get_entity_ld_name (get_irg_ent(irg)); len = id_to_strlen (id); cp = id_to_str (id); + fname = malloc (len + 5 + strlen(suffix)); - strcpy (fname, cp); /* copy the filename */ + strncpy (fname, cp, len); /* copy the filename */ + fname[len] = '\0'; strcat (fname, suffix); /* append file suffix */ - strcat (fname, ".vcg"); /* append the .vcg suffix */ - F = fopen (fname, "w"); /* open file for writing */ + fname = malloc (len + 5 + strlen(suffix)); + strncpy (fname, cp, len); /* copy the filename */ + fname[len] = '\0'; /* ensure string termination */ + /*strcpy (fname, cp); * copy the filename * + this produces wrong, too long strings in conjuction with the + jocca frontend. The \0 seems to be missing. */ + strcat (fname, suffix); /* append file suffix */ + strcat (fname, ".vcg"); /* append the .vcg suffix */ + F = fopen (fname, "w"); /* open file for writing */ if (!F) { panic ("cannot open %s for writing (%m)", fname); /* not reached */ } @@ -402,21 +525,47 @@ void vcg_open (ir_graph *irg, char *suffix) { xfprintf (F, "\n"); /* a separator */ } +void vcg_open_name (const char *name) { + char *fname; /* filename to put the vcg information in */ + int len; + + /** open file for vcg graph */ + len = strlen(name); + fname = malloc (len + 5); + strcpy (fname, name); /* copy the filename */ + strcat (fname, ".vcg"); /* append the .vcg suffix */ + F = fopen (fname, "w"); /* open file for writing */ + if (!F) { + panic ("cannot open %s for writing (%m)", fname); /* not reached */ + } + + /* print header */ + xfprintf (F, + "graph: { title: \"ir graph of %s\"\n" + "display_edge_labels: yes\n" + "layoutalgorithm: mindepth\n" + "manhattan_edges: yes\n" + "port_sharing: no\n" + "orientation: bottom_to_top\n" + "classname 1: \"Data\"\n" + "classname 2: \"Block\"\n", name); + + xfprintf (F, "\n"); /* a separator */ +} + void vcg_close () { xfprintf (F, "}\n"); /* print footer */ fclose (F); /* close vcg file */ } - - /************************************************************************/ /* routines to dump a graph, blocks as conventional nodes. */ /************************************************************************/ void dump_whole_node (ir_node *n, void* env) { - dump_ir_node(n); + dump_node(n); dump_ir_block_edge(n); dump_ir_data_edges(n); } @@ -424,12 +573,18 @@ dump_whole_node (ir_node *n, void* env) { void dump_ir_graph (ir_graph *irg) { + ir_graph *rem; + rem = current_ir_graph; + current_ir_graph = irg; + vcg_open (irg, ""); /* walk over the graph */ irg_walk(irg->end, dump_whole_node, NULL, NULL); vcg_close(); + + current_ir_graph = rem; } /***********************************************************************/ @@ -441,20 +596,25 @@ dump_ir_blocks_nodes (ir_node *n, void *env) { ir_node *block = (ir_node *)env; if (is_no_Block(n) && get_nodes_Block(n) == block) { - dump_ir_node(n); + dump_node(n); dump_ir_data_edges(n); } } - void dump_ir_block (ir_node *block, void *env) { ir_graph *irg = (ir_graph *)env; if (get_irn_opcode(block) == iro_Block) { + /* This is a block. So dump the vcg information to make a block. */ - xfprintf(F, "graph: { title: \"%p\" status:clustered color:lightyellow \n", - block); + xfprintf(F, "graph: { title: \""); PRINT_NODEID(block); fprintf(F, "\" label: \""); +#ifdef DEBUG_libfirm + xfprintf (F, "%ld", get_irn_node_nr(block)); +#else + xfprintf (F, "%I", block->op->name); +#endif + xfprintf(F, "\" status:clustered color:lightyellow \n"); /* dump the blocks edges */ dump_ir_data_edges(block); @@ -469,12 +629,17 @@ dump_ir_block (ir_node *block, void *env) { void dump_ir_block_graph (ir_graph *irg) { + ir_graph *rem; + rem = current_ir_graph; + current_ir_graph = irg; + vcg_open (irg, ""); /* walk over the blocks in the graph */ irg_block_walk(irg->end, dump_ir_block, NULL, irg); vcg_close(); + current_ir_graph = rem; } @@ -514,21 +679,39 @@ dump_cfg (ir_graph *irg) /***********************************************************************/ -/* the following routine dumps all type information */ +/* the following routine dumps all type information reachable from an */ +/* irg */ /***********************************************************************/ void dump_type_graph (ir_graph *irg) { + ir_graph *rem; + rem = current_ir_graph; + current_ir_graph = irg; + vcg_open (irg, "-type"); /* walk over the blocks in the graph */ - type_walk(irg, dump_type_info, NULL, NULL); + type_walk_irg(irg, dump_type_info, NULL, NULL); vcg_close(); + current_ir_graph = rem; } +/***********************************************************************/ +/* the following routine dumps all type information */ +/***********************************************************************/ + + +void +dump_all_types (void) +{ + vcg_open_name ("All_types"); + type_walk(dump_type_info, NULL, NULL); + vcg_close(); +} /***********************************************************************/ /* dumps a graph with type information */ @@ -538,15 +721,35 @@ dump_type_graph (ir_graph *irg) void dump_ir_graph_w_types (ir_graph *irg) { + ir_graph *rem; + rem = current_ir_graph; + current_ir_graph = irg; + vcg_open (irg, "-all"); /* dump common ir graph */ - // irg_block_walk(irg->end, dump_ir_block, NULL, irg); + /* irg_block_walk(irg->end, dump_ir_block, NULL, irg); */ irg_walk(irg->end, dump_whole_node, NULL, NULL); /* dump type info */ - type_walk(irg, dump_type_info, NULL, NULL); + type_walk_irg(irg, dump_type_info, NULL, NULL); /* dump edges from graph to type info */ irg_walk(irg->end, dump_node2type_edges, NULL, NULL); vcg_close(); + current_ir_graph = rem; +} + +/***********************************************************************/ +/* dumps all graphs with the graph-dumper passed. Possible dumpers: */ +/* dump_ir_graph */ +/* dump_ir_block_graph */ +/* dump_cfg */ +/* dump_type_graph */ +/* dump_ir_graph_w_types */ +/***********************************************************************/ +void dump_all_ir_graphs (void dump_graph(ir_graph*)) { + int i; + for (i=0; i < get_irp_n_irgs(); i++) { + dump_graph(get_irp_irg(i)); + } }