/* 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 <zadeck@naturalbridge.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
There are (4) basic forms that are matched:
+ (1) FORM_PRE_ADD
a <- b + c
...
*a
a <- b
...
*(a += c) pre
+
+
+ (2) FORM_PRE_INC
a += c
...
*a
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
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
-
- 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
-
+ can do the combination but switch the pre/post bit. */
- (4) FORM_POST_INC
-
- *(a + c)
- ...
- a <- a + c
-
- becomes
-
- *(a += c) pre
-*/
#ifdef AUTO_INC_DEC
enum form
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)
{
switch (inc_insn.form)
{
case FORM_PRE_ADD:
- mov_insn = insert_move_insn_before (mem_insn.insn,
+ /* 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,
inc_insn.reg_res, inc_insn.reg0);
move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
}
/* 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)
{
/* 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. */
}
/* Look to see if the inc register is dead after the memory
- reference. If it is do not do the combination. */
+ reference. If it is, do not do the combination. */
if (find_regno_note (last_insn, REG_DEAD, REGNO (inc_reg)))
{
if (dump_file)
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)
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)))
next add or inc, not the next insn that used the
reg. Because we are going to increment the reg
in this form, we need to make sure that there
- were no interveining uses of reg. */
+ were no intervening uses of reg. */
if (inc_insn.insn != other_insn)
return false;
}
and there is noting to update. */
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;
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;
}
-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 */
0, /* todo_flags_start */
TODO_dump_func |
TODO_df_finish, /* todo_flags_finish */
- 0 /* letter */
+ }
};
-