*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include "firm_common_t.h"
+
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irprog_t.h"
#include "entity_t.h"
#include "irop_t.h"
-#include "firm_common_t.h"
#include "irdump.h"
#endif
-int my_special_flag = 0;
+/* basis for a color range for vcg */
+static int n_colors = 0;
+static int base_color = 0;
static const char *get_mode_name_ex(ir_mode *mode, int *bad)
{
/* global and ahead declarations */
/*******************************************************************/
-/* A suffix to manipulate the file name. */
-
-char *dump_file_filter = "";
-
static void dump_whole_node(ir_node *n, void *env);
static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
/* flags to steer output */
/*******************************************************************/
+const char *dump_file_filter = "";
+
/* A compiler option to turn off edge labels */
int edge_label = 1;
/* A compiler option to turn off dumping values of constant entities */
return false;
}
+void only_dump_method_with_name(ident *name) {
+ dump_file_filter = get_id_str(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) {
opt_dump_pointer_values_to_info = b;
}
-/*******************************************************************/
+/*-----------------------------------------------------------------*/
/* Routines to dump information about a single ir node. */
-/*******************************************************************/
+/*-----------------------------------------------------------------*/
INLINE int
dump_node_opcode(FILE *F, ir_node *n)
if (ent) fprintf (F, " %s", get_entity_name(ent));
break;
}
+ case iro_Load:
+ fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
+ break;
default_case:
default: {
if (irg != get_const_code_irg())
fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
+ if (get_op_pinned(get_irn_op(n)) == op_pin_state_floats &&
+ get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
+ fprintf(F, "node was pinned in ");
+ dump_node_opcode(F, get_nodes_block(n));
+ fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
+ }
+
+#if 0
+ /* show all predecessor nodes */
+ fprintf(F, "pred nodes: \n");
+ if (!is_Block(n)) {
+ fprintf(F, " -1: ");
+ dump_node_opcode(F, get_nodes_block(n));
+ fprintf(F, " %ld\n", get_irn_node_nr(get_nodes_block(n)));
+ }
+ for ( i = 0; i < get_irn_arity(n); ++i) {
+ fprintf(F, " %d: ", i);
+ dump_node_opcode(F, get_irn_n(n, i));
+ fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
+ }
+#endif
+
fprintf(F, "arity: %d", get_irn_arity(n));
if ((get_irn_op(n) == op_Block) ||
(get_irn_op(n) == op_Phi) ||
if (interprocedural_view) {
fprintf(F, "intra predecessor nodes:\n");
for (i = 0; i < get_irn_intra_arity(n); i++) {
- ir_node *pred = get_irn_intra_n(n, i);
- fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
+ ir_node *pred = get_irn_intra_n(n, i);
+ fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
}
} else {
fprintf(F, "inter predecessor nodes:\n");
for (i = 0; i < get_irn_inter_arity(n); i++) {
- ir_node *pred = get_irn_inter_n(n, i);
- fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
+ ir_node *pred = get_irn_inter_n(n, i);
+ fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
get_irn_node_nr(pred), get_ent_dump_name(get_irg_entity(get_irn_irg(pred))));
}
}
} break;
+ case iro_Load:
+ fprintf(F, "volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
+ break;
+ case iro_Store:
+ fprintf(F, "volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
+ break;
+
default: ;
}
for (i = 0; i < get_irn_arity(n); i++) {
ir_node *con = get_irn_n(n, i);
if (is_constlike_node(con)) {
- set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
+ set_irn_visited(con, get_irg_visited(current_ir_graph) - 1);
}
}
dump_ir_block_edge(FILE *F, ir_node *n) {
if (get_opt_dump_const_local() && is_constlike_node(n)) return;
if (is_no_Block(n)) {
+ ir_node *block = get_nodes_block(n);
+
fprintf (F, "edge: { sourcename: \"");
PRINT_NODEID(n);
- fprintf (F, "\" targetname: \"");
- PRINT_NODEID(get_nodes_block(n));
- fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
+ fprintf (F, "\" targetname: ");
+ fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
+ fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
}
}
}
}
- if (dump_loop_information_flag) dump_loop_nodes_into_graph(F, irg);
+ if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
+ dump_loop_nodes_into_graph(F, irg);
current_ir_graph = rem;
}
}
#define X(a) case a: fprintf(F, #a); break
-void dump_entity_node(FILE *F, entity *ent)
+void dump_entity_node(FILE *F, entity *ent, int color)
{
fprintf (F, "node: {title: \"");
PRINT_ENTID(ent); fprintf(F, "\"");
fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
fprintf (F, "label: ");
- fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
+ fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
+ if (color)
+ fprintf(F, "color: %d", color);
+ else
+ fprintf (F, ENTITY_NODE_ATTR);
fprintf (F, "\n info1: \"");
- dump_entity_to_file(F, ent);
+ dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts);
fprintf(F, "\"\n}\n");
}
entity *ent = (entity *)tore;
ir_node *value;
/* The node */
- dump_entity_node(F, ent);
+ dump_entity_node(F, ent, 0);
/* The Edges */
/* skip this to reduce graph. Member edge of type is parallel to this edge. *
fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
if (!is_method_type(get_entity_type(ent))) break; /* GL */
if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
/* The node */
- dump_entity_node(F, ent);
+ dump_entity_node(F, ent, 0);
/* The edges */
print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
for(i = 0; i < get_entity_n_overwrites(ent); i++)
"infoname 2: \"Verification errors\"\n",
name, label, orientation);
+ /* don't use all, the range is too whith/black. */
+ n_colors = 18;
+ base_color = 105;
+ fprintf (F,
+ "colorentry 100: 0 0 0\n"
+ "colorentry 101: 20 0 0\n"
+ "colorentry 102: 40 0 0\n"
+ "colorentry 103: 60 0 0\n"
+ "colorentry 104: 80 0 0\n"
+ "colorentry 105: 100 0 0\n"
+ "colorentry 106: 120 0 0\n"
+ "colorentry 107: 140 0 0\n"
+ "colorentry 108: 150 0 0\n"
+ "colorentry 109: 180 0 0\n"
+ "colorentry 110: 200 0 0\n"
+ "colorentry 111: 220 0 0\n"
+ "colorentry 112: 240 0 0\n"
+ "colorentry 113: 255 0 0\n"
+ "colorentry 113: 255 20 20\n"
+ "colorentry 114: 255 40 40\n"
+ "colorentry 115: 255 60 60\n"
+ "colorentry 116: 255 80 80\n"
+ "colorentry 117: 255 100 100\n"
+ "colorentry 118: 255 120 120\n"
+ "colorentry 119: 255 140 140\n"
+ "colorentry 120: 255 150 150\n"
+ "colorentry 121: 255 180 180\n"
+ "colorentry 122: 255 200 200\n"
+ "colorentry 123: 255 220 220\n"
+ "colorentry 124: 255 240 240\n"
+ "colorentry 125: 255 250 250\n"
+ );
+
fprintf (F, "\n"); /* a separator */
}
char *suffix1;
rem = current_ir_graph;
- if(strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter))!=0) return;
+ if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
current_ir_graph = irg;
if (interprocedural_view) suffix1 = "-pure-ip";
else suffix1 = "-pure";
vcg_close(f);
}
-/***********************************************************************/
+/*---------------------------------------------------------------------*/
/* The following routines dump a control flow graph. */
-/***********************************************************************/
+/*---------------------------------------------------------------------*/
static void
dump_block_to_cfg(ir_node *block, void *env) {
FILE *F = env;
- int i;
+ int i, fl;
ir_node *pred;
if (is_Block(block)) {
/* This is a block. Dump a node for the block. */
fprintf (F, "node: {title: \""); PRINT_NODEID(block);
- fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
+ fprintf (F, "\" label: \"");
+ if (block == get_irg_start_block(get_irn_irg(block)))
+ fprintf(F, "Start ");
+ if (block == get_irg_end_block(get_irn_irg(block)))
+ fprintf(F, "End ");
+
+ fprintf (F, "%s ", get_op_name(get_irn_op(block)));
PRINT_NODEID(block);
fprintf (F, "\" ");
+ fprintf(F, "info1:\"");
if (dump_dominator_information_flag)
- fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
+ fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
+
+ /* show arity and possible Bad predecessors of the block */
+ fprintf(F, "arity: %d\n", get_Block_n_cfgpreds(block));
+ for (fl = i = 0; i < get_Block_n_cfgpreds(block); ++i) {
+ ir_node *pred = get_Block_cfgpred(block, i);
+ if (is_Bad(pred)) {
+ if (! fl)
+ fprintf(F, "Bad pred at pos: ");
+ fprintf(F, "%d ", i);
+ fl = 1;
+ }
+ }
+ if (fl)
+ fprintf(F, "\n");
+
+ fprintf (F, "\""); /* closing quote of info */
+
+ if ((block == get_irg_start_block(get_irn_irg(block))) ||
+ (block == get_irg_end_block(get_irn_irg(block))) )
+ fprintf(F, " color:blue ");
+ else if (fl)
+ fprintf(F, " color:yellow ");
+
fprintf (F, "}\n");
/* Dump the edges */
for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
- pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
- fprintf (F, "edge: { sourcename: \"");
- PRINT_NODEID(block);
- fprintf (F, "\" targetname: \"");
- PRINT_NODEID(pred);
- fprintf (F, "\"}\n");
+ pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
+ fprintf (F, "edge: { sourcename: \"");
+ PRINT_NODEID(block);
+ fprintf (F, "\" targetname: \"");
+ PRINT_NODEID(pred);
+ fprintf (F, "\"}\n");
}
/* Dump dominator edge */
current_ir_graph = rem;
}
+static int weight_overall(int rec, int loop) {
+ return 2*rec + loop;
+}
+
+static int compute_color (int my, int max) {
+ int color;
+ if (!max) {
+ color = 0;
+ } else {
+ /* if small, scale to the full color range. */
+ if (max < n_colors)
+ my = my * (n_colors/max);
+
+ int step = 1 + (max / n_colors);
+
+ color = my/step;
+ }
+ return base_color + n_colors - color;
+}
+
+static int get_entity_color(entity *ent) {
+ assert(get_entity_irg(ent));
+ ir_graph *irg = get_entity_irg(ent);
+
+ int rec_depth = get_irg_recursion_depth(irg);
+ int loop_depth = get_irg_loop_depth(irg);
+ int overall_depth = weight_overall(rec_depth, loop_depth);
+
+ int max_rec_depth = irp->max_callgraph_recursion_depth;
+ int max_loop_depth = irp->max_callgraph_loop_depth;
+ int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
+
+ int my_rec_color = compute_color(rec_depth, max_rec_depth);
+ int my_loop_color = compute_color(loop_depth, max_loop_depth);
+ int my_overall_color = compute_color(overall_depth, max_overall_depth);;
+
+ return my_overall_color;
+}
+
void dump_callgraph(const char *suffix) {
FILE *F;
int i, n_irgs = get_irp_n_irgs();
int rem = edge_label;
edge_label = 1;
-
- my_special_flag = 1;
+ //ident *prefix = new_id_from_str("java/");
F = vcg_open_name("Callgraph", suffix);
dump_vcg_header(F, "Callgraph", NULL);
entity *ent = get_irg_entity(irg);
int j, n_callees = get_irg_n_callees(irg);
- dump_entity_node(F, ent);
+ /* Do not dump runtime system. */
+ //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
+
+ dump_entity_node(F, ent, get_entity_color(ent));
for (j = 0; j < n_callees; ++j) {
entity *c = get_irg_entity(get_irg_callee(irg, j));
+ //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
int be = is_irg_callee_backedge(irg, j);
char *attr;
attr = (be) ?
- "label:\"recursion %d\" color:red" :
- "label:\"calls %d\"";
- print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j));
+ "label:\"recursion %d\" color: %d" :
+ "label:\"calls %d\" color: %d";
+ print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
}
}
- my_special_flag = 0;
edge_label = rem;
vcg_close(F);
}
current_ir_graph = rem;
}
-void dump_callgraph_loop_tree(char *suffix) {
+void dump_callgraph_loop_tree(const char *suffix) {
FILE *F;
F = vcg_open_name("Callgraph_looptree", suffix);
dump_vcg_header(F, "callgraph looptree", "top_to_bottom");