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,
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);
}
}
+/**
+ * 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;
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;
}
/**
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;
}
/**
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);
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;
}
}
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);
}
}
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);