X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbenode.c;h=06f44d8e1b3412a83f258c55feeb0b52153aa1b3;hb=d300330b1e6df8c8914b8fb70cf38ee1c8ca2634;hp=30be69246f5ee8b7f9c9b5e03340978306e51789;hpb=2b2050344aa7321f95ffabea0d70b93265c59401;p=libfirm diff --git a/ir/be/benode.c b/ir/be/benode.c index 30be69246..06f44d8e1 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -55,13 +55,14 @@ #include "belive_t.h" #include "besched_t.h" #include "benode_t.h" +#include "bearch_t.h" #include "beirgmod.h" #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'); @@ -78,37 +79,39 @@ typedef struct { /** The generic be nodes attribute type. */ typedef struct { - be_reg_data_t *reg_data; + be_reg_data_t *reg_data; } be_node_attr_t; /** The be_Return nodes attribute type. */ typedef struct { - be_node_attr_t node_attr; + be_node_attr_t node_attr; /**< base attributes of every be node. */ int num_ret_vals; /**< number of return values */ + unsigned pop; /**< number of bytes that should be popped */ } be_return_attr_t; -/** The be_Stack attribute type. */ +/** The be_IncSP attribute type. */ typedef struct { - be_node_attr_t node_attr; - int offset; /**< The offset by which the stack shall be expanded/shrinked. */ -} be_stack_attr_t; + be_node_attr_t node_attr; /**< base attributes of every be node. */ + int offset; /**< The offset by which the stack shall be expanded/shrinked. */ +} be_incsp_attr_t; /** The be_Frame attribute type. */ typedef struct { - be_node_attr_t node_attr; + be_node_attr_t node_attr; /**< base attributes of every be node. */ ir_entity *ent; int offset; } be_frame_attr_t; /** The be_Call attribute type. */ typedef struct { - be_node_attr_t node_attr; - ir_entity *ent; /**< The called entity if this is a static call. */ - ir_type *call_tp; /**< The call type, copied from the original Call node. */ + be_node_attr_t node_attr; /**< base attributes of every be node. */ + 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; typedef struct { - be_node_attr_t node_attr; + be_node_attr_t node_attr; /**< base attributes of every be node. */ ir_entity **in_entities; ir_entity **out_entities; } be_memperm_attr_t; @@ -125,10 +128,10 @@ ir_op *op_be_Return; ir_op *op_be_IncSP; ir_op *op_be_AddSP; ir_op *op_be_SubSP; -ir_op *op_be_SetSP; ir_op *op_be_RegParams; ir_op *op_be_FrameAddr; ir_op *op_be_Barrier; +ir_op *op_be_Unwind; static int beo_base = -1; @@ -144,18 +147,18 @@ static const ir_op_ops be_node_op_ops; #define H irop_flag_highlevel #define c irop_flag_constlike #define K irop_flag_keep -#define M irop_flag_machine +#define M irop_flag_uses_memory /** - * Compare two node attributes. + * Compare two be node attributes. * * @return zero if both attributes are identically */ -static int _node_cmp_attr(be_node_attr_t *a, be_node_attr_t *b) { +static int _node_cmp_attr(const be_node_attr_t *a, const be_node_attr_t *b) { int i, len; - if(ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data)) + if (ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data)) return 1; len = ARR_LEN(a->reg_data); @@ -169,67 +172,89 @@ static int _node_cmp_attr(be_node_attr_t *a, be_node_attr_t *b) { return 0; } +/** + * Compare the node attributes of two be_node's. + * + * @return zero if both nodes have identically attributes + */ static int node_cmp_attr(ir_node *a, ir_node *b) { - be_node_attr_t *a_attr = get_irn_attr(a); - be_node_attr_t *b_attr = get_irn_attr(b); + const be_node_attr_t *a_attr = get_irn_attr_const(a); + const be_node_attr_t *b_attr = get_irn_attr_const(b); return _node_cmp_attr(a_attr, b_attr); } /** - * Compare the attributes of two FrameAddr nodes. + * Compare the attributes of two be_FrameAddr nodes. * - * @return zero if both attributes are identically + * @return zero if both nodes have identically attributes */ static int FrameAddr_cmp_attr(ir_node *a, ir_node *b) { - be_frame_attr_t *a_attr = get_irn_attr(a); - be_frame_attr_t *b_attr = get_irn_attr(b); + const be_frame_attr_t *a_attr = get_irn_attr_const(a); + const be_frame_attr_t *b_attr = get_irn_attr_const(b); if (a_attr->ent != b_attr->ent || a_attr->offset != b_attr->offset) return 1; - return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr); + return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr); } +/** + * Compare the attributes of two be_Return nodes. + * + * @return zero if both nodes have identically attributes + */ static int Return_cmp_attr(ir_node *a, ir_node *b) { - be_return_attr_t *a_attr = get_irn_attr(a); - be_return_attr_t *b_attr = get_irn_attr(b); + const be_return_attr_t *a_attr = get_irn_attr_const(a); + const be_return_attr_t *b_attr = get_irn_attr_const(b); if (a_attr->num_ret_vals != b_attr->num_ret_vals) return 1; + if (a_attr->pop != b_attr->pop) + return 1; - return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr); + return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr); } -static int Stack_cmp_attr(ir_node *a, ir_node *b) { - be_stack_attr_t *a_attr = get_irn_attr(a); - be_stack_attr_t *b_attr = get_irn_attr(b); +/** + * Compare the attributes of two be_IncSP nodes. + * + * @return zero if both nodes have identically attributes + */ +static int IncSP_cmp_attr(ir_node *a, ir_node *b) { + const be_incsp_attr_t *a_attr = get_irn_attr_const(a); + const be_incsp_attr_t *b_attr = get_irn_attr_const(b); if (a_attr->offset != b_attr->offset) return 1; - return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr); + return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr); } +/** + * Compare the attributes of two be_Call nodes. + * + * @return zero if both nodes have identically attributes + */ static int Call_cmp_attr(ir_node *a, ir_node *b) { - be_call_attr_t *a_attr = get_irn_attr(a); - be_call_attr_t *b_attr = get_irn_attr(b); + const be_call_attr_t *a_attr = get_irn_attr_const(a); + const be_call_attr_t *b_attr = get_irn_attr_const(b); if (a_attr->ent != b_attr->ent || a_attr->call_tp != b_attr->call_tp) return 1; - return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr); + return _node_cmp_attr(&a_attr->node_attr, &b_attr->node_attr); } 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); @@ -260,22 +285,22 @@ void be_node_init(void) { /* Acquire all needed opcodes. */ beo_base = get_next_ir_opcodes(beo_Last); - op_be_Spill = new_ir_op(beo_base + beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); - op_be_Reload = new_ir_op(beo_base + beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops); - op_be_Perm = new_ir_op(beo_base + beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_MemPerm = new_ir_op(beo_base + beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops); - op_be_Copy = new_ir_op(beo_base + beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_Keep = new_ir_op(beo_base + beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_CopyKeep = new_ir_op(beo_base + beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_Call = new_ir_op(beo_base + beo_Call, "be_Call", op_pin_state_pinned, F, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops); - op_be_Return = new_ir_op(beo_base + beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops); - op_be_AddSP = new_ir_op(beo_base + beo_AddSP, "be_AddSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_SubSP = new_ir_op(beo_base + beo_SubSP, "be_SubSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_IncSP = new_ir_op(beo_base + beo_IncSP, "be_IncSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_stack_attr_t), &be_node_op_ops); - op_be_SetSP = new_ir_op(beo_base + beo_SetSP, "be_SetSP", op_pin_state_pinned, N, oparity_binary, 0, sizeof(be_stack_attr_t), &be_node_op_ops); - op_be_RegParams = new_ir_op(beo_base + beo_RegParams, "be_RegParams", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops); - op_be_FrameAddr = new_ir_op(beo_base + beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); - op_be_Barrier = new_ir_op(beo_base + beo_Barrier, "be_Barrier", op_pin_state_pinned, N, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_Spill = new_ir_op(beo_base + beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); + op_be_Reload = new_ir_op(beo_base + beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops); + op_be_Perm = new_ir_op(beo_base + beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_MemPerm = new_ir_op(beo_base + beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops); + op_be_Copy = new_ir_op(beo_base + beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_Keep = new_ir_op(beo_base + beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_CopyKeep = new_ir_op(beo_base + beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_Call = new_ir_op(beo_base + beo_Call, "be_Call", op_pin_state_pinned, F|M, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops); + op_be_Return = new_ir_op(beo_base + beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops); + op_be_AddSP = new_ir_op(beo_base + beo_AddSP, "be_AddSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_SubSP = new_ir_op(beo_base + beo_SubSP, "be_SubSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_IncSP = new_ir_op(beo_base + beo_IncSP, "be_IncSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_incsp_attr_t), &be_node_op_ops); + op_be_RegParams = new_ir_op(beo_base + beo_RegParams, "be_RegParams", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_FrameAddr = new_ir_op(beo_base + beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); + op_be_Barrier = new_ir_op(beo_base + beo_Barrier, "be_Barrier", op_pin_state_pinned, N, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops); + op_be_Unwind = new_ir_op(beo_base + beo_Unwind, "be_Unwind", op_pin_state_pinned, X, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops); set_op_tag(op_be_Spill, &be_node_tag); op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr; @@ -299,16 +324,16 @@ void be_node_init(void) { op_be_AddSP->ops.node_cmp_attr = node_cmp_attr; set_op_tag(op_be_SubSP, &be_node_tag); op_be_SubSP->ops.node_cmp_attr = node_cmp_attr; - set_op_tag(op_be_SetSP, &be_node_tag); - op_be_SetSP->ops.node_cmp_attr = Stack_cmp_attr; set_op_tag(op_be_IncSP, &be_node_tag); - op_be_IncSP->ops.node_cmp_attr = Stack_cmp_attr; + op_be_IncSP->ops.node_cmp_attr = IncSP_cmp_attr; set_op_tag(op_be_RegParams, &be_node_tag); op_be_RegParams->ops.node_cmp_attr = node_cmp_attr; set_op_tag(op_be_FrameAddr, &be_node_tag); op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr; set_op_tag(op_be_Barrier, &be_node_tag); op_be_Barrier->ops.node_cmp_attr = node_cmp_attr; + set_op_tag(op_be_Unwind, &be_node_tag); + op_be_Unwind->ops.node_cmp_attr = node_cmp_attr; } /** @@ -379,7 +404,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)) { @@ -388,7 +413,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]; @@ -478,29 +503,26 @@ ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *b void be_Perm_reduce(ir_node *perm, int new_size, int *map) { ir_graph *irg = get_irn_irg(perm); - int n = get_irn_arity(perm); - be_reg_data_t *old_data = xmalloc(n * sizeof(old_data[0])); + int arity = get_irn_arity(perm); + be_reg_data_t *old_data = alloca(arity * sizeof(old_data[0])); be_node_attr_t *attr = get_irn_attr(perm); - ir_node **new_in = NEW_ARR_D(ir_node *, irg->obst, new_size + 1); + ir_node **new_in = NEW_ARR_D(ir_node *, irg->obst, new_size); int i; assert(be_is_Perm(perm)); - assert(new_size <= n); + assert(new_size <= arity); /* save the old register data */ - memcpy(old_data, attr->reg_data, n * sizeof(old_data[0])); + memcpy(old_data, attr->reg_data, arity * sizeof(old_data[0])); /* compose the new in array and set the new register data directly in place */ - for (i = 0; i < n; ++i) { + for (i = 0; i < new_size; ++i) { int idx = map[i]; - if (idx >= 0) { - new_in[idx] = get_irn_n(perm, i); - attr->reg_data[idx] = old_data[i]; - } + new_in[i] = get_irn_n(perm, idx); + attr->reg_data[i] = old_data[idx]; } - free(old_data); set_irn_in(perm, new_size, new_in); } @@ -522,7 +544,7 @@ ir_node *be_new_MemPerm(const arch_env_t *arch_env, ir_graph *irg, ir_node *bl, init_node_attr(irn, n + 1); be_node_set_reg_class(irn, 0, sp->reg_class); - for(i = 0; i < n; ++i) { + for (i = 0; i < n; ++i) { be_node_set_reg_class(irn, i + 1, cls_frame); be_node_set_reg_class(irn, OUT_POS(i), cls_frame); } @@ -553,7 +575,7 @@ ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *b req = get_req(res, OUT_POS(0)); req->cls = cls; req->type = arch_register_req_type_should_be_same; - req->other_same = 0; + req->other_same = 1U << 0; return res; } @@ -613,12 +635,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; } @@ -632,7 +655,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; } @@ -644,9 +667,19 @@ 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, - int n, ir_node *in[]) + unsigned pop, int n, ir_node *in[]) { be_return_attr_t *a; ir_node *res; @@ -661,17 +694,24 @@ ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res, a = get_irn_attr(res); a->num_ret_vals = n_res; + a->pop = pop; return res; } /* Returns the number of real returns values */ -int be_Return_get_n_rets(ir_node *ret) +int be_Return_get_n_rets(const ir_node *ret) { - be_return_attr_t *a = get_irn_attr(ret); + const be_return_attr_t *a = get_irn_generic_attr_const(ret); return a->num_ret_vals; } +unsigned be_Return_get_pop(const ir_node *ret) +{ + const be_return_attr_t *a = get_irn_generic_attr_const(ret); + return a->pop; +} + int be_Return_append_node(ir_node *ret, ir_node *node) { int pos; @@ -684,7 +724,7 @@ int be_Return_append_node(ir_node *ret, ir_node *node) ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset) { - be_stack_attr_t *a; + be_incsp_attr_t *a; ir_node *irn; ir_node *in[1]; @@ -755,29 +795,6 @@ ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_ return irn; } -ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, - ir_node *old_sp, ir_node *op, ir_node *mem) -{ - be_node_attr_t *a; - ir_node *irn; - ir_node *in[3]; - - in[0] = mem; - in[1] = old_sp; - in[2] = op; - irn = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in); - a = init_node_attr(irn, 3); - - be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp); - - /* Set output constraint to stack register. */ - be_set_constr_single_reg(irn, OUT_POS(0), sp); - be_node_set_reg_class(irn, be_pos_AddSP_size, sp->reg_class); - be_node_set_reg_class(irn, be_pos_AddSP_old_sp, sp->reg_class); - - return irn; -} - ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs) { ir_node *res; @@ -859,10 +876,7 @@ ir_node *be_new_CopyKeep(const arch_register_class_t *cls, ir_graph *irg, ir_nod ir_node *be_new_CopyKeep_single(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, ir_node *keep, ir_mode *mode) { - ir_node *in[1]; - - in[0] = keep; - return be_new_CopyKeep(cls, irg, bl, src, 1, in, mode); + return be_new_CopyKeep(cls, irg, bl, src, 1, &keep, mode); } ir_node *be_get_CopyKeep_op(const ir_node *cpy) { @@ -901,6 +915,21 @@ ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node) return proj; } +/* Construct a new be_Unwind. */ +ir_node *be_new_Unwind(dbg_info *dbg, ir_graph *irg, ir_node *block, + ir_node *mem, ir_node *sp) +{ + ir_node *res; + ir_node *in[2]; + + in[be_pos_Unwind_mem] = mem; + in[be_pos_Unwind_sp] = sp; + res = new_ir_node(dbg, irg, block, op_be_Unwind, mode_X, 2, in); + init_node_attr(res, -1); + + return res; +} + int be_is_Spill (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill ; } int be_is_Reload (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Reload ; } int be_is_Copy (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Copy ; } @@ -911,16 +940,16 @@ int be_is_Keep (const ir_node *irn) { return be_get_irn_opcode(irn) == int be_is_Call (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Call ; } int be_is_Return (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Return ; } int be_is_IncSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_IncSP ; } -int be_is_SetSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP ; } int be_is_AddSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP ; } int be_is_SubSP (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP ; } int be_is_RegParams (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams ; } int be_is_FrameAddr (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr ; } int be_is_Barrier (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier ; } +int be_is_Unwind (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Unwind ; } int be_has_frame_entity(const ir_node *irn) { - switch(be_get_irn_opcode(irn)) { + switch (be_get_irn_opcode(irn)) { case beo_Spill: case beo_Reload: case beo_FrameAddr: @@ -933,7 +962,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; @@ -943,7 +972,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; @@ -951,7 +980,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)); @@ -961,7 +990,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)); @@ -971,7 +1000,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)); @@ -981,7 +1010,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)); @@ -1032,6 +1061,12 @@ void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags) bereq->flags = flags; } +void be_node_add_flags(ir_node *irn, int pos, arch_irn_flags_t flags) +{ + be_req_t *bereq = get_be_req(irn, pos); + bereq->flags |= flags; +} + void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls) { arch_register_req_t *req = get_req(irn, pos); @@ -1063,28 +1098,27 @@ void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) { void be_set_IncSP_offset(ir_node *irn, int offset) { - be_stack_attr_t *a = get_irn_attr(irn); + be_incsp_attr_t *a = get_irn_attr(irn); assert(be_is_IncSP(irn)); a->offset = offset; } int be_get_IncSP_offset(const ir_node *irn) { - be_stack_attr_t *a = get_irn_attr(irn); + const be_incsp_attr_t *a = get_irn_attr_const(irn); assert(be_is_IncSP(irn)); return a->offset; } -ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn) +ir_node *be_spill(const arch_env_t *arch_env, ir_node *block, ir_node *irn) { - ir_node *bl = get_nodes_block(irn); - ir_graph *irg = get_irn_irg(bl); + ir_graph *irg = get_irn_irg(block); ir_node *frame = get_irg_frame(irg); const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, irn, -1); const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1); ir_node *spill; - spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn); + spill = be_new_Spill(cls, cls_frame, irg, block, frame, irn); return spill; } @@ -1124,7 +1158,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; @@ -1136,7 +1170,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; @@ -1249,7 +1283,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 -(int)be_Call_get_pop(irn); + + return 0; } /* @@ -1639,7 +1678,7 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) fprintf(f, " [%s] ", get_entity_name(a->ent)); } if(be_is_IncSP(irn)) { - const be_stack_attr_t *attr = get_irn_generic_attr_const(irn); + const be_incsp_attr_t *attr = get_irn_generic_attr_const(irn); if(attr->offset == BE_STACK_FRAME_SIZE_EXPAND) { fprintf(f, " [Setup Stackframe] "); } else if(attr->offset == BE_STACK_FRAME_SIZE_SHRINK) { @@ -1655,9 +1694,9 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) if(be_has_frame_entity(irn)) { be_frame_attr_t *a = (be_frame_attr_t *) at; if (a->ent) { - int bits = get_type_size_bits(get_entity_type(a->ent)); - ir_fprintf(f, "frame entity: %+F, offset 0x%x (%d), size 0x%x (%d) bits\n", - a->ent, a->offset, a->offset, bits, bits); + unsigned size = get_type_size_bytes(get_entity_type(a->ent)); + ir_fprintf(f, "frame entity: %+F, offset 0x%x (%d), size 0x%x (%d) bytes\n", + a->ent, a->offset, a->offset, size, size); } } @@ -1665,7 +1704,7 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) switch(be_get_irn_opcode(irn)) { case beo_IncSP: { - be_stack_attr_t *a = (be_stack_attr_t *) at; + be_incsp_attr_t *a = (be_incsp_attr_t *) at; if (a->offset == BE_STACK_FRAME_SIZE_EXPAND) fprintf(f, "offset: FRAME_SIZE\n"); else if(a->offset == BE_STACK_FRAME_SIZE_SHRINK) @@ -1713,7 +1752,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;