Commit 3cd5b215 authored by Matthias Braun's avatar Matthias Braun
Browse files

extract be_value_live_after() from be_values_interfere()

Value live_after() is a special case of the checks performed in
values_interfere(). This commit extracts this code and use the new function
where possible.
parent 2ef7259c
...@@ -60,7 +60,7 @@ static void pair_up_operands(be_chordal_env_t const *const env, be_insn_t *const ...@@ -60,7 +60,7 @@ static void pair_up_operands(be_chordal_env_t const *const env, be_insn_t *const
be_operand_t *const out_op = &insn->ops[j]; be_operand_t *const out_op = &insn->ops[j];
for (int i = insn->use_start; i < insn->n_ops; ++i) { for (int i = insn->use_start; i < insn->n_ops; ++i) {
be_operand_t *const op = &insn->ops[i]; be_operand_t *const op = &insn->ops[i];
if (op->partner || be_values_interfere(insn->irn, op->carrier)) if (op->partner || be_value_live_after(op->carrier, insn->irn))
continue; continue;
rbitset_copy(bs, op->regs, n_regs); rbitset_copy(bs, op->regs, n_regs);
...@@ -169,7 +169,7 @@ static void handle_constraints(be_chordal_env_t *const env, ir_node *const irn) ...@@ -169,7 +169,7 @@ static void handle_constraints(be_chordal_env_t *const env, ir_node *const irn)
ir_node *const proj = get_edge_src_irn(edge); ir_node *const proj = get_edge_src_irn(edge);
assert(is_Proj(proj)); assert(is_Proj(proj));
if (!be_values_interfere(proj, irn) || pmap_contains(partners, proj)) if (!be_value_live_after(proj, irn) || pmap_contains(partners, proj))
continue; continue;
/* Don't insert a node twice. */ /* Don't insert a node twice. */
......
...@@ -445,45 +445,57 @@ void be_liveness_nodes_live_before(be_lv_t const *const lv, arch_register_class_ ...@@ -445,45 +445,57 @@ void be_liveness_nodes_live_before(be_lv_t const *const lv, arch_register_class_
} }
} }
bool be_values_interfere(const ir_node *a, const ir_node *b) /**
* Check if value @p value is live at definition of @p after.
* @note assumes value dominates after
*/
static bool value_live_after(const ir_node *const value,
const ir_node *const after)
{ {
assert(a != b); /* If value is live end in after's block it is
if (value_strictly_dominates(b, a)) { * live at after's definition (value dominates after) */
/* Adjust a and b so, that a dominates b if const ir_node *const bb = get_nodes_block(after);
* a dominates b or vice versa. */
const ir_node *const t = a;
a = b;
b = t;
} else if (!value_strictly_dominates(a, b)) {
/* If there is no dominance relation, they do not interfere. */
return false;
}
/* If a is live end in b's block it is
* live at b's definition (a dominates b) */
const ir_node *const bb = get_nodes_block(b);
const ir_graph *const irg = get_Block_irg(bb); const ir_graph *const irg = get_Block_irg(bb);
const be_lv_t *const lv = be_get_irg_liveness(irg); const be_lv_t *const lv = be_get_irg_liveness(irg);
if (be_is_live_end(lv, bb, a)) if (be_is_live_end(lv, bb, value))
return true; return true;
/* Look at all usages of a. /* Look at all usages of value.
* If there's one usage of a in the block of b, then we check, if this use * If there's one usage of value in the block of after, then we check, if
* is dominated by b, if that's true a and b interfere. Note that b must * this use is dominated by after, if that's true value and after interfere.
* strictly dominate the user, since if b is the last user of in the block, * Note that after must strictly dominate the user, since if after is the
* b and a do not interfere. * last user of in the block, after and value do not interfere.
* Uses of a not in b's block can be disobeyed, because the check for a * Uses of value not in after's block can be disobeyed, because the check
* being live at the end of b's block is already performed. */ * for value being live at the end of after's block is already performed. */
foreach_out_edge(a, edge) { foreach_out_edge(value, edge) {
const ir_node *const user = get_edge_src_irn(edge); const ir_node *const user = get_edge_src_irn(edge);
if (get_nodes_block(user) == bb && !is_Phi(user) if (get_nodes_block(user) == bb && !is_Phi(user)
&& sched_comes_before(b, user)) && sched_comes_before(after, user))
return true; return true;
} }
return false; return false;
} }
bool be_value_live_after(const ir_node *value, const ir_node *after)
{
assert(value != after);
if (!value_strictly_dominates(value, after))
return false;
return value_live_after(value, after);
}
bool be_values_interfere(const ir_node *a, const ir_node *b)
{
assert(a != b);
if (value_strictly_dominates(b, a)) {
return value_live_after(b, a);
} else if (value_strictly_dominates(a, b)) {
return value_live_after(a, b);
}
return false;
}
static bool live_at_user(const ir_node *const users_of, static bool live_at_user(const ir_node *const users_of,
const ir_node *const node, const ir_node *const bb) const ir_node *const node, const ir_node *const bb)
{ {
......
...@@ -121,6 +121,11 @@ void be_liveness_end_of_block(const be_lv_t *lv, ...@@ -121,6 +121,11 @@ void be_liveness_end_of_block(const be_lv_t *lv,
const arch_register_class_t *cls, const arch_register_class_t *cls,
const ir_node *bl, ir_nodeset_t *nodeset); const ir_node *bl, ir_nodeset_t *nodeset);
/**
* Check if value @p value is live after value @p after.
*/
bool be_value_live_after(const ir_node *value, const ir_node *after);
/** /**
* Check, if two values interfere. * Check, if two values interfere.
* @param lv Liveness information * @param lv Liveness information
......
...@@ -728,7 +728,7 @@ static int push_through_perm(ir_node *perm) ...@@ -728,7 +728,7 @@ static int push_through_perm(ir_node *perm)
goto found_front; goto found_front;
} }
be_foreach_use(irn, cls, in_req_, op, op_req_, be_foreach_use(irn, cls, in_req_, op, op_req_,
if (!be_values_interfere(op, one_proj)) { if (!be_value_live_after(op, perm)) {
frontier = irn; frontier = irn;
goto found_front; goto found_front;
} }
......
...@@ -161,7 +161,7 @@ static void prepare_constr_insn(ir_node *const node) ...@@ -161,7 +161,7 @@ static void prepare_constr_insn(ir_node *const node)
* results. Additional copies here would destroy this. */ * results. Additional copies here would destroy this. */
if (be_is_Copy(in)) if (be_is_Copy(in))
continue; continue;
if (!be_values_interfere(node, in)) if (!be_value_live_after(in, node))
continue; continue;
bool common_limits = false; bool common_limits = false;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment