From: Matthias Braun Date: Thu, 24 Aug 2006 15:14:01 +0000 (+0000) Subject: - New callback to ask nodes about constant stack pointer adjustment X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=fd1a2c6ca51ee2b6ff838581b79cf7a3c4553e36;p=libfirm - New callback to ask nodes about constant stack pointer adjustment - Make ia32_Push and ia32_Pop return their stackpointer adjustment - replaced stack_dir enum + unsigned offsets with normal integer offsets - make schedule verifier detect dead nodes in schedule --- diff --git a/ir/be/TEMPLATE/bearch_TEMPLATE.c b/ir/be/TEMPLATE/bearch_TEMPLATE.c index 219f159c6..f8904bb93 100644 --- a/ir/be/TEMPLATE/bearch_TEMPLATE.c +++ b/ir/be/TEMPLATE/bearch_TEMPLATE.c @@ -218,10 +218,14 @@ static void TEMPLATE_set_frame_entity(const void *self, const ir_node *irn, enti * This function is called by the generic backend to correct offsets for * nodes accessing the stack. */ -static void TEMPLATE_set_stack_bias(const void *self, ir_node *irn, int bias) { +static void TEMPLATE_set_frame_offset(const void *self, ir_node *irn, int offset) { /* TODO: correct offset if irn accesses the stack */ } +static int TEMPLATE_get_sp_bias(const void *self, const ir_node *irn) { + return 0; +} + /* fill register allocator interface */ static const arch_irn_ops_if_t TEMPLATE_irn_ops_if = { @@ -232,7 +236,8 @@ static const arch_irn_ops_if_t TEMPLATE_irn_ops_if = { TEMPLATE_get_flags, TEMPLATE_get_frame_entity, TEMPLATE_set_frame_entity, - TEMPLATE_set_stack_bias + TEMPLATE_set_frame_offset, + TEMPLATE_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index 64dc9d281..540595d33 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -106,9 +106,7 @@ static const char *node_offset_to_str(ir_node *n, char *buf, int buflen) { entity *ent = be_get_frame_entity(n); offset = get_entity_offset_bytes(ent); } else if (irn_op == op_be_IncSP) { - int offs = be_get_IncSP_offset(n); - be_stack_dir_t dir = be_get_IncSP_direction(n); - offset = (dir == be_stack_dir_expand) ? -offs : offs; + offset = - be_get_IncSP_offset(n); } else { return "node_offset_to_str will fuer diesen Knotentyp noch implementiert werden"; } @@ -624,8 +622,9 @@ static void emit_be_Call(ir_node *irn, void *env) { /** Emit an IncSP node */ static void emit_be_IncSP(const ir_node *irn, arm_emit_env_t *emit_env) { FILE *F = emit_env->out; - unsigned offs = be_get_IncSP_offset(irn); - if (offs) { + int offs = be_get_IncSP_offset(irn); + + if (offs != 0) { char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN]; lc_esnprintf(arm_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1D, %1S, #%O", irn, irn, irn ); lc_esnprintf(arm_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* IncSP(%O) */", irn); diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index d9a3b3aa2..80d1686cb 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -950,12 +950,12 @@ static ir_node *gen_CopyB(ir_node *irn, arm_code_gen_t *cg) { * access must be done relative the the fist IncSP ... */ static int get_sp_expand_offset(ir_node *inc_sp) { - unsigned offset = be_get_IncSP_offset(inc_sp); - be_stack_dir_t dir = be_get_IncSP_direction(inc_sp); + int offset = be_get_IncSP_offset(inc_sp); - if (offset == BE_STACK_FRAME_SIZE) + if (offset == BE_STACK_FRAME_SIZE_EXPAND) return 0; - return dir == be_stack_dir_expand ? (int)offset : -(int)offset; + + return offset; } static ir_node *gen_StackParam(ir_node *irn, arm_code_gen_t *cg) { diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index d7d3bd533..d4096a423 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -231,7 +231,7 @@ static entity *arm_get_frame_entity(const void *self, const ir_node *irn) { return NULL; } -static void arm_set_frame_entity(const void *self, const ir_node *irn, entity *ent) { +static void arm_set_frame_entity(const void *self, ir_node *irn, entity *ent) { /* TODO: set the entity assigned to the frame */ } @@ -243,6 +243,10 @@ static void arm_set_stack_bias(const void *self, ir_node *irn, int bias) { /* TODO: correct offset if irn accesses the stack */ } +static int arm_get_sp_bias(const void *self, const ir_node *irn) { + return 0; +} + /* fill register allocator interface */ static const arch_irn_ops_if_t arm_irn_ops_if = { @@ -254,6 +258,7 @@ static const arch_irn_ops_if_t arm_irn_ops_if = { arm_get_frame_entity, arm_set_frame_entity, arm_set_stack_bias, + arm_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ @@ -936,7 +941,7 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m // TODO: Activate Omit fp in epilogue if(env->flags.try_omit_fp) { - curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_shrink); + curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, *mem, BE_STACK_FRAME_SIZE_SHRINK); curr_lr = be_new_CopyKeep_single(&arm_reg_classes[CLASS_arm_gp], env->irg, bl, curr_lr, curr_sp, get_irn_mode(curr_lr)); be_node_set_reg_class(curr_lr, 1, &arm_reg_classes[CLASS_arm_gp]); diff --git a/ir/be/beabi.c b/ir/be/beabi.c index ef81cd986..34fa0dee4 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -471,7 +471,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) * moving the stack pointer along the stack's direction. */ if(stack_dir < 0 && !do_seq && !no_alloc) { - curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, no_mem, stack_size, be_stack_dir_expand); + curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, no_mem, stack_size); } assert(mode_is_reference(mach_mode) && "machine mode must be pointer"); @@ -492,7 +492,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) if (do_seq) { curr_ofs = 0; addr = curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, curr_mem, - param_size + arg->space_before, be_stack_dir_expand); + param_size + arg->space_before); } else { curr_ofs += arg->space_before; @@ -691,7 +691,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) /* Clean up the stack frame if we allocated it */ if(!no_alloc) - curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, mem_proj, stack_size, be_stack_dir_shrink); + curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, mem_proj, -stack_size); } be_abi_call_free(call); @@ -954,7 +954,7 @@ static ir_node *setup_frame(be_abi_irg_t *env) int stack_nr = get_Proj_proj(stack); if(flags.try_omit_fp) { - stack = be_new_IncSP(sp, irg, bl, stack, no_mem, BE_STACK_FRAME_SIZE, be_stack_dir_expand); + stack = be_new_IncSP(sp, irg, bl, stack, no_mem, BE_STACK_FRAME_SIZE_EXPAND); frame = stack; } @@ -968,7 +968,7 @@ static ir_node *setup_frame(be_abi_irg_t *env) arch_set_irn_register(env->birg->main_env->arch_env, frame, bp); } - stack = be_new_IncSP(sp, irg, bl, stack, frame, BE_STACK_FRAME_SIZE, be_stack_dir_expand); + stack = be_new_IncSP(sp, irg, bl, stack, frame, BE_STACK_FRAME_SIZE_EXPAND); } be_node_set_flags(env->reg_params, -(stack_nr + 1), arch_irn_flags_ignore); @@ -993,7 +993,7 @@ static void clearup_frame(be_abi_irg_t *env, ir_node *ret, pmap *reg_map, struct pmap_entry *ent; if(env->call->flags.bits.try_omit_fp) { - stack = be_new_IncSP(sp, irg, bl, stack, ret_mem, BE_STACK_FRAME_SIZE, be_stack_dir_shrink); + stack = be_new_IncSP(sp, irg, bl, stack, ret_mem, -BE_STACK_FRAME_SIZE_SHRINK); } else { @@ -1611,7 +1611,7 @@ static void modify_irg(be_abi_irg_t *env) /* do the stack allocation BEFORE the barrier, or spill code might be added before it */ env->init_sp = be_abi_reg_map_get(env->regs, sp); - env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, no_mem, BE_STACK_FRAME_SIZE, be_stack_dir_expand); + env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, no_mem, BE_STACK_FRAME_SIZE_EXPAND); be_abi_reg_map_set(env->regs, sp, env->init_sp); barrier = create_barrier(env, bl, &mem, env->regs, 0); @@ -1793,15 +1793,14 @@ struct fix_stack_walker_info { static void collect_stack_nodes_walker(ir_node *irn, void *data) { struct fix_stack_walker_info *info = data; - ir_mode *mode; if (is_Block(irn)) return; - mode = get_irn_mode(irn); - - if (arch_irn_is(info->aenv, irn, modify_sp) && mode != mode_T && mode != mode_M) + if (arch_irn_is(info->aenv, irn, modify_sp)) { + assert(get_irn_mode(irn) != mode_M && get_irn_mode(irn) != mode_T); pset_insert_ptr(info->nodes, irn); + } } void be_abi_fix_stack_nodes(be_abi_irg_t *env, be_lv_t *lv) @@ -1824,54 +1823,45 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env, be_lv_t *lv) be_free_dominance_frontiers(df); } -/** - * Translates a direction of an IncSP node (either be_stack_dir_shrink, or ...expand) - * into -1 or 1, respectively. - * @param irn The node. - * @return 1, if the direction of the IncSP was along, -1 if against. - */ -static int get_dir(ir_node *irn) -{ - return 1 - 2 * (be_get_IncSP_direction(irn) == be_stack_dir_shrink); -} - static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) { - const arch_env_t *aenv = env->birg->main_env->arch_env; + const arch_env_t *arch_env = env->birg->main_env->arch_env; int omit_fp = env->call->flags.bits.try_omit_fp; ir_node *irn; sched_foreach(bl, irn) { /* - If the node modifies the stack pointer by a constant offset, - record that in the bias. - */ - if(be_is_IncSP(irn)) { - int ofs = be_get_IncSP_offset(irn); - int dir = get_dir(irn); - - if(ofs == BE_STACK_FRAME_SIZE) { - ofs = get_type_size_bytes(get_irg_frame_type(env->birg->irg)); - be_set_IncSP_offset(irn, ofs); - } - - if(omit_fp) - bias += dir * ofs; + Check, if the node relates to an entity on the stack frame. + If so, set the true offset (including the bias) for that + node. + */ + entity *ent = arch_get_frame_entity(arch_env, irn); + if(ent) { + int offset = get_stack_entity_offset(env->frame, ent, bias); + arch_set_frame_offset(arch_env, irn, offset); + DBG((env->dbg, LEVEL_2, "%F has offset %d (including bias %d)\n", ent, offset, bias)); } /* - Else check, if the node relates to an entity on the stack frame. - If so, set the true offset (including the bias) for that - node. - */ - else { - entity *ent = arch_get_frame_entity(aenv, irn); - if(ent) { - int offset = get_stack_entity_offset(env->frame, ent, bias); - arch_set_frame_offset(aenv, irn, offset); - DBG((env->dbg, LEVEL_2, "%F has offset %d\n", ent, offset)); + If the node modifies the stack pointer by a constant offset, + record that in the bias. + */ + if(arch_irn_is(arch_env, irn, modify_sp)) { + int ofs = arch_get_sp_bias(arch_env, irn); + + if(be_is_IncSP(irn)) { + if(ofs == BE_STACK_FRAME_SIZE_EXPAND) { + ofs = get_type_size_bytes(get_irg_frame_type(env->birg->irg)); + be_set_IncSP_offset(irn, ofs); + } else if(ofs == BE_STACK_FRAME_SIZE_SHRINK) { + ofs = - get_type_size_bytes(get_irg_frame_type(env->birg->irg)); + be_set_IncSP_offset(irn, ofs); + } } + + if(omit_fp) + bias += ofs; } } @@ -2006,10 +1996,15 @@ static void abi_set_frame_entity(const void *_self, ir_node *irn, entity *ent) { } -static void abi_set_stack_bias(const void *_self, ir_node *irn, int bias) +static void abi_set_frame_offset(const void *_self, ir_node *irn, int bias) { } +static int abi_get_sp_bias(const void *self, const ir_node *irn) +{ + return 0; +} + static const arch_irn_ops_if_t abi_irn_ops = { abi_get_irn_reg_req, abi_set_irn_reg, @@ -2018,7 +2013,8 @@ static const arch_irn_ops_if_t abi_irn_ops = { abi_get_flags, abi_get_frame_entity, abi_set_frame_entity, - abi_set_stack_bias, + abi_set_frame_offset, + abi_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ diff --git a/ir/be/bearch.c b/ir/be/bearch.c index 040379b56..9aac6d343 100644 --- a/ir/be/bearch.c +++ b/ir/be/bearch.c @@ -117,6 +117,12 @@ void arch_set_frame_entity(const arch_env_t *env, ir_node *irn, entity *ent) ops->impl->set_frame_entity(ops, irn, ent); } +int arch_get_sp_bias(const arch_env_t *env, ir_node *irn) +{ + const arch_irn_ops_t *ops = get_irn_ops(env, irn); + return ops->impl->get_sp_bias(ops, irn); +} + arch_inverse_t *arch_get_inverse(const arch_env_t *env, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack) { const arch_irn_ops_t *ops = get_irn_ops(env, irn); diff --git a/ir/be/bearch.h b/ir/be/bearch.h index e6d1431d3..f6eaad8b3 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -296,6 +296,20 @@ struct _arch_irn_ops_if_t { */ void (*set_frame_offset)(const void *self, ir_node *irn, int offset); + /** + * Returns the delta of the stackpointer for nodes that increment or + * decrement the stackpointer with a constant value. (push, pop + * nodes on most architectures). + * A positive value stands for an expanding stack area, a negative value for + * a shrinking one. + * + * @param self The this pointer + * @param irn The node + * @return 0 if the stackpointer is not modified with a constant + * value, otherwise the increment/decrement value + */ + int (*get_sp_bias)(const void *self, const ir_node *irn); + /** * Returns an inverse operation which yields the i-th argument * of the given node as result. @@ -354,6 +368,7 @@ extern void arch_set_frame_offset(const arch_env_t *env, ir_node *irn, int bias) extern entity *arch_get_frame_entity(const arch_env_t *env, ir_node *irn); extern void arch_set_frame_entity(const arch_env_t *env, ir_node *irn, entity *ent); +extern int arch_get_sp_bias(const arch_env_t *env, ir_node *irn); extern int arch_get_op_estimated_cost(const arch_env_t *env, const ir_node *irn); extern arch_inverse_t *arch_get_inverse(const arch_env_t *env, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack); diff --git a/ir/be/beirgmod.c b/ir/be/beirgmod.c index 071571689..a9981971d 100644 --- a/ir/be/beirgmod.c +++ b/ir/be/beirgmod.c @@ -263,10 +263,10 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo if(pset_find_ptr(phi_blocks, curr_bl)) { ir_node *phi = get_irn_link(curr_bl); - if(!phi) { + if(phi == NULL) { int i, n_preds = get_irn_arity(curr_bl); ir_graph *irg = get_irn_irg(curr_bl); - ir_node **ins = xmalloc(n_preds * sizeof(ins[0])); + ir_node **ins = alloca(n_preds * sizeof(ins[0])); for(i = 0; i < n_preds; ++i) ins[i] = new_r_Bad(irg); @@ -276,7 +276,6 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo set_irn_link(curr_bl, phi); sched_add_after(curr_bl, phi); - free(ins); for(i = 0; i < n_preds; ++i) { ir_node *arg = search_def(phi, i, copies, copy_blocks, phis, phi_blocks, mode); @@ -284,7 +283,7 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo set_irn_n(phi, i, arg); } - if(phis) + if(phis != NULL) pset_insert_ptr(phis, phi); } @@ -354,6 +353,7 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset * obstack_free(&obst, NULL); } +#if 0 /** * Remove phis which are not necessary. * During place_phi_functions() phi functions are put on the dominance @@ -366,26 +366,27 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset * */ static void remove_odd_phis(pset *copies, pset *unused_copies) { - ir_node *irn; + ir_node *irn; - for(irn = pset_first(copies); irn; irn = pset_next(copies)) { - if(is_Phi(irn)) { - int i, n; - int illegal = 0; + for(irn = pset_first(copies); irn; irn = pset_next(copies)) { + if(is_Phi(irn)) { + int i, n; + int illegal = 0; - assert(sched_is_scheduled(irn) && "phi must be scheduled"); - for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i) - illegal = get_irn_n(irn, i) == NULL; + assert(sched_is_scheduled(irn) && "phi must be scheduled"); + for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i) + illegal = get_irn_n(irn, i) == NULL; - if(illegal) - sched_remove(irn); - } - } + if(illegal) + sched_remove(irn); + } + } - for(irn = pset_first(unused_copies); irn; irn = pset_next(unused_copies)) { + for(irn = pset_first(unused_copies); irn; irn = pset_next(unused_copies)) { sched_remove(irn); } } +#endif void be_ssa_constr_phis_ignore(dom_front_info_t *info, be_lv_t *lv, int n, ir_node *nodes[], pset *phis, pset *ignore_uses) { diff --git a/ir/be/bemain.c b/ir/be/bemain.c index c476f88b4..a5f635c75 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -550,13 +550,20 @@ static void be_main_loop(FILE *file_handle) /* fix stack offsets */ BE_TIMER_PUSH(t_abi); - be_abi_fix_stack_bias(birg.abi); + //be_abi_fix_stack_bias(birg.abi); BE_TIMER_POP(t_abi); BE_TIMER_PUSH(t_finish); arch_code_generator_finish(birg.cg); BE_TIMER_POP(t_finish); + /* fix stack offsets */ + BE_TIMER_PUSH(t_abi); + be_abi_fix_stack_nodes(birg.abi, NULL); + be_remove_dead_nodes_from_schedule(birg.irg); + be_abi_fix_stack_bias(birg.abi); + BE_TIMER_POP(t_abi); + dump(DUMP_FINAL, irg, "-finish", dump_ir_block_graph_sched); /* check schedule and register allocation */ diff --git a/ir/be/benode.c b/ir/be/benode.c index 3ba979617..3cb038b35 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -89,8 +89,7 @@ typedef struct { /** The be_Stack attribute type. */ typedef struct { be_node_attr_t node_attr; - int offset; /**< The offset by which the stack shall be increased/decreased. */ - be_stack_dir_t dir; /**< The direction in which the stack shall be modified (expand or shrink). */ + int offset; /**< The offset by which the stack shall be expanded/shrinked. */ } be_stack_attr_t; /** The be_Frame attribute type. */ @@ -530,7 +529,7 @@ int be_Return_get_n_rets(ir_node *ret) return a->num_ret_vals; } -ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, unsigned offset, be_stack_dir_t dir) +ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, int offset) { be_stack_attr_t *a; ir_node *irn; @@ -540,7 +539,6 @@ ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_ in[1] = mem; irn = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, 2, in); a = init_node_attr(irn, 1); - a->dir = dir; a->offset = offset; be_node_set_flags(irn, -1, arch_irn_flags_ignore | arch_irn_flags_modify_sp); @@ -902,34 +900,20 @@ ir_node *be_get_IncSP_mem(ir_node *irn) { return get_irn_n(irn, 1); } -void be_set_IncSP_offset(ir_node *irn, unsigned offset) +void be_set_IncSP_offset(ir_node *irn, int offset) { be_stack_attr_t *a = get_irn_attr(irn); assert(be_is_IncSP(irn)); a->offset = offset; } -unsigned be_get_IncSP_offset(const ir_node *irn) +int be_get_IncSP_offset(const ir_node *irn) { be_stack_attr_t *a = get_irn_attr(irn); assert(be_is_IncSP(irn)); return a->offset; } -void be_set_IncSP_direction(ir_node *irn, be_stack_dir_t dir) -{ - be_stack_attr_t *a = get_irn_attr(irn); - assert(be_is_IncSP(irn)); - a->dir = dir; -} - -be_stack_dir_t be_get_IncSP_direction(const ir_node *irn) -{ - be_stack_attr_t *a = get_irn_attr(irn); - assert(be_is_IncSP(irn)); - return a->dir; -} - ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn) { ir_node *bl = get_nodes_block(irn); @@ -1090,6 +1074,17 @@ static void be_node_set_frame_offset(const void *self, ir_node *irn, int offset) } } +static int be_node_get_sp_bias(const void *self, const ir_node *irn) +{ + int result = 0; + + if(be_is_IncSP(irn)) { + result = be_get_IncSP_offset(irn); + } + + return result; +} + /* ___ ____ _ _ _ _ _ _ |_ _| _ \| \ | | | | | | __ _ _ __ __| | | ___ _ __ @@ -1108,6 +1103,7 @@ static const arch_irn_ops_if_t be_node_irn_ops_if = { be_node_get_frame_entity, be_node_set_frame_entity, be_node_set_frame_offset, + be_node_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ @@ -1239,6 +1235,11 @@ static void phi_set_frame_offset(const void *_self, ir_node *irn, int bias) { } +static int phi_get_sp_bias(const void* self, const ir_node *irn) +{ + return 0; +} + static const arch_irn_ops_if_t phi_irn_ops = { phi_get_irn_reg_req, phi_set_irn_reg, @@ -1248,6 +1249,7 @@ static const arch_irn_ops_if_t phi_irn_ops = { phi_get_frame_entity, phi_set_frame_entity, phi_set_frame_offset, + phi_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ @@ -1397,11 +1399,12 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) case beo_IncSP: { be_stack_attr_t *a = (be_stack_attr_t *) at; - if (a->offset == BE_STACK_FRAME_SIZE) + if (a->offset == BE_STACK_FRAME_SIZE_EXPAND) fprintf(f, "offset: FRAME_SIZE\n"); + else if(a->offset == BE_STACK_FRAME_SIZE_SHRINK) + fprintf(f, "offset: -FRAME SIZE\n"); else fprintf(f, "offset: %u\n", a->offset); - fprintf(f, "direction: %s\n", a->dir == be_stack_dir_expand ? "expand" : "shrink"); } break; case beo_Call: diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index aa426e653..642e60dd0 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -14,6 +14,8 @@ #include "firm_config.h" +#include + #include "irmode.h" #include "irnode.h" #include "entity_t.h" @@ -68,12 +70,6 @@ typedef enum { beo_Last } be_opcode_t; -/** Expresses the direction of the stack pointer increment of IncSP nodes. */ -typedef enum { - be_stack_dir_expand = 0, - be_stack_dir_shrink = 1 -} be_stack_dir_t; - /** Not used yet. */ typedef enum { be_frame_flag_spill = 1, @@ -85,7 +81,8 @@ typedef enum { * A "symbolic constant" for the size of the stack frame to use with IncSP nodes. * It gets back-patched to the real size as soon it is known. */ -#define BE_STACK_FRAME_SIZE ((unsigned) -1) +#define BE_STACK_FRAME_SIZE_EXPAND INT_MAX +#define BE_STACK_FRAME_SIZE_SHRINK INT_MIN /** * Determines if irn is a be_node. @@ -192,13 +189,13 @@ ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_ * @param irg The graph to insert the node to. * @param bl The block to insert the node into. * @param old_sp The node defining the former stack pointer. - * @param amount The mount of bytes the stack pointer shall be increased/decreased. + * @param amount The mount of bytes the stack shall be expanded/shrinked (see set_IncSP_offset) * @param dir The direction in which the stack pointer shall be modified: * Along the stack's growing direction or against. * @return A new stack pointer increment/decrement node. * @note This node sets a register constraint to the @p sp register on its output. */ -ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, unsigned amount, be_stack_dir_t dir); +ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, int offset); /** Returns the previous node that computes the stack pointer. */ ir_node *be_get_IncSP_pred(ir_node *incsp); @@ -209,17 +206,16 @@ void be_set_IncSP_pred(ir_node *incsp, ir_node *pred); /** Returns the memory input of the IncSP. */ ir_node *be_get_IncSP_mem(ir_node *irn); -/** Sets a new offset to a IncSP node. */ -void be_set_IncSP_offset(ir_node *irn, unsigned offset); +/** + * Sets a new offset to a IncSP node. + * A positive offset means expanding the stack, a negative offset shrinking + * an offset is == BE_STACK_FRAME_SIZE will be replaced by the real size of the + * stackframe in the fix_stack_offsets phase. + */ +void be_set_IncSP_offset(ir_node *irn, int offset); /** Gets the offset from a IncSP node. */ -unsigned be_get_IncSP_offset(const ir_node *irn); - -/** Sets a new direction to a IncSP node. */ -void be_set_IncSP_direction(ir_node *irn, be_stack_dir_t dir); - -/** Gets the direction from a IncSP node. */ -be_stack_dir_t be_get_IncSP_direction(const ir_node *irn); +int be_get_IncSP_offset(const ir_node *irn); /** Gets the call entity or NULL if this is no static call. */ entity *be_Call_get_entity(const ir_node *call); diff --git a/ir/be/bespill.c b/ir/be/bespill.c index 26569538f..449f8ba7a 100644 --- a/ir/be/bespill.c +++ b/ir/be/bespill.c @@ -148,7 +148,6 @@ void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before) { rel->reloader = before; rel->next = info->reloaders; info->reloaders = rel; - be_liveness_add_missing(env->chordal_env->lv); } void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block, int pos) { @@ -542,4 +541,8 @@ void be_insert_spills_reloads(spill_env_t *env) { // reloads are placed now, but we might reuse the spill environment for further spilling decisions del_set(env->spills); env->spills = new_set(cmp_spillinfo, 1024); + + be_remove_dead_nodes_from_schedule(env->chordal_env->irg); + //be_liveness_add_missing(env->chordal_env->lv); + be_liveness_recompute(env->chordal_env->lv); } diff --git a/ir/be/bespillbelady.c b/ir/be/bespillbelady.c index 0742f4a14..6462e1b9a 100644 --- a/ir/be/bespillbelady.c +++ b/ir/be/bespillbelady.c @@ -648,9 +648,6 @@ void be_spill_belady_spill_env(const be_chordal_env_t *chordal_env, spill_env_t /* Insert spill/reload nodes into the graph and fix usages */ be_insert_spills_reloads(env.senv); - be_remove_dead_nodes_from_schedule(chordal_env->irg); - be_liveness_recompute(chordal_env->lv); - /* clean up */ if(spill_env == NULL) be_delete_spill_env(env.senv); diff --git a/ir/be/bespillmorgan.c b/ir/be/bespillmorgan.c index 890219128..84d103984 100644 --- a/ir/be/bespillmorgan.c +++ b/ir/be/bespillmorgan.c @@ -558,11 +558,6 @@ void be_spill_morgan(be_chordal_env_t *chordal_env) { del_set(env.block_attr_set); /* fix the remaining places with too high register pressure with beladies algorithm */ - - /* we have to remove dead nodes from schedule to not confuse liveness calculation */ - be_remove_dead_nodes_from_schedule(env.irg); - be_liveness_recompute(chordal_env->lv); - be_spill_belady_spill_env(chordal_env, env.senv); be_delete_spill_env(env.senv); diff --git a/ir/be/beutil.c b/ir/be/beutil.c index bcf3c286d..e48f3ed29 100644 --- a/ir/be/beutil.c +++ b/ir/be/beutil.c @@ -38,8 +38,8 @@ pset *be_empty_set(void) } struct dump_env { - FILE *f; - arch_env_t *env; + FILE *f; + arch_env_t *env; }; static void dump_allocated_block(ir_node *block, void *data) @@ -88,9 +88,9 @@ static void dump_allocated_block(ir_node *block, void *data) void dump_allocated_irg(arch_env_t *arch_env, ir_graph *irg, char *suffix) { char buf[1024]; - struct dump_env env; + struct dump_env env; - env.env = arch_env; + env.env = arch_env; ir_snprintf(buf, sizeof(buf), "%F-alloc%s.vcg", irg, suffix); diff --git a/ir/be/beverify.c b/ir/be/beverify.c index f59ebb1b5..2a9ea71c2 100644 --- a/ir/be/beverify.c +++ b/ir/be/beverify.c @@ -121,7 +121,6 @@ static void verify_schedule_walker(ir_node *block, void *data) { int cfchange_found = 0; // TODO ask arch about delay branches int delay_branches = 0; - pset *uses = pset_new_ptr_default(); /* * Tests for the following things: @@ -167,18 +166,29 @@ static void verify_schedule_walker(ir_node *block, void *data) { } // 3. Check for uses - if(pset_find_ptr(uses, node)) { - ir_fprintf(stderr, "Verify Warning: Value %+F used before it was defined in block %+F (%s)\n", - node, block, get_irg_dump_name(env->irg)); - env->problem_found = 1; - } if(!is_Phi(node)) { + int nodetime = sched_get_time_step(node); for(i = 0, arity = get_irn_arity(node); i < arity; ++i) { - pset_insert_ptr(uses, get_irn_n(node, i)); + ir_node *arg = get_irn_n(node, i); + if(get_nodes_block(arg) != block + || !sched_is_scheduled(arg)) + continue; + + if(sched_get_time_step(arg) >= nodetime) { + ir_fprintf(stderr, "Verify Warning: Value %+F used by %+F before it was defined in block %+F (%s)\n", + arg, node, block, get_irg_dump_name(env->irg)); + env->problem_found = 1; + } } } + + // 4. check for dead nodes + if(get_irn_n_edges(node) == 0) { + ir_fprintf(stderr, "Verify warning: Node %+F is dead but scheduled in block %+F (%s)\n", + node, block, get_irg_dump_name(env->irg)); + env->problem_found = 1; + } } - del_pset(uses); /* check that all delay branches are filled (at least with NOPs) */ if (cfchange_found && delay_branches != 0) { diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 14d8fc55b..d758d96f5 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -258,6 +258,17 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) { } static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) { + + if(is_Proj(irn)) { + ir_node *pred = get_Proj_pred(irn); + if(is_ia32_Push(pred) && get_Proj_proj(irn) == 0) { + return arch_irn_flags_modify_sp; + } + if(is_ia32_Pop(pred) && get_Proj_proj(irn) == 1) { + return arch_irn_flags_modify_sp; + } + } + irn = my_skip_proj(irn); if (is_ia32_irn(irn)) return get_ia32_flags(irn); @@ -276,14 +287,22 @@ static void ia32_set_frame_entity(const void *self, ir_node *irn, entity *ent) { set_ia32_frame_ent(irn, ent); } -static void ia32_set_stack_bias(const void *self, ir_node *irn, int bias) { +static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) { char buf[64]; const ia32_irn_ops_t *ops = self; if (get_ia32_frame_ent(irn)) { ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn); + /* Pop nodes modify the stack pointer before reading the destination + * address, so fix this here + */ + if(is_ia32_Pop(irn)) { + bias -= 4; + } + DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias)); + snprintf(buf, sizeof(buf), "%d", bias); if (get_ia32_op_type(irn) == ia32_Normal) { @@ -297,6 +316,20 @@ static void ia32_set_stack_bias(const void *self, ir_node *irn, int bias) { } } +static int ia32_get_sp_bias(const void *self, const ir_node *irn) { + if(is_Proj(irn)) { + int proj = get_Proj_proj(irn); + ir_node *pred = get_Proj_pred(irn); + + if(is_ia32_Push(pred) && proj == 0) + return 4; + else if(is_ia32_Pop(pred) && proj == 1) + return -4; + } + + return 0; +} + typedef struct { be_abi_call_flags_bits_t flags; const arch_isa_t *isa; @@ -397,7 +430,7 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ if (env->flags.try_omit_fp) { /* simply remove the stack frame here */ - curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_shrink); + curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, *mem, BE_STACK_FRAME_SIZE_SHRINK); } else { const ia32_isa_t *isa = (ia32_isa_t *)env->isa; @@ -731,7 +764,8 @@ static const arch_irn_ops_if_t ia32_irn_ops_if = { ia32_get_flags, ia32_get_frame_entity, ia32_set_frame_entity, - ia32_set_stack_bias, + ia32_set_frame_offset, + ia32_get_sp_bias, ia32_get_inverse, ia32_get_op_estimated_cost, ia32_possible_memory_operand, @@ -1028,12 +1062,12 @@ static ir_node *create_pop(ia32_transform_env_t *env, ir_node *schedpoint, ir_no return pop; } -static ir_node* create_spproj(ia32_transform_env_t *env, ir_node *pred, ir_node *schedpoint, const ir_node *oldsp) { +static ir_node* create_spproj(ia32_transform_env_t *env, ir_node *pred, int pos, ir_node *schedpoint, const ir_node *oldsp) { ir_mode *spmode = get_irn_mode(oldsp); const arch_register_t *spreg = arch_get_irn_register(env->cg->arch_env, oldsp); ir_node *sp; - sp = new_rd_Proj(env->dbg, env->irg, env->block, pred, spmode, 0); + sp = new_rd_Proj(env->dbg, env->irg, env->block, pred, spmode, pos); arch_set_irn_register(env->cg->arch_env, sp, spreg); sched_add_before(schedpoint, sp); @@ -1067,11 +1101,11 @@ static void transform_MemPerm(ia32_transform_env_t *env) { assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit"); push = create_push(env, node, sp, mem, ent, NULL); - sp = create_spproj(env, push, node, sp); + sp = create_spproj(env, push, 0, node, sp); if(entbits == 64) { // add another push after the first one push = create_push(env, node, sp, mem, ent, "4"); - sp = create_spproj(env, push, node, sp); + sp = create_spproj(env, push, 0, node, sp); } set_irn_n(node, i, new_Bad()); @@ -1090,12 +1124,12 @@ static void transform_MemPerm(ia32_transform_env_t *env) { pop = create_pop(env, node, sp, ent, NULL); if(entbits == 64) { // add another pop after the first one - sp = create_spproj(env, pop, node, sp); + sp = create_spproj(env, pop, 1, node, sp); pop = create_pop(env, node, sp, ent, "4"); } - if(i != 0) { - sp = create_spproj(env, pop, node, sp); - } + //if(i != 0) { + sp = create_spproj(env, pop, 1, node, sp); + //} pops[i] = pop; } diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 1ffccc880..10ebcd1e9 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -1660,15 +1660,14 @@ static void emit_be_Call(const ir_node *irn, ia32_emit_env_t *emit_env) { */ static void emit_be_IncSP(const ir_node *irn, ia32_emit_env_t *emit_env) { FILE *F = emit_env->out; - unsigned offs = be_get_IncSP_offset(irn); - be_stack_dir_t dir = be_get_IncSP_direction(irn); + int offs = be_get_IncSP_offset(irn); char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN]; if (offs) { - if (dir == be_stack_dir_expand) + if (offs > 0) lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "sub %1S, %u", irn, offs); else - lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1S, %u", irn, offs); + lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "add %1S, %u", irn, -offs); lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F (IncSP) */", irn); } else { diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 46d529aec..ead10b1ec 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -487,8 +487,7 @@ static void ia32_create_Push(ir_node *irn, ia32_code_gen_t *cg) { return; /* do not create push if IncSp doesn't expand stack or expand size is different from register size */ - if (be_get_IncSP_direction(sp) != be_stack_dir_expand || - be_get_IncSP_offset(sp) != (unsigned) get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode)) + if (be_get_IncSP_offset(sp) != get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode)) return; /* do not create push, if there is a path (inside the block) from the push value to IncSP */ @@ -613,23 +612,10 @@ static void ia32_optimize_IncSP(ir_node *irn, ia32_code_gen_t *cg) { if (be_is_IncSP(prev) && real_uses == 1) { /* first IncSP has only one IncSP user, kill the first one */ - unsigned prev_offs = be_get_IncSP_offset(prev); - be_stack_dir_t prev_dir = be_get_IncSP_direction(prev); - unsigned curr_offs = be_get_IncSP_offset(irn); - be_stack_dir_t curr_dir = be_get_IncSP_direction(irn); + int prev_offs = be_get_IncSP_offset(prev); + int curr_offs = be_get_IncSP_offset(irn); - int new_ofs = prev_offs * (prev_dir == be_stack_dir_expand ? -1 : +1) + - curr_offs * (curr_dir == be_stack_dir_expand ? -1 : +1); - - if (new_ofs < 0) { - new_ofs = -new_ofs; - curr_dir = be_stack_dir_expand; - } - else - curr_dir = be_stack_dir_shrink; - be_set_IncSP_offset(prev, 0); - be_set_IncSP_offset(irn, (unsigned)new_ofs); - be_set_IncSP_direction(irn, curr_dir); + be_set_IncSP_offset(prev, prev_offs + curr_offs); /* Omit the optimized IncSP */ be_set_IncSP_pred(irn, be_get_IncSP_pred(prev)); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 6faef6a71..9ad42a36a 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -706,6 +706,7 @@ else { }, "Push" => { + # We don't set class modify_stack here (but we will do this on proj 0) "comment" => "push a gp register on the stack", "reg_req" => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] }, "emit" => ' @@ -728,6 +729,7 @@ else { }, "Pop" => { + # We don't set class modify stack here (but we will do this on proj 1) "comment" => "pop a gp register from the stack", "reg_req" => { "in" => [ "esp", "none" ], "out" => [ "gp", "esp" ] }, "emit" => ' diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 3c2b556a3..84e319cec 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -2149,38 +2149,40 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) { * ********************************************/ +#if 0 /** * Decides in which block the transformed StackParam should be placed. * If the StackParam has more than one user, the dominator block of * the users will be returned. In case of only one user, this is either * the user block or, in case of a Phi, the predecessor block of the Phi. */ - static ir_node *get_block_transformed_stack_param(ir_node *irn) { - ir_node *dom_bl = NULL; +static ir_node *get_block_transformed_stack_param(ir_node *irn) { + ir_node *dom_bl = NULL; - if (get_irn_n_edges(irn) == 1) { - ir_node *src = get_edge_src_irn(get_irn_out_edge_first(irn)); + if (get_irn_n_edges(irn) == 1) { + ir_node *src = get_edge_src_irn(get_irn_out_edge_first(irn)); - if (! is_Phi(src)) { - dom_bl = get_nodes_block(src); - } - else { - /* Determine on which in position of the Phi the irn is */ - /* and get the corresponding cfg predecessor block. */ + if (! is_Phi(src)) { + dom_bl = get_nodes_block(src); + } + else { + /* Determine on which in position of the Phi the irn is */ + /* and get the corresponding cfg predecessor block. */ - int i = get_irn_pred_pos(src, irn); - assert(i >= 0 && "kaputt"); - dom_bl = get_Block_cfgpred_block(get_nodes_block(src), i); - } - } - else { - dom_bl = node_users_smallest_common_dominator(irn, 1); - } + int i = get_irn_pred_pos(src, irn); + assert(i >= 0 && "kaputt"); + dom_bl = get_Block_cfgpred_block(get_nodes_block(src), i); + } + } + else { + dom_bl = node_users_smallest_common_dominator(irn, 1); + } - assert(dom_bl && "dominator block not found"); + assert(dom_bl && "dominator block not found"); - return dom_bl; - } + return dom_bl; +} +#endif static ir_node *gen_be_StackParam(ia32_transform_env_t *env) { ir_node *new_op = NULL; @@ -2192,7 +2194,7 @@ static ir_node *gen_be_StackParam(ia32_transform_env_t *env) { ir_mode *mode = env->mode; /* choose the block where to place the load */ - env->block = get_block_transformed_stack_param(node); + //env->block = get_block_transformed_stack_param(node); if (mode_is_float(mode)) { FP_USED(env->cg); diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index b4f72149a..e7eb08cb2 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -254,6 +254,10 @@ static void mips_set_frame_offset(const void *self, ir_node *irn, int offset) { attr->stack_entity_offset = offset; } +static int mips_get_sp_bias(const void *self, const ir_node *irn) { + return 0; +} + /* fill register allocator interface */ static const arch_irn_ops_if_t mips_irn_ops_if = { @@ -265,6 +269,7 @@ static const arch_irn_ops_if_t mips_irn_ops_if = { mips_get_frame_entity, mips_set_frame_entity, mips_set_frame_offset, + mips_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ @@ -761,9 +766,6 @@ static void mips_abi_epilogue(void *self, ir_node *block, ir_node **mem, pmap *r int initial_frame_size = env->debug ? 24 : 4; int fp_save_offset = env->debug ? 16 : 0; - // restore sp - //sp = be_new_IncSP(&mips_gp_regs[REG_SP], irg, block, sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_against); - // copy fp to sp sp = new_rd_mips_move(dbg, irg, block, fp, mode_Iu); mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]); diff --git a/ir/be/mips/mips_emitter.c b/ir/be/mips/mips_emitter.c index dd4bf043b..23b93d54c 100644 --- a/ir/be/mips/mips_emitter.c +++ b/ir/be/mips/mips_emitter.c @@ -341,11 +341,10 @@ static void mips_emit_IncSP(const ir_node *node, mips_emit_env_t *env) FILE *F = env->out; int offset = be_get_IncSP_offset(node); - if(offset == 0) + if(offset == 0) { + fprintf(F, "\t\t\t\t # omitted IncSP with 0\n"); return; - - if(be_get_IncSP_direction(node) != be_stack_dir_expand) - offset = -offset; + } fprintf(F, "\taddi $sp, $sp, %d\n", -offset); } diff --git a/ir/be/ppc32/bearch_ppc32.c b/ir/be/ppc32/bearch_ppc32.c index 455f3710e..0dcbd51f4 100644 --- a/ir/be/ppc32/bearch_ppc32.c +++ b/ir/be/ppc32/bearch_ppc32.c @@ -247,6 +247,10 @@ static void ppc32_set_stack_bias(const void *self, ir_node *irn, int bias) { set_ppc32_offset(irn, bias); } +static int ppc32_get_sp_bias(const void *self, const ir_node *irn) { + return 0; +} + typedef struct { const be_abi_call_t *call; @@ -367,6 +371,7 @@ static const arch_irn_ops_if_t ppc32_irn_ops_if = { ppc32_get_frame_entity, ppc32_set_frame_entity, ppc32_set_stack_bias, + ppc32_get_sp_bias, NULL, /* get_inverse */ NULL, /* get_op_estimated_cost */ NULL, /* possible_memory_operand */ diff --git a/ir/be/ppc32/ppc32_emitter.c b/ir/be/ppc32/ppc32_emitter.c index 4a1a0f7b8..1ea941f54 100644 --- a/ir/be/ppc32/ppc32_emitter.c +++ b/ir/be/ppc32/ppc32_emitter.c @@ -518,15 +518,14 @@ static void emit_Proj(const ir_node *irn, ppc32_emit_env_t *env) { static void emit_be_IncSP(const ir_node *irn, ppc32_emit_env_t *emit_env) { FILE *F = emit_env->out; - unsigned offs = be_get_IncSP_offset(irn); - be_stack_dir_t dir = be_get_IncSP_direction(irn); + int offs = be_get_IncSP_offset(irn); - fprintf(F, "\t\t\t\t\t/* ignored IncSP with %c%i */\n", dir==be_stack_dir_expand ? '-' : ' ', offs); + fprintf(F, "\t\t\t\t\t/* ignored IncSP with %d */\n", -offs); // if (offs) { // assert(offs<=0x7fff); -// lc_efprintf(ppc32_get_arg_env(), F, "\taddi %1S, %1S,%s%u\t\t\t/* %+F (IncSP) */\n", irn, irn, -// (dir == be_stack_dir_expand) ? " -" : " ", offs, irn); +// lc_efprintf(ppc32_get_arg_env(), F, "\taddi %1S, %1S, %d\t\t\t/* %+F (IncSP) */\n", irn, irn, +// -offs, irn); // } // else { // fprintf(F, "\t\t\t\t\t/* omitted IncSP with 0 */\n");