X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firedges.c;h=901af749d311d81277989acbd936a0e15c0eb639;hb=31ef53136fdb86d4a98919c2148c95cadea4ea81;hp=6446ff26075d7e57189254b25c8c98846d4d5dd8;hpb=56f0477a3d69d8c67c74071ed03fb0fe34f42fbc;p=libfirm diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index 6446ff260..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,15 +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); - irg_walk_anchors(irg, init_lh_walker, build_edges_walker, &w); - visit_all_identities(irg, visitor, &w); + if (kind == EDGE_KIND_DEP) { + 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); + } } void edges_deactivate_kind(ir_graph *irg, ir_edge_kind_t kind) @@ -834,11 +880,15 @@ 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); + 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_NORMAL); + 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); } int edges_assure(ir_graph *irg) { @@ -902,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) @@ -926,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); }