X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fia32%2Fia32_transform.c;h=9d014768873eb865ec24ceb41d38514510c58607;hb=eb593ca265a302849042866b57a3cf7a6e9495ab;hp=b52656e3681c69c29ac8fc24c1bd92c8f55b532c;hpb=6313f4bf3acb1814dad036ed30e9f4e6520a69f5;p=libfirm diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index b52656e36..9d0147688 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -48,6 +48,7 @@ #include "irdom.h" #include "archop.h" #include "error.h" +#include "array_t.h" #include "height.h" #include "../benode_t.h" @@ -432,44 +433,6 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) { return ent_cache[kct]; } -static 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; - } -} - /** * return true if the node is a Proj(Load) and could be used in source address * mode for another node. Will return only true if the @p other node is not @@ -774,20 +737,19 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block, } am->op_type = ia32_AddrModeS; } else { + am->op_type = ia32_Normal; + if (flags & match_try_am) { am->new_op1 = NULL; am->new_op2 = NULL; - am->op_type = ia32_Normal; return; } new_op1 = (op1 == NULL ? NULL : be_transform_node(op1)); if (new_op2 == NULL) new_op2 = be_transform_node(op2); - am->op_type = ia32_Normal; - am->ls_mode = get_irn_mode(op2); - if (flags & match_mode_neutral) - am->ls_mode = mode_Iu; + am->ls_mode = + (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2)); } if (addr->base == NULL) addr->base = noreg_gp; @@ -801,6 +763,12 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block, am->commutative = commutative; } +static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node) +{ + mark_irn_visited(old_node); + be_set_transformed_node(old_node, new_node); +} + static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am) { ir_mode *mode; @@ -813,8 +781,7 @@ static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am) mode = get_irn_mode(node); load = get_Proj_pred(am->mem_proj); - mark_irn_visited(load); - be_set_transformed_node(load, node); + set_transformed_and_mark(load, node); if (mode != mode_T) { set_irn_mode(node, mode_T); @@ -2024,12 +1991,6 @@ static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem, return 1; } -static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node) -{ - mark_irn_visited(old_node); - be_set_transformed_node(old_node, new_node); -} - static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2, ir_node *mem, ir_node *ptr, ir_mode *mode, construct_binop_dest_func *func, @@ -2738,6 +2699,9 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode) if (get_mode_size_bits(mode) >= 32) return true; + if (is_Proj(transformed_node)) + return upper_bits_clean(get_Proj_pred(transformed_node), mode); + if (is_ia32_Conv_I2I(transformed_node) || is_ia32_Conv_I2I8Bit(transformed_node)) { ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node); @@ -2751,7 +2715,7 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode) if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) { ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count); - if (is_ia32_Immediate(right)) { + if (is_ia32_Immediate(right) || is_ia32_Const(right)) { const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(right); if (attr->symconst == 0 @@ -2759,11 +2723,12 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode) return true; } } + return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode); } if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) { ir_node *right = get_irn_n(transformed_node, n_ia32_And_right); - if (is_ia32_Immediate(right)) { + if (is_ia32_Immediate(right) || is_ia32_Const(right)) { const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(right); if (attr->symconst == 0 @@ -2772,6 +2737,25 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode) return true; } } + /* TODO recurse? */ + } + + /* TODO recurse on Or, Xor, ... if appropriate? */ + + if (is_ia32_Immediate(transformed_node) + || is_ia32_Const(transformed_node)) { + const ia32_immediate_attr_t *attr + = get_ia32_immediate_attr_const(transformed_node); + if (mode_is_signed(mode)) { + long shifted = attr->offset >> (get_mode_size_bits(mode) - 1); + if (shifted == 0 || shifted == -1) + return true; + } else { + unsigned long shifted = (unsigned long) attr->offset; + shifted >>= get_mode_size_bits(mode); + if (shifted == 0) + return true; + } } return false; @@ -2813,13 +2797,12 @@ static ir_node *gen_Cmp(ir_node *node) /* Test(and_left, and_right) */ ir_node *and_left = get_And_left(left); ir_node *and_right = get_And_right(left); - ir_mode *mode = get_irn_mode(and_left); /* matze: code here used mode instead of cmd_mode, I think it is always * the same as cmp_mode, but I leave this here to see if this is really * true... */ - assert(mode == cmp_mode); + assert(get_irn_mode(and_left) == cmp_mode); match_arguments(&am, block, and_left, and_right, NULL, match_commutative | @@ -2828,8 +2811,8 @@ static ir_node *gen_Cmp(ir_node *node) match_8bit | match_16bit); /* use 32bit compare mode if possible since the opcode is smaller */ - if (upper_bits_clean(am.new_op1, cmp_mode) - && upper_bits_clean(am.new_op2, cmp_mode)) { + if (upper_bits_clean(am.new_op1, cmp_mode) && + upper_bits_clean(am.new_op2, cmp_mode)) { cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu; } @@ -2851,8 +2834,8 @@ static ir_node *gen_Cmp(ir_node *node) match_16bit_am | match_am_and_immediates | match_immediate | match_8bit | match_16bit); /* use 32bit compare mode if possible since the opcode is smaller */ - if (upper_bits_clean(am.new_op1, cmp_mode) - && upper_bits_clean(am.new_op2, cmp_mode)) { + if (upper_bits_clean(am.new_op1, cmp_mode) && + upper_bits_clean(am.new_op2, cmp_mode)) { cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu; } @@ -3580,8 +3563,7 @@ static ir_node *gen_be_Return(ir_node *node) { arity, in); copy_node_attr(barrier, new_barrier); be_duplicate_deps(barrier, new_barrier); - be_set_transformed_node(barrier, new_barrier); - mark_irn_visited(barrier); + set_transformed_and_mark(barrier, new_barrier); /* transform normally */ return be_duplicate_node(node); @@ -4005,8 +3987,7 @@ static ir_node *gen_Proj_be_AddSP(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M); } - assert(0); - return new_rd_Unknown(irg, get_irn_mode(node)); + panic("No idea how to transform proj->AddSP"); } /** @@ -4029,8 +4010,7 @@ static ir_node *gen_Proj_be_SubSP(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M); } - assert(0); - return new_rd_Unknown(irg, get_irn_mode(node)); + panic("No idea how to transform proj->SubSP"); } /** @@ -4128,8 +4108,7 @@ static ir_node *gen_Proj_Load(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1); } - assert(0); - return new_rd_Unknown(irg, get_irn_mode(node)); + panic("No idea how to transform proj"); } /** @@ -4141,7 +4120,6 @@ static ir_node *gen_Proj_DivMod(ir_node *node) { ir_node *new_pred = be_transform_node(pred); ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); - ir_mode *mode = get_irn_mode(node); long proj = get_Proj_proj(node); assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)); @@ -4196,8 +4174,7 @@ static ir_node *gen_Proj_DivMod(ir_node *node) { break; } - assert(0); - return new_rd_Unknown(irg, mode); + panic("No idea how to transform proj->DivMod"); } /** @@ -4209,7 +4186,6 @@ static ir_node *gen_Proj_CopyB(ir_node *node) { ir_node *new_pred = be_transform_node(pred); ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); - ir_mode *mode = get_irn_mode(node); long proj = get_Proj_proj(node); switch(proj) { @@ -4224,8 +4200,7 @@ static ir_node *gen_Proj_CopyB(ir_node *node) { break; } - assert(0); - return new_rd_Unknown(irg, mode); + panic("No idea how to transform proj->CopyB"); } /** @@ -4237,7 +4212,6 @@ static ir_node *gen_Proj_Quot(ir_node *node) { ir_node *new_pred = be_transform_node(pred); ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); - ir_mode *mode = get_irn_mode(node); long proj = get_Proj_proj(node); switch(proj) { @@ -4261,8 +4235,7 @@ static ir_node *gen_Proj_Quot(ir_node *node) { break; } - assert(0); - return new_rd_Unknown(irg, mode); + panic("No idea how to transform proj->Quot"); } static ir_node *gen_be_Call(ir_node *node) { @@ -4442,8 +4415,7 @@ static ir_node *gen_Proj(ir_node *node) { if (proj == pn_Store_M) { return be_transform_node(pred); } else { - assert(0); - return new_r_Bad(current_ir_graph); + panic("No idea how to transform proj->Store"); } case iro_Load: return gen_Proj_Load(node);