X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fauto-inc-dec.c;h=3b3006c985fa414d021f4eae72502c79fd28f1d2;hb=e5d72697a63fb5fba97fa1f1027d765cc17a0711;hp=2e2d047bf97ef4873e576271b467ea3f68ff1936;hpb=a6879b1d1819c9d4761e0d4eada1a48700dfcccd;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c index 2e2d047bf97..3b3006c985f 100644 --- a/gcc/auto-inc-dec.c +++ b/gcc/auto-inc-dec.c @@ -1,5 +1,5 @@ /* Discovery of auto-inc and auto-dec instructions. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Kenneth Zadeck This file is part of GCC. @@ -40,12 +40,14 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "df.h" #include "dbgcnt.h" +#include "target.h" /* This pass was originally removed from flow.c. However there is almost nothing that remains of that code. There are (4) basic forms that are matched: + (1) FORM_PRE_ADD a <- b + c ... *a @@ -55,6 +57,9 @@ along with GCC; see the file COPYING3. If not see a <- b ... *(a += c) pre + + + (2) FORM_PRE_INC a += c ... *a @@ -62,18 +67,24 @@ along with GCC; see the file COPYING3. If not see becomes *(a += c) pre + + + (3) FORM_POST_ADD *a ... b <- a + c - for this case to be true, b must not be assigned or used between - the *a and the assignment to b. B must also be a Pmode reg. + (For this case to be true, b must not be assigned or used between + the *a and the assignment to b. B must also be a Pmode reg.) becomes b <- a ... *(b += c) post + + + (4) FORM_POST_INC *a ... a <- a + c @@ -99,56 +110,8 @@ along with GCC; see the file COPYING3. If not see The is one special case: if a already had an offset equal to it +- its width and that offset is equal to -c when the increment was before the ref or +c if the increment was after the ref, then if we - can do the combination but switch the pre/post bit. - - (1) FORM_PRE_ADD - - a <- b + c - ... - *(a - c) - - becomes + can do the combination but switch the pre/post bit. */ - a <- b - ... - *(a += c) post - - (2) FORM_PRE_INC - - a += c - ... - *(a - c) - - becomes - - *(a += c) post - - (3) FORM_POST_ADD - - *(a + c) - ... - b <- a + c - - for this case to be true, b must not be assigned or used between - the *a and the assignment to b. B must also be a Pmode reg. - - becomes - - b <- a - ... - *(b += c) pre - - - (4) FORM_POST_INC - - *(a + c) - ... - a <- a + c - - becomes - - *(a += c) pre -*/ #ifdef AUTO_INC_DEC enum form @@ -515,14 +478,15 @@ attempt_change (rtx new_addr, rtx inc_reg) rtx new_mem; int old_cost = 0; int new_cost = 0; + bool speed = optimize_bb_for_speed_p (bb); PUT_MODE (mem_tmp, mode); XEXP (mem_tmp, 0) = new_addr; - old_cost = rtx_cost (mem, 0) - + rtx_cost (PATTERN (inc_insn.insn), 0); - new_cost = rtx_cost (mem_tmp, 0); - + old_cost = (rtx_cost (mem, SET, speed) + + rtx_cost (PATTERN (inc_insn.insn), SET, speed)); + new_cost = rtx_cost (mem_tmp, SET, speed); + /* The first item of business is to see if this is profitable. */ if (old_cost < new_cost) { @@ -621,8 +585,7 @@ attempt_change (rtx new_addr, rtx inc_reg) } /* Record that this insn has an implicit side effect. */ - REG_NOTES (mem_insn.insn) - = alloc_EXPR_LIST (REG_INC, inc_reg, REG_NOTES (mem_insn.insn)); + add_reg_note (mem_insn.insn, REG_INC, inc_reg); if (dump_file) { @@ -636,7 +599,7 @@ attempt_change (rtx new_addr, rtx inc_reg) /* Try to combine the instruction in INC_INSN with the instruction in MEM_INSN. First the form is determined using the DECISION_TABLE - and and the results of parsing the INC_INSN and the MEM_INSN. + and the results of parsing the INC_INSN and the MEM_INSN. Assuming the form is ok, a prototype new address is built which is passed to ATTEMPT_CHANGE for final processing. */ @@ -651,6 +614,7 @@ try_merge (void) /* The width of the mem being accessed. */ int size = GET_MODE_SIZE (GET_MODE (mem)); rtx last_insn = NULL; + enum machine_mode reg_mode = GET_MODE (inc_reg); switch (inc_insn.form) { @@ -705,33 +669,33 @@ try_merge (void) case SIMPLE_PRE_INC: /* ++size */ if (dump_file) fprintf (dump_file, "trying SIMPLE_PRE_INC\n"); - return attempt_change (gen_rtx_PRE_INC (Pmode, inc_reg), inc_reg); + return attempt_change (gen_rtx_PRE_INC (reg_mode, inc_reg), inc_reg); break; case SIMPLE_POST_INC: /* size++ */ if (dump_file) fprintf (dump_file, "trying SIMPLE_POST_INC\n"); - return attempt_change (gen_rtx_POST_INC (Pmode, inc_reg), inc_reg); + return attempt_change (gen_rtx_POST_INC (reg_mode, inc_reg), inc_reg); break; case SIMPLE_PRE_DEC: /* --size */ if (dump_file) fprintf (dump_file, "trying SIMPLE_PRE_DEC\n"); - return attempt_change (gen_rtx_PRE_DEC (Pmode, inc_reg), inc_reg); + return attempt_change (gen_rtx_PRE_DEC (reg_mode, inc_reg), inc_reg); break; case SIMPLE_POST_DEC: /* size-- */ if (dump_file) fprintf (dump_file, "trying SIMPLE_POST_DEC\n"); - return attempt_change (gen_rtx_POST_DEC (Pmode, inc_reg), inc_reg); + return attempt_change (gen_rtx_POST_DEC (reg_mode, inc_reg), inc_reg); break; case DISP_PRE: /* ++con */ if (dump_file) fprintf (dump_file, "trying DISP_PRE\n"); - return attempt_change (gen_rtx_PRE_MODIFY (Pmode, + return attempt_change (gen_rtx_PRE_MODIFY (reg_mode, inc_reg, - gen_rtx_PLUS (Pmode, + gen_rtx_PLUS (reg_mode, inc_reg, inc_insn.reg1)), inc_reg); @@ -740,9 +704,9 @@ try_merge (void) case DISP_POST: /* con++ */ if (dump_file) fprintf (dump_file, "trying POST_DISP\n"); - return attempt_change (gen_rtx_POST_MODIFY (Pmode, + return attempt_change (gen_rtx_POST_MODIFY (reg_mode, inc_reg, - gen_rtx_PLUS (Pmode, + gen_rtx_PLUS (reg_mode, inc_reg, inc_insn.reg1)), inc_reg); @@ -751,9 +715,9 @@ try_merge (void) case REG_PRE: /* ++reg */ if (dump_file) fprintf (dump_file, "trying PRE_REG\n"); - return attempt_change (gen_rtx_PRE_MODIFY (Pmode, + return attempt_change (gen_rtx_PRE_MODIFY (reg_mode, inc_reg, - gen_rtx_PLUS (Pmode, + gen_rtx_PLUS (reg_mode, inc_reg, inc_insn.reg1)), inc_reg); @@ -762,9 +726,9 @@ try_merge (void) case REG_POST: /* reg++ */ if (dump_file) fprintf (dump_file, "trying POST_REG\n"); - return attempt_change (gen_rtx_POST_MODIFY (Pmode, + return attempt_change (gen_rtx_POST_MODIFY (reg_mode, inc_reg, - gen_rtx_PLUS (Pmode, + gen_rtx_PLUS (reg_mode, inc_reg, inc_insn.reg1)), inc_reg); @@ -851,7 +815,7 @@ parse_add_or_inc (rtx insn, bool before_mem) else inc_insn.form = before_mem ? FORM_PRE_ADD : FORM_POST_ADD; - if (GET_CODE (XEXP (SET_SRC (pat), 1)) == CONST_INT) + if (CONST_INT_P (XEXP (SET_SRC (pat), 1))) { /* Process a = b + c where c is a const. */ inc_insn.reg1_is_const = true; @@ -929,7 +893,7 @@ find_address (rtx *address_of_x) mem_insn.reg0 = inc_insn.reg_res; mem_insn.reg1 = b; mem_insn.reg1_is_const = inc_insn.reg1_is_const; - if (GET_CODE (b) == CONST_INT) + if (CONST_INT_P (b)) { /* Match with *(reg0 + reg1) where reg1 is a const. */ HOST_WIDE_INT val = INTVAL (b); @@ -1007,7 +971,7 @@ find_inc (bool first_try) rtx insn; basic_block bb = BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)); rtx other_insn; - struct df_ref **def_rec; + df_ref *def_rec; /* Make sure this reg appears only once in this insn. */ if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1) @@ -1053,7 +1017,7 @@ find_inc (bool first_try) assigned to by the mem insn. */ for (def_rec = DF_INSN_DEFS (mem_insn.insn); *def_rec; def_rec++) { - struct df_ref *def = *def_rec; + df_ref def = *def_rec; unsigned int regno = DF_REF_REGNO (def); if ((regno == REGNO (inc_insn.reg0)) || (regno == REGNO (inc_insn.reg_res))) @@ -1127,7 +1091,9 @@ find_inc (bool first_try) we are going to increment the result of the add insn. For this trick to be correct, the result reg of the inc must be a valid addressing reg. */ - if (GET_MODE (inc_insn.reg_res) != Pmode) + addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc); + if (GET_MODE (inc_insn.reg_res) + != targetm.addr_space.address_mode (as)) { if (dump_file) fprintf (dump_file, "base reg mode failure.\n"); @@ -1176,7 +1142,9 @@ find_inc (bool first_try) { /* For this trick to be correct, the result reg of the inc must be a valid addressing reg. */ - if (GET_MODE (inc_insn.reg_res) != Pmode) + addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc); + if (GET_MODE (inc_insn.reg_res) + != targetm.addr_space.address_mode (as)) { if (dump_file) fprintf (dump_file, "base reg mode failure.\n"); @@ -1317,7 +1285,7 @@ find_mem (rtx *address_of_x) mem_insn.mem_loc = address_of_x; mem_insn.reg0 = XEXP (XEXP (x, 0), 0); mem_insn.reg1 = reg1; - if (GET_CODE (reg1) == CONST_INT) + if (CONST_INT_P (reg1)) { mem_insn.reg1_is_const = true; /* Match with *(reg0 + c) where c is a const. */ @@ -1379,7 +1347,7 @@ merge_in_block (int max_reg, basic_block bb) unsigned int uid = INSN_UID (insn); bool insn_is_add_or_inc = true; - if (!INSN_P (insn)) + if (!NONDEBUG_INSN_P (insn)) continue; /* This continue is deliberate. We do not want the uses of the @@ -1452,14 +1420,14 @@ merge_in_block (int max_reg, basic_block bb) /* If the inc insn was merged with a mem, the inc insn is gone and there is noting to update. */ - if (DF_INSN_UID_GET(uid)) + if (DF_INSN_UID_GET (uid)) { - struct df_ref **def_rec; - struct df_ref **use_rec; + df_ref *def_rec; + df_ref *use_rec; /* Need to update next use. */ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) { - struct df_ref *def = *def_rec; + df_ref def = *def_rec; reg_next_use[DF_REF_REGNO (def)] = NULL; reg_next_inc_use[DF_REF_REGNO (def)] = NULL; reg_next_def[DF_REF_REGNO (def)] = insn; @@ -1467,7 +1435,7 @@ merge_in_block (int max_reg, basic_block bb) for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) { - struct df_ref *use = *use_rec; + df_ref use = *use_rec; reg_next_use[DF_REF_REGNO (use)] = insn; if (insn_is_add_or_inc) reg_next_inc_use[DF_REF_REGNO (use)] = insn; @@ -1540,9 +1508,11 @@ gate_auto_inc_dec (void) } -struct tree_opt_pass pass_inc_dec = +struct rtl_opt_pass pass_inc_dec = { - "auto-inc-dec", /* name */ + { + RTL_PASS, + "auto_inc_dec", /* name */ gate_auto_inc_dec, /* gate */ rest_of_handle_auto_inc_dec, /* execute */ NULL, /* sub */ @@ -1555,6 +1525,5 @@ struct tree_opt_pass pass_inc_dec = 0, /* todo_flags_start */ TODO_dump_func | TODO_df_finish, /* todo_flags_finish */ - 0 /* letter */ + } }; -