X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeintlive_t.h;h=0b50259b0290f8798aab9b45b55bc6166bfd390a;hb=34e3b8d50bce639e760da7233524a4db85c80290;hp=fc075a6fa3245b8721d334ab079d1eef564c4362;hpb=bb9f2e36362333c6635b89f5258171b06c786608;p=libfirm diff --git a/ir/be/beintlive_t.h b/ir/be/beintlive_t.h index fc075a6fa..0b50259b0 100644 --- a/ir/be/beintlive_t.h +++ b/ir/be/beintlive_t.h @@ -1,26 +1,14 @@ -/** - * @file beintlive_t.h - * @date 10.05.2007 - * @author Sebastian Hack - * - * Principal routines for liveness and interference checks. - * - * Copyright (C) 2007 Universitaet Karlsruhe - * Released under the GPL +/* + * This file is part of libFirm. + * Copyright (C) 2012 Universitaet Karlsruhe */ - #ifndef _BELIVECHK_T_H #define _BELIVECHK_T_H -#include "irgraph_t.h" -#include "irphase_t.h" -#include "iredges_t.h" - -#include "statev.h" - -#include "beirg_t.h" -#include "besched_t.h" +#include "besched.h" #include "belive_t.h" +#include "beutil.h" +#include "iredges_t.h" /** * Check dominance of two nodes in the same block. @@ -30,9 +18,8 @@ */ static inline int _value_dominates_intrablock(const ir_node *a, const ir_node *b) { - /* TODO: ? : can be removed?! */ - sched_timestep_t as = sched_is_scheduled(a) ? sched_get_time_step(a) : 0; - sched_timestep_t bs = sched_is_scheduled(b) ? sched_get_time_step(b) : 0; + sched_timestep_t const as = sched_get_time_step(a); + sched_timestep_t const bs = sched_get_time_step(b); return as <= bs; } @@ -44,9 +31,8 @@ static inline int _value_dominates_intrablock(const ir_node *a, const ir_node *b */ static inline int _value_strictly_dominates_intrablock(const ir_node *a, const ir_node *b) { - /* TODO: ? : can be removed?! */ - sched_timestep_t as = sched_is_scheduled(a) ? sched_get_time_step(a) : 0; - sched_timestep_t bs = sched_is_scheduled(b) ? sched_get_time_step(b) : 0; + sched_timestep_t const as = sched_get_time_step(a); + sched_timestep_t const bs = sched_get_time_step(b); return as < bs; } @@ -57,7 +43,7 @@ static inline int _value_strictly_dominates_intrablock(const ir_node *a, const i * @param b The second node. * @return 1 if a dominates b or if a == b, 0 else. */ -static inline int _value_dominates(const ir_node *a, const ir_node *b) +static inline int value_dominates(const ir_node *a, const ir_node *b) { const ir_node *block_a = get_block_const(a); const ir_node *block_b = get_block_const(b); @@ -76,199 +62,49 @@ static inline int _value_dominates(const ir_node *a, const ir_node *b) return _value_dominates_intrablock(a, b); } -/** - * Check, if one value dominates the other. - * The dominance is strict here. - * @param a The first node. - * @param b The second node. - * @return 1 if a dominates b, 0 else. - */ -static inline int _value_strictly_dominates(const ir_node *a, const ir_node *b) -{ - const ir_node *block_a = get_block_const(a); - const ir_node *block_b = get_block_const(b); - - /* - * a and b are not in the same block, - * so dominance is determined by the dominance of the blocks. - */ - if(block_a != block_b) { - return block_dominates(block_a, block_b); - } - - /* - * Dominance is determined by the time steps of the schedule. - */ - return _value_strictly_dominates_intrablock(a, b); -} - /** * Check, if two values interfere. - * @param lv Liveness information (in the future we should use a be_irg_t here). + * @param lv Liveness information * @param a The first value. * @param b The second value. - * @return 1, if a and b interfere, 0 if not. + * @return true, if a and b interfere, false if not. */ -static inline int _lv_values_interfere(const be_lv_t *lv, const ir_node *a, const ir_node *b) +static inline bool be_values_interfere(be_lv_t const *lv, ir_node const *a, ir_node const *b) { - int a2b = _value_dominates(a, b); - int b2a = _value_dominates(b, a); - int res = 0; - - /* - * Adjust a and b so, that a dominates b if - * a dominates b or vice versa. - */ - if(b2a) { - const ir_node *t = a; + if (value_dominates(b, a)) { + /* Adjust a and b so, that a dominates b if + * a dominates b or vice versa. */ + ir_node const *const t = a; a = b; b = t; - a2b = 1; + } else if (!value_dominates(a, b)) { + /* If there is no dominance relation, they do not interfere. */ + return false; } - /* If there is no dominance relation, they do not interfere. */ - if(a2b) { - const ir_edge_t *edge; - ir_node *bb = get_nodes_block(b); - - //stat_ev_dbl("beintlive_ignore", arch_irn_is(lv->birg->main_env->arch_env, a, ignore)); - - /* - * If a is live end in b's block it is - * live at b's definition (a dominates b) - */ - if(be_is_live_end(lv, bb, a)) { - res = 1; - goto end; - } - - /* - * 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 = get_edge_src_irn(edge); - if(get_nodes_block(user) == bb && !is_Phi(user) && _value_strictly_dominates(b, user)) { - res = 1; - goto end; - } - } - } - -end: - return res; -} - - - -/** - * Check if a node dominates a use. - * Note that the use of a phi is in its corresponding predecessor. - * @param irn The node. - * @param edge The use. - * @return 1, if @p irn dominates the use @p edge. - */ -static inline int _dominates_use(const ir_node *irn, const ir_edge_t *edge) -{ - ir_node *use = get_edge_src_irn(edge); - - if (is_Phi(use)) { - int pos = get_edge_src_pos(edge); - ir_node *phi_bl = get_nodes_block(use); - ir_node *use_bl = get_Block_cfgpred_block(phi_bl, pos); - ir_node *irn_bl = get_nodes_block(irn); - return block_dominates(irn_bl, use_bl); - } - - return _value_dominates(irn, use); -} - -/** - * Check if a node strictly dominates a use. - * Note that the use of a phi is in its corresponding predecessor. - * @param irn The node. - * @param edge The use. - * @return 1, if @p irn strictly dominates the use @p edge. - */ -static inline int _strictly_dominates_use(const ir_node *irn, const ir_edge_t *edge) -{ - return get_edge_src_irn(edge) != irn && _dominates_use(irn, edge); -} - -/** - * Check, if a node is live in front of another. - * @param birg The backend irg. - * @param irn The node. - * @param where The location to check for. - * @return 1, if @p irn is live in front of @p where. - */ -static inline int _be_lv_chk_before_irn(const be_irg_t *birg, const ir_node *irn, const ir_node *where) -{ - const be_lv_t *lv = be_get_birg_liveness(birg); - const ir_edge_t *edge; - - /* the node must strictly dominate the location, else it cannot be live there. */ - if (!_value_dominates(irn, where) || irn == where) - return 0; - - /* - * now that it is clear that it strictly dominates the location it is surely live - * if it is also live end at the block. - */ - if (be_is_live_end(lv, get_nodes_block(where), irn)) - return 1; - - /* - * If the node is not live out, we have to check if there - * is a use which is dominated by the location. - */ - foreach_out_edge (irn, edge) { - if (_dominates_use(where, edge)) - return 1; - } - - return 0; -} - -/** - * Check, if a node is live after another node. - * @param birg The backend irg. - * @param irn The node. - * @param where The location to check for. - * @return 1, if @p irn is live after @p where. - */ -static inline int _be_lv_chk_after_irn(const be_irg_t *birg, const ir_node *irn, const ir_node *where) -{ - const be_lv_t *lv = be_get_birg_liveness(birg); - const ir_edge_t *edge; - - if (!_value_dominates(irn, where)) - return 0; - - if (be_is_live_end(lv, get_nodes_block(where), irn)) - return 1; - - foreach_out_edge (irn, edge) { - if (_strictly_dominates_use(where, edge)) - return 1; + ir_node *const 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 (be_is_live_end(lv, bb, a)) + return true; + + /* 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) { + ir_node const *const user = get_edge_src_irn(edge); + if (get_nodes_block(user) == bb && !is_Phi(user) && _value_strictly_dominates_intrablock(b, user)) + return true; } - return 0; + return false; } -#define value_dominates_intrablock(a, b) _value_dominates_intrablock(a, b) -#define value_dominates(a, b) _value_dominates(a, b) -#define values_interfere(birg, a, b) _lv_values_interfere(be_get_birg_liveness(birg), a, b) -#define dominates_use(a, e) _dominates_use(a, e) -#define strictly_dominates_use(a, e) _strictly_dominates_use(a, e) -#define be_lv_chk_before_irn(birg, a, b) _be_lv_chk_before_irn(birg, a, b) -#define be_lv_chk_after_irn(birg, a, b) _be_lv_chk_after_irn(birg, a, b) - -#endif /* _BELIVECHK_T_H */ +#endif