From 9b8ef1ee9281e567479012e982c49957aa736021 Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Tue, 2 May 2006 11:54:26 +0000 Subject: [PATCH] Added modify_sp flag Fixed a buf in ABI stack pointer handling --- ir/be/beabi.c | 55 ++++++++++++++++++++++++++++++++++++-------------- ir/be/bearch.c | 1 + ir/be/bearch.h | 3 ++- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/ir/be/beabi.c b/ir/be/beabi.c index a763407a9..2de57d9de 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -1113,8 +1113,8 @@ static reg_node_map_t *reg_map_to_arr(struct obstack *obst, pmap *reg_map) static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pmap *regs, int in_req) { ir_graph *irg = env->birg->irg; + int n_regs = pmap_count(regs); int n; - int n_regs = pmap_count(regs); ir_node *irn; ir_node **in; reg_node_map_t *rm; @@ -1134,9 +1134,10 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm obstack_free(&env->obst, in); for(n = 0; n < n_regs; ++n) { - int pos = BE_OUT_POS(n); - ir_node *proj; const arch_register_t *reg = rm[n].reg; + int flags = 0; + int pos = BE_OUT_POS(n); + ir_node *proj; proj = new_r_Proj(irg, bl, irn, get_irn_mode(rm[n].irn), n); be_node_set_reg_class(irn, n, reg->reg_class); @@ -1148,7 +1149,12 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm /* if the proj projects a ignore register or a node which is set to ignore, propagate this property. */ if(arch_register_type_is(reg, ignore) || arch_irn_is(env->birg->main_env->arch_env, in[n], ignore)) - be_node_set_flags(irn, pos, arch_irn_flags_ignore); + flags |= arch_irn_flags_ignore; + + if(arch_irn_is(env->birg->main_env->arch_env, in[n], modify_sp)) + flags |= arch_irn_flags_modify_sp; + + be_node_set_flags(irn, pos, flags); pmap_insert(regs, (void *) reg, proj); } @@ -1193,10 +1199,12 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i */ stack = be_abi_reg_map_get(env->regs, isa->sp); if (keep) { + ir_node *bad = new_r_Bad(env->birg->irg); stack = get_irn_n(keep, 0); - exchange(keep, new_r_Bad(env->birg->irg)); + set_nodes_block(keep, bad); + set_irn_n(keep, 0, bad); + // exchange(keep, new_r_Bad(env->birg->irg)); } - be_abi_reg_map_set(reg_map, isa->sp, stack); /* Insert results for Return into the register map. */ for(i = 0; i < n_res; ++i) { @@ -1213,6 +1221,8 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i pmap_insert(reg_map, ent->key, ent->value); } + be_abi_reg_map_set(reg_map, isa->sp, stack); + /* Make the Epilogue node and call the arch's epilogue maker. */ create_barrier(env, bl, &mem, reg_map, 1); call->cb->epilogue(env->cb, bl, &mem, reg_map); @@ -1374,10 +1384,12 @@ static void modify_irg(be_abi_irg_t *env) for(i = 0, n = pmap_count(env->regs); i < n; ++i) { arch_register_t *reg = (void *) rm[i].reg; ir_node *arg_proj = rm[i].irn; - ir_node *proj; ir_mode *mode = arg_proj ? get_irn_mode(arg_proj) : reg->reg_class->mode; long nr = i; int pos = BE_OUT_POS((int) nr); + int flags = 0; + + ir_node *proj; assert(nr >= 0); bitset_set(used_proj_nr, nr); @@ -1391,7 +1403,12 @@ static void modify_irg(be_abi_irg_t *env) * The Proj for that register shall also be ignored during register allocation. */ if(arch_register_type_is(reg, ignore)) - be_node_set_flags(env->reg_params, pos, arch_irn_flags_ignore); + flags |= arch_irn_flags_ignore; + + if(reg == sp) + flags |= arch_irn_flags_modify_sp; + + be_node_set_flags(env->reg_params, pos, flags); DBG((dbg, LEVEL_2, "\tregister save proj #%d -> reg %s\n", nr, reg->name)); } @@ -1565,27 +1582,35 @@ void be_abi_put_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls, */ +struct fix_stack_walker_info { + nodeset *nodes; + const arch_env_t *aenv; +}; + /** * Walker. Collect all stack modifying nodes. */ static void collect_stack_nodes_walker(ir_node *irn, void *data) { - pset *s = data; + struct fix_stack_walker_info *info = data; - if(be_is_AddSP(irn) || be_is_IncSP(irn) || be_is_SetSP(irn)) - pset_insert_ptr(s, irn); + if(arch_irn_is(info->aenv, irn, modify_sp)) + pset_insert_ptr(info->nodes, irn); } void be_abi_fix_stack_nodes(be_abi_irg_t *env) { dom_front_info_t *df; - pset *stack_nodes; + pset *stack_nodes = pset_new_ptr(16); + struct fix_stack_walker_info info; + + info.nodes = stack_nodes; + info.aenv = env->birg->main_env->arch_env; /* We need dominance frontiers for fix up */ df = be_compute_dominance_frontiers(env->birg->irg); - stack_nodes = pset_new_ptr(16); + irg_walk_graph(env->birg->irg, collect_stack_nodes_walker, NULL, &info); pset_insert_ptr(stack_nodes, env->init_sp); - irg_walk_graph(env->birg->irg, collect_stack_nodes_walker, NULL, stack_nodes); be_ssa_constr_set_phis(df, stack_nodes, env->stack_phis); del_pset(stack_nodes); @@ -1764,7 +1789,7 @@ static arch_irn_class_t abi_classify(const void *_self, const ir_node *irn) static arch_irn_flags_t abi_get_flags(const void *_self, const ir_node *irn) { - return arch_irn_flags_ignore; + return arch_irn_flags_ignore | arch_irn_flags_modify_sp; } static entity *abi_get_frame_entity(const void *_self, const ir_node *irn) diff --git a/ir/be/bearch.c b/ir/be/bearch.c index 4ed3a95a4..e3e925f95 100644 --- a/ir/be/bearch.c +++ b/ir/be/bearch.c @@ -208,6 +208,7 @@ extern const char *arch_irn_flag_str(arch_irn_flags_t fl) XXX(dont_spill); XXX(ignore); XXX(rematerializable); + XXX(modify_sp); XXX(none); #undef XXX } diff --git a/ir/be/bearch.h b/ir/be/bearch.h index a6b5ca0eb..dcf8a7811 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -195,7 +195,8 @@ typedef enum _arch_irn_flags_t { 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, /**< Ignore node during register allocation. */ - arch_irn_flags_last = arch_irn_flags_ignore + arch_irn_flags_modify_sp = 8, /**< I modify the stack pointer. */ + arch_irn_flags_last = arch_irn_flags_modify_sp } arch_irn_flags_t; /** -- 2.20.1