X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_common_transform.c;h=99803f08fa64141223110385243ece898788bcbf;hb=5be7cbdaf827567bf40baac160ed3786f7ca34ed;hp=82a9cde77b42c7be59280abf785e2b7825703eba;hpb=cbcf8b93de62865b8564e6a47aca7a28790b65ad;p=libfirm diff --git a/ir/be/ia32/ia32_common_transform.c b/ir/be/ia32/ia32_common_transform.c index 82a9cde77..99803f08f 100644 --- a/ir/be/ia32/ia32_common_transform.c +++ b/ir/be/ia32/ia32_common_transform.c @@ -24,12 +24,9 @@ * @author Matthias Braun, Sebastian Buchwald * @version $Id: ia32_common_transform.c 21012 2008-08-06 13:35:17Z beck $ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include "error.h" -#include "irargs_t.h" #include "ircons.h" #include "irprintf.h" #include "typerep.h" @@ -75,13 +72,8 @@ static int check_immediate_constraint(long val, char immediate_constraint_type) } } -/** - * creates a unique ident by adding a number to a tag - * - * @param tag the tag string, must contain a %d if a number - * should be added - */ -static ident *unique_id(const char *tag) +/* 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]; @@ -91,7 +83,7 @@ static ident *unique_id(const char *tag) } /** - * Get a primitive type for a mode. + * Get a primitive type for a mode with alignment 16. */ static ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode) { @@ -102,7 +94,9 @@ static ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode) char buf[64]; snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode)); res = new_type_primitive(new_id_from_str(buf), mode); - set_type_alignment_bytes(res, 16); + if (get_mode_size_bits(mode) >= 10) { + set_type_alignment_bytes(res, 16); + } pmap_insert(types, mode, res); } else @@ -146,7 +140,7 @@ ir_entity *create_float_const_entity(ir_node *cnst) } else tp = ia32_get_prim_type(isa->types, mode); - res = new_entity(get_glob_type(), unique_id(".LC%u"), tp); + 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, visibility_local); @@ -172,9 +166,9 @@ ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val) { ir_graph *irg = current_ir_graph; ir_node *start_block = get_irg_start_block(irg); - ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block, - symconst, symconst_sign, val); - arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]); + ir_node *immediate = new_bd_ia32_Immediate(NULL, start_block, symconst, + symconst_sign, val); + arch_set_irn_register(immediate, &ia32_gp_regs[REG_GP_NOREG]); return immediate; } @@ -192,33 +186,23 @@ const arch_register_t *ia32_get_clobber_register(const char *clobber) cls = & ia32_reg_classes[c]; for(r = 0; r < cls->n_regs; ++r) { const arch_register_t *temp_reg = arch_register_for_index(cls, r); - if(strcmp(temp_reg->name, clobber) == 0 + if (strcmp(temp_reg->name, clobber) == 0 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) { reg = temp_reg; break; } } - if(reg != NULL) + if (reg != NULL) break; } return reg; } -#ifndef NDEBUG -const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) { - ia32_isa_t *isa = (ia32_isa_t*) cg->arch_env; - - lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn); - obstack_1grow(isa->name_obst, 0); - return obstack_finish(isa->name_obst); -} -#endif /* NDEBUG */ - int ia32_mode_needs_gp_reg(ir_mode *mode) { - if(mode == mode_fpcw) + if (mode == mode_fpcw) return 0; - if(get_mode_size_bits(mode) > 32) + if (get_mode_size_bits(mode) > 32) return 0; return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b; } @@ -226,7 +210,6 @@ int ia32_mode_needs_gp_reg(ir_mode *mode) { static void parse_asm_constraints(constraint_t *constraint, const char *c, int is_output) { - asm_constraint_flags_t flags = 0; char immediate_type = '\0'; unsigned limited = 0; const arch_register_class_t *cls = NULL; @@ -238,7 +221,7 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, memset(constraint, 0, sizeof(constraint[0])); constraint->same_as = -1; - if(*c == 0) { + if (*c == 0) { /* a memory constraint: no need to do anything in backend about it * (the dependencies are already respected by the memory edge of * the node) */ @@ -254,15 +237,11 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, case '\n': break; - case '=': - flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE - | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ; - break; + /* Skip out/in-out marker */ + case '=': break; + case '+': break; - case '+': - flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE - | ASM_CONSTRAINT_FLAG_MODIFIER_READ; - break; + case '&': break; case '*': ++c; @@ -401,7 +380,7 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, panic("can only specify same constraint on input"); sscanf(c, "%d%n", &same_as, &p); - if(same_as >= 0) { + if (same_as >= 0) { c += p; continue; } @@ -437,7 +416,7 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, ++c; } - if(same_as >= 0) { + if (same_as >= 0) { if (cls != NULL) panic("same as and register constraint not supported"); if (immediate_type != '\0') @@ -459,7 +438,6 @@ static void parse_asm_constraints(constraint_t *constraint, const char *c, ir_node *gen_ASM(ir_node *node) { - ir_graph *irg = current_ir_graph; ir_node *block = NULL; ir_node *new_block = NULL; dbg_info *dbgi = get_irn_dbg_info(node); @@ -491,6 +469,7 @@ ir_node *gen_ASM(ir_node *node) #ifdef FIRM_GRGEN_BE case TRANSFORMER_PBQP: + case TRANSFORMER_RAND: new_block = get_nodes_block(node); break; #endif @@ -507,8 +486,7 @@ ir_node *gen_ASM(ir_node *node) } arity = get_irn_arity(node); - in = alloca(arity * sizeof(in[0])); - memset(in, 0, arity * sizeof(in[0])); + in = ALLOCANZ(ir_node*, arity); clobbers = get_ASM_clobbers(node); n_clobbers = 0; @@ -542,12 +520,12 @@ ir_node *gen_ASM(ir_node *node) } for (i = 0; i < arity; ++i) { const ir_asm_constraint *constraint = &in_constraints[i]; - if(constraint->pos > reg_map_size) + if (constraint->pos > reg_map_size) reg_map_size = constraint->pos; } ++reg_map_size; - obst = get_irg_obstack(irg); + obst = get_irg_obstack(current_ir_graph); register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size); memset(register_map, 0, reg_map_size * sizeof(register_map[0])); @@ -620,6 +598,7 @@ ir_node *gen_ASM(ir_node *node) #ifdef FIRM_GRGEN_BE case TRANSFORMER_PBQP: + case TRANSFORMER_RAND: input = get_irn_n(node, i); break; #endif @@ -630,7 +609,7 @@ ir_node *gen_ASM(ir_node *node) if (parsed_constraint.cls == NULL && parsed_constraint.same_as < 0) { is_memory_op = 1; - } else if(parsed_constraint.memory_possible) { + } else if (parsed_constraint.memory_possible) { /* TODO: match Load or Load/Store if memory possible is set */ } } @@ -656,13 +635,16 @@ ir_node *gen_ASM(ir_node *node) ++out_idx; } - new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity, + new_node = new_bd_ia32_Asm(dbgi, new_block, arity, in, out_arity, get_ASM_text(node), register_map); + if (arity == 0) + be_dep_on_frame(new_node); + set_ia32_out_req_all(new_node, out_reg_reqs); set_ia32_in_req_all(new_node, in_reg_reqs); - SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); + SET_IA32_ORIG_NODE(new_node, node); return new_node; } @@ -676,7 +658,6 @@ ir_node *gen_CopyB(ir_node *node) { ir_node *mem = NULL; ir_node *new_mem = NULL; ir_node *res = NULL; - ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); int size = get_type_size_bytes(get_CopyB_type(node)); int rem; @@ -694,6 +675,7 @@ ir_node *gen_CopyB(ir_node *node) { #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); @@ -710,26 +692,25 @@ ir_node *gen_CopyB(ir_node *node) { rem = size & 0x3; /* size % 4 */ size >>= 2; - res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size); - add_irn_dep(res, get_irg_frame(irg)); + res = new_bd_ia32_Const(dbgi, block, NULL, 0, size); + be_dep_on_frame(res); - res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem); + res = new_bd_ia32_CopyB(dbgi, block, new_dst, new_src, res, new_mem, rem); } else { - if(size == 0) { + if (size == 0) { ir_fprintf(stderr, "Optimization warning copyb %+F with size <4\n", node); } - res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size); + res = new_bd_ia32_CopyB_i(dbgi, block, new_dst, new_src, new_mem, size); } - SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node)); + SET_IA32_ORIG_NODE(res, node); return res; } ir_node *gen_Proj_tls(ir_node *node) { ir_node *block = NULL; - ir_graph *irg = current_ir_graph; dbg_info *dbgi = NULL; ir_node *res = NULL; @@ -740,6 +721,7 @@ ir_node *gen_Proj_tls(ir_node *node) { #ifdef FIRM_GRGEN_BE case TRANSFORMER_PBQP: + case TRANSFORMER_RAND: block = get_nodes_block(node); break; #endif @@ -747,7 +729,7 @@ ir_node *gen_Proj_tls(ir_node *node) { default: panic("invalid transformer"); } - res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu); + res = new_bd_ia32_LdTls(dbgi, block, mode_Iu); return res; } @@ -764,14 +746,9 @@ ir_node *gen_Unknown(ir_node *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 *ret = new_rd_ia32_vfldz(dbgi, irg, block); - - /* Const Nodes before the initial IncSP are a bad idea, because - * they could be spilled and we have no SP ready at that point yet. - * So add a dependency to the initial frame pointer calculation to - * avoid that situation. - */ - add_irn_dep(ret, get_irg_frame(irg)); + ir_node *ret = new_bd_ia32_vfldz(dbgi, block); + + be_dep_on_frame(ret); return ret; } } else if (ia32_mode_needs_gp_reg(mode)) { @@ -842,7 +819,7 @@ const arch_register_req_t *parse_clobber(const char *clobber) arch_register_req_t *req; unsigned *limited; - if(reg == NULL) { + if (reg == NULL) { panic("Register '%s' mentioned in asm clobber is unknown", clobber); } @@ -860,6 +837,45 @@ const arch_register_req_t *parse_clobber(const char *clobber) return req; } + +int prevents_AM(ir_node *const block, ir_node *const am_candidate, + ir_node *const other) +{ + if (get_nodes_block(other) != block) + return 0; + + if (is_Sync(other)) { + int i; + + for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) { + ir_node *const pred = get_Sync_pred(other, i); + + if (get_nodes_block(pred) != block) + continue; + + /* Do not block ourselves from getting eaten */ + if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate) + continue; + + if (!heights_reachable_in_block(heights, pred, am_candidate)) + continue; + + return 1; + } + + return 0; + } else { + /* Do not block ourselves from getting eaten */ + if (is_Proj(other) && get_Proj_pred(other) == am_candidate) + return 0; + + if (!heights_reachable_in_block(heights, other, am_candidate)) + return 0; + + return 1; + } +} + ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) { int minus = 0; @@ -874,46 +890,46 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) ir_node *new_node; mode = get_irn_mode(node); - if(!mode_is_int(mode) && !mode_is_reference(mode)) { + if (!mode_is_int(mode) && !mode_is_reference(mode)) { return NULL; } - if(is_Minus(node)) { + if (is_Minus(node)) { minus = 1; node = get_Minus_op(node); } - if(is_Const(node)) { + if (is_Const(node)) { cnst = node; symconst = NULL; offset_sign = minus; - } else if(is_SymConst(node)) { + } else if (is_SymConst(node)) { cnst = NULL; symconst = node; symconst_sign = minus; - } else if(is_Add(node)) { + } else if (is_Add(node)) { ir_node *left = get_Add_left(node); ir_node *right = get_Add_right(node); - if(is_Const(left) && is_SymConst(right)) { + if (is_Const(left) && is_SymConst(right)) { cnst = left; symconst = right; symconst_sign = minus; offset_sign = minus; - } else if(is_SymConst(left) && is_Const(right)) { + } else if (is_SymConst(left) && is_Const(right)) { cnst = right; symconst = left; symconst_sign = minus; offset_sign = minus; } - } else if(is_Sub(node)) { + } else if (is_Sub(node)) { ir_node *left = get_Sub_left(node); ir_node *right = get_Sub_right(node); - if(is_Const(left) && is_SymConst(right)) { + if (is_Const(left) && is_SymConst(right)) { cnst = left; symconst = right; symconst_sign = !minus; offset_sign = minus; - } else if(is_SymConst(left) && is_Const(right)) { + } else if (is_SymConst(left) && is_Const(right)) { cnst = right; symconst = left; symconst_sign = minus; @@ -923,9 +939,9 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) return NULL; } - if(cnst != NULL) { + if (cnst != NULL) { offset = get_Const_tarval(cnst); - if(tarval_is_long(offset)) { + if (tarval_is_long(offset)) { val = get_tarval_long(offset); } else { ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a " @@ -933,27 +949,27 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type) return NULL; } - if(!check_immediate_constraint(val, immediate_constraint_type)) + if (!check_immediate_constraint(val, immediate_constraint_type)) return NULL; } - if(symconst != NULL) { - if(immediate_constraint_type != 0) { + if (symconst != NULL) { + if (immediate_constraint_type != 0) { /* we need full 32bits for symconsts */ return NULL; } /* unfortunately the assembler/linker doesn't support -symconst */ - if(symconst_sign) + if (symconst_sign) return NULL; - if(get_SymConst_kind(symconst) != symconst_addr_ent) + if (get_SymConst_kind(symconst) != symconst_addr_ent) return NULL; symconst_ent = get_SymConst_entity(symconst); } - if(cnst == NULL && symconst == NULL) + if (cnst == NULL && symconst == NULL) return NULL; - if(offset_sign && offset != NULL) { + if (offset_sign && offset != NULL) { offset = tarval_neg(offset); }