X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Firouts.c;h=cb32aa994802f2c7cae935687f7aaf5727a2f2a9;hb=70cfa8796df2436b48a224e0568f5ee0b595dfb0;hp=f5eba03ae57f315efafa26cad545b1a0a764fcfe;hpb=bb9f2e36362333c6635b89f5258171b06c786608;p=libfirm diff --git a/ir/ana/irouts.c b/ir/ana/irouts.c index f5eba03ae..cb32aa994 100644 --- a/ir/ana/irouts.c +++ b/ir/ana/irouts.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -26,9 +26,7 @@ */ #include "config.h" -#ifdef HAVE_STRING_H #include -#endif #include "xmalloc.h" #include "irouts.h" @@ -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(const 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(const ir_node *node) { } /* Access successor n */ -ir_node *get_irn_out(const 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(const ir_node *def, int pos) { } /* Access successor n */ -ir_node *get_irn_out_ex(const 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(const 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(const 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(const ir_node *bl) { } /* Return the number of control flow successors, honor keep-alives. */ -int get_Block_n_cfg_outs_ka(const 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(const ir_node *bl) { } /* Access predecessor n, ignore keep-alives. */ -ir_node *get_Block_cfg_out(const 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(const ir_node *bl, int pos) { } /* Access predecessor n, honor keep-alives. */ -ir_node *get_Block_cfg_out_ka(const 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(const 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,9 +234,9 @@ 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_block_visited(bl)) { @@ -249,11 +257,11 @@ static void irg_out_block_walk2(ir_node *bl, } } -/* Walks only over Block nodes in the graph. Has it's own visited +/* Walks only over Block nodes in the graph. Has its 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,11 +301,12 @@ 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); - n->out = INT_TO_PTR(1); /* Space for array size. */ + n->out = (ir_def_use_edge*) INT_TO_PTR(1); /* Space for array size. */ start = is_Block(n) ? 0 : -1; irn_arity = get_irn_arity(n); @@ -318,7 +326,7 @@ static int _count_outs(ir_node *n) { res += _count_outs(skipped_pred); /*count my Def-Use edges */ - skipped_pred->out = INT_TO_PTR(PTR_TO_INT(skipped_pred->out) + 1); + skipped_pred->out = (ir_def_use_edge*) INT_TO_PTR(PTR_TO_INT(skipped_pred->out) + 1); } return res; } @@ -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; @@ -339,7 +348,7 @@ static int count_outs(ir_graph *irg) { for (i = anchor_last - 1; i >= 0; --i) { n = get_irg_anchor(irg, i); if (!irn_visited_else_mark(n)) { - n->out = INT_TO_PTR(1); + n->out = (ir_def_use_edge*) INT_TO_PTR(1); ++res; } } @@ -354,8 +363,10 @@ 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) { - int n_outs, start, i, irn_arity, pos; +static ir_def_use_edge *_set_out_edges(ir_node *use, ir_def_use_edge *free) +{ + int start, i, irn_arity, pos; + size_t n_outs; mark_irn_visited(use); @@ -400,9 +411,10 @@ 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; + int i; inc_irg_visited(irg); free = _set_out_edges(get_irg_end(irg), free); @@ -411,7 +423,7 @@ static ir_def_use_edge *set_out_edges(ir_graph *irg, ir_def_use_edge *free) { for (i = anchor_last - 1; i >= 0; --i) { n = get_irg_anchor(irg, i); if (!irn_visited_else_mark(n)) { - n_outs = PTR_TO_INT(n->out); + size_t n_outs = PTR_TO_INT(n->out); n->out = free; #ifdef DEBUG_libfirm n->out_valid = 1; @@ -423,34 +435,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 0, the Start block at position 1. This is necessary for - * the out block walker. - */ -static inline void fix_start_proj(ir_graph *irg) { - ir_node *startbl = get_irg_start_block(irg); - - if (get_Block_n_cfg_outs(startbl)) { - ir_node *proj = get_irg_initial_exec(irg); - ir_node *irn; - int block_pos, other_pos; - - if (get_irn_n_outs(proj) == 2) { - if (get_irn_out_ex(proj, 0, &block_pos) == startbl) { - 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); - } - } else { - assert(get_irg_phase_state(irg) == phase_backend); - } - } -} - /* 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 */ @@ -480,172 +467,32 @@ 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 0, the Start block at position 1. This is necessary for - code placement (place_early() ONLY if started GCSE on graphs with dead blocks) */ - 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) { - int i; - for (i = get_irp_n_irgs() -1; i >= 0; --i) +void compute_irp_outs(void) +{ + size_t i, n; + for (i = 0, n = get_irp_n_irgs(); i < n; ++i) compute_irg_outs(get_irp_irg(i)); } -void free_irp_outs(void) { - int i; - for (i = get_irp_n_irgs() -1; i >= 0; --i) +void free_irp_outs(void) +{ + size_t i, n; + for (i = 0, n = get_irp_n_irgs(); i < n; ++i) free_irg_outs(get_irp_irg(i)); } - -/*------------------------------------------------------------* - * This computes the outedges for in interprocedural graph. * - * There is one quirk: * - * The number of the outedges for each node is saved in * - * the first member of the ir_node** array. Maybe we should * - * change this to make it more portable... * - *------------------------------------------------------------*/ - - -#ifdef INTERPROCEDURAL_VIEW -/** - * Inits the number of outedges for each node - * before counting. - */ -static void init_count(ir_node * node, void *env) { - (void) env; - node->out = (ir_node **) 1; /* 1 for the array size */ -} - - -/** - * Adjusts the out edge count for its predecessors - * and adds the current arity to the overall count, - * which is saved in "env" - */ -static void node_arity_count(ir_node * node, void * env) { - int *anz = (int *) env, arity, n_outs, i, start; - ir_node *succ; - - arity = get_irn_arity(node); - start = (is_Block(node)) ? 0 : -1; - - n_outs = 1 + arity + (-start); // ((is_Block(node)) ? 0 : 1); // Why + 1?? - *anz += n_outs; - - 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); - } -} - -/* - * Inits all nodes for setting the outedges - * Returns the overall count of edges - */ -int count_ip_outs(void) { - int res = 0; - - cg_walk(init_count, node_arity_count, &res); - - return(res); -} - -static int dummy_count = 0, global_count; /* Only for debugging */ - -/** - * For each node: Sets the pointer to array - * 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) { - int n_outs; - ir_node ***free = (ir_node ***) env; - - /* Allocate my array */ - n_outs = PTR_TO_INT(node->out); /* We wrote the count here in count_ip_outs */ - dummy_count += n_outs; - assert(dummy_count <= global_count && "More outedges than initially counted!"); - node -> out = *free; - *free = &((*free)[n_outs]); - /* We count the successors again, the space will be sufficient. - We use this counter to remember the position for the next back - edge. */ - node -> out[0] = (ir_node *) 0; -} - - -/** - * Adds an outedge from the predecessor to the - * current node. - */ -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; - (void) env; - - for (i = start; i < arity; ++i) { - succ = get_irn_n(node, i); - succ->out[get_irn_n_outs(succ)+1] = node; - succ->out[0] = INT_TO_PTR(get_irn_n_outs(succ) + 1); - } -} - - -/* - * Sets the outedges for all nodes. - */ -void set_ip_outs(void) { - ir_node **outedge_array = get_irp_ip_outedges(); - cg_walk(set_array_pointer, set_out_pointer, (void *) &outedge_array); -} - - - -/* - * Counts the outedges, allocates memory to save the - * outedges and fills this outedge array in interprocedural - * view! - */ -void compute_ip_outs(void) { - int n_out_edges; - ir_node **out_edges; - - assert(get_irp_ip_view_state() == ip_view_valid && - "Cannot construct outs for invalid ip view."); - - if (irp->outs_state != outs_none) { - free_ip_outs(); - } - - global_count = n_out_edges = count_ip_outs(); - out_edges = XMALLOCNZ(ir_node*, n_out_edges); - set_irp_ip_outedges(out_edges); - set_ip_outs(); -} - -void free_ip_outs(void) { - ir_node **out_edges = get_irp_ip_outedges(); - if (out_edges != NULL) { - free(out_edges); - set_irp_ip_outedges(NULL); - } - irp->outs_state = outs_none; -} -#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; @@ -666,46 +513,3 @@ 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"); -}