X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firdump.c;h=ee522391718af4ecae7b2f614bd7adb3f97fce27;hb=421e6e10c6cc98ade95167db91059f335497add8;hp=5f2c0d74b54e2ddbb9aa68de7b55d9a5828fb94a;hpb=59d00792290a0fc2d8b570ffb791ab2cf43c5600;p=libfirm diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 5f2c0d74b..ee5223917 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -23,11 +23,11 @@ #include "firm_common_t.h" -#include "irnode_t.h" -#include "irgraph_t.h" +#include "irnode.h" +#include "irgraph.h" #include "irprog_t.h" #include "entity_t.h" -#include "irop_t.h" +#include "irop.h" #include "irdump_t.h" @@ -41,6 +41,7 @@ #include "callgraph.h" #include "irextbb_t.h" #include "dbginfo_t.h" +#include "irtools.h" #include "irvrfy.h" @@ -67,6 +68,141 @@ static ident *dump_file_filter_id = NULL; #define ERROR_TXT "" +/*******************************************************************/ +/* 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; +int opt_dump_analysed_type_info = 1; +int opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */ + +static dumper_colors overrule_nodecolor = ird_color_default; + +/** 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 int get_opt_dump_const_local(void) { + if (!dump_out_edge_flag && !dump_loop_information_flag) + return dump_const_local; + else + return 0; +} + +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 non-zero 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(int flag) { + dump_const_local = flag; +} + +void dump_constant_entity_values(int flag) { + const_entities = flag; +} + +void dump_keepalive_edges(int flag) { + dump_keepalive = flag; +} + +int get_opt_dump_keepalive_edges(void) { + return dump_keepalive; +} + +void dump_out_edges(int flag) { + dump_out_edge_flag = flag; +} + +void dump_dominator_information(int flag) { + dump_dominator_information_flag = flag; +} + +void dump_loop_information(int flag) { + dump_loop_information_flag = flag; +} + +void dump_backedge_information(int flag) { + dump_backedge_information_flag = flag; +} + +/* 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(int flag) { + opt_dump_analysed_type_info = flag; +} + +void dump_pointer_values_to_info(int flag) { + opt_dump_pointer_values_to_info = flag; +} + +void dump_ld_names(int flag) { + dump_ld_name = flag; +} + +/* -------------- some extended helper functions ----------------- */ + /** * returns the name of a mode or if mode is NOT a mode object. * in the later case, sets bad @@ -91,6 +227,25 @@ const char *get_type_name_ex(type *tp, int *bad) return ERROR_TXT; } +/** + * printf the VCG color + */ +static void print_vcg_color(FILE *F, dumper_colors color) { + static const char *color_names[32] = { + "white", "blue", "red", "green", + "yellow", "magenta", "cyan", "darkgray", + "darkblue", "darkred", "darkgreen", "darkyellow", + "darkmagenta", "darkcyan", "gold", "lightgray", + "lightblue", "lightred", "lightgreen", "lightyellow", + "lightmagenta", "lightcyan", "lilac", "turquoise", + "aquamarine", "khaki", "purple", "yellowgreen", + "pink", "orange", "orchid", "black" + }; + + if (color != ird_color_default) + fprintf(F, "color:%s", color_names[color]); +} + /** * prints the edge from a type S to a type T with additional info fmt, ... * to the file F @@ -271,7 +426,8 @@ static void *ird_get_irn_link(ir_node *n) { * 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); } @@ -303,21 +459,31 @@ static void clear_link(ir_node * node, void * env) { } /** - * 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 ""; - /* 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); } /** @@ -377,7 +543,7 @@ static ir_node **construct_block_lists(ir_graph *irg) { irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph); /* Collect also EndReg and EndExcept. We do not want to change the walker. */ - set_interprocedural_view(false); + set_interprocedural_view(0); set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1); irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph); @@ -430,121 +596,6 @@ static list_tuple *construct_extblock_lists(ir_graph *irg) { 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. */ /*-----------------------------------------------------------------*/ @@ -552,12 +603,17 @@ void dump_pointer_values_to_info(bool b) { /* * dump the name of a node n to the File F. */ -int -dump_node_opcode(FILE *F, ir_node *n) +int dump_node_opcode(FILE *F, ir_node *n) { int bad = 0; + const ir_op_ops *ops = get_op_ops(get_irn_op(n)); + + /* call the dump_node operation if available */ + if (ops->dump_node) + return ops->dump_node(n, F, dump_node_opcode_txt); - switch(get_irn_opcode(n)) { + /* implementation for default nodes */ + switch (get_irn_opcode(n)) { case iro_Const: { int res; @@ -627,11 +683,13 @@ dump_node_opcode(FILE *F, ir_node *n) 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: default_case: fprintf (F, "%s", get_irn_opname(n)); - } } /* end switch */ return bad; @@ -641,12 +699,18 @@ default_case: * Dump the mode of a node n to a file F. * Ignore modes that are "always known". */ -static INLINE int -dump_node_mode(FILE *F, ir_node *n) +static int dump_node_mode(FILE *F, ir_node *n) { int bad = 0; - opcode iro = get_irn_opcode(n); + const ir_op_ops *ops = get_op_ops(get_irn_op(n)); + opcode iro; + + /* call the dump_node operation if available */ + if (ops->dump_node) + return ops->dump_node(n, F, dump_node_mode_txt); + /* default implementation */ + iro = get_irn_opcode(n); switch (iro) { case iro_SymConst: case iro_Sel: @@ -688,45 +752,196 @@ static int dump_node_typeinfo(FILE *F, ir_node *n) { return bad; } +typedef struct _pns_lookup { + long nr; /**< the proj number */ + const char *name; /**< the name of the Proj */ +} pns_lookup_t; + +typedef struct _proj_lookup { + opcode code; /**< the opcode of the Proj predecessor */ + unsigned num_data; /**< number of data entries */ + const pns_lookup_t *data; /**< the data */ +} proj_lookup_t; + +#define ARR_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** the lookup table for Proj(Start) names */ +static const pns_lookup_t start_lut[] = { +#define X(a) { pn_Start_##a, #a } + X(X_initial_exec), + X(P_frame_base), + X(P_globals), + X(T_args), + X(P_value_arg_base) +#undef X +}; + +/** the lookup table for Proj(Cond) names */ +static const pns_lookup_t cond_lut[] = { +#define X(a) { pn_Cond_##a, #a } + X(false), + X(true) +#undef X +}; + +/** the lookup table for Proj(Call) names */ +static const pns_lookup_t call_lut[] = { +#define X(a) { pn_Call_##a, #a } + X(M_regular), + X(T_result), + X(P_value_res_base), + X(X_except), + X(M_except) +#undef X +}; + +/** the lookup table for Proj(Quot) names */ +static const pns_lookup_t quot_lut[] = { +#define X(a) { pn_Quot_##a, #a } + X(M), + X(X_except), + X(res) +#undef X +}; + +/** the lookup table for Proj(DivMod) names */ +static const pns_lookup_t divmod_lut[] = { +#define X(a) { pn_DivMod_##a, #a } + X(M), + X(X_except), + X(res_div), + X(res_mod) +#undef X +}; + +/** the lookup table for Proj(Div) names */ +static const pns_lookup_t div_lut[] = { +#define X(a) { pn_Div_##a, #a } + X(M), + X(X_except), + X(res) +#undef X +}; + +/** the lookup table for Proj(Mod) names */ +static const pns_lookup_t mod_lut[] = { +#define X(a) { pn_Mod_##a, #a } + X(M), + X(X_except), + X(res) +#undef X +}; + +/** the lookup table for Proj(Load) names */ +static const pns_lookup_t load_lut[] = { +#define X(a) { pn_Load_##a, #a } + X(M), + X(X_except), + X(res) +#undef X +}; + +/** the lookup table for Proj(Store) names */ +static const pns_lookup_t store_lut[] = { +#define X(a) { pn_Store_##a, #a } + X(M), + X(X_except) +#undef X +}; + +/** the lookup table for Proj(Alloc) names */ +static const pns_lookup_t alloc_lut[] = { +#define X(a) { pn_Alloc_##a, #a } + X(M), + X(X_except), + X(res) +#undef X +}; + + +/** the Proj lookup table */ +static const proj_lookup_t proj_lut[] = { +#define E(a) ARR_SIZE(a), a + { iro_Start, E(start_lut) }, + { iro_Cond, E(cond_lut) }, + { iro_Call, E(call_lut) }, + { iro_Quot, E(quot_lut) }, + { iro_DivMod, E(divmod_lut) }, + { iro_Div, E(div_lut) }, + { iro_Mod, E(mod_lut) }, + { iro_Load, E(load_lut) }, + { iro_Store, E(store_lut) }, + { iro_Alloc, E(alloc_lut) } +#undef E +}; + /** * Dump additional node attributes of some nodes to a file F. */ -static INLINE int +static int dump_node_nodeattr(FILE *F, ir_node *n) { int bad = 0; ir_node *pred; + opcode code; + long proj_nr; + const ir_op_ops *ops = get_op_ops(get_irn_op(n)); + + /* call the dump_node operation if available */ + if (ops->dump_node) + return ops->dump_node(n, F, dump_node_nodeattr_txt); switch (get_irn_opcode(n)) { case iro_Start: - if (false && get_interprocedural_view()) { + if (0 && get_interprocedural_view()) { fprintf (F, "%s ", get_ent_dump_name(get_irg_entity(current_ir_graph))); } break; + case iro_Proj: - pred = get_Proj_pred(n); + pred = get_Proj_pred(n); + proj_nr = get_Proj_proj(n); +handle_lut: + code = get_irn_opcode(pred); - if (get_irn_opcode(pred) == iro_Cmp) + if (code == iro_Cmp) fprintf (F, "%s ", get_pnc_string(get_Proj_proj(n))); - else if (get_irn_opcode(pred) == iro_Start) { - switch (get_Proj_proj(n)) { - case pn_Start_P_frame_base: - fprintf (F, "FrameBase "); break; - case pn_Start_P_globals: - fprintf (F, "GlobalBase "); break; - case pn_Start_P_value_arg_base: - fprintf (F, "ValueBase "); break; - default: - fprintf (F, "%ld ", get_Proj_proj(n)); + else if (code == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start) + fprintf (F, "Arg %ld ", proj_nr); + else { + unsigned i, j, f = 0; + + for (i = 0; i < ARR_SIZE(proj_lut); ++i) { + if (code == proj_lut[i].code) { + for (j = 0; j < proj_lut[i].num_data; ++j) { + if (proj_nr == proj_lut[i].data[j].nr) { + fprintf (F, "%s ", proj_lut[i].data[j].name); + f = 1; + break; + } + } + break; + } + } + 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 "); } } - else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start) - fprintf (F, "Arg %ld ", get_Proj_proj(n)); - else - fprintf (F, "%ld ", get_Proj_proj(n)); break; case iro_Filter: - fprintf (F, "%ld ", get_Filter_proj(n)); + proj_nr = get_Filter_proj(n); + if (! get_interprocedural_view()) { + /* it's a Proj' */ + pred = get_Filter_pred(n); + goto handle_lut; + } + else + fprintf (F, "%ld ", proj_nr); break; case iro_Sel: fprintf (F, "%s ", get_ent_dump_name(get_Sel_entity(n))); @@ -737,6 +952,9 @@ dump_node_nodeattr(FILE *F, ir_node *n) case iro_Confirm: fprintf (F, "%s ", get_pnc_string(get_Confirm_cmp(n))); break; + case iro_CopyB: + fprintf (F, "(%s) ", get_type_name_ex(get_CopyB_type(n), &bad)); + break; default: ; @@ -784,7 +1002,7 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) ir_node *n; if (bad) { - fprintf(F, "color: red"); + print_vcg_color(F, ird_color_red); return; } @@ -794,6 +1012,11 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) n = local ? local : node; + if (overrule_nodecolor != ird_color_default) { + print_vcg_color(F, overrule_nodecolor); + return; + } + switch (get_irn_opcode(n)) { case iro_Start: case iro_EndReg: @@ -801,28 +1024,26 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) case iro_EndExcept: /* fall through */ case iro_End: - fprintf (F, "color: blue"); + print_vcg_color(F, ird_color_blue); break; case iro_Block: if (is_Block_dead(n)) - fprintf (F, "color: lightred"); + print_vcg_color(F, ird_color_lightred); else - fprintf (F, "color: lightyellow"); + print_vcg_color(F, ird_color_lightyellow); break; case iro_Phi: - fprintf (F, "color: green"); + print_vcg_color(F, ird_color_green); break; case iro_Const: case iro_Proj: case iro_Filter: case iro_Tuple: - fprintf (F, "color: yellow"); + print_vcg_color(F, ird_color_yellow); break; default: PRINT_DEFAULT_NODE_ATTR; } - - if (overrule_nodecolor) fprintf(F, " color: %s", overrule_nodecolor); } @@ -830,10 +1051,17 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) * Dump the node information of a node n to a file F. */ static INLINE int dump_node_info(FILE *F, ir_node *n) -{ int bad = 0; +{ + int bad = 0; + const ir_op_ops *ops = get_op_ops(get_irn_op(n)); + fprintf (F, " info1: \""); bad = dump_irnode_to_file(F, n); + /* call the dump_node operation if available */ + if (ops->dump_node) + bad = ops->dump_node(n, F, dump_node_info_txt); fprintf(F, "\"\n"); + return bad; } @@ -841,7 +1069,7 @@ static INLINE int dump_node_info(FILE *F, ir_node *n) * checks whether a node is "constant-like" ie can be treated "block-less" */ static INLINE -bool is_constlike_node(ir_node *n) { +int is_constlike_node(ir_node *n) { ir_op *op = get_irn_op(n); return (op == op_Const || op == op_Bad || op == op_NoMem || op == op_SymConst || op == op_Unknown); } @@ -904,6 +1132,19 @@ static void dump_const_block_local(FILE *F, ir_node *n) { 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"); } } @@ -922,14 +1163,14 @@ static void INLINE print_node_error(FILE *F, const char *err_msg) /** * prints debug messages of a node to file F as info3. */ -static void print_node_dbg_info(FILE *F, dbg_info *dbg) +static void print_dbg_info(FILE *F, dbg_info *dbg) { char buf[1024]; 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); } } @@ -954,7 +1195,7 @@ static void dump_node(FILE *F, ir_node *n) fprintf(F, "\" "); bad |= dump_node_info(F, n); print_node_error(F, p); - print_node_dbg_info(F, get_irn_dbg_info(n)); + print_dbg_info(F, get_irn_dbg_info(n)); dump_node_vcgattr(F, n, NULL, bad); fprintf(F, "}\n"); dump_const_node_local(F, n); @@ -982,6 +1223,19 @@ dump_ir_block_edge(FILE *F, ir_node *n) { 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"); } } @@ -989,10 +1243,10 @@ dump_ir_block_edge(FILE *F, ir_node *n) { static void print_data_edge_vcgattr(FILE *F, ir_node *from, int to) { - /* - * do not use get_nodes_block() here, will fail - * if the irg is not pinned. - */ + /* + * do not use get_nodes_block() here, will fail + * if the irg is not pinned. + */ if (get_irn_n(from, -1) == get_irn_n(get_irn_n(from, to), -1)) fprintf (F, INTRA_DATA_EDGE_ATTR); else @@ -1001,10 +1255,10 @@ print_data_edge_vcgattr(FILE *F, ir_node *from, int to) { static void print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) { - /* - * do not use get_nodes_block() here, will fail - * if the irg is not pinned. - */ + /* + * do not use get_nodes_block() here, will fail + * if the irg is not pinned. + */ if (get_irn_n(from, -1) == get_irn_n(get_irn_n(from, to), -1)) fprintf (F, INTRA_MEM_EDGE_ATTR); else @@ -1015,6 +1269,10 @@ static void 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); @@ -1221,6 +1479,8 @@ static void dump_const_expression(FILE *F, ir_node *value) { static void dump_whole_block(FILE *F, ir_node *block) { ir_node *node; + dumper_colors color = ird_color_yellow; + assert(is_Block(block)); fprintf(F, "graph: { title: \""); @@ -1231,8 +1491,20 @@ dump_whole_block(FILE *F, ir_node *block) { 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 = ird_color_red; + if (is_Block_dead(block)) + color = ird_color_orange; + + fprintf(F, "\" status:clustered "); + print_vcg_color(F, color); + fprintf(F, "\n"); + + /* yComp can show attributes for blocks, XVCG parses but ignores them */ + dump_node_info(F, block); + print_dbg_info(F, get_irn_dbg_info(block)); /* dump the blocks edges */ dump_ir_data_edges(F, block); @@ -1283,15 +1555,29 @@ dump_block_graph(FILE *F, ir_graph *irg) { current_ir_graph = rem; } +/** + * Dump the info for an irg. + * Parsed by XVCG but not shown. use yComp. + */ +static void dump_graph_info(FILE *F, ir_graph *irg) { + fprintf(F, "info1: \""); + dump_entity_to_file(F, get_irg_entity(irg), dump_verbosity_entattrs | dump_verbosity_entconsts); + fprintf(F, "\"\n"); +} + /** 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) { + entity *ent = get_irg_entity(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))); + get_ent_dump_name(ent)); + + dump_graph_info(F, irg); + print_dbg_info(F, get_entity_dbg_info(ent)); dump_block_graph(F, irg); @@ -1311,7 +1597,7 @@ dump_extblock_graph(FILE *F, 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]; + ir_node *leader = get_extbb_leader(extbb); int j; fprintf(F, "graph: { title: \""); @@ -1473,8 +1759,7 @@ static void print_typespecific_vcgattr(FILE *F, type *tp) { } -/* 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; @@ -1488,17 +1773,14 @@ static int print_type_node(FILE *F, type *tp) #else dump_type_to_file(F, tp, dump_verbosity_max); #endif - fprintf (F, "\""); + fprintf (F, "\"\n"); + print_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) @@ -1509,14 +1791,16 @@ void dump_entity_node(FILE *F, entity *ent, int color) fprintf (F, "label: "); fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent)); if (color) - fprintf(F, "color: %d", color); + fprintf(F, "color:%d", color); else fprintf (F, ENTITY_NODE_ATTR); fprintf (F, "\n info1: \""); dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts); - fprintf(F, "\"\n}\n"); + fprintf(F, "\"\n"); + print_dbg_info(F, get_entity_dbg_info(ent)); + fprintf(F, "}\n"); } #undef X @@ -1589,7 +1873,7 @@ dump_type_info(type_or_ent *tore, void *env) { 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: @@ -1691,7 +1975,7 @@ dump_class_hierarchy_node (type_or_ent *tore, void *ctx) { 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++) { @@ -1739,7 +2023,7 @@ static INLINE void dump_loop_info(FILE *F, ir_loop *loop) { 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, "\""); } @@ -1810,7 +2094,7 @@ void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) { /** * 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) { @@ -1938,7 +2222,7 @@ FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) { /** * 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) { @@ -1949,7 +2233,7 @@ 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 @. */ @@ -2019,6 +2303,11 @@ dump_ir_graph (ir_graph *irg, const char *suffix ) 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); @@ -2072,6 +2361,7 @@ void dump_ir_extblock_graph (ir_graph *irg, const char *suffix) FILE *F; int i; char *suffix1; + entity *ent; if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) return; @@ -2080,6 +2370,9 @@ void dump_ir_extblock_graph (ir_graph *irg, const char *suffix) if (get_interprocedural_view()) suffix1 = "-ip"; else suffix1 = ""; + + ent = get_irg_entity(irg); + F = vcg_open(irg, suffix, suffix1); dump_vcg_header(F, get_irg_dump_name(irg), NULL); @@ -2087,8 +2380,11 @@ void dump_ir_extblock_graph (ir_graph *irg, const char *suffix) fprintf(F, "graph: { title: \""); PRINT_IRGID(irg); - fprintf(F, "\" label: \"%s\" status:clustered color:white \n", - get_ent_dump_name(get_irg_entity(irg))); + fprintf(F, "\" label: \"%s\" status:clustered color: white \n", + get_ent_dump_name(ent)); + + dump_graph_info(F, irg); + print_dbg_info(F, get_entity_dbg_info(ent)); for (i = 0; i < get_irp_n_irgs(); i++) { ir_graph *irg = get_irp_irg(i); @@ -2127,12 +2423,16 @@ dump_ir_graph_w_types (ir_graph *irg, const char *suffix) 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"; @@ -2148,6 +2448,7 @@ dump_ir_graph_w_types (ir_graph *irg, const char *suffix) 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; } @@ -2158,11 +2459,16 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix) 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); @@ -2187,8 +2493,9 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix) /* 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; } /*---------------------------------------------------------------------*/ @@ -2198,7 +2505,7 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix) 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)) { @@ -2296,7 +2603,7 @@ dump_cfg (ir_graph *irg, const char *suffix) if (ipv) { printf("Warning: dumping cfg not in interprocedural view!\n"); - set_interprocedural_view(false); + set_interprocedural_view(0); } if (get_irg_dom_state(irg) != dom_consistent) @@ -2412,8 +2719,8 @@ void dump_callgraph(const char *suffix) { int be = is_irg_callee_backedge(irg, j); char *attr; attr = (be) ? - "label:\"recursion %d\" color: %d" : - "label:\"calls %d\" color: %d"; + "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)); } } @@ -2427,7 +2734,7 @@ void dump_all_cg_block_graph(const char *suffix) { FILE *f; int i; int rem_view = get_interprocedural_view(); - set_interprocedural_view(true); + set_interprocedural_view(1); f = vcg_open_name("All_graphs", suffix); dump_vcg_header(f, "All_graphs", NULL); @@ -2492,17 +2799,14 @@ dump_all_types (const char *suffix) } void -dump_class_hierarchy (bool entities, const char *suffix) +dump_class_hierarchy (int entities, const char *suffix) { FILE *f = vcg_open_name("class_hierarchy", suffix); h_env_t env; - env.f = f; + env.f = f; + env.dump_ent = entities; dump_vcg_header(f, "class_hierarchy", NULL); - if (entities) - env.dump_ent = 1; - else - env.dump_ent = 0; type_walk(dump_class_hierarchy_node, NULL, &env); vcg_close(f); } @@ -2517,8 +2821,8 @@ dump_class_hierarchy (bool entities, const char *suffix) /*---------------------------------------------------------------------*/ void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) { - int i, n_irgs = get_irp_n_irgs(); - for (i = 0; i < n_irgs; ++i) { + int i; + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { dmp_grph(get_irp_irg(i), suffix); } } @@ -2734,9 +3038,10 @@ void dump_loop(ir_loop *l, const char *suffix) { /* dump the nodes that go into the block */ for (n = get_irn_link(b); n; n = get_irn_link(n)) { - if (eset_contains(extnodes, n)) overrule_nodecolor = "lightblue"; + if (eset_contains(extnodes, n)) + overrule_nodecolor = ird_color_lightblue; dump_node(F, n); - overrule_nodecolor = NULL; + overrule_nodecolor = ird_color_default; if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n); } @@ -2756,9 +3061,10 @@ void dump_loop(ir_loop *l, const char *suffix) { /* dump the nodes that go into the block */ for (n = get_irn_link(b); n; n = get_irn_link(n)) { - if (!eset_contains(loopnodes, n)) overrule_nodecolor = "lightblue"; + if (!eset_contains(loopnodes, n)) + overrule_nodecolor = ird_color_lightblue; dump_node(F, n); - overrule_nodecolor = NULL; + overrule_nodecolor = ird_color_default; if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n); }