X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firdump.c;h=386d9eb4039bcc4c23911758ff75d83bb88f34fa;hb=014643c20bee2345c928105e06c815d4f083753a;hp=ea837c2857ba406467f58a5ba155650336a3e862;hpb=7c3b36d2ac42da4af0933bfdd927690fae91531f;p=libfirm diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index ea837c285..386d9eb40 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-2006 Universit�t Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ #ifdef HAVE_CONFIG_H @@ -23,6 +23,8 @@ #include "firm_common_t.h" +#include "list.h" + #include "irnode.h" #include "irgraph.h" #include "irprog_t.h" @@ -40,6 +42,7 @@ #include "irloop_t.h" #include "callgraph.h" #include "irextbb_t.h" +#include "irhooks.h" #include "dbginfo_t.h" #include "irtools.h" @@ -81,11 +84,14 @@ 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; int opt_dump_analysed_type_info = 1; int opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */ @@ -105,6 +111,19 @@ DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void) } +static DUMP_NODE_EDGE_FUNC dump_block_edge_hook = NULL; + +void set_dump_block_edge_hook(DUMP_NODE_EDGE_FUNC func) +{ + dump_block_edge_hook = func; +} + +DUMP_NODE_EDGE_FUNC get_dump_block_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. */ @@ -125,7 +144,7 @@ void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook) { dump_edge_vcgattr_hook = hook; } -INLINE int 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 @@ -201,6 +220,10 @@ void dump_ld_names(int flag) { dump_ld_name = flag; } +void dump_all_anchors(int flag) { + dump_anchors = flag; +} + /* -------------- some extended helper functions ----------------- */ /** @@ -494,6 +517,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. */ @@ -540,7 +584,7 @@ static ir_node **construct_block_lists(ir_graph *irg) { 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(0); @@ -561,8 +605,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); @@ -575,6 +621,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; @@ -589,9 +636,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; } @@ -624,21 +671,26 @@ int dump_node_opcode(FILE *F, ir_node *n) } break; case iro_SymConst: { - if (get_SymConst_kind(n) == symconst_addr_name) { + switch (get_SymConst_kind(n)) { + case symconst_addr_name: /* don't use get_SymConst_ptr_info as it mangles the name. */ - fprintf (F, "SymC %s", get_id_str(get_SymConst_name(n))); - } else if (get_SymConst_kind(n) == symconst_addr_ent) { - assert(get_SymConst_entity(n)); - assert(is_entity(get_SymConst_entity(n))); - fprintf (F, "SymC &%s", get_entity_name(get_SymConst_entity(n))); - } else { - assert(get_kind(get_SymConst_type(n)) == k_type); - assert(get_type_ident(get_SymConst_type(n))); - fprintf (F, "SymC %s ", get_type_name_ex(get_SymConst_type(n), &bad)); - if (get_SymConst_kind(n) == symconst_type_tag) - fprintf (F, "tag"); - else - fprintf (F, "size"); + fprintf(F, "SymC %s", get_id_str(get_SymConst_name(n))); + break; + case symconst_addr_ent: + fprintf(F, "SymC &%s", get_entity_name(get_SymConst_entity(n))); + break; + case symconst_type_tag: + fprintf(F, "SymC %s tag", get_type_name_ex(get_SymConst_type(n), &bad)); + break; + case symconst_type_size: + fprintf(F, "SymC %s size", get_type_name_ex(get_SymConst_type(n), &bad)); + break; + case symconst_type_align: + fprintf(F, "SymC %s align", get_type_name_ex(get_SymConst_type(n), &bad)); + break; + case symconst_enum_const: + fprintf(F, "SymC %s enum", get_enumeration_name(get_SymConst_enum(n))); + break; } } break; @@ -686,6 +738,11 @@ int dump_node_opcode(FILE *F, ir_node *n) case iro_Block: fprintf (F, "%s%s", is_Block_dead(n) ? "Dead " : "", get_irn_opname(n)); break; + case iro_Conv: + if (get_Conv_strict(n)) + fprintf (F, "strict"); + fprintf (F, "%s", get_irn_opname(n)); + break; default: default_case: @@ -771,6 +828,7 @@ static const pns_lookup_t start_lut[] = { X(X_initial_exec), X(P_frame_base), X(P_globals), + X(P_tls), X(T_args), X(P_value_arg_base) #undef X @@ -891,7 +949,6 @@ static const pns_lookup_t bound_lut[] = { X(M), X(X_except), X(res), - X(M_except) #undef X }; @@ -1077,6 +1134,13 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) case iro_Phi: print_vcg_color(F, ird_color_green); break; + case iro_Mux: + case iro_Psi: + print_vcg_color(F, ird_color_gold); + break; + case iro_Pin: + print_vcg_color(F, ird_color_orchid); + break; case iro_Const: case iro_Proj: case iro_Filter: @@ -1088,6 +1152,25 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) } } +/* Adds a new node info dumper callback. */ +void *dump_add_node_info_callback(dump_node_info_cb_t *cb, void *data) +{ + hook_entry_t *info = xmalloc(sizeof(*info)); + + info->hook._hook_node_info = cb; + info->context = data; + register_hook(hook_node_info, info); + + return info; +} + +/* Remove a previously added info dumper callback. */ +void dump_remv_node_info_callback(void *handle) +{ + hook_entry_t *info = handle; + unregister_hook(hook_node_info, info); + xfree(info); +} /** * Dump the node information of a node n to a file F. @@ -1102,6 +1185,9 @@ static INLINE int dump_node_info(FILE *F, ir_node *n) /* call the dump_node operation if available */ if (ops->dump_node) bad = ops->dump_node(n, F, dump_node_info_txt); + + /* allow additional info to be added */ + hook_node_info(F, n); fprintf(F, "\"\n"); return bad; @@ -1352,34 +1438,54 @@ print_edge_vcgattr(FILE *F, ir_node *from, int to) { /* dump edges to our inputs */ static void dump_ir_data_edges(FILE *F, ir_node *n) { - int i; - unsigned long visited = get_irn_visited(n); - - if ((get_irn_op(n) == op_End) && (!dump_keepalive)) - return; - - for (i = 0; i < get_irn_arity(n); i++) { - ir_node * pred = get_irn_n(n, i); - assert(pred); - - if ((get_interprocedural_view() && get_irn_visited(pred) < visited)) - continue; /* pred not dumped */ - - if (dump_backedge_information_flag && is_backedge(n, i)) - fprintf (F, "backedge: {sourcename: \""); - else - fprintf (F, "edge: {sourcename: \""); - PRINT_NODEID(n); - fprintf (F, "\" targetname: "); - if ((get_opt_dump_const_local()) && is_constlike_node(pred)) { - PRINT_CONSTID(n, pred); - } else { - fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\""); - } - fprintf (F, " label: \"%d\" ", i); - print_edge_vcgattr(F, n, i); - fprintf (F, "}\n"); - } + int i; + unsigned long visited = get_irn_visited(n); + + if ((get_irn_op(n) == op_End) && (!dump_keepalive)) + return; + + /* dump the dependency edges. */ + for (i = 0; i < get_irn_deps(n); ++i) { + ir_node *dep = get_irn_dep(n, i); + + if(dep) { + fprintf(F, "edge: {sourcename: \""); + PRINT_NODEID(n); + fprintf(F, "\" targetname: "); + if ((get_opt_dump_const_local()) && is_constlike_node(dep)) { + PRINT_CONSTID(n, dep); + } else { + fprintf(F, "\""); + PRINT_NODEID(dep); + fprintf(F, "\""); + } + fprintf(F, " label: \"%d\" ", i); + fprintf(F, " color: darkgreen}\n"); + } + } + + for (i = 0; i < get_irn_arity(n); i++) { + ir_node * pred = get_irn_n(n, i); + assert(pred); + + if ((get_interprocedural_view() && get_irn_visited(pred) < visited)) + continue; /* pred not dumped */ + + if (dump_backedge_information_flag && is_backedge(n, i)) + fprintf (F, "backedge: {sourcename: \""); + else + fprintf (F, "edge: {sourcename: \""); + PRINT_NODEID(n); + fprintf (F, "\" targetname: "); + if ((get_opt_dump_const_local()) && is_constlike_node(pred)) { + PRINT_CONSTID(n, pred); + } else { + fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\""); + } + fprintf (F, " label: \"%d\" ", i); + print_edge_vcgattr(F, n, i); + fprintf (F, "}\n"); + } } /** Dumps a node and its edges but not the block edge @@ -1464,6 +1570,9 @@ dump_whole_block(FILE *F, ir_node *block) { /* dump the blocks edges */ dump_ir_data_edges(F, block); + if (dump_block_edge_hook) + dump_block_edge_hook(F, block); + /* dump the nodes that go into the block */ for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) { dump_node(F, node); @@ -1549,7 +1658,6 @@ 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 = get_extbb_leader(extbb); @@ -1601,11 +1709,8 @@ static void dump_node2type_edges(ir_node *n, void *env) /* @@@ some consts have an entity */ break; case iro_SymConst: - if ( (get_SymConst_kind(n) ==symconst_type_tag) - || (get_SymConst_kind(n) ==symconst_size)) - { - print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR); - } + if (SYMCONST_HAS_TYPE(get_SymConst_kind(n))) + print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR); break; case iro_Sel: { print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR); @@ -1762,16 +1867,20 @@ void dump_entity_node(FILE *F, entity *ent, int color) static void dump_enum_item(FILE *F, ir_type *tp, int pos) { char buf[1024]; - ident *id = get_enumeration_nameid(tp, pos); - tarval *tv = get_enumeration_enum(tp, pos); + ir_enum_const *ec = get_enumeration_const(tp, pos); + ident *id = get_enumeration_nameid(ec); + tarval *tv = get_enumeration_value(ec); - tarval_snprintf(buf, sizeof(buf), tv); - fprintf (F, "node: {title: \""); + if (tv) + tarval_snprintf(buf, sizeof(buf), tv); + else + strncpy(buf, "", sizeof(buf)); + fprintf(F, "node: {title: \""); PRINT_ITEMID(tp, pos); fprintf(F, "\""); - fprintf (F, DEFAULT_ENUM_ITEM_ATTRIBUTE); - fprintf (F, "label: "); - fprintf (F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id)); - fprintf (F, "\n info1: \"value: %s\"}\n", buf); + fprintf(F, DEFAULT_ENUM_ITEM_ATTRIBUTE); + fprintf(F, "label: "); + fprintf(F, "\"enum item %s\" " ENUM_ITEM_NODE_ATTR, get_id_str(id)); + fprintf(F, "\n info1: \"value: %s\"}\n", buf); } /* dumps a type or entity and it's edges. */ @@ -2145,7 +2254,7 @@ FILE *vcg_open (ir_graph *irg, const char * suffix1, const char *suffix2) { if (!suffix2) suffix2 = ""; /* open file for vcg graph */ - fname = malloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5); + fname = xmalloc (len * 2 + strlen(suffix1) + strlen(suffix2) + 5); /* strncpy (fname, nm, len); */ /* copy the filename */ j = 0; @@ -2266,7 +2375,7 @@ dump_ir_graph (ir_graph *irg, const char *suffix ) /* 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)) { @@ -2322,7 +2431,8 @@ void dump_ir_extblock_graph (ir_graph *irg, const char *suffix) 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 = "";