X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbera.c;h=024452ab7dc4cf69a2f971a5b593f7541710c026;hb=17e47394fa72025d14172a2acef2d258a067aa42;hp=4bcc69cba8b52d98c9fc4e8ddd1604f74ec19afb;hpb=5663da1d73944b6aae2bf6d38ef58e188ad76e1c;p=libfirm diff --git a/ir/be/bera.c b/ir/be/bera.c index 4bcc69cba..024452ab7 100644 --- a/ir/be/bera.c +++ b/ir/be/bera.c @@ -3,6 +3,9 @@ * @author Sebastian Hack * @date 22.11.2004 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "pset.h" #include "impl.h" @@ -11,116 +14,89 @@ #include "irmode.h" #include "irdom.h" -#include "bera_t.h" +#include "beutil.h" #include "besched_t.h" #include "belive_t.h" -FIRM_IMPL1(is_allocatable_irn, int, const ir_node *) - -size_t ra_irn_data_offset = 0; -size_t ra_irg_data_offset = 0; - -void be_ra_init(void) +int value_dominates(const ir_node *a, const ir_node *b) { - ra_irn_data_offset = register_additional_node_data(sizeof(ra_info_t)); - ra_irg_data_offset = register_additional_graph_data(sizeof(void *)); -} - -static INLINE int values_interfere_dom(const ir_node *a, const ir_node *b) -{ - const ir_node *b1 = get_nodes_block(a); - const ir_node *b2 = get_nodes_block(b); - int lo_a, lo_b; - - assert(block_dominates(b1, b2)); - - /* - * if the two blocks are not equal, a and b can only interfere if a is - * live in at b2. - */ - if(b1 != b2 && !is_live_in(b2, a)) - return 0; - - lo_a = is_live_end(b2, a); - lo_b = is_live_end(b2, b); - - /* - * If the two blocks are the same and one value is live out and the - * definition of the other is after the definition ov the live out - * value, they interfere. - */ - if(b1 == b2) { - int pos_a = sched_get_time_step(a); - int pos_b = sched_get_time_step(b); - - if((pos_a < pos_b && lo_a) || (pos_b < pos_a && lo_b)) - return 1; - } - - /* - * Now it is left to check, if the sequence from the last use of 'b' - * (or the end of the block b2, if b is live out) - * to the def of 'b' contains a use and NOT the def of 'a'. Then they - * also interfere - */ - { - const ir_node *irn; - - /* Initialize the liveness. */ - int a_live = lo_a; - int b_live = lo_b; - - /* Go from the end of block b2 and try to detect the liveness. */ - sched_foreach_reverse(b2, irn) { - int i, n; - - /* - * If the definition of 'a' was found 'a' and 'b' interfere, if - * 'b' is live here. - */ - if(irn == a) - return b_live; - - /* Same goes for 'b'. */ - if(irn == b) - return a_live; - - /* If 'a' is not yet live, search for a use. */ - if(!a_live) { - for(i = 0, n = get_irn_arity(irn); i < n; ++i) - if(get_irn_n(irn, i) == a) { - a_live = 1; - break; - } - } - - /* Same for 'b' */ - if(!b_live) { - for(i = 0, n = get_irn_arity(irn); i < n; ++i) - if(get_irn_n(irn, i) == b) { - b_live = 1; - break; - } - } - - } - } - - assert(0 && "You may never reach this place"); - - /* This is never reached */ - return 0; + int res = 0; + const ir_node *ba = get_block(a); + const ir_node *bb = get_block(b); + + /* + * a and b are not in the same block, + * so dominance is determined by the dominance of the blocks. + */ + if(ba != bb) + res = block_dominates(ba, bb); + + /* + * Dominance is determined by the time steps of the schedule. + */ + else { + sched_timestep_t as = sched_get_time_step(a); + sched_timestep_t bs = sched_get_time_step(b); + res = as <= bs; + } + + return res; } +/** + * Check, if two values interfere. + * @param a The first value. + * @param b The second value. + * @return 1, if a and b interfere, 0 if not. + */ int values_interfere(const ir_node *a, const ir_node *b) { - const ir_node *b1 = get_nodes_block(a); - const ir_node *b2 = get_nodes_block(b); - - if(block_dominates(b1, b2)) - return values_interfere_dom(a, b); - else if(block_dominates(b2, b1)) - return values_interfere_dom(b, a); - else - return 0; + int a2b = value_dominates(a, b); + int b2a = value_dominates(b, a); + + /* If there is no dominance relation, they do not interfere. */ + if((a2b | b2a) > 0) { + const ir_edge_t *edge; + ir_node *bb; + + /* + * Adjust a and b so, that a dominates b if + * a dominates b or vice versa. + */ + if(b2a) { + const ir_node *t = a; + a = b; + b = t; + } + + bb = get_nodes_block(b); + + /* + * If a is live end in b's block it is + * live at b's definition (a dominates b) + */ + if(is_live_end(bb, a)) + return 1; + + /* + * Look at all usages of a. + * If there's one usage of a in the block of b, then + * we check, if this use is dominated by b, if that's true + * a and b interfere. Note that b must strictly dominate the user, + * since if b is the last user of in the block, b and a do not + * interfere. + * Uses of a not in b's block can be disobeyed, because the + * check for a being live at the end of b's block is already + * performed. + */ + foreach_out_edge(a, edge) { + const ir_node *user = edge->src; + if(get_nodes_block(user) == bb + && !is_Phi(user) + && b != user + && value_dominates(b, user)) + return 1; + } + } + return 0; }