Commit 8f1ba92a authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup beintlive_t

- Remove value_dominates_intrablock()/value_strictly_dominates_intrablock()
  and use sched_comes_before() instead
- Use bool instead of int return types.
- Assert that we don't check if a node interferes with itself as that is
  nearly always a bug in the code.
parent 772df979
......@@ -282,13 +282,15 @@ static int ou_max_ind_set_costs(unit_t *const ou, be_lv_t const *const lv)
int *unsafe_costs = ALLOCAN(int, ou->node_count - 1);
int unsafe_count = 0;
for (int i=1; i<ou->node_count; ++i) {
bool is_safe = true;
bool is_safe = true;
ir_node *i_node = ou->nodes[i];
for (int o=1; o<ou->node_count; ++o) {
if (i==o)
ir_node *o_node = ou->nodes[o];
if (i_node == o_node)
continue;
if (be_values_interfere(lv, ou->nodes[i], ou->nodes[o])) {
if (be_values_interfere(lv, i_node, o_node)) {
unsafe_costs[unsafe_count] = ou->costs[i];
unsafe[unsafe_count] = ou->nodes[i];
unsafe[unsafe_count] = i_node;
++unsafe_count;
is_safe = false;
break;
......@@ -296,7 +298,7 @@ static int ou_max_ind_set_costs(unit_t *const ou, be_lv_t const *const lv)
}
if (is_safe) {
safe_costs += ou->costs[i];
safe[safe_count++] = ou->nodes[i];
safe[safe_count++] = i_node;
}
}
......@@ -628,7 +630,7 @@ static void add_edge(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs)
static inline void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs)
{
be_lv_t *const lv = be_get_irg_liveness(co->irg);
if (!be_values_interfere(lv, n1, n2)) {
if (n1 != n2 && !be_values_interfere(lv, n1, n2)) {
add_edge(co, n1, n2, costs);
add_edge(co, n2, n1, costs);
}
......
......@@ -10,56 +10,25 @@
#include "beutil.h"
#include "iredges_t.h"
/**
* Check dominance of two nodes in the same block.
* @param a The first node.
* @param b The second node.
* @return 1 if a comes before b in the same block or if a == b, 0 else.
*/
static inline int _value_dominates_intrablock(const ir_node *a, const ir_node *b)
{
sched_timestep_t const as = sched_get_time_step(a);
sched_timestep_t const bs = sched_get_time_step(b);
return as <= bs;
}
/**
* Check strict dominance of two nodes in the same block.
* @param a The first node.
* @param b The second node.
* @return 1 if a comes before b in the same block, 0 else.
*/
static inline int _value_strictly_dominates_intrablock(const ir_node *a, const ir_node *b)
{
sched_timestep_t const as = sched_get_time_step(a);
sched_timestep_t const bs = sched_get_time_step(b);
return as < bs;
}
/**
* Check, if one value dominates the other.
* The dominance is not strict here.
* @param a The first node.
* @param b The second node.
* @return 1 if a dominates b or if a == b, 0 else.
* @return true if a dominates b or if a == b.
*/
static inline int value_dominates(const ir_node *a, const ir_node *b)
static inline bool value_strictly_dominates(const ir_node *a,
const ir_node *b)
{
/* if a and b are not in the same block, dominance is determined by the
* dominance of the blocks. */
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) {
if (block_a != block_b)
return block_dominates(block_a, block_b);
}
/*
* Dominance is determined by the time steps of the schedule.
*/
return _value_dominates_intrablock(a, b);
/* Dominance is determined by schedule. */
return sched_comes_before(a, b);
}
/**
......@@ -69,15 +38,17 @@ static inline int value_dominates(const ir_node *a, const ir_node *b)
* @param b The second value.
* @return true, if a and b interfere, false if not.
*/
static inline bool be_values_interfere(be_lv_t const *lv, ir_node const *a, ir_node const *b)
static inline bool be_values_interfere(be_lv_t const *lv, ir_node const *a,
ir_node const *b)
{
if (value_dominates(b, a)) {
assert(a != 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_dominates(a, b)) {
} else if (!value_strictly_dominates(a, b)) {
/* If there is no dominance relation, they do not interfere. */
return false;
}
......@@ -100,7 +71,8 @@ static inline bool be_values_interfere(be_lv_t const *lv, ir_node const *a, ir_n
* 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))
if (get_nodes_block(user) == bb && !is_Phi(user)
&& sched_comes_before(b, user))
return true;
}
......
......@@ -111,7 +111,7 @@ static void be_peephole_before_exchange(const ir_node *old_node,
/* we can't handle liveness updates correctly when exchange current node
* with something behind it */
assert(value_dominates(skip_Proj(new_node), skip_Proj_const(old_node)));
assert(value_strictly_dominates(skip_Proj(new_node), skip_Proj_const(old_node)));
}
if (!mode_is_data(get_irn_mode(old_node)))
......
......@@ -144,16 +144,17 @@ void sched_remove(ir_node *irn);
void sched_replace(ir_node *old, ir_node *irn);
/**
* Checks, if one node is scheduled before another.
* @param n1 A node.
* @param n2 Another node.
* @return true, if n1 is in front of n2 in the schedule, false else.
* @note Both nodes must be in the same block.
* Checks, if node @p a comes before node @p b.
* @param a A node.
* @param b Another node.
* @return true, if a is in front of b in the schedule, false else.
* @note Both nodes must be in the same block.
*/
static inline bool sched_comes_after(const ir_node *n1, const ir_node *n2)
static inline bool sched_comes_before(const ir_node *a, const ir_node *b)
{
assert((is_Block(n1) ? n1 : get_nodes_block(n1)) == (is_Block(n2) ? n2 : get_nodes_block(n2)));
return sched_get_time_step(n1) < sched_get_time_step(n2);
sched_timestep_t const as = sched_get_time_step(a);
sched_timestep_t const bs = sched_get_time_step(b);
return as < bs;
}
#define sched_foreach_after(after, irn) \
......
......@@ -276,13 +276,13 @@ static int merge_interferences(be_fec_env_t *env, bitset_t** interferences,
static bool my_values_interfere2(ir_graph *const irg, ir_node const *a,
ir_node const *b)
{
if (value_dominates(b, a)) {
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_dominates(a, b)) {
} else if (!value_strictly_dominates(a, b)) {
/* If there is no dominance relation, they do not interfere. */
return 0;
}
......@@ -310,12 +310,12 @@ static bool my_values_interfere2(ir_graph *const irg, ir_node const *a,
ir_node const *const user2 = get_edge_src_irn(edge2);
assert(!is_Sync(user2));
if (get_nodes_block(user2) == bb && !is_Phi(user2) &&
_value_strictly_dominates_intrablock(b, user2))
sched_comes_before(b, user2))
return true;
}
} else {
if (get_nodes_block(user) == bb && !is_Phi(user) &&
_value_strictly_dominates_intrablock(b, user))
sched_comes_before(b, user))
return true;
}
}
......
......@@ -145,12 +145,12 @@ void be_add_spill(spill_env_t *env, ir_node *to_spill, ir_node *after)
for (spill_t *s = spill_info->spills, *last = NULL ; s != NULL;
s = s->next) {
/* no need to add this spill if it is dominated by another */
if (value_dominates(s->after, after)) {
if (value_strictly_dominates(s->after, after)) {
DB((dbg, LEVEL_1, "...dominated by %+F, not added\n", s->after));
return;
}
/* remove spills that we dominate */
if (value_dominates(after, s->after)) {
if (value_strictly_dominates(after, s->after)) {
DB((dbg, LEVEL_1, "...remove old spill at %+F\n", s->after));
if (last != NULL) {
last->next = s->next;
......
......@@ -523,8 +523,9 @@ bool be_verify_spillslots(ir_graph *irg)
*/
static bool my_values_interfere(const ir_node *a, const ir_node *b)
{
int a2b = value_dominates(a, b);
int b2a = value_dominates(b, a);
assert(a != b);
int a2b = value_strictly_dominates(a, b);
int b2a = value_strictly_dominates(b, a);
/* If there is no dominance relation, they do not interfere. */
if (!a2b && !b2a)
......@@ -569,7 +570,7 @@ static bool my_values_interfere(const ir_node *a, const ir_node *b)
user = get_irn_n(phiblock, get_edge_src_pos(edge));
}
if (value_dominates(b, user))
if (value_strictly_dominates(b, user))
return true;
}
......
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