X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firedges.c;h=062cb7119c1ec8414d39a187fb491fb734ef8ad8;hb=8bae7e4a8cf8f1a323ccf7b60c4091da49324f94;hp=29a54061deb141cd7ac4f0d7a9ba092045e0e663;hpb=ed19abeed72e10f55f19b5b259fb42b89c30c6b8;p=libfirm diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index 29a54061d..062cb7119 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -316,6 +316,29 @@ static inline void vrfy_list_head(ir_node *irn, ir_edge_kind_t kind) { assert(err == 0); } +#ifdef DEBUG_libfirm +/** + * Helper function to dump the edge set of a graph, + * unused in normal code. + */ +void edges_dump_kind(ir_graph *irg, ir_edge_kind_t kind) +{ + irg_edge_info_t *info; + ir_edgeset_t *edges; + ir_edgeset_iterator_t iter; + ir_edge_t *e; + + if (!edges_activated_kind(irg, kind)) + return; + + info = _get_irg_edge_info(irg, kind); + edges = &info->edges; + foreach_ir_edgeset(edges, e, iter) { + ir_printf("%+F %d %d\n", e->src, e->pos, e->invalid); + } +} +#endif + /* The edge from (src, pos) -> old_tgt is redirected to tgt */ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir_edge_kind_t kind, @@ -407,7 +430,7 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, edge->kind = kind; edge->list.next = NULL; edge->list.prev = NULL; - memset(((char*)edge) + sizeof(ir_edge_t), 0, edges_private_size); + memset(edge + 1, 0, edges_private_size); DEBUG_ONLY(edge->src_nr = get_irn_node_nr(src)); new_edge = ir_edgeset_insert(edges, edge); @@ -479,6 +502,34 @@ static void edges_node_deleted_kind(ir_node *old, ir_edge_kind_t kind, ir_graph } } +/** + * A node might be revivaled by CSE. Assure its edges. + * + * @param irn the node + * @param kind the kind of edges to remove + * @param irg the irg of the old node + */ +static void edges_node_revival_kind(ir_node *irn, ir_edge_kind_t kind, ir_graph *irg) +{ + irn_edge_info_t *info; + int i, n; + + if (!edges_activated_kind(irg, kind)) + return; + + info = _get_irn_edge_info(irn, kind); + if (info->edges_built) + return; + + DBG((dbg, LEVEL_5, "node revivaled (kind: %s): %+F\n", get_kind_str(kind), irn)); + + foreach_tgt(irn, i, n, kind) { + ir_node *tgt = get_n(irn, i, kind); + edges_notify_edge_kind(irn, i, tgt, NULL, kind, irg); + } + info->edges_built = 1; +} + struct build_walker { ir_graph *irg; ir_edge_kind_t kind; @@ -501,6 +552,7 @@ static void build_edges_walker(ir_node *irn, void *data) { ir_node *pred = get_n(irn, i, kind); edges_notify_edge_kind(irn, i, pred, NULL, kind, irg); } + _get_irn_edge_info(irn, kind)->edges_built = 1; } /** @@ -512,7 +564,8 @@ static void init_lh_walker(ir_node *irn, void *data) { ir_edge_kind_t kind = w->kind; list_head *head = _get_irn_outs_head(irn, kind); INIT_LIST_HEAD(head); - _get_irn_edge_info(irn, kind)->out_count = 0; + _get_irn_edge_info(irn, kind)->edges_built = 0; + _get_irn_edge_info(irn, kind)->out_count = 0; } /** @@ -533,7 +586,8 @@ static void init_lh_walker_dep(ir_node *irn, void *data) { int i; INIT_LIST_HEAD(head); - _get_irn_edge_info(irn, kind)->out_count = 0; + _get_irn_edge_info(irn, kind)->edges_built = 0; + _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); @@ -541,7 +595,8 @@ static void init_lh_walker_dep(ir_node *irn, void *data) { head = _get_irn_outs_head(dep, kind); INIT_LIST_HEAD(head); - _get_irn_edge_info(dep, kind)->out_count = 0; + _get_irn_edge_info(dep, kind)->edges_built = 0; + _get_irn_edge_info(dep, kind)->out_count = 0; } } @@ -557,8 +612,7 @@ typedef struct visitor_info_t { static void visitor(ir_node *irn, void *data) { visitor_info_t *info = data; - if (!irn_visited(irn)) { - mark_irn_visited(irn); + if (!irn_visited_else_mark(irn)) { info->visit(irn, info->data); } } @@ -968,6 +1022,10 @@ void edges_node_deleted(ir_node *irn, ir_graph *irg) { edges_node_deleted_kind(irn, EDGE_KIND_BLOCK, irg); } +void edges_node_revival(ir_node *irn, ir_graph *irg) { + edges_node_revival_kind(irn, EDGE_KIND_NORMAL, irg); + edges_node_revival_kind(irn, EDGE_KIND_BLOCK, irg); +} const ir_edge_t *(get_irn_out_edge_first_kind)(const ir_node *irn, ir_edge_kind_t kind) { return _get_irn_out_edge_first_kind(irn, kind);