From: Matthias Braun Date: Wed, 14 Feb 2007 12:55:21 +0000 (+0000) Subject: fix alloc node in beabit, to calculate correct size, use be_kill_node X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=1acb2d4d85e5a1a753692044c17c21843262cd91;p=libfirm fix alloc node in beabit, to calculate correct size, use be_kill_node --- diff --git a/ir/be/beabi.c b/ir/be/beabi.c index c0ce1e357..d515e3bb0 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -683,7 +683,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i /* set the now unnecessary projT to bad */ if(res_proj != NULL) { - set_Proj_pred(res_proj, new_Bad()); + be_kill_node(res_proj); } /* Make additional projs for the caller save registers @@ -762,81 +762,104 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i */ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp, ir_node **result_copy) { - if (get_Alloc_where(alloc) == stack_alloc) { - ir_node *bl = get_nodes_block(alloc); - ir_graph *irg = get_irn_irg(bl); - ir_node *alloc_mem = NULL; - ir_node *alloc_res = NULL; + ir_node *block; + ir_graph *irg; + ir_node *alloc_mem; + ir_node *alloc_res; + ir_type *type; - const ir_edge_t *edge; - ir_node *new_alloc; - ir_node *addr; - ir_node *copy; - ir_node *ins[2]; + const ir_edge_t *edge; + ir_node *new_alloc; + ir_node *size; + ir_node *addr; + ir_node *copy; + ir_node *ins[2]; + + if (get_Alloc_where(alloc) != stack_alloc) { + assert(0); + return alloc; + } - foreach_out_edge(alloc, edge) { - ir_node *irn = get_edge_src_irn(edge); + block = get_nodes_block(alloc); + irg = get_irn_irg(block); + alloc_mem = NULL; + alloc_res = NULL; + type = get_Alloc_type(alloc); - assert(is_Proj(irn)); - switch(get_Proj_proj(irn)) { - case pn_Alloc_M: - alloc_mem = irn; - break; - case pn_Alloc_res: - alloc_res = irn; - break; - default: - break; - } - } + foreach_out_edge(alloc, edge) { + ir_node *irn = get_edge_src_irn(edge); - /* Beware: currently Alloc nodes without a result might happen, - only escape analysis kills them and this phase runs only for object - oriented source. We kill the Alloc here. */ - if (alloc_res == NULL && alloc_mem) { - exchange(alloc_mem, get_Alloc_mem(alloc)); - return curr_sp; + assert(is_Proj(irn)); + switch(get_Proj_proj(irn)) { + case pn_Alloc_M: + alloc_mem = irn; + break; + case pn_Alloc_res: + alloc_res = irn; + break; + default: + break; } + } - /* The stack pointer will be modified in an unknown manner. - We cannot omit it. */ - env->call->flags.bits.try_omit_fp = 0; - new_alloc = be_new_AddSP(env->isa->sp, irg, bl, curr_sp, get_Alloc_size(alloc)); + /* Beware: currently Alloc nodes without a result might happen, + only escape analysis kills them and this phase runs only for object + oriented source. We kill the Alloc here. */ + if (alloc_res == NULL && alloc_mem) { + exchange(alloc_mem, get_Alloc_mem(alloc)); + return curr_sp; + } + + /* we might need to multiply the size with the element size */ + if(type != get_unknown_type() && get_type_size_bytes(type) != 1) { + tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu); + ir_node *cnst = new_rd_Const(NULL, irg, block, mode_Iu, tv); + ir_node *mul = new_rd_Mul(NULL, irg, block, get_Alloc_size(alloc), + cnst, mode_Iu); + size = mul; + } else { + size = get_Alloc_size(alloc); + } - if(alloc_mem != NULL) { - ir_node *addsp_mem; - ir_node *sync; + /* The stack pointer will be modified in an unknown manner. + We cannot omit it. */ + env->call->flags.bits.try_omit_fp = 0; + new_alloc = be_new_AddSP(env->isa->sp, irg, block, curr_sp, size); - addsp_mem = new_r_Proj(irg, bl, new_alloc, mode_M, pn_be_AddSP_M); + if(alloc_mem != NULL) { + ir_node *addsp_mem; + ir_node *sync; - // We need to sync the output mem of the AddSP with the input mem - // edge into the alloc node - ins[0] = get_Alloc_mem(alloc); - ins[1] = addsp_mem; - sync = new_r_Sync(irg, bl, 2, ins); + addsp_mem = new_r_Proj(irg, block, new_alloc, mode_M, pn_be_AddSP_M); - exchange(alloc_mem, sync); - } + // We need to sync the output mem of the AddSP with the input mem + // edge into the alloc node + ins[0] = get_Alloc_mem(alloc); + ins[1] = addsp_mem; + sync = new_r_Sync(irg, block, 2, ins); - exchange(alloc, new_alloc); + exchange(alloc_mem, sync); + } - /* fix projnum of alloca res */ - set_Proj_proj(alloc_res, pn_be_AddSP_res); + exchange(alloc, new_alloc); - addr = env->isa->stack_dir < 0 ? alloc_res : curr_sp; + /* fix projnum of alloca res */ + set_Proj_proj(alloc_res, pn_be_AddSP_res); - /* copy the address away, since it could be used after further stack pointer modifications. */ - /* Let it point curr_sp just for the moment, I'll reroute it in a second. */ - *result_copy = copy = be_new_Copy(env->isa->sp->reg_class, irg, bl, curr_sp); + addr = env->isa->stack_dir < 0 ? alloc_res : curr_sp; - /* Let all users of the Alloc() result now point to the copy. */ - edges_reroute(alloc_res, copy, irg); + /* copy the address away, since it could be used after further stack pointer modifications. */ + /* Let it point curr_sp just for the moment, I'll reroute it in a second. */ + *result_copy = copy = be_new_Copy(env->isa->sp->reg_class, irg, block, curr_sp); - /* Rewire the copy appropriately. */ - set_irn_n(copy, be_pos_Copy_op, addr); + /* Let all users of the Alloc() result now point to the copy. */ + edges_reroute(alloc_res, copy, irg); + + /* Rewire the copy appropriately. */ + set_irn_n(copy, be_pos_Copy_op, addr); + + curr_sp = alloc_res; - curr_sp = alloc_res; - } return curr_sp; } /* adjust_alloc */ @@ -846,22 +869,42 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp */ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) { - if (get_Free_where(free) == stack_alloc) { - ir_node *bl = get_nodes_block(free); - ir_graph *irg = get_irn_irg(bl); - ir_node *addsp, *mem, *res; - - /* The stack pointer will be modified in an unknown manner. - We cannot omit it. */ - env->call->flags.bits.try_omit_fp = 0; - addsp = be_new_SubSP(env->isa->sp, irg, bl, curr_sp, get_Free_size(free)); + ir_node *block; + ir_graph *irg; + ir_node *addsp, *mem, *res, *size; + ir_type *type; - mem = new_r_Proj(irg, bl, addsp, mode_M, pn_be_SubSP_M); - res = new_r_Proj(irg, bl, addsp, mode_P_data, pn_be_SubSP_res); + if (get_Free_where(free) != stack_alloc) { + assert(0); + return free; + } - exchange(free, mem); - curr_sp = res; + block = get_nodes_block(free); + irg = get_irn_irg(block); + type = get_Free_type(free); + + /* we might need to multiply the size with the element size */ + if(type != get_unknown_type() && get_type_size_bytes(type) != 1) { + tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu); + ir_node *cnst = new_rd_Const(NULL, irg, block, mode_Iu, tv); + ir_node *mul = new_rd_Mul(NULL, irg, block, get_Free_size(free), + cnst, mode_Iu); + size = mul; + } else { + size = get_Free_size(free); } + + /* The stack pointer will be modified in an unknown manner. + We cannot omit it. */ + env->call->flags.bits.try_omit_fp = 0; + addsp = be_new_SubSP(env->isa->sp, irg, block, curr_sp, size); + + mem = new_r_Proj(irg, block, addsp, mode_M, pn_be_SubSP_M); + res = new_r_Proj(irg, block, addsp, mode_P_data, pn_be_SubSP_res); + + exchange(free, mem); + curr_sp = res; + return curr_sp; } /* adjust_free */ @@ -1634,7 +1677,7 @@ static void modify_irg(be_abi_irg_t *env) /* value_param_base anchor is not needed anymore now */ value_param_base = get_irg_value_param_base(irg); - set_Proj_pred(value_param_base, new_r_Bad(irg)); + be_kill_node(value_param_base); set_irg_value_param_base(irg, new_r_Bad(irg)); env->frame = obstack_alloc(&env->obst, sizeof(env->frame[0])); @@ -1802,7 +1845,7 @@ static void modify_irg(be_abi_irg_t *env) /* the arg proj is not needed anymore now */ assert(get_irn_n_edges(arg_tuple) == 0); - set_irn_n(arg_tuple, 0, new_rd_Bad(irg)); + be_kill_node(arg_tuple); set_irg_args(irg, new_rd_Bad(irg)); /* All Return nodes hang on the End node, so look for them there. */