X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=76ae7d378f9620260fbf247338b99d93d849e62e;hb=8211b5f77a80b6a504f07cc807fc00fd8cfb77df;hp=a4c75c15e1986ff393df940d1b887fe7a39c02f2;hpb=96518c10e38be68048d3dc8810832d78db145fec;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index a4c75c15e..76ae7d378 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -883,16 +883,16 @@ static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func, ir_node *src_block = get_nodes_block(node); ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left); ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right); + ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags); dbg_info *dbgi; - ir_node *block, *new_node, *eflags, *new_eflags; + ir_node *block, *new_node, *new_eflags; ia32_address_mode_t am; ia32_address_t *addr = &am.addr; - match_arguments(&am, src_block, op1, op2, NULL, flags); + match_arguments(&am, src_block, op1, op2, eflags, flags); dbgi = get_irn_dbg_info(node); block = be_transform_node(src_block); - eflags = get_irn_n(node, n_ia32_l_binop_eflags); new_eflags = be_transform_node(eflags); new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, new_eflags); @@ -1974,30 +1974,49 @@ static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem, { ir_node *load; - if(!is_Proj(node)) + if (!is_Proj(node)) return 0; /* we only use address mode if we're the only user of the load */ - if(get_irn_n_edges(node) > 1) + if (get_irn_n_edges(node) > 1) return 0; load = get_Proj_pred(node); - if(!is_Load(load)) + if (!is_Load(load)) return 0; - if(get_nodes_block(load) != block) + if (get_nodes_block(load) != block) return 0; - /* Store should be attached to the load */ - if(!is_Proj(mem) || get_Proj_pred(mem) != load) - return 0; /* store should have the same pointer as the load */ - if(get_Load_ptr(load) != ptr) + if (get_Load_ptr(load) != ptr) return 0; /* don't do AM if other node inputs depend on the load (via mem-proj) */ - if(other != NULL && get_nodes_block(other) == block - && heights_reachable_in_block(heights, other, load)) + if (other != NULL && + get_nodes_block(other) == block && + heights_reachable_in_block(heights, other, load)) { return 0; + } + + if (is_Sync(mem)) { + int i; + + for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) { + ir_node *const pred = get_Sync_pred(mem, i); + + if (is_Proj(pred) && get_Proj_pred(pred) == load) + continue; + + if (get_nodes_block(pred) == block && + heights_reachable_in_block(heights, pred, load)) { + return 0; + } + } + } else { + /* Store should be attached to the load */ + if (!is_Proj(mem) || get_Proj_pred(mem) != load) + return 0; + } return 1; } @@ -2205,8 +2224,7 @@ static ir_node *try_create_dest_am(ir_node *node) { op1 = get_Sub_left(val); op2 = get_Sub_right(val); if(is_Const(op2)) { - ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C" - "found\n"); + ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n"); } new_node = dest_am_binop(val, op1, op2, mem, ptr, mode, new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit, @@ -2324,20 +2342,22 @@ static int is_float_to_int32_conv(const ir_node *node) */ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) { - ir_mode *mode = get_irn_mode(cns); - unsigned size = get_mode_size_bytes(mode); - tarval *tv = get_Const_tarval(cns); - ir_node *block = get_nodes_block(node); - ir_node *new_block = be_transform_node(block); - ir_node *ptr = get_Store_ptr(node); - ir_node *mem = get_Store_mem(node); - ir_graph *irg = current_ir_graph; - dbg_info *dbgi = get_irn_dbg_info(node); - int ofs = 0; - ir_node *new_node; - ia32_address_t addr; + ir_mode *mode = get_irn_mode(cns); + unsigned size = get_mode_size_bytes(mode); + tarval *tv = get_Const_tarval(cns); + ir_node *block = get_nodes_block(node); + ir_node *new_block = be_transform_node(block); + ir_node *ptr = get_Store_ptr(node); + ir_node *mem = get_Store_mem(node); + ir_graph *irg = current_ir_graph; + dbg_info *dbgi = get_irn_dbg_info(node); + int ofs = 0; + size_t i = 0; + ir_node *ins[4]; + ia32_address_t addr; - assert(size % 4 == 0); + assert(size % 4 == 0); + assert(size <= 16); build_address_ptr(&addr, ptr, mem); @@ -2349,7 +2369,7 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) (get_tarval_sub_bits(tv, ofs + 3) << 24); ir_node *imm = create_Immediate(NULL, 0, val); - new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base, + ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base, addr.index, addr.mem, imm); set_irn_pinned(new_node, get_irn_pinned(node)); @@ -2358,13 +2378,14 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) set_address(new_node, &addr); SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); + ins[i++] = new_node; + size -= 4; ofs += 4; addr.offset += 4; - addr.mem = new_node; } while (size != 0); - return new_node; + return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins); } /** @@ -2503,7 +2524,7 @@ static ir_node *gen_Store(ir_node *node) ir_mode *mode = get_irn_mode(val); if (mode_is_float(mode) && is_Const(val)) { - int transform = 1; + int transform; /* we are storing a floating point constant */ if (ia32_cg_config.use_sse2) {