X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firedges.c;h=901af749d311d81277989acbd936a0e15c0eb639;hb=afbbc0b1ccd684c4c24bfd43d0f994123245f39f;hp=1a6a88844721d498eb1ce09bafde015e7a3279bc;hpb=bf8e498d7ca3073ab0368a68a5f3e95e73953214;p=libfirm diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index 1a6a88844..901af749d 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -42,7 +42,6 @@ #include "debug.h" #include "set.h" #include "bitset.h" -#include "xmalloc.h" #include "iredgeset.h" #include "hashptr.h" @@ -485,9 +484,6 @@ static void build_edges_walker(ir_node *irn, void *data) { ir_graph *irg = w->irg; get_edge_src_n_func_t *get_n; - if (! edges_activated_kind(irg, kind)) - return; - get_n = edge_kind_info[kind].get_n; foreach_tgt(irn, i, n, kind) { ir_node *pred = get_n(irn, i, kind); @@ -502,18 +498,56 @@ static void build_edges_walker(ir_node *irn, void *data) { static void init_lh_walker(ir_node *irn, void *data) { struct build_walker *w = data; ir_edge_kind_t kind = w->kind; - INIT_LIST_HEAD(_get_irn_outs_head(irn, kind)); + list_head *head = _get_irn_outs_head(irn, kind); + INIT_LIST_HEAD(head); + _get_irn_edge_info(irn, kind)->out_count = 0; +} + +/** + * Pre-Walker: initializes the list-heads and set the out-count + * of all nodes to 0. + * + * Additionally touches DEP nodes, as they might be DEAD. + * THIS IS UGLY, but I don't find a better way until we + * + * a) ensure that dead nodes are not used as input + * b) it might be sufficient to add those stupid NO_REG nodes + * to the anchor + */ +static void init_lh_walker_dep(ir_node *irn, void *data) { + struct build_walker *w = data; + ir_edge_kind_t kind = w->kind; + list_head *head = _get_irn_outs_head(irn, kind); + int i; + + INIT_LIST_HEAD(head); _get_irn_edge_info(irn, kind)->out_count = 0; + + for (i = get_irn_deps(irn) - 1; i >= 0; --i) { + ir_node *dep = get_irn_dep(irn, i); + + head = _get_irn_outs_head(dep, kind); + + INIT_LIST_HEAD(head); + _get_irn_edge_info(dep, kind)->out_count = 0; + } } +typedef struct visitor_info_t { + irg_walk_func *visit; + void *data; +} visitor_info_t; + /** * Visitor: initializes the list-heads and set the out-count * of all nodes to 0 of nodes that are not seen so far. */ static void visitor(ir_node *irn, void *data) { - if (irn_not_visited(irn)) { + visitor_info_t *info = data; + + if (!irn_visited(irn)) { mark_irn_visited(irn); - init_lh_walker(irn, data); + info->visit(irn, info->data); } } @@ -542,20 +576,27 @@ static void visitor(ir_node *irn, void *data) { void edges_activate_kind(ir_graph *irg, ir_edge_kind_t kind) { struct build_walker w; - irg_edge_info_t *info = _get_irg_edge_info(irg, kind); + irg_edge_info_t *info = _get_irg_edge_info(irg, kind); + visitor_info_t visit; w.irg = irg; w.kind = kind; + visit.data = &w; + info->activated = 1; edges_init_graph_kind(irg, kind); if (kind == EDGE_KIND_DEP) { - irg_walk_anchors(irg, init_lh_walker, NULL, &w); + irg_walk_anchors(irg, init_lh_walker_dep, NULL, &w); + /* Argh: Dep nodes might be dead, so we MUST visit identities first */ + visit.visit = init_lh_walker_dep; + visit_all_identities(irg, visitor, &visit); irg_walk_anchors(irg, NULL, build_edges_walker, &w); } else { irg_walk_anchors(irg, init_lh_walker, build_edges_walker, &w); + visit.visit = init_lh_walker; + visit_all_identities(irg, visitor, &visit); } - visit_all_identities(irg, visitor, &w); } void edges_deactivate_kind(ir_graph *irg, ir_edge_kind_t kind) @@ -839,11 +880,13 @@ void edges_init_dbg(int do_dbg) { void edges_activate(ir_graph *irg) { edges_activate_kind(irg, EDGE_KIND_NORMAL); edges_activate_kind(irg, EDGE_KIND_BLOCK); - edges_activate_kind(irg, EDGE_KIND_DEP); + if (get_irg_phase_state(irg) == phase_backend) + edges_activate_kind(irg, EDGE_KIND_DEP); } void edges_deactivate(ir_graph *irg) { - edges_deactivate_kind(irg, EDGE_KIND_DEP); + if (get_irg_phase_state(irg) == phase_backend) + edges_deactivate_kind(irg, EDGE_KIND_DEP); edges_deactivate_kind(irg, EDGE_KIND_BLOCK); edges_deactivate_kind(irg, EDGE_KIND_NORMAL); } @@ -909,7 +952,7 @@ static void irg_block_edges_walk2(ir_node *bl, void *env) { const ir_edge_t *edge, *next; - if (Block_not_block_visited(bl)) { + if (!Block_block_visited(bl)) { mark_Block_block_visited(bl); if (pre) @@ -933,10 +976,10 @@ void irg_block_edges_walk(ir_node *node, assert(edges_activated(current_ir_graph)); assert(is_Block(node)); - set_using_block_visited(current_ir_graph); + ir_reserve_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED); inc_irg_block_visited(current_ir_graph); irg_block_edges_walk2(node, pre, post, env); - clear_using_block_visited(current_ir_graph); + ir_free_resources(current_ir_graph, IR_RESOURCE_BLOCK_VISITED); }