X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firdump.c;h=f7e2b9ab861a6a1bd8cfea32e71c45a55d8c1316;hb=fed1bdc07c9ec7b4d07a9243ad093c9fdd239fbd;hp=5ed8a48fc33b5c1cfe2be32b4e9f5da7e67e6eb4;hpb=e868bbdae8b0cf35ca72c382ae022116af095491;p=libfirm diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 5ed8a48fc..f7e2b9ab8 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,10 +41,11 @@ #include "callgraph.h" #include "irextbb_t.h" #include "dbginfo_t.h" +#include "irtools.h" #include "irvrfy.h" -#include "panic.h" +#include "error.h" #include "array.h" #include "pmap.h" #include "eset.h" @@ -80,43 +81,58 @@ 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; +static int dump_out_edge_flag = 0; +static int dump_loop_information_flag = 0; +static int dump_backedge_information_flag = 1; +static int dump_const_local = 0; +/** An option to dump all graph anchors */ +static int dump_anchors = 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!! */ +int opt_dump_analysed_type_info = 1; +int opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */ -static const char *overrule_nodecolor = NULL; +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_hook = func; } DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void) { - return dump_node_edge_hook; + return dump_node_edge_hook; } -/** The vcg attribute 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 hook */ +/* 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) { +int get_opt_dump_const_local(void) { if (!dump_out_edge_flag && !dump_loop_information_flag) return dump_const_local; else - return false; + return 0; } void only_dump_method_with_name(ident *name) { @@ -127,65 +143,69 @@ 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 +/** 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 offen cause xvcg to +/* 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_consts_local(int flag) { + dump_const_local = flag; } -void dump_constant_entity_values(bool b) { - const_entities = b; +void dump_constant_entity_values(int flag) { + const_entities = flag; } -void dump_keepalive_edges(bool b) { - dump_keepalive = b; +void dump_keepalive_edges(int flag) { + dump_keepalive = flag; } -bool get_opt_dump_keepalive_edges(void) { +int get_opt_dump_keepalive_edges(void) { return dump_keepalive; } -void dump_out_edges(bool b) { - dump_out_edge_flag = b; +void dump_out_edges(int flag) { + dump_out_edge_flag = flag; } -void dump_dominator_information(bool b) { - dump_dominator_information_flag = b; +void dump_dominator_information(int flag) { + dump_dominator_information_flag = flag; } -void dump_loop_information(bool b) { - dump_loop_information_flag = b; +void dump_loop_information(int flag) { + dump_loop_information_flag = flag; } -void dump_backedge_information(bool b) { - dump_backedge_information_flag = b; +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(bool b) { - opt_dump_analysed_type_info = b; +void set_opt_dump_analysed_type_info(int flag) { + opt_dump_analysed_type_info = flag; } -void dump_pointer_values_to_info(bool b) { - opt_dump_pointer_values_to_info = b; +void dump_pointer_values_to_info(int flag) { + opt_dump_pointer_values_to_info = flag; } -void dump_ld_names(bool b) { - dump_ld_name = b; +void dump_ld_names(int flag) { + dump_ld_name = flag; +} + +void dump_all_anchors(int flag) { + dump_anchors = flag; } /* -------------- some extended helper functions ----------------- */ @@ -206,7 +226,7 @@ const char *get_mode_name_ex(ir_mode *mode, int *bad) * returns the name of a type or if mode is NOT a mode object. * in the later case, sets bad */ -const char *get_type_name_ex(type *tp, int *bad) +const char *get_type_name_ex(ir_type *tp, int *bad) { if (is_type(tp)) return get_type_name(tp); @@ -214,11 +234,30 @@ 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 */ -static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...) +static void print_type_type_edge(FILE *F, ir_type *S, ir_type *T, const char *fmt, ...) { va_list ap; @@ -234,7 +273,7 @@ static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ... * prints the edge from a type T to an entity E with additional info fmt, ... * to the file F */ -static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...) +static void print_type_ent_edge(FILE *F, ir_type *T, entity *E, const char *fmt, ...) { va_list ap; @@ -270,7 +309,7 @@ static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, cons * prints the edge from an entity E to a type T with additional info fmt, ... * to the file F */ -static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...) +static void print_ent_type_edge(FILE *F, entity *E, ir_type *T, const char *fmt, ...) { va_list ap; @@ -286,7 +325,7 @@ static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, .. * prints the edge from a node N to a type T with additional info fmt, ... * to the file F */ -static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...) +static void print_node_type_edge(FILE *F, const ir_node *N, ir_type *T, const char *fmt, ...) { va_list ap; @@ -335,7 +374,7 @@ static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char * prints the edge from a type E to an enumeration item item with additional info fmt, ... * to the file F */ -static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...) +static void print_enum_item_edge(FILE *F, ir_type *E, int item, const char *fmt, ...) { va_list ap; @@ -394,7 +433,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); } @@ -461,6 +501,27 @@ static int node_floats(ir_node *n) { (get_irg_pinned(current_ir_graph) == op_pin_state_floats)); } +/** + * Walker that visits the anchors + */ +static void ird_walk_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) { + irg_walk_graph(irg, pre, post, env); + + if (dump_anchors) { + int i; + + for (i = anchor_max - 1; i >= 0; --i) { + ir_node *n = irg->anchors[i]; + + if (n) { + /* reset the visit flag: will be increase in the walker */ + set_irg_visited(irg, get_irg_visited(irg) - 1); + irg_walk(n, pre, post, env); + } + } + } +} + /** * Walker, allocates an array for all blocks and puts it's nodes non-floating nodes into this array. */ @@ -504,13 +565,13 @@ static ir_node **construct_block_lists(ir_graph *irg) { ir_graph *rem = current_ir_graph; current_ir_graph = irg; - for (i = 0; i < get_irp_n_irgs(); i++) + for (i = get_irp_n_irgs() - 1; i >= 0; --i) ird_set_irg_link(get_irp_irg(i), NULL); - irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph); + ird_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); @@ -528,8 +589,10 @@ typedef struct _list_tuple { ir_extblk **extbb_list; } list_tuple; -/** Construct lists to walk ir extended block-wise. +/** Construct lists to walk IR extended block-wise. * Free the lists in the tuple with DEL_ARR_F(). + * Sets the irg link field to NULL in all + * graphs not visited. */ static list_tuple *construct_extblock_lists(ir_graph *irg) { ir_node **blk_list = construct_block_lists(irg); @@ -542,6 +605,7 @@ static list_tuple *construct_extblock_lists(ir_graph *irg) { lists->blk_list = NEW_ARR_F(ir_node *, 0); lists->extbb_list = NEW_ARR_F(ir_extblk *, 0); + inc_irg_block_visited(irg); for (i = ARR_LEN(blk_list) - 1; i >= 0; --i) { ir_extblk *ext; @@ -556,9 +620,9 @@ static list_tuple *construct_extblock_lists(ir_graph *irg) { else ARR_APP1(ir_node *, lists->blk_list, blk_list[i]); } + DEL_ARR_F(blk_list); current_ir_graph = rem; - DEL_ARR_F(blk_list); ird_set_irg_link(irg, lists); return lists; } @@ -570,12 +634,17 @@ static list_tuple *construct_extblock_lists(ir_graph *irg) { /* * 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)); - switch(get_irn_opcode(n)) { + /* call the dump_node operation if available */ + if (ops->dump_node) + return ops->dump_node(n, F, dump_node_opcode_txt); + + /* implementation for default nodes */ + switch (get_irn_opcode(n)) { case iro_Const: { int res; @@ -645,11 +714,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; @@ -659,12 +730,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: @@ -696,7 +773,7 @@ static int dump_node_typeinfo(FILE *F, ir_node *n) { if (opt_dump_analysed_type_info) { 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); + ir_type *tp = get_irn_typeinfo_type(n); if (tp != firm_none_type) fprintf(F, "[%s] ", get_type_name_ex(tp, &bad)); else @@ -812,6 +889,42 @@ static const pns_lookup_t alloc_lut[] = { #undef X }; +/** the lookup table for Proj(CopyB) names */ +static const pns_lookup_t copyb_lut[] = { +#define X(a) { pn_CopyB_##a, #a } + X(M), + X(X_except), + X(M_except) +#undef X +}; + +/** the lookup table for Proj(InstOf) names */ +static const pns_lookup_t instof_lut[] = { +#define X(a) { pn_InstOf_##a, #a } + X(M), + X(X_except), + X(res), + X(M_except), +#undef X +}; + +/** the lookup table for Proj(Raise) names */ +static const pns_lookup_t raise_lut[] = { +#define X(a) { pn_Raise_##a, #a } + X(M), + X(X), +#undef X +}; + +/** the lookup table for Proj(Bound) names */ +static const pns_lookup_t bound_lut[] = { +#define X(a) { pn_Bound_##a, #a } + X(M), + X(X_except), + X(res), + X(M_except) +#undef X +}; /** the Proj lookup table */ static const proj_lookup_t proj_lut[] = { @@ -825,24 +938,33 @@ static const proj_lookup_t proj_lut[] = { { iro_Mod, E(mod_lut) }, { iro_Load, E(load_lut) }, { iro_Store, E(store_lut) }, - { iro_Alloc, E(alloc_lut) } + { iro_Alloc, E(alloc_lut) }, + { iro_CopyB, E(copyb_lut) }, + { iro_InstOf, E(instof_lut) }, + { iro_Raise, E(raise_lut) }, + { iro_Bound, E(bound_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; @@ -857,6 +979,8 @@ handle_lut: fprintf (F, "%s ", get_pnc_string(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 if (code == iro_Cond && get_irn_mode(get_Cond_selector(pred)) != mode_b) + fprintf (F, "%ld ", proj_nr); else { unsigned i, j, f = 0; @@ -874,6 +998,12 @@ handle_lut: } 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: @@ -895,6 +1025,9 @@ handle_lut: 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: ; @@ -942,7 +1075,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; } @@ -952,6 +1085,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: @@ -959,28 +1097,30 @@ 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_Mux: + case iro_Psi: + print_vcg_color(F, ird_color_gold); 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); } @@ -988,10 +1128,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; } @@ -999,7 +1146,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); } @@ -1062,6 +1209,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"); } } @@ -1080,7 +1240,7 @@ 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]; @@ -1112,7 +1272,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); @@ -1140,6 +1300,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"); } } @@ -1147,10 +1320,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 @@ -1159,10 +1332,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 @@ -1173,6 +1346,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); @@ -1180,7 +1357,7 @@ print_edge_vcgattr(FILE *F, ir_node *from, int to) { case iro_Block: fprintf (F, CF_EDGE_ATTR); break; - case iro_Start: break; + case iro_Start: break; case iro_End: if (to >= 0) { if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB) @@ -1189,108 +1366,21 @@ print_edge_vcgattr(FILE *F, ir_node *from, int to) { fprintf (F, INTER_MEM_EDGE_ATTR); } break; - case iro_EndReg: - case iro_EndExcept: - case iro_Jmp: - case iro_Break: - case iro_Cond: - print_data_edge_vcgattr(F, from, to); - break; - case iro_Return: - case iro_Raise: - if (to == 0) - print_mem_edge_vcgattr(F, from, to); - else - print_data_edge_vcgattr(F, from, to); - break; - case iro_Const: - case iro_SymConst: - print_data_edge_vcgattr(F, from, to); - break; - case iro_Sel: - case iro_Call: - if (to == 0) - print_mem_edge_vcgattr(F, from, to); - else - print_data_edge_vcgattr(F, from, to); - break; - case iro_CallBegin: - case iro_Add: - case iro_Sub: - case iro_Minus: - case iro_Mul: - print_data_edge_vcgattr(F, from, to); - break; - case iro_Quot: - case iro_DivMod: - case iro_Div: - case iro_Mod: - if (to == 0) - print_mem_edge_vcgattr(F, from, to); - else - print_data_edge_vcgattr(F, from, to); - break; - case iro_Abs: - case iro_And: - case iro_Or: - case iro_Eor: - case iro_Shl: - case iro_Shr: - case iro_Shrs: - case iro_Rot: - case iro_Cmp: - case iro_Conv: - print_data_edge_vcgattr(F, from, to); - break; - case iro_Phi: - if (get_irn_modecode(from) == irm_M) - fprintf (F, INTER_MEM_EDGE_ATTR); - else - print_data_edge_vcgattr(F, from, to); - break; - case iro_Load: - case iro_Store: - case iro_Alloc: - case iro_Free: - if (to == 0) - print_mem_edge_vcgattr(F, from, to); - else - print_data_edge_vcgattr(F, from, to); - break; - case iro_Sync: - print_mem_edge_vcgattr(F, from, to); - break; - case iro_Tuple: break; - case iro_Proj: - case iro_Filter: - switch (get_irn_modecode(from)) { - case irm_X: - fprintf (F, CF_EDGE_ATTR); - break; - case irm_M: - fprintf (F, INTER_MEM_EDGE_ATTR); - break; - default: - print_data_edge_vcgattr(F, from, to); - break; + default: + if (is_Proj(from)) { + if (get_irn_mode(from) == mode_M) + print_mem_edge_vcgattr(F, from, to); + else if (get_irn_mode(from) == mode_X) + fprintf(F, CF_EDGE_ATTR); + else + print_data_edge_vcgattr(F, from, to); } - break; - case iro_Bad: break; - case iro_Unknown: break; - case iro_Id: - switch (get_irn_modecode(from)) { - case irm_M: - fprintf (F, INTRA_MEM_EDGE_ATTR); - break; - case irm_X: + else if (get_irn_mode(get_irn_n(from, to)) == mode_M) + print_mem_edge_vcgattr(F, from, to); + else if (get_irn_mode(get_irn_n(from, to)) == mode_X) fprintf (F, CF_EDGE_ATTR); - break; - default: + else print_data_edge_vcgattr(F, from, to); - break; - } break; - default: - ; } } @@ -1379,6 +1469,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: \""); @@ -1389,8 +1481,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); @@ -1441,15 +1545,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); @@ -1466,10 +1584,9 @@ dump_extblock_graph(FILE *F, ir_graph *irg) { 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]; + ir_node *leader = get_extbb_leader(extbb); int j; fprintf(F, "graph: { title: \""); @@ -1545,7 +1662,7 @@ static void dump_node2type_edges(ir_node *n, void *env) } #if 0 -static int print_type_info(FILE *F, type *tp) { +static int print_type_info(FILE *F, ir_type *tp) { int bad = 0; if (get_type_state(tp) == layout_undefined) { @@ -1560,7 +1677,7 @@ static int print_type_info(FILE *F, type *tp) { return bad; } -static void print_typespecific_info(FILE *F, type *tp) { +static void print_typespecific_info(FILE *F, ir_type *tp) { switch (get_type_tpop_code(tp)) { case tpo_class: { @@ -1595,7 +1712,7 @@ static void print_typespecific_info(FILE *F, type *tp) { } #endif -static void print_typespecific_vcgattr(FILE *F, type *tp) { +static void print_typespecific_vcgattr(FILE *F, ir_type *tp) { switch (get_type_tpop_code(tp)) { case tpo_class: { @@ -1631,7 +1748,7 @@ static void print_typespecific_vcgattr(FILE *F, type *tp) { } -int dump_type_node(FILE *F, type *tp) +int dump_type_node(FILE *F, ir_type *tp) { int bad = 0; @@ -1646,7 +1763,7 @@ int dump_type_node(FILE *F, type *tp) dump_type_to_file(F, tp, dump_verbosity_max); #endif fprintf (F, "\"\n"); - print_node_dbg_info(F, get_type_dbg_info(tp)); + print_dbg_info(F, get_type_dbg_info(tp)); print_typespecific_vcgattr(F, tp); fprintf (F, "}\n"); @@ -1663,7 +1780,7 @@ 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: \""); @@ -1671,12 +1788,12 @@ 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"); - print_node_dbg_info(F, get_entity_dbg_info(ent)); + print_dbg_info(F, get_entity_dbg_info(ent)); fprintf(F, "}\n"); } #undef X -static void dump_enum_item(FILE *F, type *tp, int pos) +static void dump_enum_item(FILE *F, ir_type *tp, int pos) { char buf[1024]; ident *id = get_enumeration_nameid(tp, pos); @@ -1744,7 +1861,7 @@ dump_type_info(type_or_ent *tore, void *env) { } break; case k_type: { - type *tp = (type *)tore; + ir_type *tp = (ir_type *)tore; dump_type_node(F, tp); /* and now the edges */ switch (get_type_tpop_code(tp)) { @@ -1843,7 +1960,7 @@ dump_class_hierarchy_node (type_or_ent *tore, void *ctx) { } break; /* case k_entity */ case k_type: { - type *tp = (type *)tore; + ir_type *tp = (ir_type *)tore; if (tp == get_glob_type()) break; switch (get_type_tpop_code(tp)) { case tpo_class: { @@ -1895,7 +2012,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, "\""); } @@ -1986,13 +2103,7 @@ void dump_vcg_header(FILE *F, const char *name, const char *orientation) { "port_sharing: no\n" "orientation: %s\n" "classname 1: \"intrablock Data\"\n" - "classname 16: \"interblock Data\"\n" "classname 2: \"Block\"\n" - "classname 13: \"Control Flow\"\n" - "classname 18: \"Exception Control Flow for Interval Analysis\"\n" - "classname 14: \"intrablock Memory\"\n" - "classname 17: \"interblock Memory\"\n" - "classname 15: \"Dominators\"\n" "classname 3: \"Entity type\"\n" "classname 4: \"Entity owner\"\n" "classname 5: \"Method Param\"\n" @@ -2003,6 +2114,13 @@ void dump_vcg_header(FILE *F, const char *name, const char *orientation) { "classname 10: \"Array Element Type\"\n" "classname 11: \"Overwrites\"\n" "classname 12: \"Member\"\n" + "classname 13: \"Control Flow\"\n" + "classname 14: \"intrablock Memory\"\n" + "classname 15: \"Dominators\"\n" + "classname 16: \"interblock Data\"\n" + "classname 17: \"interblock Memory\"\n" + "classname 18: \"Exception Control Flow for Interval Analysis\"\n" + "classname 19: \"Postdominators\"\n" "infoname 1: \"Attribute\"\n" "infoname 2: \"Verification errors\"\n" "infoname 3: \"Debug info\"\n", @@ -2175,9 +2293,14 @@ 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); + ird_walk_graph(irg, NULL, dump_whole_node, f); /* dump the out edges in a separate walk */ if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) { @@ -2211,7 +2334,7 @@ void dump_ir_block_graph (ir_graph *irg, const char *suffix) * only the requested irg but also all irgs that can be reached * from irg. */ - for (i = 0; i < get_irp_n_irgs(); i++) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_node **arr = ird_get_irg_link(get_irp_irg(i)); if (arr) { dump_graph_from_list(f, get_irp_irg(i)); @@ -2228,14 +2351,19 @@ 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; - compute_extbb(irg); + if (get_irg_extblk_state(irg) != extblk_valid) + compute_extbb(irg); 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); @@ -2243,10 +2371,13 @@ 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++) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_graph *irg = get_irp_irg(i); list_tuple *lists = ird_get_irg_link(irg); @@ -2337,7 +2468,7 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix) /* dump common blocked ir graph */ construct_block_lists(irg); - for (i = 0; i < get_irp_n_irgs(); i++) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_node **arr = ird_get_irg_link(get_irp_irg(i)); if (arr) { dump_graph_from_list(f, get_irp_irg(i)); @@ -2382,27 +2513,6 @@ dump_block_to_cfg(ir_node *block, void *env) { fprintf (F, "\" "); fprintf(F, "info1:\""); -#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, "\n"); -#else /* the generic version. */ dump_irnode_to_file(F, block); @@ -2410,7 +2520,6 @@ dump_block_to_cfg(ir_node *block, void *env) { 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 */ @@ -2432,14 +2541,24 @@ dump_block_to_cfg(ir_node *block, void *env) { fprintf (F, "\"}\n"); } - /* Dump dominator edge */ - if (dump_dominator_information_flag && get_Block_idom(block)) { - pred = get_Block_idom(block); - fprintf (F, "edge: { sourcename: \""); - PRINT_NODEID(block); - fprintf (F, "\" targetname: \""); - PRINT_NODEID(pred); - fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n"); + /* Dump dominator/postdominator edge */ + if (dump_dominator_information_flag) { + if (get_irg_dom_state(current_ir_graph) == dom_consistent && get_Block_idom(block)) { + pred = get_Block_idom(block); + fprintf (F, "edge: { sourcename: \""); + PRINT_NODEID(block); + fprintf (F, "\" targetname: \""); + PRINT_NODEID(pred); + fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n"); + } + if (get_irg_postdom_state(current_ir_graph) == dom_consistent && get_Block_ipostdom(block)) { + pred = get_Block_ipostdom(block); + fprintf (F, "edge: { sourcename: \""); + PRINT_NODEID(block); + fprintf (F, "\" targetname: \""); + PRINT_NODEID(pred); + fprintf (F, "\" " POSTDOMINATOR_EDGE_ATTR "}\n"); + } } } } @@ -2449,7 +2568,6 @@ dump_cfg (ir_graph *irg, const char *suffix) { FILE *f; ir_graph *rem = current_ir_graph; - int ddif = dump_dominator_information_flag; int ipv = get_interprocedural_view(); /* if a filter is set, dump only the irg's that match the filter */ @@ -2463,17 +2581,13 @@ 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) - dump_dominator_information_flag = 0; - /* walk over the blocks in the graph */ irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f); dump_node(f, get_irg_bad(irg)); - dump_dominator_information_flag = ddif; set_interprocedural_view(ipv); vcg_close(f); current_ir_graph = rem; @@ -2556,7 +2670,7 @@ static int get_entity_color(entity *ent) { void dump_callgraph(const char *suffix) { FILE *F; - int i, n_irgs = get_irp_n_irgs(); + int i; int rem = edge_label; edge_label = 1; //ident *prefix = new_id_from_str("java/"); @@ -2564,7 +2678,7 @@ void dump_callgraph(const char *suffix) { F = vcg_open_name("Callgraph", suffix); dump_vcg_header(F, "Callgraph", NULL); - for (i = 0; i < n_irgs; ++i) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { ir_graph *irg = get_irp_irg(i); entity *ent = get_irg_entity(irg); int j, n_callees = get_irg_n_callees(irg); @@ -2579,8 +2693,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)); } } @@ -2594,19 +2708,19 @@ 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); /* collect nodes in all irgs reachable in call graph*/ - for (i = 0; i < get_irp_n_irgs(); i++) + for (i = get_irp_n_irgs() - 1; i >= 0; --i) ird_set_irg_link(get_irp_irg(i), NULL); cg_walk(clear_link, collect_node, NULL); /* dump all graphs */ - for (i = 0; i < get_irp_n_irgs(); i++) { + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { current_ir_graph = get_irp_irg(i); assert(ird_get_irg_link(current_ir_graph)); dump_graph_from_list(f, current_ir_graph); @@ -2659,17 +2773,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); } @@ -2684,10 +2795,9 @@ 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); - } } @@ -2901,9 +3011,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); } @@ -2923,9 +3034,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); }