X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fstat%2Fdags.c;h=b14c990ff544fc27e00e3ee0e9e6f1af4d87906b;hb=6a768b09064c37b361871ba888213cdd5ed5a700;hp=5b3caeced2964c33945d8636555c925361f39c62;hpb=7f443d190f851ff3c38508253495470421fdb439;p=libfirm diff --git a/ir/stat/dags.c b/ir/stat/dags.c index 5b3caeced..b14c990ff 100644 --- a/ir/stat/dags.c +++ b/ir/stat/dags.c @@ -18,20 +18,16 @@ #include "irprintf.h" #include "irdump.h" #include "dags.h" +#include "irtools.h" enum dag_counting_options_t { FIRMSTAT_COPY_CONSTANTS = 0x00000001, /**< if set, constants will be treated as they are in the same block as its successors */ + FIRMSTAT_LOAD_IS_LEAVE = 0x00000002, /**< Load nodes are always leaves */ + FIRMSTAT_CALL_IS_LEAVE = 0x00000004, /**< Call nodes are always leaves */ + FIRMSTAT_ARGS_ARE_ROOTS = 0x00000008, /**< arguments (Proj(Proj(Start)) are roots */ }; -/** - * walker for clearing node links - */ -static void clear_links(ir_node *node, void *env) -{ - set_irn_link(node, NULL); -} - typedef struct _dag_entry_t dag_entry_t; /** @@ -80,6 +76,22 @@ static dag_entry_t *get_irn_dag_entry(ir_node *n) #define set_irn_dag_entry(n, e) set_irn_link(n, e) +/** + * checks wether a node is an arg + */ +static int is_arg(ir_node *node) +{ + if (! is_Proj(node)) + return 0; + + node = get_Proj_pred(node); + if (! is_Proj(node)) + return 0; + + node = get_Proj_pred(node); + return get_irn_op(node) == op_Start; +} + /** * walker for connecting DAGs and counting. */ @@ -104,6 +116,9 @@ static void connect_dags(ir_node *node, void *env) if (is_Phi(node)) return; + if (dag_env->options & FIRMSTAT_ARGS_ARE_ROOTS && is_arg(node)) + return; + mode = get_irn_mode(node); if (mode == mode_X || mode == mode_M) { /* do NOT count mode_X nodes */ @@ -130,6 +145,13 @@ static void connect_dags(ir_node *node, void *env) set_irn_dag_entry(node, entry); } + /* if this option is set, Loads are allways leaves */ + if (dag_env->options & FIRMSTAT_LOAD_IS_LEAVE && get_irn_op(node) == op_Load) + return; + + if (dag_env->options & FIRMSTAT_CALL_IS_LEAVE && get_irn_op(node) == op_Call) + return; + /* put the predecessors into the same DAG as the current */ for (i = 0, arity = get_irn_arity(node); i < arity; ++i) { ir_node *prev = get_irn_n(node, i); @@ -181,6 +203,11 @@ static void connect_dags(ir_node *node, void *env) } } +#define DEFAULT_RET 1 +#define COLOR_RET 1 + +static unsigned mark_options; + /** * a vcg attribute hook */ @@ -190,17 +217,30 @@ static int stat_dag_mark_hook(FILE *F, ir_node *n, ir_node *l) dag_entry_t *entry; /* do not count Bad / NoMem */ - if (l && (get_irn_op(l) == op_NoMem || get_irn_op(l) == op_Bad)) - return 0; + if (l) { + ir_op *op = get_irn_op(l); + + if (op == op_NoMem || op == op_Bad) + return DEFAULT_RET; + + /* check for additional options */ + op = get_irn_op(n); + + if (mark_options & FIRMSTAT_LOAD_IS_LEAVE && op == op_Load) + return DEFAULT_RET; + + if (mark_options & FIRMSTAT_CALL_IS_LEAVE && op == op_Call) + return DEFAULT_RET; + } entry = get_irn_dag_entry(n); if (! entry) - return 0; + return DEFAULT_RET; fprintf(F, "color: %s info3: \"DAG id: %u\"", colors[entry->id & 7], entry->id); /* I know the color! */ - return 1; + return COLOR_RET; } /** @@ -217,17 +257,17 @@ void count_dags_in_graph(graph_entry_t *global, graph_entry_t *graph) return; /* first step, clear the links */ - irg_walk_graph(graph->irg, clear_links, NULL, NULL); + irg_walk_graph(graph->irg, firm_clear_link, NULL, NULL); obstack_init(&root_env.obst); root_env.num_of_dags = 0; root_env.list_of_dags = NULL; - root_env.options = FIRMSTAT_COPY_CONSTANTS; + root_env.options = FIRMSTAT_COPY_CONSTANTS | FIRMSTAT_LOAD_IS_LEAVE | FIRMSTAT_CALL_IS_LEAVE; /* count them */ irg_walk_graph(graph->irg, connect_dags, NULL, &root_env); - printf("Graph %p %s --- %d\n", graph->irg, get_entity_name(get_irg_entity(graph->irg)), + printf("Graph %p %s --- %d\n", (void *)graph->irg, get_entity_name(get_irg_entity(graph->irg)), root_env.num_of_dags); for (id = 0, entry = root_env.list_of_dags; entry; entry = entry->next) { @@ -244,6 +284,7 @@ void count_dags_in_graph(graph_entry_t *global, graph_entry_t *graph) #if 1 /* dump for test */ + mark_options = root_env.options; set_dump_node_vcgattr_hook(stat_dag_mark_hook); dump_ir_block_graph(graph->irg, "-dag"); set_dump_node_vcgattr_hook(NULL);