From 5b6742592ed3923024137f06664a07cf37f2ff5e Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Mon, 20 Oct 2008 19:56:45 +0000 Subject: [PATCH] - old code probably crashes in the edge set contains already the newly created edge, so add a panic if this happens - put freed edges into a free-list, reducing memory count used for edges [r23050] --- ir/ir/iredges.c | 65 ++++++++++++++++++++++++----------------------- ir/ir/iredges_t.h | 16 ++++++------ 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index b593ed143..e7b3c348a 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -39,6 +39,7 @@ #include "debug.h" #include "set.h" #include "bitset.h" +#include "error.h" #include "iredgeset.h" #include "hashptr.h" @@ -199,6 +200,7 @@ void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind) { obstack_free(&info->edges_obst, NULL); } obstack_init(&info->edges_obst); + INIT_LIST_HEAD(&info->free_edges); ir_edgeset_init_size(&info->edges, amount); info->allocated = 1; } @@ -340,6 +342,7 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, msg = "deleting"; list_del(&edge->list); ir_edgeset_remove(edges, edge); + list_add(&edge->list, &info->free_edges); edge->invalid = 1; edge->pos = -2; edge->src = NULL; @@ -347,21 +350,17 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, edge->edge_nr = -1; #endif /* DEBUG_libfirm */ edge_change_cnt(old_tgt, kind, -1); - } - - /* If the edge was not found issue a warning on the debug stream */ - else { + } else { + /* If the edge was not found issue a warning on the debug stream */ msg = "edge to delete not found!\n"; } - } /* if */ - - /* - * The target is not NULL and the old target differs - * from the new target, the edge shall be moved (if the - * old target was != NULL) or added (if the old target was - * NULL). - */ - else { + } else { + /* + * The target is not NULL and the old target differs + * from the new target, the edge shall be moved (if the + * old target was != NULL) or added (if the old target was + * NULL). + */ struct list_head *head = _get_irn_outs_head(tgt, kind); assert(head->next && head->prev && @@ -377,33 +376,35 @@ void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, list_move(&edge->list, head); edge_change_cnt(old_tgt, kind, -1); - } - - /* The old target was null, thus, the edge is newly created. */ - else { + } else { + /* The old target was NULL, thus, the edge is newly created. */ ir_edge_t *new_edge; - ir_edge_t *edge - = obstack_alloc(&info->edges_obst, EDGE_SIZE); - memset(edge, 0, EDGE_SIZE); - edge->src = src; - edge->pos = pos; - edge->kind = kind; + ir_edge_t *edge; + + if (list_empty(&info->free_edges)) { + edge = obstack_alloc(&info->edges_obst, EDGE_SIZE); + } else { + edge = list_entry(info->free_edges.next, ir_edge_t, list); + list_del(&edge->list); + } + + edge->src = src; + edge->pos = pos; + edge->invalid = 0; + edge->present = 0; + edge->kind = kind; + edge->list.next = NULL; + edge->list.prev = NULL; DEBUG_ONLY(edge->src_nr = get_irn_node_nr(src)); new_edge = ir_edgeset_insert(edges, edge); - if(new_edge != edge) { - obstack_free(&info->edges_obst, edge); + if (new_edge != edge) { + panic("new edge exists already"); } - assert(! edge->invalid && "Freshly inserted edge is invalid?!?"); - assert(edge->list.next == NULL && edge->list.prev == NULL && - "New edge must not have list head initialized"); - msg = "adding"; list_add(&edge->list, head); -#ifdef DEBUG_libfirm - edge->edge_nr = ++last_edge_num; -#endif /* DEBUG_libfirm */ + DEBUG_ONLY(edge->edge_nr = ++last_edge_num); } edge_change_cnt(tgt, kind, +1); diff --git a/ir/ir/iredges_t.h b/ir/ir/iredges_t.h index ced465037..07f8d733f 100644 --- a/ir/ir/iredges_t.h +++ b/ir/ir/iredges_t.h @@ -44,15 +44,15 @@ * An edge. */ struct _ir_edge_t { - ir_node *src; /**< The source node of the edge. */ - int pos; /**< The position of the edge at @p src. */ - unsigned invalid : 1; /**< edges that are removed are marked invalid. */ - unsigned present : 1; /**< Used by the verifier. Don't rely on its content. */ - unsigned kind : 4; /**< The kind of the edge. */ - struct list_head list; /**< The list head to queue all out edges at a node. */ + ir_node *src; /**< The source node of the edge. */ + int pos; /**< The position of the edge at @p src. */ + unsigned invalid : 1; /**< edges that are removed are marked invalid. */ + unsigned present : 1; /**< Used by the verifier. Don't rely on its content. */ + unsigned kind : 4; /**< The kind of the edge. */ + struct list_head list; /**< The list head to queue all out edges at a node. */ #ifdef DEBUG_libfirm - long src_nr; /**< The node number of the source node. */ - long edge_nr; /**< A unique number identifying the edge. */ + long src_nr; /**< The node number of the source node. */ + long edge_nr; /**< A unique number identifying the edge. */ #endif }; -- 2.20.1