/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
-** All rights reserved.
-**
-** Authors: Martin Trapp, Christian Schaefer
-**
-** irdump.h: dumping of an intermediate representation graph
+* All rights reserved.
+*
+* Authors: Martin Trapp, Christian Schaefer
+*
+* irdump.h: dumping of an intermediate representation graph
*/
/* $Id$ */
# include "typewalk.h"
# include "irouts.h"
# include "irdom.h"
-# include "common_t.h"
+# include "firm_common_t.h"
# include "irloop.h"
# include "exc.h"
#define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
#define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
#define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
-#define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
+#define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
#define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
#define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
#define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
int dump_out_edge_flag = 0;
int dump_dominator_information_flag = 0;
int dump_loop_information_flag = 0;
+int dump_const_local = 0;
+static INLINE bool dump_const_local_set() {
+ if (!dump_out_edge_flag && !dump_loop_information_flag)
+ return dump_const_local;
+ else
+ return false;
+}
/* A global variable to record output of the Bad node. */
-int Bad_dumped;
+static int Bad_dumped;
-void dump_ir_blocks_nodes (ir_node *n, void *env);
-void dump_whole_node (ir_node *n, void* env);
+static void dump_ir_blocks_nodes (ir_node *n, void *env);
+static void dump_whole_node(ir_node *n, void* env);
/*******************************************************************/
/* routines to dump information about a single node */
-INLINE void
+static INLINE void
dump_node_opcode (ir_node *n)
{
assert(n && n->op);
assert(get_kind(get_SymConst_type(n)) == k_type);
assert(get_type_ident(get_SymConst_type(n)));
xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
- if (get_SymConst_kind == type_tag)
- xfprintf (F, "tag");
+ if (get_SymConst_kind(n) == type_tag)
+ xfprintf (F, "tag");
else
- xfprintf (F, "size");
+ xfprintf (F, "size");
}
/* Filter */
}
}
-INLINE void
+static INLINE void
dump_node_mode (ir_node *n)
{
switch (n->op->code) {
xfprintf (F, "%I", get_mode_ident(n->mode));
break;
default:
+ ;
}
}
-void dump_node_loop_info(ir_node *n) {
- // if (get_irn_loop(n))
- // xfprintf(F, "\n in loop %d", get_loop_depth(get_irn_loop(n)));
-}
-
-INLINE void
+static INLINE void
dump_node_nodeattr (ir_node *n)
{
switch (n->op->code) {
xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
} break;
default:
+ ;
} /* end switch */
}
-INLINE void
+static INLINE void
dump_node_vcgattr (ir_node *n)
{
switch (n->op->code) {
}
}
-void
-dump_node (ir_node *n) {
+static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
+ ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
+
+ if (irgmap &&
+ ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
+ ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
+ if (is_ip_cfop(pred)) {
+ ir_graph *irg = get_ip_cfop_irg(pred);
+ if (pmap_find(irgmap, irg) == NULL) return true;
+ }
+ }
+
+ return false;
+}
+
+
+static INLINE
+bool is_constlike_node(ir_node *n) {
+ ir_op *op = get_irn_op(n);
+ return (op == op_Const || op == op_Bad || op == op_SymConst);
+}
+
+
+static void dump_const_node_local(ir_node *n, pmap *irgmap) {
+ int i;
+ if (!dump_const_local_set()) return;
+ /* Use visited flag to avoid outputting nodes twice.
+ initialize it first. */
+ for (i = 0; i < get_irn_arity(n); i++) {
+ ir_node *con = get_irn_n(n, i);
+ if (is_constlike_node(con)) {
+ if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
+ set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
+ }
+ }
+ for (i = 0; i < get_irn_arity(n); i++) {
+ ir_node *con = get_irn_n(n, i);
+ if (is_constlike_node(con) && irn_not_visited(con)) {
+ if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
+ mark_irn_visited(con);
+ /* Generate a new name for the node by appending the names of
+ n and const. */
+ xfprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
+ fprintf(F, "\" label: \"");
+ dump_node_opcode(con);
+ dump_node_mode (con);
+ xfprintf (F, " ");
+ dump_node_nodeattr(con);
+#ifdef DEBUG_libfirm
+ xfprintf (F, " %ld", get_irn_node_nr(con));
+#endif
+ xfprintf (F, "\" ");
+ dump_node_vcgattr(con);
+ xfprintf (F, "}\n");
+ }
+ }
+}
+
+static void
+dump_node (ir_node *n, pmap * map) {
+ if (dump_const_local_set() && is_constlike_node(n)) return;
/* dump this node */
xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
dump_node_opcode(n);
dump_node_mode (n);
- //if (dump_loop_information_flag) dump_node_loop_info(n);
xfprintf (F, " ");
dump_node_nodeattr(n);
#ifdef DEBUG_libfirm
xfprintf (F, "\" ");
dump_node_vcgattr(n);
xfprintf (F, "}\n");
+ dump_const_node_local(n, map);
}
-void
+static void
dump_ir_node (ir_node *n)
{
/* dump this node */
/* dump the edge to the block this node belongs to */
-void
+static void
dump_ir_block_edge(ir_node *n) {
+ if (dump_const_local_set() && is_constlike_node(n)) return;
if (is_no_Block(n)) {
xfprintf (F, "edge: { sourcename: \"");
PRINT_NODEID(n);
}
}
-void print_edge_vcgattr(ir_node *from, int to) {
+static void print_edge_vcgattr(ir_node *from, int to) {
assert(from);
if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
case iro_Start: break;
case iro_End:
if (to >= 0) {
- if (get_irn_mode(get_End_keepalive(from, to)) == mode_R)
+ if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
xfprintf (F, CF_EDGE_ATTR);
if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
xfprintf (F, MEM_EDGE_ATTR);
case iro_Unknown: break;
case iro_Id: break;
default:
+ ;
}
}
/* dump edges to our inputs */
-void
+static void
dump_ir_data_edges(ir_node *n) {
int i, visited = get_irn_visited(n);
for (i = 0; i < get_irn_arity(n); i++) {
ir_node * pred = get_irn_n(n, i);
assert(pred);
- if (interprocedural_view && get_irn_visited(pred) < visited)
+ if ((interprocedural_view && get_irn_visited(pred) < visited))
continue; /* pred not dumped */
if (is_backedge(n, i))
fprintf (F, "backedge: {sourcename: \"");
fprintf (F, "edge: {sourcename: \"");
PRINT_NODEID(n);
fprintf (F, "\" targetname: \"");
+ if ((dump_const_local_set()) && is_constlike_node(pred))
+ PRINT_NODEID(n);
PRINT_NODEID(pred);
fprintf (F, "\"");
fprintf (F, " label: \"%d\" ", i);
}
/* dump out edges */
-void
+static void
dump_out_edge (ir_node *n, void* env) {
int i;
for (i = 0; i < get_irn_n_outs(n); i++) {
/* dumps the edges between nodes and their type or entity attributes. */
-void dump_node2type_edges (ir_node *n, void *env)
+static void dump_node2type_edges (ir_node *n, void *env)
{
assert(n);
}
-void dump_const_expression(ir_node *value) {
+static void dump_const_expression(ir_node *value) {
ir_graph *rem = current_ir_graph;
+ int rem_dump_const_local = dump_const_local;
+ dump_const_local = 0;
current_ir_graph = get_const_code_irg();
irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
current_ir_graph = rem;
+ dump_const_local = rem_dump_const_local;
}
-void print_type_info(type *tp) {
+static void print_type_info(type *tp) {
if (get_type_state(tp) == layout_undefined) {
xfprintf(F, "state: layout_undefined\n");
} else {
xfprintf(F, "state: layout_fixed,\n");
}
if (get_type_mode(tp))
- xfprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
+ xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
xfprintf(F, "size: %dB,\n", get_type_size(tp));
}
-void print_typespecific_info(type *tp) {
+static void print_typespecific_info(type *tp) {
switch (get_type_tpop_code(tp)) {
case tpo_class:
{
} /* switch type */
}
-void print_type_node(type *tp) {
+static void print_type_node(type *tp) {
xfprintf (F, "node: {title: \"%p\" ", tp);
xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
xfprintf (F, "info1: \"");
xfprintf (F, "}\n");
}
+void dump_entity_node(entity *ent) {
+ xfprintf (F, "node: {title: \"%p\" ", ent);
+ xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
+ xfprintf (F, "label: ");
+ xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
+ fprintf (F, "\n info1:\"\nallocation: ");
+ switch (get_entity_allocation(ent)) {
+ case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
+ case automatic_allocated: fprintf (F, "automatic allocated"); break;
+ case static_allocated: fprintf (F, "static allocated"); break;
+ case parameter_allocated: fprintf (F, "parameter allocated"); break;
+ }
+ fprintf (F, "\nvisibility: ");
+ switch (get_entity_visibility(ent)) {
+ case local: fprintf (F, "local"); break;
+ case external_visible: fprintf (F, "external_visible"); break;
+ case external_allocated: fprintf (F, "external_allocate"); break;
+ }
+ fprintf (F, "\nvariability: ");
+ switch (get_entity_variability(ent)) {
+ case uninitialized: fprintf (F, "uninitialized");break;
+ case initialized: fprintf (F, "initialized"); break;
+ case part_constant: fprintf (F, "part_constant");break;
+ case constant: fprintf (F, "constant"); break;
+ }
+ fprintf (F, "\nvolatility: ");
+ switch (get_entity_volatility(ent)) {
+ case non_volatile: fprintf (F, "non_volatile"); break;
+ case is_volatile: fprintf (F, "is_volatile"); break;
+ }
+ fprintf (F, "\npeculiarity: ");
+ switch (get_entity_peculiarity(ent)) {
+ case description: fprintf (F, "description"); break;
+ case inherited: fprintf (F, "inherited"); break;
+ case existent: fprintf (F, "existent"); break;
+ }
+ xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
+ fprintf(F, "\noffset: %d", get_entity_offset(ent));
+ if (is_method_type(get_entity_type(ent)))
+ xfprintf (F, "\nirg = %p ", get_entity_irg(ent));
+ xfprintf(F, "\"\n}\n");
+}
+
/* dumps a type or entity and it's edges. */
-void
+static void
dump_type_info (type_or_ent *tore, void *env) {
int i = 0; /* to shutup gcc */
entity *ent = (entity *)tore;
ir_node *value;
/* The node */
- xfprintf (F, "node: {title: \"%p\" ", tore);
- xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
- xfprintf (F, "label: ");
- xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
- switch (get_entity_allocation(ent)) {
- case dynamic_allocated: fprintf (F, " info1:\"dynamic allocated\n"); break;
- case automatic_allocated: fprintf (F, " info1:\"automatic allocated\n"); break;
- case static_allocated: fprintf (F, " info1:\"static allocated\n"); break;
- }
- switch (get_entity_visibility(ent)) {
- case local: fprintf (F, "local\n"); break;
- case external_visible: fprintf (F, "external_visible\n"); break;
- case external_allocated: fprintf (F, "external_allocate\n"); break;
- }
- switch (get_entity_variability(ent)) {
- case uninitialized: fprintf (F, "uninitialized\n");break;
- case initialized: fprintf (F, "initialized\n"); break;
- case part_constant: fprintf (F, "part_constant\n");break;
- case constant: fprintf (F, "constant\n"); break;
- }
- switch (get_entity_volatility(ent)) {
- case non_volatile: fprintf (F, "non_volatile\n"); break;
- case is_volatile: fprintf (F, "is_volatile\n"); break;
- }
- switch (get_entity_peculiarity(ent)) {
- case description: fprintf (F, "description\n"); break;
- case inherited: fprintf (F, "inherited\n"); break;
- case existent: fprintf (F, "existent\n"); break;
- }
- if (is_method_type(get_entity_type(ent)))
- xfprintf (F, "\n irg = %p ", get_entity_irg(ent));
- xfprintf(F, "\"}\n");
+ dump_entity_node(ent);
/* The Edges */
/* skip this to reduce graph. Member edge of type is parallel to this edge. *
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
break; /* case k_type */
default:
{
- printf(" *** irdump, %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
+ printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
+ } break;
+ } /* switch kind_or_entity */
+}
+
+/* dumps a class type node and a superclass edge.
+ If env != null dumps entities of classes and overwrites edges. */
+static void
+dump_class_hierarchy_node (type_or_ent *tore, void *env) {
+ int i = 0; /* to shutup gcc */
+
+ /* dump this type or entity */
+ switch (get_kind(tore)) {
+ case k_entity: {
+ entity *ent = (entity *)tore;
+ if (get_entity_owner(ent) == get_glob_type()) break;
+ if ((env) && is_class_type(get_entity_owner(ent))) {
+ /* The node */
+ dump_entity_node(ent);
+ /* The edges */
+ xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+ TYPE_MEMBER_EDGE_ATTR "}\n", get_entity_owner(ent), ent);
+ for(i = 0; i < get_entity_n_overwrites(ent); i++)
+ xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+ ENT_OVERWRITES_EDGE_ATTR "}\n",
+ ent, get_entity_overwrites(ent, i));
+ }
+ } break; /* case k_entity */
+ case k_type:
+ {
+ type *tp = (type *)tore;
+ if (tp == get_glob_type()) break;
+ switch (get_type_tpop_code(tp)) {
+ case tpo_class: {
+ print_type_node(tp);
+ /* and now the edges */
+ for (i=0; i < get_class_n_supertypes(tp); i++)
+ xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+ TYPE_SUPER_EDGE_ATTR "}\n",
+ tp, get_class_supertype(tp, i));
+ } break;
+ default: break;
+ } /* switch type */
+ }
+ break; /* case k_type */
+ default:
+ {
+ printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
} break;
} /* switch kind_or_entity */
}
/* open and close vcg file */
/************************************************************************/
-void vcg_open (ir_graph *irg, char *suffix) {
+static void vcg_open (ir_graph *irg, char *suffix) {
char *fname; /* filename to put the vcg information in */
const char *cp;
ident *id;
xfprintf (F, "\n"); /* a separator */
}
-void vcg_open_name (const char *name) {
+static void vcg_open_name (const char *name) {
char *fname; /* filename to put the vcg information in */
int len;
char label[4];
/** open file for vcg graph */
len = strlen(name);
fname = malloc (len + 5);
+ if (dump_file_suffix)
+ fname = malloc (len + 5 + strlen(dump_file_suffix));
+ else
+ fname = malloc (len + 5);
strcpy (fname, name); /* copy the filename */
+ if (dump_file_suffix) strcat (fname, dump_file_suffix);
strcat (fname, ".vcg"); /* append the .vcg suffix */
F = fopen (fname, "w"); /* open file for writing */
if (!F) {
xfprintf (F, "\n"); /* a separator */
}
-void
+static void
vcg_close () {
xfprintf (F, "}\n"); /* print footer */
fclose (F); /* close vcg file */
/* routines to dump a graph, blocks as conventional nodes. */
/************************************************************************/
-int node_floats(ir_node *n) {
+static int node_floats(ir_node *n) {
return ((get_op_pinned(get_irn_op(n)) == floats) &&
(get_irg_pinned(current_ir_graph) == floats));
}
-void
+static void
dump_whole_node (ir_node *n, void* env) {
- dump_node(n);
+ dump_node(n, NULL);
if (!node_floats(n)) dump_ir_block_edge(n);
dump_ir_data_edges(n);
}
/* the following routines dump the nodes as attached to the blocks. */
/***********************************************************************/
-void
+static void
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 && !node_floats(n)) {
- dump_node(n);
+ dump_node(n, NULL);
dump_ir_data_edges(n);
}
if (get_irn_op(n) == op_Bad)
Bad_dumped = 1;
}
-void
+static void
dump_ir_block (ir_node *block, void *env) {
ir_graph *irg = (ir_graph *)env;
/* Close the vcg information for the block */
xfprintf(F, "}\n\n");
+ dump_const_node_local(block, NULL);
}
}
-void
+static void
dump_blockless_nodes (ir_node *n, void *env) {
if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
- dump_node(n);
+ dump_node(n, NULL);
dump_ir_data_edges(n);
dump_ir_block_edge(n);
if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
return;
}
if (node_floats(n)) {
- dump_node(n);
+ dump_node(n, NULL);
dump_ir_data_edges(n);
if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
}
}
-void dump_ir_block_graph_2 (ir_graph *irg)
+static void dump_ir_block_graph_2 (ir_graph *irg)
{
Bad_dumped = 0;
/* walk over the blocks in the graph */
/* dump the Bad node */
if (!Bad_dumped)
- dump_node(get_irg_bad(irg));
+ dump_node(get_irg_bad(irg), NULL);
}
void
dump_ir_block_graph_2 (irg);
- if (dump_loop_information_flag) {
- dump_loop_info(irg);
- }
+ if (dump_loop_information_flag) dump_loop_info(irg);
vcg_close();
current_ir_graph = rem;
/***********************************************************************/
-void
+static void
dump_block_to_cfg (ir_node *block, void *env) {
int i;
ir_node *pred;
vcg_close();
}
+void
+dump_class_hierarchy (bool entities)
+{
+ vcg_open_name ("class_hierarchy");
+ if (entities)
+ type_walk(dump_class_hierarchy_node, NULL, (void *)1);
+ else
+ type_walk(dump_class_hierarchy_node, NULL, NULL);
+ vcg_close();
+}
+
/***********************************************************************/
/* dumps a graph with type information */
/***********************************************************************/
/* dump_type_graph */
/* dump_ir_graph_w_types */
/***********************************************************************/
-void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
+void dump_all_ir_graphs (dump_graph_func *dump_graph) {
int i;
for (i=0; i < get_irp_n_irgs(); i++) {
dump_graph(get_irp_irg(i));
edge_label = 0;
}
+
+void dump_consts_local(bool b) {
+ dump_const_local = b;
+}
+
void turn_off_constant_entity_values() {
const_entities = 0;
}
-void dump_keepalive_edges() {
- dump_keepalive = 1;
+void dump_keepalive_edges(bool b) {
+ dump_keepalive = b;
}
void dump_out_edges() {
set_irn_link(node, NULL);
}
-
-static INLINE bool is_Block(ir_node * node) {
- return !is_no_Block(node);
-}
-
-
static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
if (is_Block(node)
|| node_floats(node)
}
-static void dump_cg_ir_block(ir_node * node, void * env) {
- assert(is_Block(node));
+static void dump_cg_ir_block(ir_node * block, void * env) {
+ ir_node *node;
+ pmap *irgmap = (pmap *)env;
+ assert(is_Block(block));
xfprintf(F, "graph: { title: \"");
- PRINT_NODEID(node);
+ PRINT_NODEID(block);
fprintf(F, "\" label: \"");
#ifdef DEBUG_libfirm
- xfprintf (F, "%ld", get_irn_node_nr(node));
+ xfprintf (F, "%ld", get_irn_node_nr(block));
#else
- xfprintf (F, "%I", node->op->name);
+ xfprintf (F, "%I", block->op->name);
#endif
- if (exc_normal != get_Block_exc(node)) {
- fprintf (F, " (%s)", exc_to_string (get_Block_exc(node)));
+ if (exc_normal != get_Block_exc(block)) {
+ fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
}
xfprintf(F, "\" status:clustered color:%s \n",
- get_Block_matured(node) ? "yellow" : "red");
+ get_Block_matured(block) ? "yellow" : "red");
/* dump the blocks edges */
- dump_ir_data_edges(node);
+ dump_ir_data_edges(block);
/* dump the nodes that go into the block */
- for (node = get_irn_link(node); node; node = get_irn_link(node)) {
- dump_node(node);
+ for (node = get_irn_link(block); node; node = get_irn_link(node)) {
+ dump_node(node, irgmap);
dump_ir_data_edges(node);
}
xfprintf(F, "}\n\n");
}
+static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
+ int i;
+
+ xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
+ irg, get_entity_ident(get_irg_ent(irg)));
+
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_node * node = arr[i];
+ if (is_Block(node)) {
+ /* Dumps the block and all the nodes in the block , which are to
+ be found in Block->link. */
+ dump_cg_ir_block(node, irgmap);
+ } else {
+ /* Nodes that are not in a Block. */
+ dump_node(node, NULL);
+ dump_ir_data_edges(node);
+ }
+ }
+ /* Close the vcg information for the irg */
+ xfprintf(F, "}\n\n");
+}
/* dump interprocedural graph with surrounding methods */
void dump_cg_block_graph(ir_graph * irg) {
pmap * map = pmap_create();
+ pmap * map2 = pmap_create();
pmap_entry * entry;
+
vcg_open(irg, "");
- irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+ irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map))
+ pmap_insert(map2, entry->key, entry->value);
for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
- ir_node ** arr = entry->value;
- int i;
-
- xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
- get_entity_ident(get_irg_ent(entry->key)),
- get_entity_ident(get_irg_ent(entry->key)));
+ d_cg_block_graph(entry->key, entry->value, map2);
+ DEL_ARR_F(entry->value);
+ }
- for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
- ir_node * node = arr[i];
- if (is_Block(node)) {
- /* Dumps the block and all the nodes in the block , with are to be found in
- Block->link. */
- dump_cg_ir_block(node, NULL);
- } else {
- /* Node that are not in a Block. */
- dump_node(node);
- dump_ir_data_edges(node);
- }
- }
+ pmap_destroy(map);
+ pmap_destroy(map2);
- DEL_ARR_F(arr);
+ if (dump_loop_information_flag) dump_loop_info(irg);
+ vcg_close();
+}
- /* Close the vcg information for the irg */
- xfprintf(F, "}\n\n");
+static void collect_node(ir_node * node, void *env) {
+ if (is_Block(node)
+ || node_floats(node)
+ || get_irn_op(node) == op_Bad
+ || get_irn_op(node) == op_Unknown) {
+ ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
+ ARR_APP1(ir_node *, arr, node);
+ set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
+ } else {
+ ir_node * block = get_nodes_Block(node);
+ set_irn_link(node, get_irn_link(block));
+ set_irn_link(block, node);
}
+}
- pmap_destroy(map);
+/* Links all nodes that have the block field set in the link field of
+ the block. Adds all blocks and nodes not associated with a block
+ in a array in irg->link. */
+static void collect_nodes() {
+ int i;
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
+ cg_walk(clear_link, collect_node, NULL);
+}
- if (dump_loop_information_flag) {
- dump_loop_info(irg);
+static void dump_graphs() {
+ int i;
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ current_ir_graph = get_irp_irg(i);
+ d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
}
+}
+
+/* Dump all irgs in interprocedural view to a single file. */
+void dump_all_cg_block_graph() {
+ int i;
+ int rem_view = interprocedural_view;
+ interprocedural_view = 1;
+ vcg_open_name ("All_graphs");
+
+ collect_nodes();
+ dump_graphs();
+
+ if (dump_loop_information_flag)
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ dump_loop_info(get_irp_irg(i));
vcg_close();
+ interprocedural_view = rem_view;
}
-
/* dump interprocedural block graph with surrounding methods */
void dump_cg_graph(ir_graph * irg) {
pmap * map = pmap_create();
+ pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
pmap_entry * entry;
vcg_open(irg, "");
- irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+ irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map))
+ pmap_insert(map2, entry->key, entry->value);
for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
ir_node ** arr = entry->value;
int i;
for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
ir_node * node = arr[i];
- dump_node(node);
+ dump_node(node, map2);
dump_ir_data_edges(node);
if (is_Block(node)) {
for (node = get_irn_link(node); node; node = get_irn_link(node)) {
- dump_node(node);
+ dump_node(node, map2);
dump_ir_block_edge(node);
dump_ir_data_edges(node);
}
}
pmap_destroy(map);
+ pmap_destroy(map2);
vcg_close();
}