From: Matthias Braun Date: Tue, 2 Oct 2007 14:05:27 +0000 (+0000) Subject: - Route esp through calls X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=e4b61083553236f2a83c88807a8d11621956bbbc;p=libfirm - Route esp through calls - Mark struct returning calls as modify_stack - Cleanup benode a bit [r16034] --- diff --git a/ir/be/beabi.c b/ir/be/beabi.c index 83c6a3879..a0b935de7 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -650,6 +650,14 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) } ARR_APP1(ir_node *, env->calls, low_call); + /* create new stack pointer */ + curr_sp = new_r_Proj(irg, bl, low_call, get_irn_mode(curr_sp), + pn_be_Call_sp); + be_set_constr_single_reg(low_call, BE_OUT_POS(pn_be_Call_sp), sp); + arch_set_irn_register(arch_env, curr_sp, sp); + be_node_set_flags(low_call, BE_OUT_POS(pn_be_Call_sp), + arch_irn_flags_ignore | arch_irn_flags_modify_sp); + for(i = 0; i < n_res; ++i) { int pn; ir_node *proj = res_projs[i]; @@ -730,7 +738,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) /* memorize the register in the link field. we need afterwards to set the register class of the keep correctly. */ be_set_constr_single_reg(low_call, BE_OUT_POS(curr_res_proj), reg); - arch_set_irn_register(env->birg->main_env->arch_env, proj, reg); + arch_set_irn_register(arch_env, proj, reg); /* a call can produce ignore registers, in this case set the flag and register for the Proj */ if (arch_register_type_is(reg, ignore)) { @@ -782,11 +790,13 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) if (! no_alloc) { /* the callee pops the shadow parameter */ if(get_method_calling_convention(mt) & cc_compound_ret) { - stack_size -= get_mode_size_bytes(mode_P_data); + unsigned size = get_mode_size_bytes(mode_P_data); + stack_size -= size; + be_Call_set_pop(low_call, size); } curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size); - add_irn_dep(curr_sp, mem_proj); + //add_irn_dep(curr_sp, mem_proj); } } diff --git a/ir/be/benode.c b/ir/be/benode.c index ecdfeb2eb..f3bd5455f 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -60,8 +60,8 @@ #define OUT_POS(x) (-((x) + 1)) -/* Sometimes we want to put const nodes into get_irn_generic_attr ... */ -#define get_irn_attr(irn) get_irn_generic_attr((ir_node *) (irn)) +#define get_irn_attr(irn) get_irn_generic_attr(irn) +#define get_irn_attr_const(irn) get_irn_generic_attr_const(irn) static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O'); @@ -105,6 +105,7 @@ typedef struct { typedef struct { be_node_attr_t node_attr; ir_entity *ent; /**< The called entity if this is a static call. */ + unsigned pop; ir_type *call_tp; /**< The call type, copied from the original Call node. */ } be_call_attr_t; @@ -227,11 +228,11 @@ static int Call_cmp_attr(ir_node *a, ir_node *b) { static INLINE be_req_t *get_be_req(const ir_node *node, int pos) { int idx; - be_node_attr_t *attr; + const be_node_attr_t *attr; be_reg_data_t *rd; assert(is_be_node(node)); - attr = get_irn_attr(node); + attr = get_irn_attr_const(node); if(pos < 0) { idx = -(pos + 1); @@ -378,7 +379,7 @@ static int redir_proj(const ir_node **node) static be_reg_data_t *retrieve_reg_data(const ir_node *node) { - be_node_attr_t *attr; + const be_node_attr_t *attr; int pos = 0; if(is_Proj(node)) { @@ -387,7 +388,7 @@ static be_reg_data_t *retrieve_reg_data(const ir_node *node) } assert(is_be_node(node)); - attr = get_irn_attr(node); + attr = get_irn_attr_const(node); assert(pos >= 0 && pos < ARR_LEN(attr->reg_data) && "illegal proj number"); return &attr->reg_data[pos]; @@ -610,12 +611,13 @@ ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir a = init_node_attr(irn, (n_outs > real_n ? n_outs : real_n)); a->ent = NULL; a->call_tp = call_tp; + a->pop = 0; return irn; } /* Gets the call entity or NULL if this is no static call. */ ir_entity *be_Call_get_entity(const ir_node *call) { - be_call_attr_t *a = get_irn_attr(call); + const be_call_attr_t *a = get_irn_attr_const(call); assert(be_is_Call(call)); return a->ent; } @@ -629,7 +631,7 @@ void be_Call_set_entity(ir_node *call, ir_entity *ent) { /* Gets the call type. */ ir_type *be_Call_get_type(ir_node *call) { - be_call_attr_t *a = get_irn_attr(call); + const be_call_attr_t *a = get_irn_attr_const(call); assert(be_is_Call(call)); return a->call_tp; } @@ -641,6 +643,16 @@ void be_Call_set_type(ir_node *call, ir_type *call_tp) { a->call_tp = call_tp; } +void be_Call_set_pop(ir_node *call, unsigned pop) { + be_call_attr_t *a = get_irn_attr(call); + a->pop = pop; +} + +unsigned be_Call_get_pop(const ir_node *call) { + const be_call_attr_t *a = get_irn_attr_const(call); + return a->pop; +} + /* Construct a new be_Return. */ ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res, unsigned pop, int n, ir_node *in[]) @@ -913,7 +925,7 @@ int be_has_frame_entity(const ir_node *irn) ir_entity *be_get_frame_entity(const ir_node *irn) { if (be_has_frame_entity(irn)) { - be_frame_attr_t *a = get_irn_attr(irn); + const be_frame_attr_t *a = get_irn_attr_const(irn); return a->ent; } return NULL; @@ -923,7 +935,7 @@ int be_get_frame_offset(const ir_node *irn) { assert(is_be_node(irn)); if (be_has_frame_entity(irn)) { - be_frame_attr_t *a = get_irn_attr(irn); + const be_frame_attr_t *a = get_irn_attr_const(irn); return a->offset; } return 0; @@ -931,7 +943,7 @@ int be_get_frame_offset(const ir_node *irn) void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent) { - be_memperm_attr_t *attr = get_irn_attr(irn); + const be_memperm_attr_t *attr = get_irn_attr_const(irn); assert(be_is_MemPerm(irn)); assert(n < be_get_MemPerm_entity_arity(irn)); @@ -941,7 +953,7 @@ void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent) ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n) { - be_memperm_attr_t *attr = get_irn_attr(irn); + const be_memperm_attr_t *attr = get_irn_attr_const(irn); assert(be_is_MemPerm(irn)); assert(n < be_get_MemPerm_entity_arity(irn)); @@ -951,7 +963,7 @@ ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n) void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent) { - be_memperm_attr_t *attr = get_irn_attr(irn); + const be_memperm_attr_t *attr = get_irn_attr_const(irn); assert(be_is_MemPerm(irn)); assert(n < be_get_MemPerm_entity_arity(irn)); @@ -961,7 +973,7 @@ void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent) ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n) { - be_memperm_attr_t *attr = get_irn_attr(irn); + const be_memperm_attr_t *attr = get_irn_attr_const(irn); assert(be_is_MemPerm(irn)); assert(n < be_get_MemPerm_entity_arity(irn)); @@ -1056,7 +1068,7 @@ void be_set_IncSP_offset(ir_node *irn, int offset) int be_get_IncSP_offset(const ir_node *irn) { - be_stack_attr_t *a = get_irn_attr(irn); + const be_stack_attr_t *a = get_irn_attr_const(irn); assert(be_is_IncSP(irn)); return a->offset; } @@ -1110,7 +1122,7 @@ ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls, static const arch_register_req_t *get_out_reg_req(const ir_node *irn, int out_pos) { - const be_node_attr_t *a = get_irn_attr(irn); + const be_node_attr_t *a = get_irn_attr_const(irn); if(out_pos >= ARR_LEN(a->reg_data)) { return arch_no_register_req; @@ -1122,7 +1134,7 @@ arch_register_req_t *get_out_reg_req(const ir_node *irn, int out_pos) static const arch_register_req_t *get_in_reg_req(const ir_node *irn, int pos) { - const be_node_attr_t *a = get_irn_attr(irn); + const be_node_attr_t *a = get_irn_attr_const(irn); if(pos >= get_irn_arity(irn) || pos >= ARR_LEN(a->reg_data)) return arch_no_register_req; @@ -1235,7 +1247,12 @@ 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) { (void) self; - return be_is_IncSP(irn) ? be_get_IncSP_offset(irn) : 0; + if(be_is_IncSP(irn)) + return be_get_IncSP_offset(irn); + if(be_is_Call(irn)) + return -be_Call_get_pop(irn); + + return 0; } /* @@ -1699,7 +1716,7 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) */ static void copy_attr(const ir_node *old_node, ir_node *new_node) { - be_node_attr_t *old_attr = get_irn_attr(old_node); + const be_node_attr_t *old_attr = get_irn_attr_const(old_node); be_node_attr_t *new_attr = get_irn_attr(new_node); struct obstack *obst = get_irg_obstack(get_irn_irg(new_node)); unsigned i, len; diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index ddd3c059a..64e71da87 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -285,6 +285,10 @@ ir_type *be_Call_get_type(ir_node *call); /** Sets the call type. */ void be_Call_set_type(ir_node *call, ir_type *call_tp); +void be_Call_set_pop(ir_node *call, unsigned pop); + +unsigned be_Call_get_pop(const ir_node *call); + /** * Position numbers for the be_Call inputs. */ @@ -300,7 +304,8 @@ enum { */ typedef enum { pn_be_Call_M_regular = pn_Call_M_regular, /**< The memory result of a be_Call. */ - pn_be_Call_first_res = pn_Call_max /**< The first result proj number of a be_Call. */ + pn_be_Call_sp = pn_Call_max, + pn_be_Call_first_res /**< The first result proj number of a be_Call. */ } pn_be_Call; /** diff --git a/ir/be/test/fehler55.c b/ir/be/test/fehler55.c index 4fccba33a..18d779f03 100644 --- a/ir/be/test/fehler55.c +++ b/ir/be/test/fehler55.c @@ -1,11 +1,11 @@ -typedef struct sv SV; +#include -struct sv { -}; +typedef struct sv { +}SV ; typedef struct hek HEK; struct hek { - char hek_key[3]; + char hek_key[4]; }; HEK hekimek;