X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firedges.c;h=2619a14a8d01905619ef1b394aecd02eb41cb553;hb=f9d25133f86594ca2b1f33fb0b41a591ecc9b914;hp=f2795cbee7b638b9ecb009481c213fdbb7578dcf;hpb=9ffff1800dc2d51c50a80b41023cfed0f073edf5;p=libfirm diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index f2795cbee..2619a14a8 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -8,6 +8,13 @@ #include "config.h" #endif +#ifdef HAVE_ALLOCA_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif + #include "irnode_t.h" #include "iredges_t.h" #include "irdump_t.h" @@ -74,6 +81,10 @@ void edges_init_graph(ir_graph *irg) } } +#define EDGE_SIZE(src) \ + (edges_private_size + (is_Block(src) ? sizeof(ir_block_edge_t) : sizeof(ir_edge_t))) + + /** * Get the edge object of an outgoing edge at a node. * @param irg The graph, the node is in. @@ -86,11 +97,13 @@ const ir_edge_t *get_irn_edge(ir_graph *irg, const ir_node *src, int pos) { if(edges_activated(irg)) { irg_edge_info_t *info = _get_irg_edge_info(irg); - ir_edge_t templ; + size_t size = EDGE_SIZE(src); + ir_edge_t *templ = alloca(size); - templ.src = (ir_node *) src; - templ.pos = pos; - return set_find(info->edges, &templ, sizeof(templ), edge_hash(&templ)); + memset(templ, 0, size); + templ->src = (ir_node *) src; + templ->pos = pos; + return set_find(info->edges, templ, size, edge_hash(templ)); } return NULL; @@ -103,7 +116,9 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir if(!edges_activated(irg)) return; +#if 0 assert(node_is_in_irgs_storage(irg, src) && "source not in irg"); +#endif /* * Only do something, if the old and new target differ. @@ -111,26 +126,23 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir if(tgt != old_tgt) { int is_block_edge = is_Block(src); set *edges = _get_irg_edge_info(irg)->edges; - ir_block_edge_t space; - ir_edge_t *templ = (ir_edge_t *) &space; ir_edge_t *edge; - size_t size; - - /* - * This is scray, but: - * If two entries in a set do not have the same size, they are - * treated as unequal, ignoring the comparison function. - * So, edges from blocks have extra storage (they are - * ir_block_edge_t's). + + /* + * This is scray, but: + * If two entries in a set do not have the same size, they are + * treated as unequal, ignoring the comparison function. + * So, edges from blocks have extra storage (they are + * ir_block_edge_t's). * * Also add the amount of registered private data to the * size of the edge. - */ - size = edges_private_size + - is_block_edge ? sizeof(ir_block_edge_t) : sizeof(ir_edge_t); + */ + size_t size = EDGE_SIZE(src); + ir_edge_t *templ = alloca(size); /* Initialize the edge template to search in the set. */ - memset(templ, 0, size); + memset(templ, 0, size); #ifdef DEBUG_libfirm templ->src_nr = get_irn_node_nr(src); #endif @@ -148,7 +160,7 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir /* mark the edge invalid if it was found */ if(edge) { - ir_block_edge_t *block_edge = (ir_block_edge_t *) edge; + ir_block_edge_t *block_edge = (ir_block_edge_t *) edge; msg = "deleting"; list_del(&edge->list); @@ -156,12 +168,12 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir edge->pos = -2; edge->src = NULL; - /* - * If the edge is a cf edge, we delete it also - * from the list of all block successor edges. - */ - if(is_block_edge) - list_del(&block_edge->succ_list); + /* + * If the edge is a cf edge, we delete it also + * from the list of all block successor edges. + */ + if(is_block_edge) + list_del(&block_edge->succ_list); } /* If the edge was not found issue a warning on the debug stream */ @@ -179,19 +191,20 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir else { struct list_head *head = _get_irn_outs_head(tgt); - /* - * The list head in the block of the edges target. - * Therein all control flow edges directed at that block - * are recorded. - */ - struct list_head *succ_head = - is_block_edge ? _get_block_succ_head(get_nodes_block(tgt)) : NULL; + /* + * The list head in the block of the edges target. + * Therein all control flow edges directed at that block + * are recorded. + */ + struct list_head *succ_head = + is_block_edge ? _get_block_succ_head(get_nodes_block(tgt)) : NULL; - ir_block_edge_t *block_edge; + ir_block_edge_t *block_edge; +#if 0 if(!node_is_in_irgs_storage(irg, tgt)) return; - +#endif assert(head->next && head->prev && "target list head must have been initialized"); @@ -200,7 +213,7 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir * the instance in the set. */ edge = set_insert(edges, templ, size, edge_hash(templ)); - block_edge = (ir_block_edge_t *) edge; + block_edge = (ir_block_edge_t *) edge; #ifdef DEBUG_libfirm assert(!edge->invalid && "Invalid edge encountered"); @@ -211,9 +224,9 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir msg = "redirecting"; list_move(&edge->list, head); - /* If the edge is a cf edge, move it from the successor list. */ - if(is_block_edge) - list_move(&block_edge->succ_list, succ_head); + /* If the edge is a cf edge, move it from the successor list. */ + if(is_block_edge) + list_move(&block_edge->succ_list, succ_head); _get_irn_edge_info(old_tgt)->out_count -= 1; } @@ -223,12 +236,12 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir msg = "adding"; list_add(&edge->list, head); - /* - * If the edge is cf edge, enter it into the successor list - * of the target node's block. - */ - if(is_block_edge) - list_add(&block_edge->succ_list, succ_head); + /* + * If the edge is cf edge, enter it into the successor list + * of the target node's block. + */ + if(is_block_edge) + list_add(&block_edge->succ_list, succ_head); } _get_irn_edge_info(tgt)->out_count += 1;