X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firdump.c;h=f7e2b9ab861a6a1bd8cfea32e71c45a55d8c1316;hb=fed1bdc07c9ec7b4d07a9243ad093c9fdd239fbd;hp=ff85cd478343b5126633bc52b95f97ae785de630;hpb=06ef46c37273872f9212e9e844e59dfbd24c6ddf;p=libfirm diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index ff85cd478..f7e2b9ab8 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -6,7 +6,7 @@ * Modified by: Goetz Lindenmaier, Hubert Schmidt * Created: * CVS-ID: $Id$ - * Copyright: (c) 1998-2003 Universität Karlsruhe + * Copyright: (c) 1998-2003 Universit�t Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ #ifdef HAVE_CONFIG_H @@ -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" @@ -37,13 +37,15 @@ #include "type_or_entity.h" #include "irouts.h" #include "irdom.h" -#include "irloop.h" +#include "irloop_t.h" #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" @@ -66,6 +68,148 @@ 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 */ +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 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; +} + +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; +} + +void dump_all_anchors(int flag) { + dump_anchors = 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 @@ -82,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); @@ -90,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; @@ -110,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; @@ -146,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; @@ -162,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; @@ -211,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; @@ -240,12 +403,19 @@ static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg); */ static pmap *irdump_link_map = NULL; -/** Creates the link attribut map. */ +/** NOT A STANDARD LIBFIRM INIT METHOD + * + * We do not want to integrate dumping into libfirm, i.e., if the dumpers + * are off, we want to have as few interferences as possible. Therefore the + * initialization is performed lazily and not called from within init_firm. + * + * Creates the link attribute map. */ static void init_irdump(void) { /* 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(""); + if (!dump_file_filter_id) + dump_file_filter_id = new_id_from_str(""); } /** * Returns the private link field. @@ -263,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); } @@ -295,21 +466,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); } /** @@ -320,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. */ @@ -363,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); @@ -387,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); @@ -401,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; @@ -415,114 +620,13 @@ 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; } -/*******************************************************************/ -/* 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; - -/** 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. */ /*-----------------------------------------------------------------*/ @@ -530,12 +634,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)); - 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; @@ -578,10 +687,6 @@ dump_node_opcode(FILE *F, ir_node *n) && get_Proj_proj(n) == get_Cond_defaultProj(pred) && get_irn_mode(get_Cond_selector(pred)) != mode_b) fprintf (F, "defProj"); -/* - * else if (get_irn_opcode(pred) == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start) - * fprintf (F, "Arg"); - */ else goto default_case; } break; @@ -609,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; @@ -623,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: @@ -660,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 @@ -670,29 +783,238 @@ 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 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[] = { +#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) }, + { 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; + case iro_Proj: - if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) { + pred = get_Proj_pred(n); + proj_nr = get_Proj_proj(n); +handle_lut: + code = get_irn_opcode(pred); + + if (code == iro_Cmp) fprintf (F, "%s ", get_pnc_string(get_Proj_proj(n))); - } else { - 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 if (code == iro_Cond && get_irn_mode(get_Cond_selector(pred)) != mode_b) + fprintf (F, "%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 "); + } } 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))); @@ -703,6 +1025,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: ; @@ -750,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; } @@ -760,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: @@ -767,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); } @@ -796,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; } @@ -807,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); } @@ -870,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"); } } @@ -885,6 +1237,20 @@ static void INLINE print_node_error(FILE *F, const char *err_msg) fprintf (F, " info2: \"%s\"", err_msg); } +/** + * prints debug messages of a node to file F as info3. + */ +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\"\n", buf); + } +} + /** * Dump a node */ @@ -906,9 +1272,13 @@ static void dump_node(FILE *F, ir_node *n) fprintf(F, "\" "); bad |= dump_node_info(F, n); print_node_error(F, p); + 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); + + if(dump_node_edge_hook) + dump_node_edge_hook(F, n); #if DO_HEAPANALYSIS dump_irn_chi_term(F, n); dump_irn_state(F, n); @@ -930,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"); } } @@ -937,7 +1320,11 @@ dump_ir_block_edge(FILE *F, ir_node *n) { static void print_data_edge_vcgattr(FILE *F, ir_node *from, int to) { - if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to))) + /* + * 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 fprintf (F, INTER_DATA_EDGE_ATTR); @@ -945,7 +1332,11 @@ print_data_edge_vcgattr(FILE *F, ir_node *from, int to) { static void print_mem_edge_vcgattr(FILE *F, ir_node *from, int to) { - if (get_nodes_block(from) == get_nodes_block(get_irn_n(from, to))) + /* + * 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 fprintf (F, INTER_MEM_EDGE_ATTR); @@ -955,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); @@ -962,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) @@ -971,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: - ; } } @@ -1161,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: \""); @@ -1171,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); @@ -1210,7 +1532,7 @@ dump_block_graph(FILE *F, ir_graph *irg) { } else { /* Nodes that are not in a Block. */ dump_node(F, node); - if (is_Bad(get_nodes_block(node)) && !node_floats(node)) { + if (!node_floats(node) && is_Bad(get_nodes_block(node))) { dump_const_block_local(F, node); } dump_ir_data_edges(F, node); @@ -1223,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); @@ -1248,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: \""); @@ -1327,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) { @@ -1342,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: { @@ -1377,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: { @@ -1413,8 +1748,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, ir_type *tp) { int bad = 0; @@ -1428,17 +1762,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) @@ -1449,18 +1780,20 @@ 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 -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); @@ -1528,8 +1861,8 @@ dump_type_info(type_or_ent *tore, void *env) { } break; case k_type: { - type *tp = (type *)tore; - print_type_node(F, tp); + ir_type *tp = (ir_type *)tore; + dump_type_node(F, tp); /* and now the edges */ switch (get_type_tpop_code(tp)) { case tpo_class: @@ -1627,11 +1960,11 @@ 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: { - print_type_node(F, tp); + dump_type_node(F, tp); /* and now the edges */ for (i=0; i < get_class_n_supertypes(tp); i++) { @@ -1679,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, "\""); } @@ -1750,7 +2083,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) { @@ -1770,13 +2103,7 @@ INLINE 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" @@ -1787,8 +2114,16 @@ INLINE 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 2: \"Verification errors\"\n" + "infoname 3: \"Debug info\"\n", name, label, orientation); /* don't use all, the range is too whith/black. */ @@ -1877,7 +2212,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) { @@ -1888,7 +2223,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 @. */ @@ -1958,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)) { @@ -1994,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)); @@ -2011,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); @@ -2026,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)); - for (i = 0; i < get_irp_n_irgs(); i++) { + dump_graph_info(F, irg); + print_dbg_info(F, get_entity_dbg_info(ent)); + + 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); @@ -2066,12 +2414,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"; @@ -2087,6 +2439,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; } @@ -2097,11 +2450,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); @@ -2110,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)); @@ -2126,8 +2484,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; } /*---------------------------------------------------------------------*/ @@ -2137,7 +2496,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)) { @@ -2154,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); @@ -2182,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 */ @@ -2204,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"); + } } } } @@ -2221,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 */ @@ -2235,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; @@ -2328,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/"); @@ -2336,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); @@ -2351,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)); } } @@ -2366,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); @@ -2431,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); } @@ -2456,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); - } } @@ -2673,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); } @@ -2695,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); }