*/
-#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);
static int node_floats(ir_node *n) {
- return ((get_op_pinned(get_irn_op(n)) == op_pin_state_floats) &&
+ return ((get_irn_pinned(n) == op_pin_state_floats) &&
(get_irg_pinned(current_ir_graph) == op_pin_state_floats));
}
-static const char *get_ent_dump_name(entity *ent) {
+const char *get_ent_dump_name(entity *ent) {
if (! ent)
return "<NULL entity>";
/* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
return get_id_str(ent->name);
}
-static const char *get_irg_dump_name(ir_graph *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);
/* 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: {
dump_node_mode(FILE *F, ir_node *n)
{
int bad = 0;
+ opcode iro = get_irn_opcode(n);
+
+ switch (iro) {
+ case iro_SymConst:
+ case iro_Sel:
+ case iro_End:
+ case iro_Return:
+ case iro_Free:
+ case iro_Sync:
+ case iro_Jmp:
+ break;
+ default: {
+ ir_mode *mode = get_irn_mode(n);
- switch (get_irn_opcode(n)) {
- case iro_Phi:
- case iro_Const:
- case iro_Id:
- case iro_Proj:
- case iro_Filter:
- 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:
- case iro_Confirm:
- fprintf(F, "%s", get_mode_name_ex(get_irn_mode(n), &bad));
- break;
- default:
- ;
+ if (mode && mode != mode_BB && mode != mode_ANY && mode != mode_BAD &&
+ (mode != mode_T || iro == iro_Proj))
+ fprintf(F, "%s", get_mode_name_ex(mode, &bad));
+ }
}
+
return bad;
}
if (irg != get_const_code_irg())
fprintf (F, "irg: %s\n", get_ent_dump_name(get_irg_entity(irg)));
+ if (get_irn_pinned(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) ||
fprintf(F, "start of method of type %s \n", get_type_name_ex(tp, &bad));
for (i = 0; i < get_method_n_params(tp); ++i)
fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
+ if ((get_irp_ip_view_state() == ip_view_valid) && !interprocedural_view) {
+ ir_node *sbl = get_nodes_block(n);
+ int i, n_cfgpreds = get_Block_cg_n_cfgpreds(sbl);
+ fprintf(F, "graph has %d interprocedural predecessors:\n", n_cfgpreds);
+ for (i = 0; i < n_cfgpreds; ++i) {
+ ir_node *cfgpred = get_Block_cg_cfgpred(sbl, i);
+ fprintf(F, " %d: Call %ld in graph %s\n", i, get_irn_node_nr(cfgpred),
+ get_irg_dump_name(get_irn_irg(cfgpred)));
+ }
+ }
} break;
case iro_Alloc: {
fprintf(F, "allocating entity of type %s \n", get_type_name_ex(get_Alloc_type(n), &bad));
fprintf(F, " param %d type: %s \n", i, get_type_name_ex(get_method_param_type(tp, i), &bad));
for (i = 0; i < get_method_n_ress(tp); ++i)
fprintf(F, " resul %d type: %s \n", i, get_type_name_ex(get_method_res_type(tp, i), &bad));
- if (0 && Call_has_callees(n)) {
+ if (Call_has_callees(n)) {
fprintf(F, "possible callees: \n");
for (i = 0; i < get_Call_n_callees(n); i++) {
if (!get_Call_callee(n, i)) {
break;
case symconst_addr_ent:
fprintf(F, "kind addr_ent\n");
+ dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames);
break;
case symconst_type_tag:
fprintf(F, "kind type_tag\n");
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";
int i;
char *suffix1;
- 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;
+
if (interprocedural_view) suffix1 = "-ip";
else suffix1 = "";
f = vcg_open(irg, suffix, suffix1);
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);
}
/***********************************************************************/
void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) {
- int i;
- for (i=0; i < get_irp_n_irgs(); i++) {
+ int i, n_irgs = get_irp_n_irgs();
+ for (i = 0; i < n_irgs; ++i) {
dmp_grph(get_irp_irg(i), suffix);
}
}
/**********************************************************************************
- * Dumps a stand alone loop graph with firm nodes which belong to one loop nodes *
+ * Dumps a stand alone loop graph with firm nodes which belong to one loop node *
* packed together in one subgraph/box *
**********************************************************************************/
dump_loop_son_edge(F, loop, son_number++);
dump_loops_standalone(F, son);
} else if (get_kind(son) == k_ir_node) {
- /* We are a loop node -> Collect firm nodes */
+ /* We are a loop node -> Collect firm nodes */
ir_node *n = le.node;
int bad = 0;
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");