X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbestack.c;h=a28b4a43ad5a7bfbbe110587160c9581533dc8e8;hb=5474a1c188c9d59eea2c915515980cd9cbab58d8;hp=320c5c842a698c01c6dfdf7465f091ab25c6df2f;hpb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;p=libfirm diff --git a/ir/be/bestack.c b/ir/be/bestack.c index 320c5c842..a28b4a43a 100644 --- a/ir/be/bestack.c +++ b/ir/be/bestack.c @@ -20,7 +20,6 @@ /** * @file * @author Sebastian Hack, Matthias Braun - * @version $Id$ * * Handling of the stack frame. It is composed of three types: * 1) The type of the arguments which are pushed on the stack. @@ -86,12 +85,11 @@ static ir_entity *search_ent_with_offset(ir_type *t, int offset) static int stack_frame_compute_initial_offset(be_stack_layout_t *frame) { - ir_type *base = frame->stack_dir < 0 ? frame->between_type : frame->frame_type; + ir_type *base = frame->between_type; ir_entity *ent = search_ent_with_offset(base, 0); if (ent == NULL) { - frame->initial_offset - = frame->stack_dir < 0 ? get_type_size_bytes(frame->frame_type) : get_type_size_bytes(frame->between_type); + frame->initial_offset = get_type_size_bytes(frame->frame_type); } else { frame->initial_offset = be_get_stack_entity_offset(frame, ent, 0); } @@ -183,44 +181,41 @@ static int process_stack_bias(ir_node *bl, int real_bias) * If the node modifies the stack pointer by a constant offset, * record that in the bias. */ - ofs = arch_get_sp_bias(irn); - if (be_is_IncSP(irn)) { + ofs = be_get_IncSP_offset(irn); /* fill in real stack frame size */ - if (ofs == BE_STACK_FRAME_SIZE_EXPAND) { - ir_type *frame_type = get_irg_frame_type(irg); - ofs = (int) get_type_size_bytes(frame_type); - be_set_IncSP_offset(irn, ofs); - } else if (ofs == BE_STACK_FRAME_SIZE_SHRINK) { - ir_type *frame_type = get_irg_frame_type(irg); - ofs = - (int)get_type_size_bytes(frame_type); - be_set_IncSP_offset(irn, ofs); + if (be_get_IncSP_align(irn)) { + /* patch IncSP to produce an aligned stack pointer */ + ir_type *between_type = layout->between_type; + int between_size = get_type_size_bytes(between_type); + int alignment = 1 << arch_env->stack_alignment; + int delta = (real_bias + ofs + between_size) & (alignment - 1); + assert(ofs >= 0); + if (delta > 0) { + be_set_IncSP_offset(irn, ofs + alignment - delta); + real_bias += alignment - delta; + } } else { - if (be_get_IncSP_align(irn)) { - /* patch IncSP to produce an aligned stack pointer */ - ir_type *between_type = layout->between_type; - int between_size = get_type_size_bytes(between_type); - int alignment = 1 << arch_env->stack_alignment; - int delta = (real_bias + ofs + between_size) & (alignment - 1); - assert(ofs >= 0); - if (delta > 0) { - be_set_IncSP_offset(irn, ofs + alignment - delta); - real_bias += alignment - delta; - } - } else { - /* adjust so real_bias corresponds with wanted_bias */ - int delta = wanted_bias - real_bias; - assert(delta <= 0); - if (delta != 0) { - be_set_IncSP_offset(irn, ofs + delta); - real_bias += delta; - } + /* adjust so real_bias corresponds with wanted_bias */ + int delta = wanted_bias - real_bias; + assert(delta <= 0); + if (delta != 0) { + be_set_IncSP_offset(irn, ofs + delta); + real_bias += delta; } } + real_bias += ofs; + wanted_bias += ofs; + } else { + ofs = arch_get_sp_bias(irn); + if (ofs == SP_BIAS_RESET) { + real_bias = 0; + wanted_bias = 0; + } else { + real_bias += ofs; + wanted_bias += ofs; + } } - - real_bias += ofs; - wanted_bias += ofs; } assert(real_bias == wanted_bias); @@ -287,12 +282,12 @@ static void collect_stack_nodes_walker(ir_node *node, void *data) insn = get_Proj_pred(node); } - if (arch_irn_get_n_outs(insn) == 0) + if (arch_get_irn_n_outs(insn) == 0) return; if (get_irn_mode(node) == mode_T) return; - req = arch_get_register_req_out(node); + req = arch_get_irn_register_req(node); if (! (req->type & arch_register_req_type_produces_sp)) return; @@ -372,6 +367,28 @@ void be_abi_fix_stack_nodes(ir_graph *irg) arch_set_irn_register(phi, arch_env->sp); } be_ssa_construction_destroy(&senv); - DEL_ARR_F(walker_env.sp_nodes); + + /* when doing code with frame-pointers then often the last incsp-nodes are + * not used anymore because we copy the framepointer to the stack pointer + * when leaving the function. Though the last incsp is often kept (because + * you often don't know which incsp is the last one and fixstack should find + * them all). Remove unnecessary keeps and IncSP nodes */ + { + ir_node *end = get_irg_end(irg); + int arity = get_irn_arity(end); + int i; + for (i = arity-1; i >= 0; --i) { + ir_node *in = get_irn_n(end, i); + if (!be_is_IncSP(in)) { + continue; + } + + remove_End_keepalive(end, in); + if (get_irn_n_edges(in) == 0) { + sched_remove(in); + kill_node(in); + } + } + } }