From: Sebastian Hack Date: Wed, 25 Jan 2006 17:27:02 +0000 (+0000) Subject: Minor changes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=cdf28710bfb9bc07406af412d6780c7cdb9283d2;p=libfirm Minor changes --- diff --git a/ir/be/bearch.h b/ir/be/bearch.h index c189cbe8b..9c0e92446 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -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. */ diff --git a/ir/be/beconstrperm.c b/ir/be/beconstrperm.c index 515572770..52ac06bb5 100644 --- a/ir/be/beconstrperm.c +++ b/ir/be/beconstrperm.c @@ -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, diff --git a/ir/be/belistsched.c b/ir/be/belistsched.c index 8ffed4d9e..16712488b 100644 --- a/ir/be/belistsched.c +++ b/ir/be/belistsched.c @@ -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; diff --git a/ir/be/belower.c b/ir/be/belower.c index 535d8b2d4..e9b7ac9d0 100644 --- a/ir/be/belower.c +++ b/ir/be/belower.c @@ -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) */ diff --git a/ir/be/benode.c b/ir/be/benode.c index 83c12406c..b1c6f5934 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -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) diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index 55bb3603a..c3fb7ba73 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -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); diff --git a/ir/be/firm/bearch_firm.c b/ir/be/firm/bearch_firm.c index 4e01c33da..3233dce94 100644 --- a/ir/be/firm/bearch_firm.c +++ b/ir/be/firm/bearch_firm.c @@ -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;