X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fdfs.c;h=209ff084d61ef003542475f4ef047ba530d06b77;hb=c25b0f5781313f72027722783ce6286978bdd757;hp=d8596c12ba37440614dce4f57e68173fdebff7c8;hpb=ca84eb318328b3bd580c7ce2591745f83c6605e0;p=libfirm diff --git a/ir/ana/dfs.c b/ir/ana/dfs.c index d8596c12b..209ff084d 100644 --- a/ir/ana/dfs.c +++ b/ir/ana/dfs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -37,6 +37,7 @@ #include "irprintf.h" #include "irdom.h" #include "set.h" +#include "statev.h" #include "dfs_t.h" static int cmp_edge(const void *a, const void *b, size_t sz) @@ -59,7 +60,7 @@ static int cmp_node(const void *a, const void *b, size_t sz) #define get_node(dfs, node) _dfs_get_node(dfs, node) -static dfs_edge_t *get_edge(const dfs_t *self, void *src, void *tgt) +static dfs_edge_t *get_edge(const dfs_t *self, const void *src, const void *tgt) { unsigned hash = HASH_COMBINE(HASH_PTR(src), HASH_PTR(tgt)); dfs_edge_t templ; @@ -113,24 +114,41 @@ static void dfs_perform(dfs_t *dfs, void *n, void *anc, int level) static void classify_edges(dfs_t *dfs) { + stat_ev_cnt_decl(anc); + stat_ev_cnt_decl(back); + stat_ev_cnt_decl(fwd); + stat_ev_cnt_decl(cross); dfs_edge_t *edge; foreach_set (dfs->edges, edge) { dfs_node_t *src = edge->s; dfs_node_t *tgt = edge->t; - if (tgt->ancestor == src) + if (tgt->ancestor == src) { + stat_ev_cnt_inc(anc); edge->kind = DFS_EDGE_ANC; - else if (_dfs_int_is_ancestor(tgt, src)) + } + else if (_dfs_int_is_ancestor(tgt, src)) { + stat_ev_cnt_inc(back); edge->kind = DFS_EDGE_BACK; - else if (_dfs_int_is_ancestor(src, tgt)) + } + else if (_dfs_int_is_ancestor(src, tgt)) { + stat_ev_cnt_inc(fwd); edge->kind = DFS_EDGE_FWD; - else + } + else { + stat_ev_cnt_inc(cross); edge->kind = DFS_EDGE_CROSS; + } } + + stat_ev_cnt_done(anc, "dfs_edge_anc"); + stat_ev_cnt_done(back, "dfs_edge_back"); + stat_ev_cnt_done(fwd, "dfs_edge_fwd"); + stat_ev_cnt_done(cross, "dfs_edge_cross"); } -dfs_edge_kind_t dfs_get_edge_kind(const dfs_t *dfs, void *a, void *b) +dfs_edge_kind_t dfs_get_edge_kind(const dfs_t *dfs, const void *a, const void *b) { if (!dfs->edges_classified) { dfs_t *urg = (dfs_t *) dfs; @@ -157,15 +175,34 @@ dfs_t *dfs_new(const absgraph_t *graph_impl, void *graph_self) obstack_init(&res->obst); dfs_perform(res, graph_impl->get_root(graph_self), NULL, 0); + + /* make sure the end node (which might not be accessible) has a number */ + node = get_node(res, graph_impl->get_end(graph_self)); + if (!node->visited) { + node->visited = 1; + node->node = graph_impl->get_end(graph_self); + node->ancestor = NULL; + node->pre_num = res->pre_num++; + node->post_num = res->post_num++; + node->max_pre_num = node->pre_num; + node->level = 0; + } + classify_edges(res); + assert(res->pre_num == res->post_num); res->pre_order = xmalloc(res->pre_num * sizeof(res->pre_order)); - res->post_order = xmalloc(res->pre_num * sizeof(res->post_order)); + res->post_order = xmalloc(res->post_num * sizeof(res->post_order)); foreach_set (res->nodes, node) { + assert(node->pre_num < res->pre_num); + assert(node->post_num < res->post_num); + res->pre_order[node->pre_num] = node; res->post_order[node->post_num] = node; } + stat_ev_dbl("dfs_n_blocks", res->pre_num); + return res; }