Commit cdf28710 authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Minor changes

parent 2bf11d78
......@@ -37,7 +37,6 @@ struct _be_node_factory_t;
typedef enum _arch_register_type_t {
arch_register_type_none = 0,
arch_register_type_write_invariant,
arch_register_type_caller_saved, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
in the called function. */
......@@ -187,8 +186,9 @@ typedef enum _arch_irn_class_t {
* Some flags describing a node in more detail.
*/
typedef enum _arch_irn_flags_t {
arch_irn_flags_spillable = 1,
arch_irn_flags_rematerializable = 2
arch_irn_flags_dont_spill = 1, /**< This must not be spilled. */
arch_irn_flags_rematerializable = 2, /**< This should be replicated instead of spilled/reloaded. */
arch_irn_flags_ignore = 4, /**< Do not consider the node during register allocation. */
} arch_irn_flags_t;
struct _arch_irn_ops_if_t {
......@@ -348,9 +348,15 @@ extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node *
*/
extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn);
#define arch_irn_is_ignore(env, irn) \
(arch_irn_get_flags(env, irn) == arch_irn_flags_ignore)
#define arch_irn_has_reg_class(env, irn, pos, cls) \
((cls) == arch_get_irn_reg_class(env, irn, pos))
#define arch_irn_consider_in_reg_alloc(env, cls, irn) \
(arch_irn_has_reg_class(env, irn, -1, cls) && !arch_irn_is_ignore(env, irn))
/**
* Somebody who can be asked about nodes.
*/
......
......@@ -31,7 +31,9 @@ static void check_constraints(const be_chordal_env_t *cenv, ir_node *base, ir_no
for(pos = -1, n = get_irn_arity(irn); pos < n; ++pos) {
arch_get_register_req(aenv, &req, irn, pos);
if(arch_irn_has_reg_class(aenv, irn, pos, cenv->cls) && arch_register_req_is(&req, limited)) {
if(arch_irn_has_reg_class(aenv, irn, pos, cenv->cls)
&& arch_register_req_is(&req, limited)
&& !arch_irn_is_ignore(aenv, irn)) {
/*
* If we inserted a perm,
......
......@@ -144,14 +144,23 @@ static INLINE usage_stats_t *get_usage_stats(ir_node *irn)
return us;
}
static int max_hops_walker(ir_node *irn, ir_node *tgt, int depth, unsigned visited_nr)
static int max_hops_walker(reg_pressure_selector_env_t *env, ir_node *irn, ir_node *curr_bl, int depth, unsigned visited_nr)
{
int i, n;
int res = 0;
if(irn != tgt) {
res = INT_MAX;
ir_node *bl = get_nodes_block(irn);
/*
* If the reached node is not in the block desired,
* return the value passed for this situation.
*/
if(get_nodes_block(irn) != bl)
return block_dominates(bl, curr_bl) ? 0 : INT_MAX;
/*
* If the node is in the current block but not
* yet scheduled, we keep on searching from that node.
*/
if(!pset_find_ptr(env->already_scheduled, irn)) {
int i, n;
int res = 0;
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *operand = get_irn_n(irn, i);
......@@ -159,34 +168,38 @@ static int max_hops_walker(ir_node *irn, ir_node *tgt, int depth, unsigned visit
int tmp;
set_irn_visited(operand, visited_nr);
tmp = max_hops_walker(operand, tgt, depth + 1, visited_nr);
tmp = max_hops_walker(env, operand, bl, depth + 1, visited_nr);
res = MAX(tmp, res);
}
}
return res;
}
return res;
/*
* If the node is in the current block and scheduled, return
* the depth which indicates the number of steps to the
* region of scheduled nodes.
*/
return depth;
}
static int compute_max_hops(reg_pressure_selector_env_t *env, ir_node *irn)
{
ir_node *bl = get_nodes_block(irn);
ir_graph *irg = get_irn_irg(bl);
int res = INT_MAX;
int res = 0;
const ir_edge_t *edge;
foreach_out_edge(irn, edge) {
ir_node *user = get_edge_src_irn(edge);
if(get_nodes_block(user) == bl && !pset_find_ptr(env->already_scheduled, user)) {
unsigned visited_nr = get_irg_visited(irg) + 1;
int max_hops;
ir_node *user = get_edge_src_irn(edge);
unsigned visited_nr = get_irg_visited(irg) + 1;
int max_hops;
set_irg_visited(irg, visited_nr);
max_hops = max_hops_walker(user, irn, 0, visited_nr);
res = MAX(res, max_hops);
}
set_irg_visited(irg, visited_nr);
max_hops = max_hops_walker(env, user, irn, 0, visited_nr);
res = MAX(res, max_hops);
}
return res;
......@@ -244,6 +257,23 @@ static void reg_pressure_block_free(void *block_env)
free(env);
}
static int get_result_hops_sum(reg_pressure_selector_env_t *env, ir_node *irn)
{
int res = 0;
if(get_irn_mode(irn) == mode_T) {
const ir_edge_t *edge;
foreach_out_edge(irn, edge)
res += get_result_hops_sum(env, get_edge_src_irn(edge));
}
else if(mode_is_data(get_irn_mode(irn)))
res = compute_max_hops(env, irn);
return res;
}
static INLINE int reg_pr_costs(reg_pressure_selector_env_t *env, ir_node *irn)
{
int i, n;
......@@ -256,10 +286,12 @@ static INLINE int reg_pr_costs(reg_pressure_selector_env_t *env, ir_node *irn)
sum += compute_max_hops(env, op);
}
sum += get_result_hops_sum(env, irn);
return sum;
}
ir_node *reg_pressure_select(void *block_env, pset *ready_set)
static ir_node *reg_pressure_select(void *block_env, pset *ready_set)
{
reg_pressure_selector_env_t *env = block_env;
ir_node *irn, *res = NULL;
......
......@@ -464,6 +464,7 @@ static void lower_call_node(ir_node *call, const void *walk_env) {
}
else {
proj_T = new_r_Proj(current_ir_graph, block, call, mode_T, pn_Call_T_result);
last_proj = call;
}
/* Create for each caller save register a proj (keep node argument) */
......
......@@ -543,38 +543,29 @@ static const ir_op_ops be_node_op_ops = {
NULL
};
ir_node *insert_Perm_after(const arch_env_t *arch_env,
const arch_register_class_t *cls,
dom_front_info_t *dom_front,
ir_node *pos)
pset *nodes_live_at(const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live)
{
ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
ir_graph *irg = get_irn_irg(bl);
pset *live = pset_new_ptr_default();
firm_dbg_module_t *dbg = firm_dbg_register("be.node");
firm_dbg_module_t *dbg = firm_dbg_register("firm.be.node");
ir_node *bl = get_nodes_block(pos);
ir_node *irn;
irn_live_t *li;
ir_node *curr, *irn, *perm, **nodes;
int i, n;
DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos));
live_foreach(bl, li) {
ir_node *irn = (ir_node *) li->irn;
if(live_is_end(li) && arch_irn_has_reg_class(arch_env, irn, -1, cls))
if(live_is_end(li) && arch_irn_consider_in_reg_alloc(arch_env, cls, irn))
pset_insert_ptr(live, irn);
}
sched_foreach_reverse(bl, irn) {
int i, n;
ir_node *x;
/*
* If we encounter the node we want to insert the Perm after,
* exit immediately, so that this node is still live
*/
/*
* If we encounter the node we want to insert the Perm after,
* exit immediately, so that this node is still live
*/
if(irn == pos)
break;
return live;
DBG((dbg, LEVEL_1, "%+F\n", irn));
for(x = pset_first(live); x; x = pset_next(live))
......@@ -586,11 +577,32 @@ ir_node *insert_Perm_after(const arch_env_t *arch_env,
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
if(arch_irn_has_reg_class(arch_env, op, -1, cls))
if(arch_irn_consider_in_reg_alloc(arch_env, cls, op))
pset_insert_ptr(live, op);
}
}
return NULL;
}
ir_node *insert_Perm_after(const arch_env_t *arch_env,
const arch_register_class_t *cls,
dom_front_info_t *dom_front,
ir_node *pos)
{
ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
ir_graph *irg = get_irn_irg(bl);
pset *live = pset_new_ptr_default();
firm_dbg_module_t *dbg = firm_dbg_register("be.node");
ir_node *curr, *irn, *perm, **nodes;
int i, n;
DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos));
if(!nodes_live_at(arch_env, cls, pos, live))
assert(0 && "position not found");
n = pset_count(live);
if(n == 0)
......
......@@ -52,7 +52,7 @@ int be_is_Copy(const ir_node *irn);
int be_is_Perm(const ir_node *irn);
int be_is_Keep(const ir_node *irn);
void be_set_Spill_offset(ir_node *irn, unsigned offset);
void be_set_Spill_offset(ir_node *irn, unsigned offset);
unsigned be_get_spill_offset(ir_node *irn);
ir_node *be_get_Spill_context(const ir_node *irn);
......
......@@ -275,7 +275,7 @@ static arch_irn_class_t firm_classify(const void *self, const ir_node *irn)
static arch_irn_flags_t firm_get_flags(const void *self, const ir_node *irn)
{
arch_irn_flags_t res = arch_irn_flags_spillable;
arch_irn_flags_t res = 0;
if(get_irn_op(irn) == op_imm)
res |= arch_irn_flags_rematerializable;
......
Supports Markdown
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