#include "irdom.h"
#include "irloop.h"
#include "callgraph.h"
+#include "irextbb_t.h"
#include "irvrfy.h"
#include "pset.h"
#if DO_HEAPANALYSIS
-void dump_irn_chi_term(FILE *FL, ir_node *n);
-void dump_irn_state(FILE *FL, ir_node *n);
-int get_opt_dump_abstvals(void);
+extern void dump_irn_chi_term(FILE *FL, ir_node *n);
+extern void dump_irn_state(FILE *FL, ir_node *n);
+extern int get_opt_dump_abstvals(void);
typedef unsigned long SeqNo;
-SeqNo get_Block_seqno(ir_node *n);
+extern SeqNo get_Block_seqno(ir_node *n);
#endif
/* basis for a color range for vcg */
static int n_colors = 0;
static int base_color = 0;
+/** Dump only irgs with names that start with this string */
+static ident *dump_file_filter_id = NULL;
+
#define ERROR_TXT "<ERROR>"
/**
/* We need a new, empty map. */
if (irdump_link_map) pmap_destroy(irdump_link_map);
irdump_link_map = pmap_create();
+ dump_file_filter_id = new_id_from_str("");
}
-
/**
* Returns the private link field.
*/
}
/**
- * Walker, clears tzhe private link field
+ * Walker, clears the private link field.
*/
static void clear_link(ir_node * node, void * env) {
ird_set_irn_link(node, NULL);
* graphs not visited.
* Free the list with DEL_ARR_F().
*/
-static ir_node ** construct_block_lists(ir_graph *irg) {
+static ir_node **construct_block_lists(ir_graph *irg) {
int i, rem_view = get_interprocedural_view();
ir_graph *rem = current_ir_graph;
current_ir_graph = irg;
return ird_get_irg_link(irg);
}
+typedef struct _list_tuple {
+ ir_node **blk_list;
+ ir_extblk **extbb_list;
+} list_tuple;
+
+/** Construct lists to walk ir extended block-wise.
+ * Free the lists in the tuple with DEL_ARR_F().
+ */
+static list_tuple *construct_extblock_lists(ir_graph *irg) {
+ ir_node **blk_list = construct_block_lists(irg);
+ int i;
+ ir_graph *rem = current_ir_graph;
+ list_tuple *lists = xmalloc(sizeof(*lists));
+
+ current_ir_graph = irg;
+
+ lists->blk_list = NEW_ARR_F(ir_node *, 0);
+ lists->extbb_list = NEW_ARR_F(ir_extblk *, 0);
+
+ for (i = ARR_LEN(blk_list) - 1; i >= 0; --i) {
+ ir_extblk *ext;
+
+ if (is_Block(blk_list[i])) {
+ ext = get_Block_extbb(blk_list[i]);
+
+ if (extbb_not_visited(ext)) {
+ ARR_APP1(ir_extblk *, lists->extbb_list, ext);
+ mark_extbb_visited(ext);
+ }
+ }
+ else
+ ARR_APP1(ir_node *, lists->blk_list, blk_list[i]);
+ }
+
+ current_ir_graph = rem;
+ DEL_ARR_F(blk_list);
+ ird_set_irg_link(irg, lists);
+ return lists;
+}
+
/*******************************************************************/
/* flags to steer output */
/*******************************************************************/
-/** Dump only irgs with names start with this string */
-const char *dump_file_filter = "";
-
/** 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 DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL;
/* set the hook */
-void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook)
-{
+void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook) {
dump_node_vcgattr_hook = hook;
}
}
void only_dump_method_with_name(ident *name) {
- dump_file_filter = get_id_str(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. */
* If the flag is set, the type name is output in [] in the node label,
* else it is output as info.
*/
-void dump_analysed_type_info(bool b) {
+void set_opt_dump_analysed_type_info(bool b) {
opt_dump_analysed_type_info = b;
}
fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
break;
-default_case:
default: {
+default_case:
fprintf (F, "%s", get_irn_opname(n));
}
}
/**
- * Dump the tpe of a node n to a file F if it's known.
+ * Dump the type of a node n to a file F if it's known.
*/
static int dump_node_typeinfo(FILE *F, ir_node *n) {
int bad = 0;
if (opt_dump_analysed_type_info) {
- if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
- get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent) {
+ if (get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent ||
+ get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent) {
type *tp = get_irn_typeinfo_type(n);
if (tp != firm_none_type)
- fprintf(F, " [%s]", get_type_name_ex(tp, &bad));
+ fprintf(F, "[%s] ", get_type_name_ex(tp, &bad));
else
- fprintf(F, " []");
+ fprintf(F, "[] ");
}
}
return bad;
}
/**
- * Dump addinional node attributes of some nodes to a file F.
+ * Dump additional node attributes of some nodes to a file F.
*/
static INLINE int
dump_node_nodeattr(FILE *F, ir_node *n)
switch (get_irn_opcode(n)) {
case iro_Start:
if (false && get_interprocedural_view()) {
- fprintf (F, "%s", get_ent_dump_name(get_irg_entity(current_ir_graph)));
+ fprintf (F, "%s ", get_ent_dump_name(get_irg_entity(current_ir_graph)));
}
break;
case iro_Proj:
if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
- fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
+ fprintf (F, "%s ", get_pnc_string(get_Proj_proj(n)));
} else {
- fprintf (F, "%ld", get_Proj_proj(n));
+ fprintf (F, "%ld ", get_Proj_proj(n));
}
break;
case iro_Filter:
- fprintf (F, "%ld", get_Filter_proj(n));
+ fprintf (F, "%ld ", get_Filter_proj(n));
break;
case iro_Sel:
- fprintf (F, "%s", get_ent_dump_name(get_Sel_entity(n)));
+ fprintf (F, "%s ", get_ent_dump_name(get_Sel_entity(n)));
break;
case iro_Cast:
- fprintf (F, "(%s)", get_type_name_ex(get_Cast_type(n), &bad));
+ fprintf (F, "(%s) ", get_type_name_ex(get_Cast_type(n), &bad));
break;
case iro_Confirm:
- fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
+ fprintf (F, "%s ", get_pnc_string(get_Confirm_cmp(n)));
break;
default:
return bad;
}
+#include <math.h>
+#include "execution_frequency.h"
+#include "callgraph.h"
+
+void dump_node_ana_vals(FILE *F, ir_node *n) {
+ return;
+ fprintf(F, " %lf*(%2.0lf + %2.0lf) = %2.0lf ",
+ get_irn_exec_freq(n),
+ get_irg_method_execution_frequency(get_irn_irg(n)),
+ pow(5, get_irg_recursion_depth(get_irn_irg(n))),
+ get_irn_exec_freq(n) * (get_irg_method_execution_frequency(get_irn_irg(n)) + pow(5, get_irg_recursion_depth(get_irn_irg(n))))
+ );
+}
+
+
+/* Dumps a node label without the enclosing ". */
+int dump_node_label(FILE *F, ir_node *n) {
+ int bad = 0;
+
+ bad |= dump_node_opcode(F, n);
+ bad |= dump_node_mode(F, n);
+ fprintf (F, " ");
+ bad |= dump_node_typeinfo(F, n);
+ bad |= dump_node_nodeattr(F, n);
+ fprintf(F, "%ld", get_irn_node_nr(n));
+
+ return bad;
+}
+
+
/**
- * dumps the attributes of a node n into the file F.
+ * Dumps the attributes of a node n into the file F.
* Currently this is only the color of a node.
*/
static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad)
}
/**
- * checks wheater a node is "constant-like", ie can be treated "block-less"
+ * checks whether a node is "constant-like" ie can be treated "block-less"
*/
static INLINE
bool is_constlike_node(ir_node *n) {
n and const. */
fprintf(F, "node: {title: "); PRINT_CONSTID(n, con);
fprintf(F, " label: \"");
- bad |= dump_node_opcode(F, con);
- bad |= dump_node_mode(F, con);
- bad |= dump_node_typeinfo(F, con);
- fprintf (F, " ");
- bad |= dump_node_nodeattr(F, con);
- fprintf(F, " %ld", get_irn_node_nr(con));
+ bad |= dump_node_label(F, con);
fprintf(F, "\" ");
bad |= dump_node_info(F, con);
dump_node_vcgattr(F, n, con, bad);
n and blk. */
fprintf(F, "node: {title: \""); PRINT_CONSTBLKID(n, blk);
fprintf(F, "\" label: \"");
- bad |= dump_node_opcode(F, blk);
- bad |= dump_node_mode(F, blk);
- bad |= dump_node_typeinfo(F, blk);
- fprintf (F, " ");
- bad |= dump_node_nodeattr(F, blk);
- fprintf(F, " %ld", get_irn_node_nr(blk));
+ bad |= dump_node_label(F, blk);
fprintf(F, "\" ");
bad |= dump_node_info(F, blk);
dump_node_vcgattr(F, n, blk, bad);
fprintf(F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p);
- bad |= dump_node_opcode(F, n);
- bad |= dump_node_mode(F, n);
- bad |= dump_node_typeinfo(F, n);
- fprintf(F, " ");
- bad |= dump_node_nodeattr(F, n);
- fprintf(F, " %ld", get_irn_node_nr(n));
+ bad |= dump_node_label(F, n);
+ dump_node_ana_vals(F, n);
+ //dump_node_ana_info(F, n);
fprintf(F, "\" ");
bad |= dump_node_info(F, n);
print_node_error(F, p);
current_ir_graph = get_const_code_irg();
irg_walk(value, dump_const_node, NULL, F);
/* Decrease visited flag so that we walk with the same flag for the next
- expresssion. This guarantees that we don't dump the same node twice,
+ expression. This guarantees that we don't dump the same node twice,
as for const expressions cse is performed to save memory. */
set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
current_ir_graph = rem;
fprintf(F, "graph: { title: \"");
PRINT_NODEID(block);
fprintf(F, "\" label: \"");
- dump_node_opcode(F, block);
- fprintf (F, " %ld", get_irn_node_nr(block));
+ dump_node_label(F, block);
#if DO_HEAPANALYSIS
if (get_opt_dump_abstvals())
fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
current_ir_graph = rem;
}
-/** Dumps an irg as a graph.
+/** Dumps an irg as a graph clustered by block nodes.
* If interprocedural view edges can point to nodes out of this graph.
*/
static void dump_graph_from_list(FILE *F, ir_graph *irg) {
fprintf(F, "}\n\n");
}
+/** dumps a graph extended block-wise. Expects all blockless nodes in arr in irgs link.
+ * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */
+static void
+dump_extblock_graph(FILE *F, ir_graph *irg) {
+ int i;
+ ir_graph *rem = current_ir_graph;
+ ir_extblk **arr = ird_get_irg_link(irg);
+ current_ir_graph = irg;
+
+ compute_extbb(irg);
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_extblk *extbb = arr[i];
+ ir_node *leader = extbb->blks[0];
+ int j;
+
+ fprintf(F, "graph: { title: \"");
+ PRINT_EXTBBID(leader);
+ fprintf(F, "\" label: \"ExtBB %ld\" status:clustered color:lightgreen\n",
+ get_irn_node_nr(leader));
+
+ for (j = ARR_LEN(extbb->blks) - 1; j >= 0; --j) {
+ ir_node * node = extbb->blks[j];
+ if (is_Block(node)) {
+ /* Dumps the block and all the nodes in the block, which are to
+ be found in Block->link. */
+ dump_whole_block(F, node);
+ } else {
+ /* Nodes that are not in a Block. */
+ dump_node(F, node);
+ if (is_Bad(get_nodes_block(node)) && !node_floats(node)) {
+ dump_const_block_local(F, node);
+ }
+ dump_ir_data_edges(F, node);
+ }
+ }
+ fprintf(F, "}\n");
+ }
+
+ if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid))
+ dump_loop_nodes_into_graph(F, irg);
+
+ current_ir_graph = rem;
+ free_extbb(irg);
+}
+
+
/*******************************************************************/
/* Basic type and entity nodes and edges. */
/*******************************************************************/
}
}
-
+#if 0
static int print_type_info(FILE *F, type *tp) {
int bad = 0;
default: break;
} /* switch type */
}
-
+#endif
static void print_typespecific_vcgattr(FILE *F, type *tp) {
switch (get_type_tpop_code(tp)) {
} /* switch type */
}
+
+/* Why not dump_type_node as the others? */
static int print_type_node(FILE *F, type *tp)
{
int bad = 0;
PRINT_TYPEID(tp);
fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name_ex(tp, &bad));
fprintf (F, " info1: \"");
+#if 0
bad |= print_type_info(F, tp);
print_typespecific_info(F, tp);
+#else
+ dump_type_to_file(F, tp, dump_verbosity_max);
+#endif
fprintf (F, "\"");
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)
{
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 (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) return;
current_ir_graph = irg;
if (get_interprocedural_view()) suffix1 = "-pure-ip";
current_ir_graph = rem;
}
-
-void
-dump_ir_block_graph (ir_graph *irg, const char *suffix)
+/* Dump a firm graph without explicit block nodes. */
+void dump_ir_block_graph (ir_graph *irg, const char *suffix)
{
FILE *f;
int i;
char *suffix1;
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
if (get_interprocedural_view()) suffix1 = "-ip";
construct_block_lists(irg);
+ /*
+ * If we are in the interprocedural view, we dump not
+ * only the requested irg but also all irgs that can be reached
+ * from irg.
+ */
for (i = 0; i < get_irp_n_irgs(); i++) {
ir_node **arr = ird_get_irg_link(get_irp_irg(i));
if (arr) {
vcg_close(f);
}
-/** dumps a graph with type information */
+/* Dump a firm graph without explicit block nodes but grouped in extended blocks. */
+void dump_ir_extblock_graph (ir_graph *irg, const char *suffix)
+{
+ FILE *F;
+ int i;
+ char *suffix1;
+
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
+ return;
+
+ compute_extbb(irg);
+
+ if (get_interprocedural_view()) suffix1 = "-ip";
+ else suffix1 = "";
+ F = vcg_open(irg, suffix, suffix1);
+ dump_vcg_header(F, get_irg_dump_name(irg), NULL);
+
+ construct_extblock_lists(irg);
+
+ fprintf(F, "graph: { title: \"");
+ PRINT_IRGID(irg);
+ fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
+ get_ent_dump_name(get_irg_entity(irg)));
+
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_graph *irg = get_irp_irg(i);
+ list_tuple *lists = ird_get_irg_link(irg);
+
+ if (lists) {
+ /* dump the extended blocks first */
+ if (ARR_LEN(lists->extbb_list)) {
+ ird_set_irg_link(irg, lists->extbb_list);
+ dump_extblock_graph(F, irg);
+ }
+
+ /* we may have blocks without extended blocks, bad for instance */
+ if (ARR_LEN(lists->blk_list)) {
+ ird_set_irg_link(irg, lists->blk_list);
+ dump_block_graph(F, irg);
+ }
+
+ DEL_ARR_F(lists->extbb_list);
+ DEL_ARR_F(lists->blk_list);
+ xfree(lists);
+ }
+ }
+
+ /* Close the vcg information for the irg */
+ fprintf(F, "}\n\n");
+
+ vcg_close(F);
+ free_extbb(irg);
+}
+
+/* dumps a graph with type information */
void
dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
{
char *suffix1;
/* if a filter is set, dump only the irg's that match the filter */
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
current_ir_graph = irg;
ir_graph *rem = current_ir_graph;
/* if a filter is set, dump only the irg's that match the filter */
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
PRINT_NODEID(block);
fprintf (F, "\" ");
fprintf(F, "info1:\"");
- if (dump_dominator_information_flag)
+
+#if 0
+ if (dump_dominator_information_flag) {
fprintf(F, "dom depth %d\n", get_Block_dom_depth(block));
+ fprintf(F, "tree pre num %d\n", get_Block_dom_tree_pre_num(block));
+ fprintf(F, "max subtree pre num %d\n", get_Block_dom_max_subtree_pre_num(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, "Bad pred at pos: ");
+ fprintf(F, "%d ", i);
+ fl = 1;
}
}
if (fl)
fprintf(F, "\n");
+#else
+ /* the generic version. */
+ dump_irnode_to_file(F, block);
+
+ /* Check whether we have bad predecessors to color the block. */
+ for (i = 0; i < get_Block_n_cfgpreds(block); ++i)
+ if ((fl = is_Bad(get_Block_cfgpred(block, i))))
+ break;
+#endif
fprintf (F, "\""); /* closing quote of info */
int ipv = get_interprocedural_view();
/* if a filter is set, dump only the irg's that match the filter */
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
return;
current_ir_graph = irg;
rem = current_ir_graph;
/* if a filter is set, dump only the irg's that match the filter */
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) return;
current_ir_graph = irg;
else
fprintf(F, "\n");
- bad |= dump_node_opcode(F, n);
- bad |= dump_node_mode(F, n);
- bad |= dump_node_typeinfo(F, n);
- fprintf (F, " ");
- bad |= dump_node_nodeattr(F, n);
- fprintf (F, " %ld", get_irn_node_nr(n));
+ bad |= dump_node_label(F, n);
/* Causes indeterministic output: if (is_Block(n)) fprintf (F, "\t ->%d", (int)get_irn_link(n)); */
if (has_backedges(n)) fprintf(F, "\t loop head!");
} else { /* for callgraph loop tree */
edge_label = 1;
/* if a filter is set, dump only the irg's that match the filter */
- if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0)
- return;
+ if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) return;
current_ir_graph = irg;