From: Matthias Braun Date: Thu, 1 Mar 2007 13:55:02 +0000 (+0000) Subject: - make spillslot coalescer pickup float-int convert loads which are folded X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=b5fdd484372a10d1bc964c9fc5eaf1ddb4a2e3af;p=libfirm - make spillslot coalescer pickup float-int convert loads which are folded into other nodes - correctly fix Copies in x87 simulator --- diff --git a/ir/be/benode.c b/ir/be/benode.c index d1caba4e6..9f2960023 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -199,7 +199,7 @@ void be_node_init(void) { 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_mem_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_variable, 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_variable, 0, sizeof(be_return_attr_t), &be_node_op_ops); @@ -212,7 +212,7 @@ void be_node_init(void) { op_be_FrameAddr = new_ir_op(beo_base + beo_FrameAddr, "be_FrameAddr", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); op_be_FrameLoad = new_ir_op(beo_base + beo_FrameLoad, "be_FrameLoad", op_pin_state_pinned, N, oparity_any, 0, sizeof(be_frame_attr_t), &be_node_op_ops); op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "be_FrameStore", op_pin_state_pinned, N, oparity_any, 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_any, 0, sizeof(be_node_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); set_op_tag(op_be_Spill, &be_node_tag); set_op_tag(op_be_Reload, &be_node_tag); @@ -240,28 +240,32 @@ void be_node_init(void) { /** * Initializes the generic attribute of all be nodes and return ir. */ -static void *init_node_attr(ir_node* irn, int max_reg_data) +static void *init_node_attr(ir_node *node, int max_reg_data) { - ir_graph *irg = get_irn_irg(irn); + ir_graph *irg = get_irn_irg(node); struct obstack *obst = get_irg_obstack(irg); - be_node_attr_t *a = get_irn_attr(irn); - int i; + be_node_attr_t *a = get_irn_attr(node); - memset(a, 0, sizeof(get_op_attr_size(get_irn_op(irn)))); + memset(a, 0, sizeof(get_op_attr_size(get_irn_op(node)))); if(max_reg_data >= 0) { a->reg_data = NEW_ARR_D(be_reg_data_t, obst, max_reg_data); memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0])); - } - - for(i = 0; i < max_reg_data; ++i) { - a->reg_data[i].req.req.cls = NULL; - a->reg_data[i].req.req.type = arch_register_req_type_none; + } else { + a->reg_data = NEW_ARR_F(be_reg_data_t, 0); } return a; } +static void add_register_req(ir_node *node) +{ + be_node_attr_t *a = get_irn_attr(node); + be_reg_data_t regreq; + memset(®req, 0, sizeof(regreq)); + ARR_APP1(be_reg_data_t, a->reg_data, regreq); +} + int is_be_node(const ir_node *irn) { return get_op_tag(get_irn_op(irn)) == &be_node_tag; @@ -474,15 +478,29 @@ void be_set_Copy_op(ir_node *cpy, ir_node *op) { ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[]) { int i; - ir_node *irn; + ir_node *res; + + res = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, -1, NULL); + init_node_attr(res, -1); - irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in); - init_node_attr(irn, n); for(i = 0; i < n; ++i) { - be_node_set_reg_class(irn, i, cls); + add_irn_n(res, in[i]); + add_register_req(res); + be_node_set_reg_class(res, i, cls); } - keep_alive(irn); - return irn; + keep_alive(res); + + return res; +} + +void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node) +{ + int n; + + assert(be_is_Keep(keep)); + n = add_irn_n(keep, node); + add_register_req(keep); + be_node_set_reg_class(keep, n, cls); } ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr, @@ -660,12 +678,37 @@ ir_node *be_new_StackParam(const arch_register_class_t *cls, const arch_register ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs) { - ir_node *irn; - ir_node *in[1]; + ir_node *res; + int i; - irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in); - init_node_attr(irn, n_outs); - return irn; + res = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, NULL); + init_node_attr(res, -1); + for(i = 0; i < n_outs; ++i) + add_register_req(res); + + return res; +} + +ir_node *be_RegParams_append_out_reg(ir_node *regparams, + const arch_env_t *arch_env, + const arch_register_t *reg) +{ + ir_graph *irg = get_irn_irg(regparams); + ir_node *block = get_nodes_block(regparams); + be_node_attr_t *attr = get_irn_attr(regparams); + const arch_register_class_t *cls = arch_register_get_class(reg); + ir_mode *mode = arch_register_class_mode(cls); + int n = ARR_LEN(attr->reg_data); + + assert(be_is_RegParams(regparams)); + ir_node *proj = new_r_Proj(irg, block, regparams, mode, n); + add_register_req(regparams); + be_set_constr_single_reg(regparams, n, reg); + arch_set_irn_register(arch_env, proj, reg); + + /* TODO decide, whether we need to set ignore/modifysp flags here? */ + + return proj; } ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data, @@ -755,11 +798,29 @@ void be_set_CopyKeep_op(ir_node *cpy, ir_node *op) { ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[]) { - ir_node *irn; + ir_node *res; + int i; - irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in); - init_node_attr(irn, n); - return irn; + res = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, -1, NULL); + init_node_attr(res, -1); + for(i = 0; i < n; ++i) { + add_irn_n(res, in[i]); + add_register_req(res); + } + + return res; +} + +ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node) +{ + ir_graph *irg = get_irn_irg(barrier); + ir_node *block = get_nodes_block(barrier); + ir_mode *mode = get_irn_mode(node); + int n = add_irn_n(barrier, node); + ir_node *proj = new_r_Proj(irg, block, barrier, mode, n); + add_register_req(barrier); + + return proj; } int be_is_Spill (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill ; } @@ -933,10 +994,11 @@ void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *c r->req.cls = cls; - if (cls == NULL) + if (cls == NULL) { r->req.type = arch_register_req_type_none; - else if (r->req.type == arch_register_req_type_none) + } else if (r->req.type == arch_register_req_type_none) { r->req.type = arch_register_req_type_normal; + } } void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type) @@ -1525,7 +1587,11 @@ static void copy_attr(const ir_node *old_node, ir_node *new_node) else len = 0; - new_attr->reg_data = NEW_ARR_D(be_reg_data_t, obst, len); + if(be_is_Keep(old_node) || be_is_RegParams(old_node) || be_is_Barrier(old_node)) { + new_attr->reg_data = NEW_ARR_F(be_reg_data_t, len); + } else { + new_attr->reg_data = NEW_ARR_D(be_reg_data_t, obst, len); + } if(len > 0) { memcpy(new_attr->reg_data, old_attr->reg_data, len * sizeof(be_reg_data_t)); diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index 2c7760cf3..b97810580 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -150,6 +150,8 @@ ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *b ir_node *be_new_MemPerm(const arch_env_t *arch_env, ir_graph *irg, ir_node *bl, int n, ir_node *in[]); ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int arity, ir_node *in[]); +void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node); + ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent); ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data, @@ -310,6 +312,19 @@ ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_out); ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[]); +/** + * Appends a node to a barrier, returns the result proj of the node + */ +ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node); + +/** + * Appends a register out requirement to a RegParams node + * + * @returns the proj node for the new register + */ +ir_node *be_RegParams_append_out_req(ir_node *regparams, + const arch_register_t *reg); + /** * Make a spill node. * diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 19ad640a0..36b89a79d 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -324,7 +324,7 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) { if (is_ia32_St(irn) || is_ia32_Store8Bit(irn)) classification |= arch_irn_class_store; - if (is_ia32_got_reload(irn)) + if (is_ia32_need_stackent(irn)) classification |= arch_irn_class_reload; return classification; @@ -992,7 +992,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node set_ia32_am_flavour(irn, ia32_B); set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i))); set_ia32_use_frame(irn); - set_ia32_got_reload(irn); + set_ia32_need_stackent(irn); set_irn_n(irn, 0, get_irg_frame(get_irn_irg(irn))); set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3)); @@ -1460,7 +1460,7 @@ static void ia32_collect_frame_entity_nodes(ir_node *node, void *data) be_node_needs_frame_entity(env, node, mode, align); } else if(is_ia32_irn(node) && get_ia32_frame_ent(node) == NULL && is_ia32_use_frame(node)) { - if (is_ia32_got_reload(node) || is_ia32_Load(node)) { + if (is_ia32_need_stackent(node) || is_ia32_Load(node)) { const ir_mode *mode = get_ia32_ls_mode(node); int align = get_mode_size_bytes(mode); be_node_needs_frame_entity(env, node, mode, align); diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index 2ec104dfe..3c7db4071 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -374,8 +374,8 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { /* got lea */ fprintf(F, "got loea = %d\n", is_ia32_got_lea(n)); - /* got reload */ - fprintf(F, "got reload = %d\n", is_ia32_got_reload(n)); + /* need stackent */ + fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n)); /* dump latency */ fprintf(F, "latency = %d\n", get_ia32_latency(n)); @@ -723,28 +723,19 @@ int is_ia32_got_lea(const ir_node *node) { return attr->data.got_lea; } -/** - * Sets node got_reload. - */ -void set_ia32_got_reload(ir_node *node) { +void set_ia32_need_stackent(ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); - attr->data.got_reload = 1; + attr->data.need_stackent = 1; } -/** - * Clears node got_reload. - */ -void clear_ia32_got_reload(ir_node *node) { +void clear_ia32_need_stackent(ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); - attr->data.got_reload = 0; + attr->data.need_stackent = 0; } -/** - * Checks if node got reload. - */ -int is_ia32_got_reload(const ir_node *node) { +int is_ia32_need_stackent(const ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); - return attr->data.got_reload; + return attr->data.need_stackent; } /** diff --git a/ir/be/ia32/ia32_new_nodes.h b/ir/be/ia32/ia32_new_nodes.h index 1df4f3be0..736e3e9a8 100644 --- a/ir/be/ia32/ia32_new_nodes.h +++ b/ir/be/ia32/ia32_new_nodes.h @@ -199,19 +199,19 @@ void clear_ia32_got_lea(ir_node *node); int is_ia32_got_lea(const ir_node *node); /** - * Sets node got_reload. + * Sets node needs_stackent */ -void set_ia32_got_reload(ir_node *node); +void set_ia32_need_stackent(ir_node *node); /** - * Clears node got_reload. + * Clears node needs_stackent */ -void clear_ia32_got_reload(ir_node *node); +void clear_ia32_need_stackent(ir_node *node); /** - * Checks if node got reload. + * Checks if node needs a stackentity assigned */ -int is_ia32_got_reload(const ir_node *node); +int is_ia32_need_stackent(const ir_node *node); /** * Gets the mode of the stored/loaded value (only set for Store/Load) diff --git a/ir/be/ia32/ia32_nodes_attr.h b/ir/be/ia32/ia32_nodes_attr.h index a607fa538..19d520211 100644 --- a/ir/be/ia32/ia32_nodes_attr.h +++ b/ir/be/ia32/ia32_nodes_attr.h @@ -98,7 +98,7 @@ typedef struct _ia32_attr_t { unsigned got_lea:1; /**< indicates whether or not this node already consumed a LEA */ - unsigned got_reload:1; /**< set to 1 if node cosumed a reload */ + unsigned need_stackent:1; /**< set to 1 if node need space on stack */ unsigned n_res:6; /**< number of results produced by this node */ } data; diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 46364438a..876564fc2 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -7,9 +7,8 @@ * Copyright: (c) 2006 Universitaet Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ - #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif #include "irnode.h" @@ -1336,17 +1335,12 @@ static void optimize_am(ir_node *irn, void *env) { set_ia32_am_flavour(irn, get_ia32_am_flavour(load)); set_ia32_op_type(irn, ia32_AddrModeD); set_ia32_frame_ent(irn, get_ia32_frame_ent(load)); - if(is_ia32_use_frame(load)) - set_ia32_use_frame(irn); set_ia32_ls_mode(irn, get_ia32_ls_mode(load)); set_ia32_am_sc(irn, get_ia32_am_sc(load)); if (is_ia32_am_sc_sign(load)) set_ia32_am_sc_sign(irn); - if (is_ia32_use_frame(load)) - set_ia32_use_frame(irn); - /* connect to Load memory and disconnect Load */ if (get_irn_arity(irn) == 5) { /* binary AMop */ @@ -1420,8 +1414,13 @@ static void optimize_am(ir_node *irn, void *env) { /* clear remat flag */ set_ia32_flags(irn, get_ia32_flags(irn) & ~arch_irn_flags_rematerializable); - if (is_ia32_use_frame(load)) + if (is_ia32_use_frame(load)) { + if(get_ia32_frame_ent(load) == NULL) { + ir_fprintf(stderr, "Falte ent==NULL %+F, %+F\n", load, irn); + set_ia32_need_stackent(irn); + } set_ia32_use_frame(irn); + } /* connect to Load memory and disconnect Load */ if (get_irn_arity(irn) == 5) { diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 868f2586f..9cef9e40e 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -1554,6 +1554,8 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) { /* copy a constant */ res = (*cnstr)(n_dbg, irg, block, mode); + x87_push(state, arch_register_get_index(out), res); + attr = get_ia32_attr(res); attr->x87[2] = out = &ia32_st_regs[0]; } else { @@ -1561,13 +1563,13 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) { res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode); + x87_push(state, arch_register_get_index(out), res); + attr = get_ia32_attr(res); attr->x87[0] = op1 = &ia32_st_regs[op1_idx]; attr->x87[2] = out = &ia32_st_regs[0]; } - arch_set_irn_register(sim->env, res, out); - x87_push(state, arch_register_get_index(out), res); DB((dbg, LEVEL_1, ">>> %+F -> %s\n", res, arch_register_get_name(out))); return res;