X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=00007f8a0fe6a52ccbd25f3149ac6f3b2e451235;hb=a824d376c1c37f80c7e1ebd6304665380d28fc5f;hp=1161c18079e59f6c1248b29b19f6a106d369d76e;hpb=c1fdf770d4d000dd5cf22daead32369342c5f5d1;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 1161c1807..00007f8a0 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -268,7 +268,7 @@ static ir_node *gen_Const(ir_node *node) mode); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_sc(load, floatent); - set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable); + arch_irn_add_flags(load, arch_irn_flags_rematerializable); res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res); } } else { @@ -286,7 +286,7 @@ static ir_node *gen_Const(ir_node *node) load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_sc(load, floatent); - set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable); + arch_irn_add_flags(load, arch_irn_flags_rematerializable); res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res); /* take the mode from the entity */ set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent))); @@ -504,7 +504,8 @@ static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem) addr->mem = be_transform_node(mem); } -static void build_address(ia32_address_mode_t *am, ir_node *node) +static void build_address(ia32_address_mode_t *am, ir_node *node, + ia32_create_am_flags_t flags) { ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); ia32_address_t *addr = &am->addr; @@ -535,7 +536,7 @@ static void build_address(ia32_address_mode_t *am, ir_node *node) am->am_node = node; /* construct load address */ - ia32_create_address_mode(addr, ptr, 0); + ia32_create_address_mode(addr, ptr, flags); addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp; addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp; @@ -696,7 +697,7 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block, noreg_gp = ia32_new_NoReg_gp(env_cg); if (new_op2 == NULL && use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) { - build_address(am, op2); + build_address(am, op2, 0); new_op1 = (op1 == NULL ? NULL : be_transform_node(op1)); if (mode_is_float(mode)) { new_op2 = ia32_new_NoReg_vfp(env_cg); @@ -708,7 +709,7 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block, use_am && ia32_use_source_address_mode(block, op1, op2, other_op, flags)) { ir_node *noreg; - build_address(am, op1); + build_address(am, op1, 0); if (mode_is_float(mode)) { noreg = ia32_new_NoReg_vfp(env_cg); @@ -1311,6 +1312,9 @@ static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block, NEW_ARR_A(ir_node*, ins, arity + 1); + /* NOTE: This sometimes produces dead-code because the old sync in + * src_mem might not be used anymore, we should detect this case + * and kill the sync... */ for (i = arity - 1; i >= 0; --i) { ir_node *const pred = get_Sync_pred(src_mem, i); @@ -1904,7 +1908,10 @@ static ir_node *gen_Load(ir_node *node) set_address(new_node, &addr); if (get_irn_pinned(node) == op_pin_state_floats) { - add_ia32_flags(new_node, arch_irn_flags_rematerializable); + assert(pn_ia32_xLoad_res == pn_ia32_vfld_res + && pn_ia32_vfld_res == pn_ia32_Load_res + && pn_ia32_Load_res == pn_ia32_res); + arch_irn_add_flags(new_node, arch_irn_flags_rematerializable); } SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); @@ -1975,10 +1982,10 @@ static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2, commutative = (flags & match_commutative) != 0; if (use_dest_am(src_block, op1, mem, ptr, op2)) { - build_address(&am, op1); + build_address(&am, op1, ia32_create_am_double_use); new_op = create_immediate_or_transform(op2, 0); } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) { - build_address(&am, op2); + build_address(&am, op2, ia32_create_am_double_use); new_op = create_immediate_or_transform(op1, 0); } else { return NULL; @@ -2032,7 +2039,7 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem, return NULL; memset(&am, 0, sizeof(am)); - build_address(&am, op); + build_address(&am, op, ia32_create_am_double_use); dbgi = get_irn_dbg_info(node); block = be_transform_node(src_block); @@ -2263,7 +2270,8 @@ static int is_float_to_int_conv(const ir_node *node) } /** - * Transform a Store(floatConst). + * Transform a Store(floatConst) into a sequence of + * integer stores. * * @return the created ia32 Store node */ @@ -2305,6 +2313,7 @@ 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)); + assert(i < 4); ins[i++] = new_node; size -= 4; @@ -2312,7 +2321,11 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) addr.offset += 4; } while (size != 0); - return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins); + if (i > 1) { + return new_rd_Sync(dbgi, irg, new_block, i, ins); + } else { + return ins[0]; + } } /** @@ -2343,11 +2356,11 @@ static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node return new_node; } /** - * Transforms a normal Store. + * Transforms a general (no special case) Store. * * @return the created ia32 Store node */ -static ir_node *gen_normal_Store(ir_node *node) +static ir_node *gen_general_Store(ir_node *node) { ir_node *val = get_Store_value(node); ir_mode *mode = get_irn_mode(val); @@ -2451,18 +2464,14 @@ 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; - - /* we are storing a floating point constant */ - if (ia32_cg_config.use_sse2) { - transform = !is_simple_sse_Const(val); - } else { - transform = !is_simple_x87_Const(val); - } - if (transform) - return gen_float_const_Store(node, val); + /* We can transform every floating const store + into a sequence of integer stores. + If the constant is already in a register, + it would be better to use it, but we don't + have this information here. */ + return gen_float_const_Store(node, val); } - return gen_normal_Store(node); + return gen_general_Store(node); } /** @@ -3506,7 +3515,7 @@ static ir_node *gen_be_Return(ir_node *node) /* create a new barrier */ arity = get_irn_arity(barrier); - in = alloca(arity * sizeof(in[0])); + in = ALLOCAN(ir_node*, arity); for (i = 0; i < arity; ++i) { ir_node *new_in; @@ -4288,7 +4297,7 @@ static ir_node *gen_be_Call(ir_node *node) static ir_node *gen_be_IncSP(ir_node *node) { ir_node *res = be_duplicate_node(node); - be_node_add_flags(res, -1, arch_irn_flags_modify_flags); + arch_irn_add_flags(res, arch_irn_flags_modify_flags); return res; } @@ -4308,8 +4317,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node) long proj = get_Proj_proj(node); ir_mode *mode = get_irn_mode(node); ir_node *sse_load; - const arch_register_class_t *cls; - ir_node *res; + ir_node *res; /* The following is kinda tricky: If we're using SSE, then we have to * move the result value of the call in floating point registers to an @@ -4373,7 +4381,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node) /* transform call modes */ if (mode_is_data(mode)) { - cls = arch_get_irn_reg_class(node, -1); + const arch_register_class_t *cls = arch_get_irn_reg_class_out(node); mode = cls->mode; } @@ -4383,18 +4391,18 @@ static ir_node *gen_Proj_be_Call(ir_node *node) } else if (proj == pn_be_Call_M_regular) { proj = pn_ia32_Call_M; } else { - arch_register_req_t const *const req = arch_get_register_req(node, BE_OUT_POS(proj)); - int const n_outs = get_ia32_n_res(new_call); + arch_register_req_t const *const req = arch_get_register_req_out(node); + int const n_outs = arch_irn_get_n_outs(new_call); int i; assert(proj >= pn_be_Call_first_res); - assert(req->type == arch_register_req_type_limited); + assert(req->type & arch_register_req_type_limited); for (i = 0; i < n_outs; ++i) { arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i); - if (new_req->type != arch_register_req_type_limited || - new_req->cls != req->cls || + if (!(new_req->type & arch_register_req_type_limited) || + new_req->cls != req->cls || *new_req->limited != *req->limited) continue; @@ -4469,7 +4477,7 @@ static ir_node *gen_Proj_ASM(ir_node *node) new_pred = be_transform_node(pred); block = get_nodes_block(new_pred); return new_r_Proj(current_ir_graph, block, new_pred, mode_M, - get_ia32_n_res(new_pred) + 1); + arch_irn_get_n_outs(new_pred) + 1); } /** @@ -4685,7 +4693,7 @@ static void add_missing_keep_walker(ir_node *node, void *data) if (!is_ia32_irn(node)) return; - n_outs = get_ia32_n_res(node); + n_outs = arch_irn_get_n_outs(node); if (n_outs <= 0) return; if (is_ia32_SwitchJmp(node))