diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-30 09:27:48 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-30 09:27:48 +0000 |
commit | 279dc72feede56719335d771f23babe9330096a3 (patch) | |
tree | ff400275b8d7c6494715874e348b5de2b2f15faa /gcc/auto-inc-dec.c | |
parent | 744c2d412b76c9b2abc14176d120429d7207ad95 (diff) | |
download | gcc-279dc72feede56719335d771f23babe9330096a3.tar.gz |
2009-11-30 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 154750 (or near)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@154757 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/auto-inc-dec.c')
-rw-r--r-- | gcc/auto-inc-dec.c | 212 |
1 files changed, 106 insertions, 106 deletions
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c index 3b3006c985f..830fc5e09f0 100644 --- a/gcc/auto-inc-dec.c +++ b/gcc/auto-inc-dec.c @@ -1,7 +1,7 @@ /* Discovery of auto-inc and auto-dec instructions. Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> - + This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under @@ -74,7 +74,7 @@ along with GCC; see the file COPYING3. If not see ... b <- a + c - (For this case to be true, b must not be assigned or used between + (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 @@ -104,9 +104,9 @@ along with GCC; see the file COPYING3. If not see by the pointer. This is useful for machines that have HAVE_PRE_MODIFY_DISP, HAVE_POST_MODIFY_DISP defined. - 3) c is a register. This is useful for machines that have - HAVE_PRE_MODIFY_REG, HAVE_POST_MODIFY_REG - + 3) c is a register. This is useful for machines that have + HAVE_PRE_MODIFY_REG, HAVE_POST_MODIFY_REG + 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 @@ -129,7 +129,7 @@ enum form ANY is used for constants that are not +-size or 0. REG is used if the forms are reg1 + reg2. */ -enum inc_state +enum inc_state { INC_ZERO, /* == 0 */ INC_NEG_SIZE, /* == +size */ @@ -295,7 +295,7 @@ init_decision_table (void) /* Parsed fields of an inc insn of the form "reg_res = reg0+reg1" or "reg_res = reg0+c". */ -static struct inc_insn +static struct inc_insn { rtx insn; /* The insn being parsed. */ rtx pat; /* The pattern of the insn. */ @@ -311,10 +311,10 @@ static struct inc_insn /* Dump the parsed inc insn to FILE. */ -static void +static void dump_inc_insn (FILE *file) { - const char *f = ((inc_insn.form == FORM_PRE_ADD) + const char *f = ((inc_insn.form == FORM_PRE_ADD) || (inc_insn.form == FORM_PRE_INC)) ? "pre" : "post"; dump_insn_slim (file, inc_insn.insn); @@ -324,26 +324,26 @@ dump_inc_insn (FILE *file) case FORM_PRE_ADD: case FORM_POST_ADD: if (inc_insn.reg1_is_const) - fprintf (file, "found %s add(%d) r[%d]=r[%d]+%d\n", - f, INSN_UID (inc_insn.insn), - REGNO (inc_insn.reg_res), + fprintf (file, "found %s add(%d) r[%d]=r[%d]+%d\n", + f, INSN_UID (inc_insn.insn), + REGNO (inc_insn.reg_res), REGNO (inc_insn.reg0), (int) inc_insn.reg1_val); else - fprintf (file, "found %s add(%d) r[%d]=r[%d]+r[%d]\n", - f, INSN_UID (inc_insn.insn), - REGNO (inc_insn.reg_res), + fprintf (file, "found %s add(%d) r[%d]=r[%d]+r[%d]\n", + f, INSN_UID (inc_insn.insn), + REGNO (inc_insn.reg_res), REGNO (inc_insn.reg0), REGNO (inc_insn.reg1)); break; - + case FORM_PRE_INC: case FORM_POST_INC: if (inc_insn.reg1_is_const) - fprintf (file, "found %s inc(%d) r[%d]+=%d\n", - f, INSN_UID (inc_insn.insn), + fprintf (file, "found %s inc(%d) r[%d]+=%d\n", + f, INSN_UID (inc_insn.insn), REGNO (inc_insn.reg_res), (int) inc_insn.reg1_val); else - fprintf (file, "found %s inc(%d) r[%d]+=r[%d]\n", - f, INSN_UID (inc_insn.insn), + fprintf (file, "found %s inc(%d) r[%d]+=r[%d]\n", + f, INSN_UID (inc_insn.insn), REGNO (inc_insn.reg_res), REGNO (inc_insn.reg1)); break; @@ -372,18 +372,18 @@ static struct mem_insn /* Dump the parsed mem insn to FILE. */ -static void +static void dump_mem_insn (FILE *file) { dump_insn_slim (file, mem_insn.insn); if (mem_insn.reg1_is_const) - fprintf (file, "found mem(%d) *(r[%d]+%d)\n", - INSN_UID (mem_insn.insn), + fprintf (file, "found mem(%d) *(r[%d]+%d)\n", + INSN_UID (mem_insn.insn), REGNO (mem_insn.reg0), (int) mem_insn.reg1_val); else - fprintf (file, "found mem(%d) *(r[%d]+r[%d])\n", - INSN_UID (mem_insn.insn), + fprintf (file, "found mem(%d) *(r[%d]+r[%d])\n", + INSN_UID (mem_insn.insn), REGNO (mem_insn.reg0), REGNO (mem_insn.reg1)); } @@ -409,17 +409,17 @@ static rtx *reg_next_def = NULL; insn. Moving the REG_EQUAL and REG_EQUIV is clearly wrong and it does not appear that there are any other kinds of relevant notes. */ -static void +static void move_dead_notes (rtx to_insn, rtx from_insn, rtx pattern) { - rtx note; + rtx note; rtx next_note; rtx prev_note = NULL; for (note = REG_NOTES (from_insn); note; note = next_note) { next_note = XEXP (note, 1); - + if ((REG_NOTE_KIND (note) == REG_DEAD) && pattern == XEXP (note, 0)) { @@ -451,7 +451,7 @@ insert_move_insn_before (rtx next_insn, rtx dest_reg, rtx src_reg) return insns; } - + /* Change mem_insn.mem_loc so that uses NEW_ADDR which has an increment of INC_REG. To have reached this point, the change is a legitimate one from a dataflow point of view. The only questions @@ -504,7 +504,7 @@ attempt_change (rtx new_addr, rtx inc_reg) if (! validate_change (mem_insn.insn, mem_insn.mem_loc, new_mem, 0)) { if (dump_file) - fprintf (dump_file, "validation failure\n"); + fprintf (dump_file, "validation failure\n"); return false; } @@ -517,7 +517,7 @@ attempt_change (rtx new_addr, rtx inc_reg) /* Replace the addition with a move. Do it at the location of the addition since the operand of the addition may change before the memory reference. */ - mov_insn = insert_move_insn_before (inc_insn.insn, + mov_insn = insert_move_insn_before (inc_insn.insn, inc_insn.reg_res, inc_insn.reg0); move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0); @@ -543,7 +543,7 @@ attempt_change (rtx new_addr, rtx inc_reg) break; case FORM_POST_ADD: - mov_insn = insert_move_insn_before (mem_insn.insn, + mov_insn = insert_move_insn_before (mem_insn.insn, inc_insn.reg_res, inc_insn.reg0); move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0); @@ -603,7 +603,7 @@ attempt_change (rtx new_addr, rtx inc_reg) Assuming the form is ok, a prototype new address is built which is passed to ATTEMPT_CHANGE for final processing. */ -static bool +static bool try_merge (void) { enum gen_form gen_form; @@ -648,13 +648,13 @@ try_merge (void) return false; } - mem_insn.reg1_state = (mem_insn.reg1_is_const) + mem_insn.reg1_state = (mem_insn.reg1_is_const) ? set_inc_state (mem_insn.reg1_val, size) : INC_REG; inc_insn.reg1_state = (inc_insn.reg1_is_const) ? set_inc_state (inc_insn.reg1_val, size) : INC_REG; /* Now get the form that we are generating. */ - gen_form = decision_table + gen_form = decision_table [inc_insn.reg1_state][mem_insn.reg1_state][inc_insn.form]; if (dbg_cnt (auto_inc_dec) == false) @@ -671,25 +671,25 @@ try_merge (void) fprintf (dump_file, "trying SIMPLE_PRE_INC\n"); 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 (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 (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 (reg_mode, inc_reg), inc_reg); break; - + case DISP_PRE: /* ++con */ if (dump_file) fprintf (dump_file, "trying DISP_PRE\n"); @@ -700,7 +700,7 @@ try_merge (void) inc_insn.reg1)), inc_reg); break; - + case DISP_POST: /* con++ */ if (dump_file) fprintf (dump_file, "trying POST_DISP\n"); @@ -711,7 +711,7 @@ try_merge (void) inc_insn.reg1)), inc_reg); break; - + case REG_PRE: /* ++reg */ if (dump_file) fprintf (dump_file, "trying PRE_REG\n"); @@ -722,7 +722,7 @@ try_merge (void) inc_insn.reg1)), inc_reg); break; - + case REG_POST: /* reg++ */ if (dump_file) fprintf (dump_file, "trying POST_REG\n"); @@ -758,10 +758,10 @@ get_next_ref (int regno, basic_block bb, rtx *next_array) /* Reverse the operands in a mem insn. */ -static void +static void reverse_mem (void) { - rtx tmp = mem_insn.reg1; + rtx tmp = mem_insn.reg1; mem_insn.reg1 = mem_insn.reg0; mem_insn.reg0 = tmp; } @@ -769,10 +769,10 @@ reverse_mem (void) /* Reverse the operands in a inc insn. */ -static void +static void reverse_inc (void) { - rtx tmp = inc_insn.reg1; + rtx tmp = inc_insn.reg1; inc_insn.reg1 = inc_insn.reg0; inc_insn.reg0 = tmp; } @@ -780,8 +780,8 @@ reverse_inc (void) /* Return true if INSN is of a form "a = b op c" where a and b are regs. op is + if c is a reg and +|- if c is a const. Fill in - INC_INSN with what is found. - + INC_INSN with what is found. + This function is called in two contexts, if BEFORE_MEM is true, this is called for each insn in the basic block. If BEFORE_MEM is false, it is called for the instruction in the block that uses the @@ -812,7 +812,7 @@ parse_add_or_inc (rtx insn, bool before_mem) inc_insn.reg0 = XEXP (SET_SRC (pat), 0); if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg0)) inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC; - else + else inc_insn.form = before_mem ? FORM_PRE_ADD : FORM_POST_ADD; if (CONST_INT_P (XEXP (SET_SRC (pat), 1))) @@ -838,8 +838,8 @@ parse_add_or_inc (rtx insn, bool before_mem) /* Process a = b + c where c is a reg. */ inc_insn.reg1 = XEXP (SET_SRC (pat), 1); inc_insn.reg1_is_const = false; - - if (inc_insn.form == FORM_PRE_INC + + if (inc_insn.form == FORM_PRE_INC || inc_insn.form == FORM_POST_INC) return true; else if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg1)) @@ -850,7 +850,7 @@ parse_add_or_inc (rtx insn, bool before_mem) inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC; return true; } - else + else return true; } @@ -862,7 +862,7 @@ parse_add_or_inc (rtx insn, bool before_mem) ADDRESS_OF_X to see if any single one of them is compatible with what has been found in inc_insn. - -1 is returned for success. 0 is returned if nothing was found and + -1 is returned for success. 0 is returned if nothing was found and 1 is returned for failure. */ static int @@ -897,15 +897,15 @@ find_address (rtx *address_of_x) { /* Match with *(reg0 + reg1) where reg1 is a const. */ HOST_WIDE_INT val = INTVAL (b); - if (inc_insn.reg1_is_const + if (inc_insn.reg1_is_const && (inc_insn.reg1_val == val || inc_insn.reg1_val == -val)) { mem_insn.reg1_val = val; return -1; } } - else if (!inc_insn.reg1_is_const - && rtx_equal_p (inc_insn.reg1, b)) + else if (!inc_insn.reg1_is_const + && rtx_equal_p (inc_insn.reg1, b)) /* Match with *(reg0 + reg1). */ return -1; } @@ -965,7 +965,7 @@ find_address (rtx *address_of_x) add of the second register. The FIRST_TRY parameter is used to only allow the parameters to be reversed once. */ -static bool +static bool find_inc (bool first_try) { rtx insn; @@ -977,7 +977,7 @@ find_inc (bool first_try) if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1) { if (dump_file) - fprintf (dump_file, "mem count failure\n"); + fprintf (dump_file, "mem count failure\n"); return false; } @@ -985,8 +985,8 @@ find_inc (bool first_try) dump_mem_insn (dump_file); /* Find the next use that is an inc. */ - insn = get_next_ref (REGNO (mem_insn.reg0), - BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), + insn = get_next_ref (REGNO (mem_insn.reg0), + BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), reg_next_inc_use); if (!insn) return false; @@ -997,11 +997,11 @@ find_inc (bool first_try) { /* Next use was not an add. Look for one extra case. It could be that we have: - + *(a + b) ...= a; ...= b + a - + if we reverse the operands in the mem ref we would find this. Only try it once though. */ if (first_try && !mem_insn.reg1_is_const) @@ -1013,13 +1013,13 @@ find_inc (bool first_try) return false; } - /* Need to assure that none of the operands of the inc instruction are + /* Need to assure that none of the operands of the inc instruction are assigned to by the mem insn. */ for (def_rec = DF_INSN_DEFS (mem_insn.insn); *def_rec; def_rec++) { df_ref def = *def_rec; unsigned int regno = DF_REF_REGNO (def); - if ((regno == REGNO (inc_insn.reg0)) + if ((regno == REGNO (inc_insn.reg0)) || (regno == REGNO (inc_insn.reg_res))) { if (dump_file) @@ -1041,26 +1041,26 @@ find_inc (bool first_try) { /* Make sure that there is no insn that assigns to inc_insn.res between the mem_insn and the inc_insn. */ - rtx other_insn = get_next_ref (REGNO (inc_insn.reg_res), - BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), + rtx other_insn = get_next_ref (REGNO (inc_insn.reg_res), + BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), reg_next_def); if (other_insn != inc_insn.insn) { if (dump_file) - fprintf (dump_file, + fprintf (dump_file, "result of add is assigned to between mem and inc insns.\n"); return false; } - other_insn = get_next_ref (REGNO (inc_insn.reg_res), - BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), + other_insn = get_next_ref (REGNO (inc_insn.reg_res), + BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), reg_next_use); - if (other_insn + if (other_insn && (other_insn != inc_insn.insn) && (DF_INSN_LUID (inc_insn.insn) > DF_INSN_LUID (other_insn))) { if (dump_file) - fprintf (dump_file, + fprintf (dump_file, "result of add is used between mem and inc insns.\n"); return false; } @@ -1087,7 +1087,7 @@ find_inc (bool first_try) int luid = DF_INSN_LUID (inc_insn.insn); if (inc_insn.form == FORM_POST_ADD) { - /* The trick is that we are not going to increment r0, + /* The trick is that we are not going to increment r0, 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. */ @@ -1102,16 +1102,16 @@ find_inc (bool first_try) /* We also need to make sure that the next use of inc result is after the inc. */ - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_use); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0)) - reverse_inc (); + reverse_inc (); } - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; @@ -1130,14 +1130,14 @@ find_inc (bool first_try) need to treat it as if it was *(b + a). It may also be that the add is of the form a + c where c does not match b and then we just abandon this. */ - + int luid = DF_INSN_LUID (inc_insn.insn); rtx other_insn; - + /* Make sure this reg appears only once in this insn. */ if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg1, 1) != 1) return false; - + if (inc_insn.form == FORM_POST_ADD) { /* For this trick to be correct, the result reg of the inc @@ -1167,7 +1167,7 @@ find_inc (bool first_try) /* Need to check that there are no assignments to b before the add insn. */ - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; @@ -1188,14 +1188,14 @@ find_inc (bool first_try) } /* To have gotten here know that. *(b + a) - + ... = (b + a) - + We also know that the lhs of the inc is not b or a. We need to make sure that there are no assignments to b - between the mem ref and the inc. */ - - other_insn + between the mem ref and the inc. */ + + other_insn = get_next_ref (REGNO (inc_insn.reg0), bb, reg_next_def); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; @@ -1203,13 +1203,13 @@ find_inc (bool first_try) /* Need to check that the next use of the add result is later than add insn since this will be the reg incremented. */ - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg_res), bb, reg_next_use); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; } else /* FORM_POST_INC. There is less to check here because we - know that operands must line up. */ + know that operands must line up. */ { if (!rtx_equal_p (mem_insn.reg1, inc_insn.reg1)) /* See comment above on find_inc (false) call. */ @@ -1219,19 +1219,19 @@ find_inc (bool first_try) reverse_mem (); return find_inc (false); } - else + else return false; } - + /* To have gotten here know that. *(a + b) - + ... = (a + b) - + We also know that the lhs of the inc is not b. We need to make sure that there are no assignments to b between the mem ref and the inc. */ - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def); if (other_insn && luid > DF_INSN_LUID (other_insn)) return false; @@ -1240,7 +1240,7 @@ find_inc (bool first_try) if (inc_insn.form == FORM_POST_INC) { - other_insn + other_insn = get_next_ref (REGNO (inc_insn.reg0), bb, reg_next_use); /* When we found inc_insn, we were looking for the next add or inc, not the next insn that used the @@ -1348,10 +1348,10 @@ merge_in_block (int max_reg, basic_block bb) bool insn_is_add_or_inc = true; if (!NONDEBUG_INSN_P (insn)) - continue; + continue; /* This continue is deliberate. We do not want the uses of the - jump put into reg_next_use because it is not considered safe to + jump put into reg_next_use because it is not considered safe to combine a preincrement with a jump. */ if (JUMP_P (insn)) continue; @@ -1381,22 +1381,22 @@ merge_in_block (int max_reg, basic_block bb) clear of c because the inc insn is going to move into the mem_insn.insn. */ int luid = DF_INSN_LUID (mem_insn.insn); - rtx other_insn + rtx other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_use); - + if (other_insn && luid > DF_INSN_LUID (other_insn)) ok = false; - - other_insn + + other_insn = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def); - + if (other_insn && luid > DF_INSN_LUID (other_insn)) ok = false; } - + if (dump_file) dump_inc_insn (dump_file); - + if (ok && find_address (&PATTERN (mem_insn.insn)) == -1) { if (dump_file) @@ -1417,7 +1417,7 @@ merge_in_block (int max_reg, basic_block bb) if (find_mem (&PATTERN (insn))) success_in_block++; } - + /* 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)) @@ -1432,7 +1432,7 @@ merge_in_block (int max_reg, basic_block bb) reg_next_inc_use[DF_REF_REGNO (def)] = NULL; reg_next_def[DF_REF_REGNO (def)] = insn; } - + for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) { df_ref use = *use_rec; @@ -1441,7 +1441,7 @@ merge_in_block (int max_reg, basic_block bb) reg_next_inc_use[DF_REF_REGNO (use)] = insn; else reg_next_inc_use[DF_REF_REGNO (use)] = NULL; - } + } } else if (dump_file) fprintf (dump_file, "skipping update of deleted insn %d\n", uid); @@ -1464,7 +1464,7 @@ merge_in_block (int max_reg, basic_block bb) #endif -static unsigned int +static unsigned int rest_of_handle_auto_inc_dec (void) { #ifdef AUTO_INC_DEC @@ -1523,7 +1523,7 @@ struct rtl_opt_pass pass_inc_dec = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | + TODO_dump_func | TODO_df_finish, /* todo_flags_finish */ } }; |