X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Firouts.c;h=12031b81bca9916072900491f48b1353fa4aac58;hb=d4840ad0100f33ed436c036d90f557f50d745e6b;hp=19d8f507a48c8e319e70f6519d80bea8a878eccf;hpb=8428d50114020cce61e2fccae4e23244a99db918;p=libfirm diff --git a/ir/ana/irouts.c b/ir/ana/irouts.c index 19d8f507a..12031b81b 100644 --- a/ir/ana/irouts.c +++ b/ir/ana/irouts.c @@ -24,13 +24,9 @@ * @date 1.2002 * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif -#ifdef HAVE_STRING_H #include -#endif #include "xmalloc.h" #include "irouts.h" @@ -39,6 +35,8 @@ #include "irprog_t.h" #include "irgwalk.h" #include "irtools.h" +#include "irprintf.h" +#include "error.h" #ifdef DEBUG_libfirm /* Note: ir_node.out_valid and ir_graph.n_outs are only present when DEBUG_libfirm is defined */ @@ -52,7 +50,8 @@ #ifdef DEBUG_libfirm /** Clear the outs of a node */ -static void reset_outs(ir_node *node, void *unused) { +static void reset_outs(ir_node *node, void *unused) +{ (void) unused; node->out = NULL; node->out_valid = 0; @@ -65,7 +64,8 @@ int get_irn_outs_computed(const ir_node *node) } /* returns the number of successors of the node: */ -int get_irn_n_outs(ir_node *node) { +int get_irn_n_outs(const ir_node *node) +{ assert(node && node->kind == k_ir_node); #ifdef DEBUG_libfirm /* assert(node->out_valid); */ @@ -75,7 +75,8 @@ int get_irn_n_outs(ir_node *node) { } /* Access successor n */ -ir_node *get_irn_out(ir_node *def, int pos) { +ir_node *get_irn_out(const ir_node *def, int pos) +{ assert(pos >= 0 && pos < get_irn_n_outs(def)); #ifdef DEBUG_libfirm /* assert(def->out_valid); */ @@ -84,7 +85,8 @@ ir_node *get_irn_out(ir_node *def, int pos) { } /* Access successor n */ -ir_node *get_irn_out_ex(ir_node *def, int pos, int *in_pos) { +ir_node *get_irn_out_ex(const ir_node *def, int pos, int *in_pos) +{ assert(pos >= 0 && pos < get_irn_n_outs(def)); #ifdef DEBUG_libfirm /* assert(def->out_valid); */ @@ -93,7 +95,8 @@ ir_node *get_irn_out_ex(ir_node *def, int pos, int *in_pos) { return def->out[pos+1].use; } -void set_irn_out(ir_node *def, int pos, ir_node *use, int in_pos) { +void set_irn_out(ir_node *def, int pos, ir_node *use, int in_pos) +{ assert(def && use); assert(pos >= 0 && pos < get_irn_n_outs(def)); #ifdef DEBUG_libfirm @@ -104,7 +107,8 @@ void set_irn_out(ir_node *def, int pos, ir_node *use, int in_pos) { } /* Return the number of control flow successors, ignore keep-alives. */ -int get_Block_n_cfg_outs(ir_node *bl) { +int get_Block_n_cfg_outs(const ir_node *bl) +{ int i, n_cfg_outs = 0; assert(bl && is_Block(bl)); #ifdef DEBUG_libfirm @@ -119,7 +123,8 @@ int get_Block_n_cfg_outs(ir_node *bl) { } /* Return the number of control flow successors, honor keep-alives. */ -int get_Block_n_cfg_outs_ka(ir_node *bl) { +int get_Block_n_cfg_outs_ka(const ir_node *bl) +{ int i, n_cfg_outs = 0; assert(bl && is_Block(bl)); #ifdef DEBUG_libfirm @@ -143,7 +148,8 @@ int get_Block_n_cfg_outs_ka(ir_node *bl) { } /* Access predecessor n, ignore keep-alives. */ -ir_node *get_Block_cfg_out(ir_node *bl, int pos) { +ir_node *get_Block_cfg_out(const ir_node *bl, int pos) +{ int i; assert(bl && is_Block(bl)); #ifdef DEBUG_libfirm @@ -163,7 +169,8 @@ ir_node *get_Block_cfg_out(ir_node *bl, int pos) { } /* Access predecessor n, honor keep-alives. */ -ir_node *get_Block_cfg_out_ka(ir_node *bl, int pos) { +ir_node *get_Block_cfg_out_ka(const ir_node *bl, int pos) +{ int i, n_outs; assert(bl && is_Block(bl)); #ifdef DEBUG_libfirm @@ -196,7 +203,8 @@ ir_node *get_Block_cfg_out_ka(ir_node *bl, int pos) { } static void irg_out_walk_2(ir_node *node, irg_walk_func *pre, - irg_walk_func *post, void *env) { + irg_walk_func *post, void *env) +{ int i, n; ir_node *succ; @@ -216,9 +224,9 @@ static void irg_out_walk_2(ir_node *node, irg_walk_func *pre, if (post) post(node, env); } -void irg_out_walk(ir_node *node, - irg_walk_func *pre, irg_walk_func *post, - void *env) { +void irg_out_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, + void *env) +{ assert(node); if (get_irg_outs_state(current_ir_graph) != outs_none) { inc_irg_visited (current_ir_graph); @@ -226,12 +234,12 @@ void irg_out_walk(ir_node *node, } } -static void irg_out_block_walk2(ir_node *bl, - irg_walk_func *pre, irg_walk_func *post, - void *env) { +static void irg_out_block_walk2(ir_node *bl, irg_walk_func *pre, + irg_walk_func *post, void *env) +{ int i, n; - if (Block_not_block_visited(bl)) { + if (!Block_block_visited(bl)) { mark_Block_block_visited(bl); if (pre) @@ -251,9 +259,9 @@ static void irg_out_block_walk2(ir_node *bl, /* Walks only over Block nodes in the graph. Has it's own visited flag, so that it can be interleaved with the other walker. */ -void irg_out_block_walk(ir_node *node, - irg_walk_func *pre, irg_walk_func *post, - void *env) { +void irg_out_block_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, + void *env) +{ assert(is_Block(node) || (get_irn_mode(node) == mode_X)); @@ -264,8 +272,7 @@ void irg_out_block_walk(ir_node *node, for (i = 0, n = get_irn_n_outs(node); i < n; ++i) { ir_node *succ = get_irn_out(node, i); - if (get_irn_visited(succ) < get_irg_visited(current_ir_graph)) - irg_out_walk_2(succ, pre, post, env); + irg_out_block_walk2(succ, pre, post, env); } } else { @@ -294,7 +301,8 @@ void irg_out_block_walk(ir_node *node, /** Returns the amount of out edges for not yet visited successors. */ -static int _count_outs(ir_node *n) { +static int _count_outs(ir_node *n) +{ int start, i, res, irn_arity; mark_irn_visited(n); @@ -314,7 +322,7 @@ static int _count_outs(ir_node *n) { } /* count Def-Use edges for predecessors */ - if (irn_not_visited(skipped_pred)) + if (!irn_visited(skipped_pred)) res += _count_outs(skipped_pred); /*count my Def-Use edges */ @@ -327,7 +335,8 @@ static int _count_outs(ir_node *n) { /** Returns the amount of out edges for not yet visited successors. * This version handles some special nodes like irg_frame, irg_args etc. */ -static int count_outs(ir_graph *irg) { +static int count_outs(ir_graph *irg) +{ ir_node *n; int i, res; @@ -338,9 +347,7 @@ static int count_outs(ir_graph *irg) { even if they are not visible. */ for (i = anchor_last - 1; i >= 0; --i) { n = get_irg_anchor(irg, i); - if (irn_not_visited(n)) { - mark_irn_visited(n); - + if (!irn_visited_else_mark(n)) { n->out = INT_TO_PTR(1); ++res; } @@ -356,7 +363,8 @@ static int count_outs(ir_graph *irg) { * * @return The next free address */ -static ir_def_use_edge *_set_out_edges(ir_node *use, ir_def_use_edge *free) { +static ir_def_use_edge *_set_out_edges(ir_node *use, ir_def_use_edge *free) +{ int n_outs, start, i, irn_arity, pos; mark_irn_visited(use); @@ -380,7 +388,7 @@ static ir_def_use_edge *_set_out_edges(ir_node *use, ir_def_use_edge *free) { ir_node *def = get_irn_n(use, i); /* Recursion */ - if (irn_not_visited(def)) + if (!irn_visited(def)) free = _set_out_edges(def, free); /* Remember this Def-Use edge */ @@ -402,7 +410,8 @@ static ir_def_use_edge *_set_out_edges(ir_node *use, ir_def_use_edge *free) { * * @return The next free address */ -static ir_def_use_edge *set_out_edges(ir_graph *irg, ir_def_use_edge *free) { +static ir_def_use_edge *set_out_edges(ir_graph *irg, ir_def_use_edge *free) +{ ir_node *n; int i, n_outs; @@ -412,9 +421,7 @@ static ir_def_use_edge *set_out_edges(ir_graph *irg, ir_def_use_edge *free) { /* handle anchored nodes */ for (i = anchor_last - 1; i >= 0; --i) { n = get_irg_anchor(irg, i); - if (irn_not_visited(n)) { - mark_irn_visited(n); - + if (!irn_visited_else_mark(n)) { n_outs = PTR_TO_INT(n->out); n->out = free; #ifdef DEBUG_libfirm @@ -427,36 +434,9 @@ static ir_def_use_edge *set_out_edges(ir_graph *irg, ir_def_use_edge *free) { return free; } - -/** - * We want that the out of ProjX from Start contains the next block at - * position 1, the Start block at position 2. This is necessary for - * the out block walker. - */ -static INLINE void fix_start_proj(ir_graph *irg) { - ir_node *proj = NULL; - ir_node *irn; - ir_node *startbl = get_irg_start_block(irg); - int i, block_pos, other_pos; - - if (get_Block_n_cfg_outs(startbl)) { - for (i = get_irn_n_outs(startbl) - 1; i >= 0; --i) - if (get_irn_mode(get_irn_out(startbl, i)) == mode_X) { - proj = get_irn_out(startbl, i); - break; - } - - if (get_irn_out_ex(proj, 0, &block_pos) == startbl) { - assert(get_irn_n_outs(proj) == 2); - irn = get_irn_out_ex(proj, 1, &other_pos); - set_irn_out(proj, 0, irn, other_pos); - set_irn_out(proj, 1, startbl, block_pos); - } - } -} - /* compute the outs for a given graph */ -void compute_irg_outs(ir_graph *irg) { +void compute_irg_outs(ir_graph *irg) +{ ir_graph *rem = current_ir_graph; int n_out_edges = 0; ir_def_use_edge *end = NULL; /* Only for debugging */ @@ -474,7 +454,7 @@ void compute_irg_outs(ir_graph *irg) { n_out_edges = count_outs(irg); /* allocate memory for all out edges. */ - irg->outs = xcalloc(n_out_edges, sizeof(irg->outs[0])); + irg->outs = XMALLOCNZ(ir_def_use_edge, n_out_edges); #ifdef DEBUG_libfirm irg->n_outs = n_out_edges; #endif /* defined DEBUG_libfirm */ @@ -486,27 +466,25 @@ void compute_irg_outs(ir_graph *irg) { /* Check how much memory we have used */ assert (end == (irg->outs + n_out_edges)); - /* We want that the out of ProjX from Start contains the next block at - position 1, the Start block at position 2. This is necessary for - the out block walker. */ - fix_start_proj(irg); - current_ir_graph->outs_state = outs_consistent; current_ir_graph = rem; } -void assure_irg_outs(ir_graph *irg) { +void assure_irg_outs(ir_graph *irg) +{ if (get_irg_outs_state(irg) != outs_consistent) compute_irg_outs(irg); } -void compute_irp_outs(void) { +void compute_irp_outs(void) +{ int i; for (i = get_irp_n_irgs() -1; i >= 0; --i) compute_irg_outs(get_irp_irg(i)); } -void free_irp_outs(void) { +void free_irp_outs(void) +{ int i; for (i = get_irp_n_irgs() -1; i >= 0; --i) free_irg_outs(get_irp_irg(i)); @@ -527,7 +505,8 @@ void free_irp_outs(void) { * Inits the number of outedges for each node * before counting. */ -static void init_count(ir_node * node, void *env) { +static void init_count(ir_node * node, void *env) +{ (void) env; node->out = (ir_node **) 1; /* 1 for the array size */ } @@ -538,7 +517,8 @@ static void init_count(ir_node * node, void *env) { * and adds the current arity to the overall count, * which is saved in "env" */ -static void node_arity_count(ir_node * node, void * env) { +static void node_arity_count(ir_node * node, void * env) +{ int *anz = (int *) env, arity, n_outs, i, start; ir_node *succ; @@ -548,7 +528,7 @@ static void node_arity_count(ir_node * node, void * env) { n_outs = 1 + arity + (-start); // ((is_Block(node)) ? 0 : 1); // Why + 1?? *anz += n_outs; - for(i = start; i < arity; i++) { + for (i = start; i < arity; i++) { succ = get_irn_n(node, i); succ->out = (ir_node **)INT_TO_PTR(PTR_TO_INT(succ->out) + 1); } @@ -558,7 +538,8 @@ static void node_arity_count(ir_node * node, void * env) { * Inits all nodes for setting the outedges * Returns the overall count of edges */ -int count_ip_outs(void) { +int count_ip_outs(void) +{ int res = 0; cg_walk(init_count, node_arity_count, &res); @@ -573,7 +554,8 @@ static int dummy_count = 0, global_count; /* Only for debugging */ * in which the outedges are written later. * The current array start is transported in env */ -static void set_array_pointer(ir_node *node, void *env) { +static void set_array_pointer(ir_node *node, void *env) +{ int n_outs; ir_node ***free = (ir_node ***) env; @@ -594,7 +576,8 @@ static void set_array_pointer(ir_node *node, void *env) { * Adds an outedge from the predecessor to the * current node. */ -static void set_out_pointer(ir_node * node, void *env) { +static void set_out_pointer(ir_node * node, void *env) +{ int i, arity = get_irn_arity(node); ir_node *succ; int start = (!is_Block(node)) ? -1 : 0; @@ -611,7 +594,8 @@ static void set_out_pointer(ir_node * node, void *env) { /* * Sets the outedges for all nodes. */ -void set_ip_outs(void) { +void set_ip_outs(void) +{ ir_node **outedge_array = get_irp_ip_outedges(); cg_walk(set_array_pointer, set_out_pointer, (void *) &outedge_array); } @@ -623,7 +607,8 @@ void set_ip_outs(void) { * outedges and fills this outedge array in interprocedural * view! */ -void compute_ip_outs(void) { +void compute_ip_outs(void) +{ int n_out_edges; ir_node **out_edges; @@ -635,12 +620,13 @@ void compute_ip_outs(void) { } global_count = n_out_edges = count_ip_outs(); - out_edges = xcalloc(n_out_edges, sizeof(out_edges[0])); + out_edges = XMALLOCNZ(ir_node*, n_out_edges); set_irp_ip_outedges(out_edges); set_ip_outs(); } -void free_ip_outs(void) { +void free_ip_outs(void) +{ ir_node **out_edges = get_irp_ip_outedges(); if (out_edges != NULL) { free(out_edges); @@ -651,7 +637,8 @@ void free_ip_outs(void) { #endif -void free_irg_outs(ir_graph *irg) { +void free_irg_outs(ir_graph *irg) +{ /* current_ir_graph->outs_state = outs_none; */ irg->outs_state = outs_none; @@ -672,3 +659,48 @@ void free_irg_outs(ir_graph *irg) { irg_walk_graph (irg, reset_outs, NULL, NULL); #endif /* defined DEBUG_libfirm */ } + +static void check_out_edges(ir_node *irn, void *env) +{ + int i, j, pos; + int *pError = env; + int error = *pError; + int last = is_Block(irn) ? 0 : -1; + + /* check forward: every input must have an out edge */ + for (i = get_irn_arity(irn) - 1; i >= last; --i) { + ir_node *pred = get_irn_n(irn, i); + + for (j = get_irn_n_outs(pred) - 1; j >= 0; --j) { + ir_node *user = get_irn_out_ex(pred, j, &pos); + + if (user == irn && pos == i) { + break; + } + } + if (j < 0) { + ir_fprintf(stderr, "Missing out edge from %+F input %d to %+F", irn, i, pred); + ++error; + } + } + + /* checking backward */ + for (i = get_irn_n_outs(irn) - 1; i >= 0; --i) { + ir_node *user = get_irn_out_ex(irn, i, &pos); + + if (get_irn_n(user, pos) != irn) { + ir_fprintf(stderr, "Spurious out edge from %+F output %d to %+F", irn, i, user); + ++error; + } + } + *pError = error; +} + +/* verify outs edges. */ +void verify_outs(ir_graph *irg) +{ + int errors = 0; + irg_walk_graph(irg, NULL, check_out_edges, &errors); + if (errors > 0) + panic("Out edges are corrupt"); +}