Commit 2ef7259c authored by Matthias Braun's avatar Matthias Braun
Browse files

bespillslots: move memory value interference check to belive

parent 6097e32c
......@@ -484,6 +484,71 @@ bool be_values_interfere(const ir_node *a, const ir_node *b)
return false;
}
static bool live_at_user(const ir_node *const users_of,
const ir_node *const node, const ir_node *const bb)
{
foreach_out_edge(users_of, edge) {
const ir_node *const user = get_edge_src_irn(edge);
if (is_Sync(user))
return live_at_user(user, node, bb);
if (get_nodes_block(user) == bb && !is_Phi(user)
&& sched_comes_before(node, user))
return true;
}
return false;
}
static const ir_node *get_highest_sync_op(const ir_node *const sync)
{
const ir_node *best = get_irn_n(sync, 0);
for (int i = 1, arity = get_irn_arity(sync); i < arity; ++i) {
const ir_node *other = get_irn_n(sync, i);
if (is_Sync(other))
other = get_highest_sync_op(other);
if (value_strictly_dominates(other, best))
best = other;
}
return best;
}
bool be_memory_values_interfere(const ir_node *a, const ir_node *b)
{
if (is_Sync(a))
a = get_highest_sync_op(a);
if (is_Sync(b))
b = get_highest_sync_op(b);
if (value_strictly_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;
} 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 be_lv_t *const lv = be_get_irg_liveness(irg);
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. */
return live_at_user(a, b, bb);
}
static void collect_node(ir_node *irn, void *data)
{
struct obstack *obst = (struct obstack*)data;
......
......@@ -130,6 +130,11 @@ void be_liveness_end_of_block(const be_lv_t *lv,
*/
bool be_values_interfere(const ir_node *a, const ir_node *b);
/**
* Similar to by_values_interfere() but with special handling for Sync nodes.
*/
bool be_memory_values_interfere(const ir_node *a, const ir_node *b);
/**
* Compute a set of nodes which are live just before the given node.
* @param cls The register class to consider.
......
......@@ -273,71 +273,6 @@ static int merge_interferences(be_fec_env_t *env, bitset_t** interferences,
return res;
}
static bool live_at_user(const ir_node *const users_of,
const ir_node *const node, const ir_node *const bb)
{
foreach_out_edge(users_of, edge) {
const ir_node *const user = get_edge_src_irn(edge);
if (is_Sync(user))
return live_at_user(user, node, bb);
if (get_nodes_block(user) == bb && !is_Phi(user)
&& sched_comes_before(node, user))
return true;
}
return false;
}
static const ir_node *get_highest_sync_op(const ir_node *sync)
{
const ir_node *best = get_irn_n(sync, 0);
for (int i = 1, arity = get_irn_arity(sync); i < arity; ++i) {
const ir_node *other = get_irn_n(sync, i);
if (is_Sync(other))
other = get_highest_sync_op(other);
if (value_strictly_dominates(other, best))
best = other;
}
return best;
}
static bool memory_values_interfere(const ir_node *a, const ir_node *b)
{
if (is_Sync(a))
a = get_highest_sync_op(a);
if (is_Sync(b))
b = get_highest_sync_op(b);
if (value_strictly_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;
} 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 be_lv_t *const lv = be_get_irg_liveness(irg);
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. */
return live_at_user(a, b, bb);
}
/**
* A greedy coalescing algorithm for spillslots:
* 1. Sort the list of affinity edges
......@@ -376,7 +311,7 @@ static void do_greedy_coalescing(be_fec_env_t *env)
if (is_NoMem(spill2))
continue;
if (memory_values_interfere(spill1, spill2)) {
if (be_memory_values_interfere(spill1, spill2)) {
DB((dbg, DBG_INTERFERENCES,
"Slot %d and %d interfere\n", i, i2));
......
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