X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fia32%2Fia32_common_transform.c;h=35de90533a7dcb6f38efb2a6ac812d3283ba7318;hb=9815fbf8d1bcc62558574a4ac0ef7a2849cd2e00;hp=9f3267033807f0474c9e84feb3eb39081669db05;hpb=d4840ad0100f33ed436c036d90f557f50d745e6b;p=libfirm diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index 9f3267033..35de90533 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -48,14 +48,6 @@ ia32_code_gen_t *env_cg = NULL; heights_t *heights = NULL; -static const arch_register_req_t no_register_req = { - arch_register_req_type_none, - NULL, /* regclass */ - NULL, /* limit bitset */ - 0, /* same pos */ - 0 /* different pos */ -}; - static int check_immediate_constraint(long val, char immediate_constraint_type) { switch (immediate_constraint_type) { @@ -74,90 +66,62 @@ static int check_immediate_constraint(long val, char immediate_constraint_type) } } -/* creates a unique ident by adding a number to a tag */ -ident *ia32_unique_id(const char *tag) -{ - static unsigned id = 0; - char str[256]; - - snprintf(str, sizeof(str), tag, ++id); - return new_id_from_str(str); -} - /** * Get a primitive type for a mode with alignment 16. */ static ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode) { - pmap_entry *e = pmap_find(types, mode); - ir_type *res; + ir_type *res = pmap_get(types, mode); + if (res != NULL) + return res; - if (! e) { - res = new_type_primitive(mode); - if (get_mode_size_bits(mode) >= 80) { - set_type_alignment_bytes(res, 16); - } - pmap_insert(types, mode, res); + res = new_type_primitive(mode); + if (get_mode_size_bits(mode) >= 80) { + set_type_alignment_bytes(res, 16); } - else - res = e->value; + pmap_insert(types, mode, res); return res; } ir_entity *create_float_const_entity(ir_node *cnst) { - ia32_isa_t *isa = env_cg->isa; - tarval *key = get_Const_tarval(cnst); - pmap_entry *e = pmap_find(isa->tv_ent, key); - ir_entity *res; - ir_graph *rem; - - if (e == NULL) { - tarval *tv = key; - ir_mode *mode = get_tarval_mode(tv); - ir_type *tp; - - if (! ia32_cg_config.use_sse2) { - /* try to reduce the mode to produce smaller sized entities */ - if (mode != mode_F) { - if (tarval_ieee754_can_conv_lossless(tv, mode_F)) { - mode = mode_F; + ia32_isa_t *isa = env_cg->isa; + tarval *tv = get_Const_tarval(cnst); + ir_entity *res = pmap_get(isa->tv_ent, tv); + ir_initializer_t *initializer; + ir_mode *mode; + ir_type *tp; + + if (res != NULL) + return res; + + mode = get_tarval_mode(tv); + + if (! ia32_cg_config.use_sse2) { + /* try to reduce the mode to produce smaller sized entities */ + if (mode != mode_F) { + if (tarval_ieee754_can_conv_lossless(tv, mode_F)) { + mode = mode_F; + tv = tarval_convert_to(tv, mode); + } else if (mode != mode_D) { + if (tarval_ieee754_can_conv_lossless(tv, mode_D)) { + mode = mode_D; tv = tarval_convert_to(tv, mode); - } else if (mode != mode_D) { - if (tarval_ieee754_can_conv_lossless(tv, mode_D)) { - mode = mode_D; - tv = tarval_convert_to(tv, mode); - } } } } + } - if (mode == get_irn_mode(cnst)) { - /* mode was not changed */ - tp = get_Const_type(cnst); - if (tp == firm_unknown_type) - tp = ia32_get_prim_type(isa->types, mode); - } else - tp = ia32_get_prim_type(isa->types, mode); - - res = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp); - - set_entity_ld_ident(res, get_entity_ident(res)); - set_entity_visibility(res, ir_visibility_local); - add_entity_linkage(res, IR_LINKAGE_CONSTANT); + tp = ia32_get_prim_type(isa->types, mode); + res = new_entity(get_glob_type(), id_unique("C%u"), tp); + set_entity_ld_ident(res, get_entity_ident(res)); + set_entity_visibility(res, ir_visibility_private); + add_entity_linkage(res, IR_LINKAGE_CONSTANT); - /* we create a new entity here: It's initialization must resist on the - const code irg */ - rem = current_ir_graph; - current_ir_graph = get_const_code_irg(); - set_atomic_ent_value(res, new_Const_type(tv, tp)); - current_ir_graph = rem; - - pmap_insert(isa->tv_ent, key, res); - } else { - res = e->value; - } + initializer = create_initializer_tarval(tv); + set_entity_initializer(res, initializer); + pmap_insert(isa->tv_ent, tv, res); return res; } @@ -448,12 +412,26 @@ static bool can_match(const arch_register_req_t *in, return (*in->limited & *out->limited) != 0; } +static inline ir_node *get_new_node(ir_node *node) +{ +#ifdef FIRM_GRGEN_BE + if (be_transformer == TRANSFORMER_DEFAULT) { + return be_transform_node(node); + } else { + return node; + } +#else + return be_transform_node(node); +#endif +} + ir_node *gen_ASM(ir_node *node) { - ir_node *block = NULL; - ir_node *new_block = NULL; + ir_node *block = get_nodes_block(node); + ir_node *new_block = get_new_node(block); dbg_info *dbgi = get_irn_dbg_info(node); int i, arity; + int value_arity; int out_idx; ir_node **in; ir_node *new_node; @@ -475,23 +453,6 @@ ir_node *gen_ASM(ir_node *node) memset(&clobber_bits, 0, sizeof(clobber_bits)); - switch (be_transformer) { - case TRANSFORMER_DEFAULT: - block = get_nodes_block(node); - new_block = be_transform_node(block); - break; - -#ifdef FIRM_GRGEN_BE - case TRANSFORMER_PBQP: - case TRANSFORMER_RAND: - new_block = get_nodes_block(node); - break; -#endif - - default: - panic("invalid transformer"); - } - /* workaround for lots of buggy code out there as most people think volatile * asm is enough for everything and forget the flags (linux kernel, etc.) */ @@ -533,7 +494,7 @@ ir_node *gen_ASM(ir_node *node) reg_map_size = constraint->pos; } for (i = 0; i < arity; ++i) { - const ir_asm_constraint *constraint = &in_constraints[i]; + const ir_asm_constraint *constraint = &in_constraints[i]; if (constraint->pos > reg_map_size) reg_map_size = constraint->pos; } @@ -586,7 +547,7 @@ ir_node *gen_ASM(ir_node *node) if (r_clobber_bits != 0) { if (parsed_constraint.all_registers_allowed) { parsed_constraint.all_registers_allowed = 0; - be_abi_set_non_ignore_regs(env_cg->birg->abi, + be_abi_set_non_ignore_regs(be_get_irg_abi(env_cg->irg), parsed_constraint.cls, &parsed_constraint.allowed_registers); } @@ -604,22 +565,8 @@ ir_node *gen_ASM(ir_node *node) } if (input == NULL) { - ir_node *pred = NULL; - switch (be_transformer) { - case TRANSFORMER_DEFAULT: - pred = get_irn_n(node, i); - input = be_transform_node(pred); - break; - -#ifdef FIRM_GRGEN_BE - case TRANSFORMER_PBQP: - case TRANSFORMER_RAND: - input = get_irn_n(node, i); - break; -#endif - - default: panic("invalid transformer"); - } + ir_node *pred = get_irn_n(node, i); + input = get_new_node(pred); if (parsed_constraint.cls == NULL && parsed_constraint.same_as < 0) { @@ -650,6 +597,15 @@ ir_node *gen_ASM(ir_node *node) ++out_idx; } + /* count inputs which are real values (and not memory) */ + value_arity = 0; + for (i = 0; i < arity; ++i) { + ir_node *in = get_irn_n(node, i); + if (get_irn_mode(in) == mode_M) + continue; + ++value_arity; + } + /* Attempt to make ASM node register pressure faithful. * (This does not work for complicated cases yet!) * @@ -662,7 +618,7 @@ ir_node *gen_ASM(ir_node *node) * before... * FIXME: need to do this per register class... */ - if (out_arity <= arity) { + if (out_arity <= value_arity) { int orig_arity = arity; int in_size = arity; int o; @@ -792,42 +748,18 @@ ir_node *gen_ASM(ir_node *node) ir_node *gen_CopyB(ir_node *node) { - ir_node *block = NULL; - ir_node *src = NULL; - ir_node *new_src = NULL; - ir_node *dst = NULL; - ir_node *new_dst = NULL; - ir_node *mem = NULL; - ir_node *new_mem = NULL; + ir_node *block = get_new_node(get_nodes_block(node)); + ir_node *src = get_CopyB_src(node); + ir_node *new_src = get_new_node(src); + ir_node *dst = get_CopyB_dst(node); + ir_node *new_dst = get_new_node(dst); + ir_node *mem = get_CopyB_mem(node); + ir_node *new_mem = get_new_node(mem); ir_node *res = NULL; dbg_info *dbgi = get_irn_dbg_info(node); int size = get_type_size_bytes(get_CopyB_type(node)); int rem; - switch (be_transformer) { - case TRANSFORMER_DEFAULT: - block = be_transform_node(get_nodes_block(node)); - src = get_CopyB_src(node); - new_src = be_transform_node(src); - dst = get_CopyB_dst(node); - new_dst = be_transform_node(dst); - mem = get_CopyB_mem(node); - new_mem = be_transform_node(mem); - break; - -#ifdef FIRM_GRGEN_BE - case TRANSFORMER_PBQP: - case TRANSFORMER_RAND: - block = get_nodes_block(node); - new_src = get_CopyB_src(node); - new_dst = get_CopyB_dst(node); - new_mem = get_CopyB_mem(node); - break; -#endif - - default: panic("invalid transformer"); - } - /* If we have to copy more than 32 bytes, we use REP MOVSx and */ /* then we need the size explicitly in ECX. */ if (size >= 32 * 4) { @@ -853,53 +785,36 @@ ir_node *gen_CopyB(ir_node *node) ir_node *gen_Proj_tls(ir_node *node) { - ir_node *block = NULL; - dbg_info *dbgi = NULL; - ir_node *res = NULL; - - switch (be_transformer) { - case TRANSFORMER_DEFAULT: - block = be_transform_node(get_nodes_block(node)); - break; - -#ifdef FIRM_GRGEN_BE - case TRANSFORMER_PBQP: - case TRANSFORMER_RAND: - block = get_nodes_block(node); - break; -#endif - - default: panic("invalid transformer"); - } + ir_node *block = get_new_node(get_nodes_block(node)); + ir_node *res = NULL; - res = new_bd_ia32_LdTls(dbgi, block, mode_Iu); + res = new_bd_ia32_LdTls(NULL, block, mode_Iu); return res; } ir_node *gen_Unknown(ir_node *node) { - ir_mode *mode = get_irn_mode(node); + ir_mode *mode = get_irn_mode(node); + ir_graph *irg = current_ir_graph; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *block = get_irg_start_block(irg); + ir_node *res = NULL; if (mode_is_float(mode)) { if (ia32_cg_config.use_sse2) { - return ia32_new_Unknown_xmm(env_cg); + res = new_bd_ia32_xUnknown(dbgi, block); } else { - /* Unknown nodes are buggy in x87 simulator, use zero for now... */ - ir_graph *irg = current_ir_graph; - dbg_info *dbgi = get_irn_dbg_info(node); - ir_node *block = get_irg_start_block(irg); - ir_node *ret = new_bd_ia32_vfldz(dbgi, block); - - be_dep_on_frame(ret); - return ret; + res = new_bd_ia32_vfldz(dbgi, block); } } else if (ia32_mode_needs_gp_reg(mode)) { - return ia32_new_Unknown_gp(env_cg); + res = new_bd_ia32_Unknown(dbgi, block); } else { panic("unsupported Unknown-Mode"); } - return NULL; + + be_dep_on_frame(res); + return res; } const arch_register_req_t *make_register_req(const constraint_t *constraint, @@ -931,7 +846,7 @@ const arch_register_req_t *make_register_req(const constraint_t *constraint, /* pure memory ops */ if (constraint->cls == NULL) { - return &no_register_req; + return arch_no_register_req; } if (constraint->allowed_registers != 0