X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=f19817e581cc7209ddc399ee695aa01707ab782b;hb=dc5eb2926b1ff88193b0ec00f3fbc8f969baaa4f;hp=8f8ed7b7dfa8b014b4fd7bea2cc7ef16f1c5867f;hpb=9af128bc5ad9480ecc5c78fdeebe3a2776126d2a;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 8f8ed7b7d..f19817e58 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -1,20 +1,6 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. + * Copyright (C) 2012 University of Karlsruhe. */ /** @@ -161,13 +147,11 @@ static void peephole_ia32_Cmp(ir_node *const node) ir_node *const op = get_irn_n(node, n_ia32_Cmp_left); int const ins_permuted = get_ia32_attr(node)->data.ins_permuted; - ir_node *test; - if (is_ia32_Cmp(node)) { - test = new_bd_ia32_Test(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted); - } else { - test = new_bd_ia32_Test_8bit(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted); - } - set_ia32_ls_mode(test, get_ia32_ls_mode(node)); + ir_mode *const ls_mode = get_ia32_ls_mode(node); + ir_node *const test = get_mode_size_bits(ls_mode) == 8 + ? new_bd_ia32_Test_8bit(dbgi, block, noreg, noreg, nomem, op, op, ins_permuted) + : new_bd_ia32_Test (dbgi, block, noreg, noreg, nomem, op, op, ins_permuted); + set_ia32_ls_mode(test, ls_mode); arch_register_t const *const reg = arch_get_irn_register_out(node, pn_ia32_Cmp_eflags); arch_set_irn_register_out(test, pn_ia32_Test_eflags, reg); @@ -346,12 +330,8 @@ static void peephole_ia32_Return(ir_node *node) return; /* check if this return is the first on the block */ - sched_foreach_reverse_from(node, irn) { + sched_foreach_reverse_before(node, irn) { switch (get_irn_opcode(irn)) { - case beo_Return: - /* the return node itself, ignore */ - continue; - case iro_Start: case beo_Start: /* ignore no code generated */ continue; @@ -383,8 +363,6 @@ static void peephole_IncSP_Store_to_push(ir_node *irn) { int i; int maxslot; - int inc_ofs; - ir_node *node; ir_node *stores[MAXPUSH_OPTIMIZE]; ir_node *block; ir_graph *irg; @@ -394,9 +372,7 @@ static void peephole_IncSP_Store_to_push(ir_node *irn) memset(stores, 0, sizeof(stores)); - assert(be_is_IncSP(irn)); - - inc_ofs = be_get_IncSP_offset(irn); + int inc_ofs = be_get_IncSP_offset(irn); if (inc_ofs < 4) return; @@ -407,7 +383,7 @@ static void peephole_IncSP_Store_to_push(ir_node *irn) * attached to the node */ maxslot = -1; - for (node = sched_next(irn); !sched_is_end(node); node = sched_next(node)) { + sched_foreach_after(irn, node) { ir_node *mem; int offset; int storeslot; @@ -521,120 +497,6 @@ static void peephole_IncSP_Store_to_push(ir_node *irn) be_set_IncSP_offset(irn, inc_ofs); } -#if 0 -/** - * Creates a Push instruction before the given schedule point. - * - * @param dbgi debug info - * @param block the block - * @param stack the previous stack value - * @param schedpoint the new node is added before this node - * @param reg the register to pop - * - * @return the new stack value - */ -static ir_node *create_push(dbg_info *dbgi, ir_node *block, - ir_node *stack, ir_node *schedpoint) -{ - const arch_register_t *esp = &ia32_registers[REG_ESP]; - - ir_node *val = ia32_new_NoReg_gp(cg); - ir_node *noreg = ia32_new_NoReg_gp(cg); - ir_graph *irg = get_irn_irg(block); - ir_node *nomem = get_irg_no_mem(irg); - ir_node *push = new_bd_ia32_Push(dbgi, block, noreg, noreg, nomem, val, stack); - sched_add_before(schedpoint, push); - - stack = new_r_Proj(push, mode_Iu, pn_ia32_Push_stack); - arch_set_irn_register(stack, esp); - - return stack; -} - -static void peephole_store_incsp(ir_node *store) -{ - dbg_info *dbgi; - ir_node *block; - ir_node *noreg; - ir_node *mem; - ir_node *push; - ir_node *val; - ir_node *base; - ir_node *index; - ir_node *am_base = get_irn_n(store, n_ia32_Store_base); - if (!be_is_IncSP(am_base) - || get_nodes_block(am_base) != get_nodes_block(store)) - return; - mem = get_irn_n(store, n_ia32_Store_mem); - if (!is_ia32_NoReg_GP(get_irn_n(store, n_ia32_Store_index)) - || !is_NoMem(mem)) - return; - - int incsp_offset = be_get_IncSP_offset(am_base); - if (incsp_offset <= 0) - return; - - /* we have to be at offset 0 */ - int my_offset = get_ia32_am_offs_int(store); - if (my_offset != 0) { - /* TODO here: find out whether there is a store with offset 0 before - * us and whether we can move it down to our place */ - return; - } - ir_mode *ls_mode = get_ia32_ls_mode(store); - int my_store_size = get_mode_size_bytes(ls_mode); - - if (my_offset + my_store_size > incsp_offset) - return; - - /* correctness checking: - - noone else must write to that stackslot - (because after translation incsp won't allocate it anymore) - */ - sched_foreach_reverse_from(store, node) { - int i, arity; - - if (node == am_base) - break; - - /* make sure noone else can use the space on the stack */ - arity = get_irn_arity(node); - for (i = 0; i < arity; ++i) { - ir_node *pred = get_irn_n(node, i); - if (pred != am_base) - continue; - - if (i == n_ia32_base && - (get_ia32_op_type(node) == ia32_AddrModeS - || get_ia32_op_type(node) == ia32_AddrModeD)) { - int node_offset = get_ia32_am_offs_int(node); - ir_mode *node_ls_mode = get_ia32_ls_mode(node); - int node_size = get_mode_size_bytes(node_ls_mode); - /* overlapping with our position? abort */ - if (node_offset < my_offset + my_store_size - && node_offset + node_size >= my_offset) - return; - /* otherwise it's fine */ - continue; - } - - /* strange use of esp: abort */ - return; - } - } - - /* all ok, change to push */ - dbgi = get_irn_dbg_info(store); - block = get_nodes_block(store); - noreg = ia32_new_NoReg_gp(cg); - val = get_irn_n(store, n_ia32_Store_val); - - push = new_bd_ia32_Push(dbgi, block, noreg, noreg, mem, - - create_push(dbgi, block, am_base, store); -} -#endif - /** * Return true if a mode can be stored in the GP register set */ @@ -655,16 +517,14 @@ static inline int mode_needs_gp_reg(ir_mode *mode) static void peephole_Load_IncSP_to_pop(ir_node *irn) { const arch_register_t *esp = &ia32_registers[REG_ESP]; - int i, maxslot, inc_ofs, ofs; - ir_node *node, *pred_sp, *block; + int i, maxslot, ofs; ir_node *loads[MAXPUSH_OPTIMIZE]; unsigned regmask = 0; unsigned copymask = ~0; memset(loads, 0, sizeof(loads)); - assert(be_is_IncSP(irn)); - inc_ofs = -be_get_IncSP_offset(irn); + int inc_ofs = -be_get_IncSP_offset(irn); if (inc_ofs < 4) return; @@ -675,8 +535,8 @@ static void peephole_Load_IncSP_to_pop(ir_node *irn) * attached to the node */ maxslot = -1; - pred_sp = be_get_IncSP_pred(irn); - for (node = sched_prev(irn); !sched_is_end(node); node = sched_prev(node)) { + ir_node *pred_sp = be_get_IncSP_pred(irn); + sched_foreach_reverse_before(irn, node) { int offset; int loadslot; const arch_register_t *sreg, *dreg; @@ -766,7 +626,7 @@ static void peephole_Load_IncSP_to_pop(ir_node *irn) inc_ofs = (i+1) * 4; /* create a new IncSP if needed */ - block = get_nodes_block(irn); + ir_node *const block = get_nodes_block(irn); if (inc_ofs > 0) { pred_sp = be_new_IncSP(esp, block, pred_sp, -inc_ofs, be_get_IncSP_align(irn)); sched_add_before(irn, pred_sp); @@ -1246,7 +1106,6 @@ void ia32_peephole_optimization(ir_graph *irg) /* pass 1 */ ir_clear_opcodes_generic_func(); register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp); - register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp); register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); if (ia32_cg_config.use_short_sex_eax) register_peephole_optimisation(op_ia32_Conv_I2I, peephole_ia32_Conv_I2I); @@ -1296,17 +1155,16 @@ static void optimize_conv_store(ir_node *node) ir_mode *conv_mode; ir_mode *store_mode; - if (!is_ia32_Store(node) && !is_ia32_Store8Bit(node)) + if (!is_ia32_Store(node)) return; - assert((int)n_ia32_Store_val == (int)n_ia32_Store8Bit_val); pred_proj = get_irn_n(node, n_ia32_Store_val); if (is_Proj(pred_proj)) { pred = get_Proj_pred(pred_proj); } else { pred = pred_proj; } - if (!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred)) + if (!is_ia32_Conv_I2I(pred)) return; if (get_ia32_op_type(pred) != ia32_Normal) return; @@ -1333,10 +1191,9 @@ static void optimize_load_conv(ir_node *node) ir_mode *load_mode; ir_mode *conv_mode; - if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node)) + if (!is_ia32_Conv_I2I(node)) return; - assert((int)n_ia32_Conv_I2I_val == (int)n_ia32_Conv_I2I8Bit_val); pred = get_irn_n(node, n_ia32_Conv_I2I_val); if (!is_Proj(pred)) return; @@ -1381,17 +1238,16 @@ static void optimize_conv_conv(ir_node *node) int conv_mode_bits; int pred_mode_bits; - if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node)) + if (!is_ia32_Conv_I2I(node)) return; - assert((int)n_ia32_Conv_I2I_val == (int)n_ia32_Conv_I2I8Bit_val); pred_proj = get_irn_n(node, n_ia32_Conv_I2I_val); if (is_Proj(pred_proj)) pred = get_Proj_pred(pred_proj); else pred = pred_proj; - if (!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred)) + if (!is_ia32_Conv_I2I(pred)) return; /* we know that after a conv, the upper bits are sign extended @@ -1414,7 +1270,7 @@ static void optimize_conv_conv(ir_node *node) /* Argh:We must change the opcode to 8bit AND copy the register constraints */ if (get_mode_size_bits(conv_mode) == 8) { const arch_register_req_t **reqs = arch_get_irn_register_reqs_in(node); - set_irn_op(pred, op_ia32_Conv_I2I8Bit); + set_irn_op(pred, op_ia32_Conv_I2I); arch_set_irn_register_reqs_in(pred, reqs); } } else { @@ -1429,7 +1285,7 @@ static void optimize_conv_conv(ir_node *node) /* Argh:We must change the opcode to 8bit AND copy the register constraints */ if (get_mode_size_bits(conv_mode) == 8) { const arch_register_req_t **reqs = arch_get_irn_register_reqs_in(node); - set_irn_op(result_conv, op_ia32_Conv_I2I8Bit); + set_irn_op(result_conv, op_ia32_Conv_I2I); arch_set_irn_register_reqs_in(result_conv, reqs); } }