#include "callgraph.h"
#include "irextbb_t.h"
#include "dbginfo_t.h"
+#include "irtools.h"
#include "irvrfy.h"
#define ERROR_TXT "<ERROR>"
+/*******************************************************************/
+/* flags to steer output */
+/*******************************************************************/
+
+/** An option to turn off edge labels */
+static int edge_label = 1;
+/** An option to turn off dumping values of constant entities */
+static int const_entities = 1;
+/** An option to dump the keep alive edges */
+static int dump_keepalive = 0;
+/** An option to dump ld_names instead of names. */
+static int dump_ld_name = 1;
+/** Compiler options to dump analysis information in dump_ir_graph */
+int dump_out_edge_flag = 0;
+int dump_dominator_information_flag = 0;
+int dump_loop_information_flag = 0;
+int dump_backedge_information_flag = 1;
+int dump_const_local = 0;
+bool opt_dump_analysed_type_info = 1;
+bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
+
+static const char *overrule_nodecolor = NULL;
+
+/** An additional edge hook. */
+static DUMP_NODE_EDGE_FUNC dump_node_edge_hook = NULL;
+
+void set_dump_node_edge_hook(DUMP_NODE_EDGE_FUNC func)
+{
+ dump_node_edge_hook = func;
+}
+
+DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void)
+{
+ return dump_node_edge_hook;
+}
+
+
+/** The vcg node attribute hook. */
+static DUMP_IR_GRAPH_FUNC dump_ir_graph_hook = NULL;
+/** The vcg node attribute hook. */
+static DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL;
+/** The vcg edge attribute hook. */
+static DUMP_EDGE_VCGATTR_FUNC dump_edge_vcgattr_hook = NULL;
+
+/* set the ir graph hook */
+void set_dump_ir_graph_hook(DUMP_IR_GRAPH_FUNC hook) {
+ dump_ir_graph_hook = hook;
+}
+/* set the node attribute hook */
+void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook) {
+ dump_node_vcgattr_hook = hook;
+}
+/* set the edge attribute hook */
+void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook) {
+ dump_edge_vcgattr_hook = hook;
+}
+
+INLINE bool get_opt_dump_const_local(void) {
+ if (!dump_out_edge_flag && !dump_loop_information_flag)
+ return dump_const_local;
+ else
+ return false;
+}
+
+void only_dump_method_with_name(ident *name) {
+ dump_file_filter_id = name;
+}
+
+ident *get_dump_file_filter_ident(void) {
+ return dump_file_filter_id;
+}
+
+/** Returns true if dump file filter is not set, or if it is a
+ * prefix of name. */
+int is_filtered_dump_name(ident *name) {
+ if (!dump_file_filter_id) return 1;
+ return id_is_prefix(dump_file_filter_id, name);
+}
+
+/* To turn off display of edge labels. Edge labels often cause xvcg to
+ abort with a segmentation fault. */
+void turn_off_edge_labels(void) {
+ edge_label = 0;
+}
+
+void dump_consts_local(bool b) {
+ dump_const_local = b;
+}
+
+void dump_constant_entity_values(bool b) {
+ const_entities = b;
+}
+
+void dump_keepalive_edges(bool b) {
+ dump_keepalive = b;
+}
+
+bool get_opt_dump_keepalive_edges(void) {
+ return dump_keepalive;
+}
+
+void dump_out_edges(bool b) {
+ dump_out_edge_flag = b;
+}
+
+void dump_dominator_information(bool b) {
+ dump_dominator_information_flag = b;
+}
+
+void dump_loop_information(bool b) {
+ dump_loop_information_flag = b;
+}
+
+void dump_backedge_information(bool b) {
+ dump_backedge_information_flag = b;
+}
+
+/* Dump the information of type field specified in ana/irtypeinfo.h.
+ * If the flag is set, the type name is output in [] in the node label,
+ * else it is output as info.
+ */
+void set_opt_dump_analysed_type_info(bool b) {
+ opt_dump_analysed_type_info = b;
+}
+
+void dump_pointer_values_to_info(bool b) {
+ opt_dump_pointer_values_to_info = b;
+}
+
+void dump_ld_names(bool b) {
+ dump_ld_name = b;
+}
+
+/* -------------- some extended helper functions ----------------- */
+
/**
* returns the name of a mode or <ERROR> if mode is NOT a mode object.
* in the later case, sets bad
* Sets the private link field.
*/
static void ird_set_irn_link(ir_node *n, void *x) {
- if (!irdump_link_map) init_irdump();
+ if (!irdump_link_map)
+ init_irdump();
pmap_insert(irdump_link_map, (void *)n, x);
}
}
/**
- * If the entity has a ld_name, returns it, else returns the name of the entity.
+ * If the entity has a ld_name, returns it if the dump_ld_name is set,
+ * else returns the name of the entity.
*/
-const char *get_ent_dump_name(entity *ent) {
+static const char *_get_ent_dump_name(entity *ent, int dump_ld_name) {
if (!ent)
return "<NULL entity>";
- /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
- if (ent->ld_name) return get_id_str(ent->ld_name);
+ if (dump_ld_name) {
+ /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
+ if (ent->ld_name) return get_id_str(ent->ld_name);
+ }
return get_id_str(ent->name);
}
+/**
+ * If the entity has a ld_name, returns it if the option dump_ld_name is set,
+ * else returns the name of the entity.
+ */
+const char *get_ent_dump_name(entity *ent) {
+ return _get_ent_dump_name(ent, dump_ld_name);
+}
+
/* Returns the name of an IRG. */
const char *get_irg_dump_name(ir_graph *irg) {
/* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
- entity *ent = get_irg_entity(irg);
- return get_ent_dump_name(ent);
+ return _get_ent_dump_name(get_irg_entity(irg), 1);
}
/**
return lists;
}
-/*******************************************************************/
-/* flags to steer output */
-/*******************************************************************/
-
-/** A compiler option to turn off edge labels */
-static int edge_label = 1;
-/** A compiler option to turn off dumping values of constant entities */
-static int const_entities = 1;
-/** A compiler option to dump the keep alive edges */
-static int dump_keepalive = 0;
-/** Compiler options to dump analysis information in dump_ir_graph */
-int dump_out_edge_flag = 0;
-int dump_dominator_information_flag = 0;
-int dump_loop_information_flag = 0;
-int dump_backedge_information_flag = 1;
-int dump_const_local = 0;
-bool opt_dump_analysed_type_info = 1;
-bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
-
-static const char *overrule_nodecolor = NULL;
-
-/** An additional edge hook. */
-static DUMP_NODE_EDGE_FUNC dump_node_edge_hook = NULL;
-
-void set_dump_node_edge_hook(DUMP_NODE_EDGE_FUNC func)
-{
- dump_node_edge_hook = func;
-}
-
-DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void)
-{
- return dump_node_edge_hook;
-}
-
-
-/** The vcg attribute hook. */
-static DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL;
-
-/* set the hook */
-void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook) {
- dump_node_vcgattr_hook = hook;
-}
-
-INLINE bool get_opt_dump_const_local(void) {
- if (!dump_out_edge_flag && !dump_loop_information_flag)
- return dump_const_local;
- else
- return false;
-}
-
-void only_dump_method_with_name(ident *name) {
- dump_file_filter_id = name;
-}
-
-ident *get_dump_file_filter_ident(void) {
- return dump_file_filter_id;
-}
-
-/** Returns true if dump file filter is not set, or if it is a
- * prefix of name. */
-int is_filtered_dump_name(ident *name) {
- if (!dump_file_filter_id) return 1;
- return id_is_prefix(dump_file_filter_id, name);
-}
-
-/* To turn off display of edge labels. Edge labels offen cause xvcg to
- abort with a segmentation fault. */
-void turn_off_edge_labels(void) {
- edge_label = 0;
-}
-
-void dump_consts_local(bool b) {
- dump_const_local = b;
-}
-
-void dump_constant_entity_values(bool b) {
- const_entities = b;
-}
-
-void dump_keepalive_edges(bool b) {
- dump_keepalive = b;
-}
-
-bool get_opt_dump_keepalive_edges(void) {
- return dump_keepalive;
-}
-
-void dump_out_edges(bool b) {
- dump_out_edge_flag = b;
-}
-
-void dump_dominator_information(bool b) {
- dump_dominator_information_flag = b;
-}
-
-void dump_loop_information(bool b) {
- dump_loop_information_flag = b;
-}
-
-void dump_backedge_information(bool b) {
- dump_backedge_information_flag = b;
-}
-
-/* Dump the information of type field specified in ana/irtypeinfo.h.
- * If the flag is set, the type name is output in [] in the node label,
- * else it is output as info.
- */
-void set_opt_dump_analysed_type_info(bool b) {
- opt_dump_analysed_type_info = b;
-}
-
-void dump_pointer_values_to_info(bool b) {
- opt_dump_pointer_values_to_info = b;
-}
-
/*-----------------------------------------------------------------*/
/* Routines to dump information about a single ir node. */
/*-----------------------------------------------------------------*/
case iro_Load:
fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
break;
+ case iro_Block:
+ fprintf (F, "%s%s", is_Block_dead(n) ? "Dead " : "", get_irn_opname(n));
+ break;
default: {
default_case:
}
if (! f)
fprintf (F, "%ld ", proj_nr);
+ if (code == iro_Cond && get_Cond_jmp_pred(pred) != COND_JMP_PRED_NONE) {
+ if (proj_nr == pn_Cond_false && get_Cond_jmp_pred(pred) == COND_JMP_PRED_FALSE)
+ fprintf(F, "PRED ");
+ if (proj_nr == pn_Cond_true && get_Cond_jmp_pred(pred) == COND_JMP_PRED_TRUE)
+ fprintf(F, "PRED ");
+ }
}
break;
case iro_Filter:
fprintf (F, "edge: { sourcename: \"");
PRINT_NODEID(n);
fprintf (F, "\" targetname: \""); PRINT_CONSTBLKID(n,blk);
+
+ if (dump_edge_vcgattr_hook) {
+ fprintf (F, "\" ");
+ if (dump_edge_vcgattr_hook(F, n, -1)) {
+ fprintf (F, "}\n");
+ return;
+ }
+ else {
+ fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
+ return;
+ }
+ }
+
fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
}
}
if (__dbg_info_snprint) {
buf[0] = '\0';
if (__dbg_info_snprint(buf, sizeof(buf), dbg) > 0)
- fprintf (F, " info3: \"%s\"", buf);
+ fprintf (F, " info3: \"%s\"\n", buf);
}
}
PRINT_NODEID(n);
fprintf (F, "\" targetname: ");
fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
+
+ if (dump_edge_vcgattr_hook) {
+ fprintf (F, " ");
+ if (dump_edge_vcgattr_hook(F, n, -1)) {
+ fprintf (F, "}\n");
+ return;
+ }
+ else {
+ fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
+ return;
+ }
+ }
+
fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
}
}
print_edge_vcgattr(FILE *F, ir_node *from, int to) {
assert(from);
+ if (dump_edge_vcgattr_hook)
+ if (dump_edge_vcgattr_hook(F, from, to))
+ return;
+
if (dump_backedge_information_flag && is_backedge(from, to))
fprintf (F, BACK_EDGE_ATTR);
static void
dump_whole_block(FILE *F, ir_node *block) {
ir_node *node;
+ const char *color = "yellow";
+
assert(is_Block(block));
fprintf(F, "graph: { title: \"");
if (get_opt_dump_abstvals())
fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
#endif
- fprintf(F, "\" status:clustered color:%s \n",
- get_Block_matured(block) ? "yellow" : "red");
+
+ /* colorize blocks */
+ if (! get_Block_matured(block))
+ color = "red";
+ if (is_Block_dead(block))
+ color = "orange";
+
+ fprintf(F, "\" status:clustered color:%s \n", color);
+
+ /* ycomp can show attributs for blocks, VCG parses but ignores them */
+ dump_node_info(F, block);
/* dump the blocks edges */
dump_ir_data_edges(F, block);
compute_extbb(irg);
for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
ir_extblk *extbb = arr[i];
- ir_node *leader = extbb->blks[0];
+ ir_node *leader = get_extbb_leader(extbb);
int j;
fprintf(F, "graph: { title: \"");
}
-/* Why not dump_type_node as the others? */
-static int print_type_node(FILE *F, type *tp)
+int dump_type_node(FILE *F, type *tp)
{
int bad = 0;
#else
dump_type_to_file(F, tp, dump_verbosity_max);
#endif
- fprintf (F, "\"");
+ fprintf (F, "\"\n");
+ print_node_dbg_info(F, get_type_dbg_info(tp));
print_typespecific_vcgattr(F, tp);
fprintf (F, "}\n");
return bad;
}
-int dump_type_node(FILE *F, type *tp) {
- return print_type_node(F, tp);
-}
-
#define X(a) case a: fprintf(F, #a); break
void dump_entity_node(FILE *F, entity *ent, int color)
dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
- fprintf(F, "\"\n}\n");
+ fprintf(F, "\"\n");
+ print_node_dbg_info(F, get_entity_dbg_info(ent));
+ fprintf(F, "}\n");
}
#undef X
case k_type:
{
type *tp = (type *)tore;
- print_type_node(F, tp);
+ dump_type_node(F, tp);
/* and now the edges */
switch (get_type_tpop_code(tp)) {
case tpo_class:
if (tp == get_glob_type()) break;
switch (get_type_tpop_code(tp)) {
case tpo_class: {
- print_type_node(F, tp);
+ dump_type_node(F, tp);
/* and now the edges */
for (i=0; i < get_class_n_supertypes(tp); i++)
{
fprintf (F, " info1: \"");
fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
#if DEBUG_libfirm /* GL @@@ debug analyses */
- fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
+ fprintf (F, "\n The loop was analyzed %d times.", PTR_TO_INT(get_loop_link(loop)));
#endif
fprintf (F, "\"");
}
/**
* dumps the VCG header
*/
-INLINE void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
+void dump_vcg_header(FILE *F, const char *name, const char *orientation) {
char *label;
if (edge_label) {
/**
* open a vcg file
*
- * @param irg The graph to be dumped
+ * @param name prefix file name
* @param suffix filename suffix
*/
FILE *vcg_open_name (const char *name, const char *suffix) {
if (!suffix) suffix = "";
/** open file for vcg graph */
- fname = malloc (len * 2 + 5 + strlen(suffix));
+ fname = xmalloc(len * 2 + 5 + strlen(suffix));
/* strcpy (fname, name);*/ /* copy the filename */
j = 0;
for (i = 0; i < len; ++i) { /* replace '/' in the name: escape by @. */
f = vcg_open(irg, suffix, suffix1);
dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+ /* call the dump graph hook */
+ if (dump_ir_graph_hook)
+ if (dump_ir_graph_hook(f, irg))
+ return;
+
/* walk over the graph */
/* dump_whole_node must be called in post visiting predecessors */
irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);
FILE *f;
ir_graph *rem = current_ir_graph;
char *suffix1;
+ int rem_dump_const_local;
/* if a filter is set, dump only the irg's that match the filter */
if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
current_ir_graph = irg;
+ rem_dump_const_local = dump_const_local;
+ /* dumping types does not work with local nodes */
+ dump_const_local = 0;
if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
else suffix1 = "-pure-wtypes";
irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
vcg_close(f);
+ dump_const_local = rem_dump_const_local;
current_ir_graph = rem;
}
int i;
char *suffix1;
ir_graph *rem = current_ir_graph;
+ int rem_dump_const_local;
/* if a filter is set, dump only the irg's that match the filter */
if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
+ rem_dump_const_local = dump_const_local;
+ /* dumping types does not work with local nodes */
+ dump_const_local = 0;
+
if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
else suffix1 = "-wtypes";
f = vcg_open(irg, suffix, suffix1);
/* dump edges from graph to type info */
irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
- current_ir_graph = rem;
vcg_close(f);
+ dump_const_local = rem_dump_const_local;
+ current_ir_graph = rem;
}
/*---------------------------------------------------------------------*/
static void
dump_block_to_cfg(ir_node *block, void *env) {
FILE *F = env;
- int i, fl;
+ int i, fl = 0;
ir_node *pred;
if (is_Block(block)) {