/* Discovery of auto-inc and auto-dec instructions.
   Copyright (C) 2006-2019 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 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "df.h"
#include "insn-config.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cfgrtl.h"
#include "expr.h"
#include "tree-pass.h"
#include "dbgcnt.h"
#include "print-rtl.h"
#include "valtrack.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

        becomes

           a <- b
           ...
           *(a += c) pre

        or, alternately,

           a <- b + c
           ...
           *b

        becomes

           a <- b
           ...
           *(a += c) post

        This uses a post-add, but it's handled as FORM_PRE_ADD because
        the "increment" insn appears before the memory access.


      (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.)

        becomes

           b <- a
           *(b += c) post
           ...


      (4) FORM_POST_INC
           *a
           ...
           a <- a + c

        becomes

           *(a += c) post
           ...


  There are three types of values of c.

    1) c is a constant equal to the width of the value being accessed by
       the pointer.  This is useful for machines that have
       HAVE_PRE_INCREMENT, HAVE_POST_INCREMENT, HAVE_PRE_DECREMENT or
       HAVE_POST_DECREMENT defined.

    2) c is a constant not equal to the width of the value being accessed
       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

  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.  */


enum form
{
  FORM_PRE_ADD,
  FORM_PRE_INC,
  FORM_POST_ADD,
  FORM_POST_INC,
  FORM_last
};

/* The states of the second operands of mem refs and inc insns.  If no
   second operand of the mem_ref was found, it is assumed to just be
   ZERO.  SIZE is the size of the mode accessed in the memref.  The
   ANY is used for constants that are not +-size or 0.  REG is used if
   the forms are reg1 + reg2.  */

enum inc_state
{
  INC_ZERO,           /* == 0  */
  INC_NEG_SIZE,       /* == +size  */
  INC_POS_SIZE,       /* == -size */
  INC_NEG_ANY,        /* == some -constant  */
  INC_POS_ANY,        /* == some +constant  */
  INC_REG,            /* == some register  */
  INC_last
};

/* The eight forms that pre/post inc/dec can take.  */
enum gen_form
{
  NOTHING,
  SIMPLE_PRE_INC,     /* ++size  */
  SIMPLE_POST_INC,    /* size++  */
  SIMPLE_PRE_DEC,     /* --size  */
  SIMPLE_POST_DEC,    /* size--  */
  DISP_PRE,           /* ++con   */
  DISP_POST,          /* con++   */
  REG_PRE,            /* ++reg   */
  REG_POST            /* reg++   */
};

/* Tmp mem rtx for use in cost modeling.  */
static rtx mem_tmp;

static enum inc_state
set_inc_state (HOST_WIDE_INT val, poly_int64 size)
{
  if (val == 0)
    return INC_ZERO;
  if (val < 0)
    return known_eq (val, -size) ? INC_NEG_SIZE : INC_NEG_ANY;
  else
    return known_eq (val, size) ? INC_POS_SIZE : INC_POS_ANY;
}

/* The DECISION_TABLE that describes what form, if any, the increment
   or decrement will take. It is a three dimensional table.  The first
   index is the type of constant or register found as the second
   operand of the inc insn.  The second index is the type of constant
   or register found as the second operand of the memory reference (if
   no second operand exists, 0 is used).  The third index is the form
   and location (relative to the mem reference) of inc insn.  */

static bool initialized = false;
static enum gen_form decision_table[INC_last][INC_last][FORM_last];

static void
init_decision_table (void)
{
  enum gen_form value;

  if (HAVE_PRE_INCREMENT || HAVE_PRE_MODIFY_DISP)
    {
      /* Prefer the simple form if both are available.  */
      value = (HAVE_PRE_INCREMENT) ? SIMPLE_PRE_INC : DISP_PRE;

      decision_table[INC_POS_SIZE][INC_ZERO][FORM_PRE_ADD] = value;
      decision_table[INC_POS_SIZE][INC_ZERO][FORM_PRE_INC] = value;

      decision_table[INC_POS_SIZE][INC_POS_SIZE][FORM_POST_ADD] = value;
      decision_table[INC_POS_SIZE][INC_POS_SIZE][FORM_POST_INC] = value;
    }

  if (HAVE_POST_INCREMENT || HAVE_POST_MODIFY_DISP)
    {
      /* Prefer the simple form if both are available.  */
      value = (HAVE_POST_INCREMENT) ? SIMPLE_POST_INC : DISP_POST;

      decision_table[INC_POS_SIZE][INC_ZERO][FORM_POST_ADD] = value;
      decision_table[INC_POS_SIZE][INC_ZERO][FORM_POST_INC] = value;

      decision_table[INC_POS_SIZE][INC_NEG_SIZE][FORM_PRE_ADD] = value;
      decision_table[INC_POS_SIZE][INC_NEG_SIZE][FORM_PRE_INC] = value;
    }

  if (HAVE_PRE_DECREMENT || HAVE_PRE_MODIFY_DISP)
    {
      /* Prefer the simple form if both are available.  */
      value = (HAVE_PRE_DECREMENT) ? SIMPLE_PRE_DEC : DISP_PRE;

      decision_table[INC_NEG_SIZE][INC_ZERO][FORM_PRE_ADD] = value;
      decision_table[INC_NEG_SIZE][INC_ZERO][FORM_PRE_INC] = value;

      decision_table[INC_NEG_SIZE][INC_NEG_SIZE][FORM_POST_ADD] = value;
      decision_table[INC_NEG_SIZE][INC_NEG_SIZE][FORM_POST_INC] = value;
    }

  if (HAVE_POST_DECREMENT || HAVE_POST_MODIFY_DISP)
    {
      /* Prefer the simple form if both are available.  */
      value = (HAVE_POST_DECREMENT) ? SIMPLE_POST_DEC : DISP_POST;

      decision_table[INC_NEG_SIZE][INC_ZERO][FORM_POST_ADD] = value;
      decision_table[INC_NEG_SIZE][INC_ZERO][FORM_POST_INC] = value;

      decision_table[INC_NEG_SIZE][INC_POS_SIZE][FORM_PRE_ADD] = value;
      decision_table[INC_NEG_SIZE][INC_POS_SIZE][FORM_PRE_INC] = value;
    }

  if (HAVE_PRE_MODIFY_DISP)
    {
      decision_table[INC_POS_ANY][INC_ZERO][FORM_PRE_ADD] = DISP_PRE;
      decision_table[INC_POS_ANY][INC_ZERO][FORM_PRE_INC] = DISP_PRE;

      decision_table[INC_POS_ANY][INC_POS_ANY][FORM_POST_ADD] = DISP_PRE;
      decision_table[INC_POS_ANY][INC_POS_ANY][FORM_POST_INC] = DISP_PRE;

      decision_table[INC_NEG_ANY][INC_ZERO][FORM_PRE_ADD] = DISP_PRE;
      decision_table[INC_NEG_ANY][INC_ZERO][FORM_PRE_INC] = DISP_PRE;

      decision_table[INC_NEG_ANY][INC_NEG_ANY][FORM_POST_ADD] = DISP_PRE;
      decision_table[INC_NEG_ANY][INC_NEG_ANY][FORM_POST_INC] = DISP_PRE;
    }

  if (HAVE_POST_MODIFY_DISP)
    {
      decision_table[INC_POS_ANY][INC_ZERO][FORM_POST_ADD] = DISP_POST;
      decision_table[INC_POS_ANY][INC_ZERO][FORM_POST_INC] = DISP_POST;

      decision_table[INC_POS_ANY][INC_NEG_ANY][FORM_PRE_ADD] = DISP_POST;
      decision_table[INC_POS_ANY][INC_NEG_ANY][FORM_PRE_INC] = DISP_POST;

      decision_table[INC_NEG_ANY][INC_ZERO][FORM_POST_ADD] = DISP_POST;
      decision_table[INC_NEG_ANY][INC_ZERO][FORM_POST_INC] = DISP_POST;

      decision_table[INC_NEG_ANY][INC_POS_ANY][FORM_PRE_ADD] = DISP_POST;
      decision_table[INC_NEG_ANY][INC_POS_ANY][FORM_PRE_INC] = DISP_POST;
    }

  /* This is much simpler than the other cases because we do not look
     for the reg1-reg2 case.  Note that we do not have a INC_POS_REG
     and INC_NEG_REG states.  Most of the use of such states would be
     on a target that had an R1 - R2 update address form.

     There is the remote possibility that you could also catch a = a +
     b; *(a - b) as a postdecrement of (a + b).  However, it is
     unclear if *(a - b) would ever be generated on a machine that did
     not have that kind of addressing mode.  The IA-64 and RS6000 will
     not do this, and I cannot speak for any other.  If any
     architecture does have an a-b update for, these cases should be
     added.  */
  if (HAVE_PRE_MODIFY_REG)
    {
      decision_table[INC_REG][INC_ZERO][FORM_PRE_ADD] = REG_PRE;
      decision_table[INC_REG][INC_ZERO][FORM_PRE_INC] = REG_PRE;

      decision_table[INC_REG][INC_REG][FORM_POST_ADD] = REG_PRE;
      decision_table[INC_REG][INC_REG][FORM_POST_INC] = REG_PRE;
    }

  if (HAVE_POST_MODIFY_REG)
    {
      decision_table[INC_REG][INC_ZERO][FORM_POST_ADD] = REG_POST;
      decision_table[INC_REG][INC_ZERO][FORM_POST_INC] = REG_POST;
    }

  initialized = true;
}

/* Parsed fields of an inc insn of the form "reg_res = reg0+reg1" or
   "reg_res = reg0+c".  */

static struct inc_insn
{
  rtx_insn *insn;     /* The insn being parsed.  */
  rtx pat;            /* The pattern of the insn.  */
  bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
  enum form form;
  rtx reg_res;
  rtx reg0;
  rtx reg1;
  enum inc_state reg1_state;/* The form of the const if reg1 is a const.  */
  HOST_WIDE_INT reg1_val;/* Value if reg1 is const.  */
} inc_insn;


/* Dump the parsed inc insn to FILE.  */

static void
dump_inc_insn (FILE *file)
{
  const char *f = ((inc_insn.form == FORM_PRE_ADD)
	      || (inc_insn.form == FORM_PRE_INC)) ? "pre" : "post";

  dump_insn_slim (file, inc_insn.insn);

  switch (inc_insn.form)
    {
    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),
		 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),
		 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),
		 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),
		 REGNO (inc_insn.reg_res), REGNO (inc_insn.reg1));
      break;

    default:
      break;
    }
}


/* Parsed fields of a mem ref of the form "*(reg0+reg1)" or "*(reg0+c)".  */

static struct mem_insn
{
  rtx_insn *insn;     /* The insn being parsed.  */
  rtx pat;            /* The pattern of the insn.  */
  rtx *mem_loc;       /* The address of the field that holds the mem */
                      /* that is to be replaced.  */
  bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
  rtx reg0;
  rtx reg1;           /* This is either a reg or a const depending on
			 reg1_is_const.  */
  enum inc_state reg1_state;/* The form of the const if reg1 is a const.  */
  HOST_WIDE_INT reg1_val;/* Value if reg1 is const.  */
} mem_insn;


/* Dump the parsed mem insn to FILE.  */

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),
	     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),
	     REGNO (mem_insn.reg0), REGNO (mem_insn.reg1));
}


/* The following three arrays contain pointers to instructions. They
   are indexed by REGNO.  At any point in the basic block where we are
   looking these three arrays contain, respectively, the next insn
   that uses REGNO, the next inc or add insn that uses REGNO and the
   next insn that sets REGNO.

   The arrays are not cleared when we move from block to block so
   whenever an insn is retrieved from these arrays, it's block number
   must be compared with the current block.
*/

static rtx_insn **reg_next_debug_use = NULL;
static rtx_insn **reg_next_use = NULL;
static rtx_insn **reg_next_inc_use = NULL;
static rtx_insn **reg_next_def = NULL;


/* Move dead note that match PATTERN to TO_INSN from FROM_INSN.  We do
   not really care about moving any other notes from the inc or add
   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
move_dead_notes (rtx_insn *to_insn, rtx_insn *from_insn, rtx pattern)
{
  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))
	{
	  XEXP (note, 1) = REG_NOTES (to_insn);
	  REG_NOTES (to_insn) = note;
	  if (prev_note)
	    XEXP (prev_note, 1) = next_note;
	  else
	    REG_NOTES (from_insn) = next_note;
	}
      else prev_note = note;
    }
}

/* 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
   are is this a valid change to the instruction and is this a
   profitable change to the instruction.  */

static bool
attempt_change (rtx new_addr, rtx inc_reg)
{
  /* There are four cases: For the two cases that involve an add
     instruction, we are going to have to delete the add and insert a
     mov.  We are going to assume that the mov is free.  This is
     fairly early in the backend and there are a lot of opportunities
     for removing that move later.  In particular, there is the case
     where the move may be dead, this is what dead code elimination
     passes are for.  The two cases where we have an inc insn will be
     handled mov free.  */

  basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
  rtx_insn *mov_insn = NULL;
  int regno;
  rtx mem = *mem_insn.mem_loc;
  machine_mode mode = GET_MODE (mem);
  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 = (set_src_cost (mem, mode, speed)
	      + set_rtx_cost (PATTERN (inc_insn.insn), speed));

  new_cost = set_src_cost (mem_tmp, mode, speed);

  /* In the FORM_PRE_ADD and FORM_POST_ADD cases we emit an extra move
     whose cost we should account for.  */
  if (inc_insn.form == FORM_PRE_ADD
      || inc_insn.form == FORM_POST_ADD)
    {
      start_sequence ();
      emit_move_insn (inc_insn.reg_res, inc_insn.reg0);
      mov_insn = get_insns ();
      end_sequence ();
      new_cost += seq_cost (mov_insn, speed);
    }

  /* The first item of business is to see if this is profitable.  */
  if (old_cost < new_cost)
    {
      if (dump_file)
	fprintf (dump_file, "cost failure old=%d new=%d\n", old_cost, new_cost);
      return false;
    }

  /* Jump through a lot of hoops to keep the attributes up to date.  We
     do not want to call one of the change address variants that take
     an offset even though we know the offset in many cases.  These
     assume you are changing where the address is pointing by the
     offset.  */
  new_mem = replace_equiv_address_nv (mem, new_addr);
  if (! validate_change (mem_insn.insn, mem_insn.mem_loc, new_mem, 0))
    {
      if (dump_file)
	fprintf (dump_file, "validation failure\n");
      return false;
    }

  /* From here to the end of the function we are committed to the
     change, i.e. nothing fails.  Generate any necessary movs, move
     any regnotes, and fix up the reg_next_{use,inc_use,def}.  */
  switch (inc_insn.form)
    {
    case FORM_PRE_ADD:
      /* 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.  */
      gcc_assert (mov_insn);
      emit_insn_before (mov_insn, inc_insn.insn);
      regno = REGNO (inc_insn.reg0);
      /* ??? Could REGNO possibly be used in MEM_INSN other than in
	 the MEM address, and still die there, so that move_dead_notes
	 would incorrectly move the note?  */
      if (reg_next_use[regno] == mem_insn.insn)
	move_dead_notes (mov_insn, mem_insn.insn, inc_insn.reg0);
      else
	move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);

      regno = REGNO (inc_insn.reg_res);
      if (reg_next_debug_use && reg_next_debug_use[regno]
	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
	{
	  rtx adjres = gen_rtx_PLUS (GET_MODE (inc_insn.reg_res),
				     inc_insn.reg_res, inc_insn.reg1);
	  if (dump_file)
	    fprintf (dump_file, "adjusting debug insns\n");
	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
			       mem_insn.insn,
			       inc_insn.reg_res, adjres, bb);
	  reg_next_debug_use[regno] = NULL;
	}
      reg_next_def[regno] = mov_insn;
      reg_next_use[regno] = NULL;

      regno = REGNO (inc_insn.reg0);
      if (reg_next_debug_use && reg_next_debug_use[regno]
	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb
	  && find_reg_note (mov_insn, REG_DEAD, inc_insn.reg0))
	{
	  if (dump_file)
	    fprintf (dump_file, "remapping debug insns\n");
	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
			       mem_insn.insn,
			       inc_insn.reg0, inc_insn.reg_res, bb);
	  reg_next_debug_use[regno] = NULL;
	}
      reg_next_use[regno] = mov_insn;
      df_recompute_luids (bb);
      break;

    case FORM_POST_INC:
      regno = REGNO (inc_insn.reg_res);
      if (reg_next_debug_use && reg_next_debug_use[regno]
	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
	{
	  rtx adjres = gen_rtx_MINUS (GET_MODE (inc_insn.reg_res),
				      inc_insn.reg_res, inc_insn.reg1);
	  if (dump_file)
	    fprintf (dump_file, "adjusting debug insns\n");
	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
			       inc_insn.insn,
			       inc_insn.reg_res, adjres, bb);
	  reg_next_debug_use[regno] = NULL;
	}
      if (reg_next_use[regno] == reg_next_inc_use[regno])
	reg_next_inc_use[regno] = NULL;

      /* Fallthru.  */
    case FORM_PRE_INC:
      regno = REGNO (inc_insn.reg_res);
      /* Despite the fall-through, we won't run this twice: we'll have
	 already cleared reg_next_debug_use[regno] before falling
	 through.  */
      if (reg_next_debug_use && reg_next_debug_use[regno]
	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
	{
	  rtx adjres = gen_rtx_PLUS (GET_MODE (inc_insn.reg_res),
				     inc_insn.reg_res, inc_insn.reg1);
	  if (dump_file)
	    fprintf (dump_file, "adjusting debug insns\n");
	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
			       mem_insn.insn,
			       inc_insn.reg_res, adjres, bb);
	  if (DF_INSN_LUID (mem_insn.insn)
	      < DF_INSN_LUID (reg_next_debug_use[regno]))
	    reg_next_debug_use[regno] = NULL;
	}
      reg_next_def[regno] = mem_insn.insn;
      reg_next_use[regno] = NULL;

      break;

    case FORM_POST_ADD:
      gcc_assert (mov_insn);
      emit_insn_before (mov_insn, mem_insn.insn);
      move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);

      /* Do not move anything to the mov insn because the instruction
	 pointer for the main iteration has not yet hit that.  It is
	 still pointing to the mem insn. */
      regno = REGNO (inc_insn.reg_res);
      /* The pseudo is now set earlier, so it must have been dead in
	 that range, and dead registers cannot be referenced in debug
	 insns.  */
      gcc_assert (!(reg_next_debug_use && reg_next_debug_use[regno]
		    && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb));
      reg_next_def[regno] = mem_insn.insn;
      reg_next_use[regno] = NULL;

      regno = REGNO (inc_insn.reg0);
      if (reg_next_debug_use && reg_next_debug_use[regno]
	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb
	  && find_reg_note (mov_insn, REG_DEAD, inc_insn.reg0))
	{
	  if (dump_file)
	    fprintf (dump_file, "remapping debug insns\n");
	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
			       inc_insn.insn,
			       inc_insn.reg0, inc_insn.reg_res, bb);
	  reg_next_debug_use[regno] = NULL;
	}
      reg_next_use[regno] = mem_insn.insn;
      if ((reg_next_use[regno] == reg_next_inc_use[regno])
	  || (reg_next_inc_use[regno] == inc_insn.insn))
	reg_next_inc_use[regno] = NULL;
      df_recompute_luids (bb);
      break;

    case FORM_last:
    default:
      gcc_unreachable ();
    }

  if (!inc_insn.reg1_is_const)
    {
      regno = REGNO (inc_insn.reg1);
      reg_next_use[regno] = mem_insn.insn;
      if ((reg_next_use[regno] == reg_next_inc_use[regno])
	  || (reg_next_inc_use[regno] == inc_insn.insn))
	reg_next_inc_use[regno] = NULL;
    }

  delete_insn (inc_insn.insn);

  if (dump_file && mov_insn)
    {
      fprintf (dump_file, "inserting mov ");
      dump_insn_slim (dump_file, mov_insn);
    }

  /* Record that this insn has an implicit side effect.  */
  add_reg_note (mem_insn.insn, REG_INC, inc_reg);

  if (dump_file)
    {
      fprintf (dump_file, "****success ");
      dump_insn_slim (dump_file, mem_insn.insn);
    }

  return true;
}


/* Try to combine the instruction in INC_INSN with the instruction in
   MEM_INSN.  First the form is determined using the DECISION_TABLE
   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.  */

static bool
try_merge (void)
{
  enum gen_form gen_form;
  rtx mem = *mem_insn.mem_loc;
  rtx inc_reg = inc_insn.form == FORM_POST_ADD ?
    inc_insn.reg_res : mem_insn.reg0;

  /* The width of the mem being accessed.  */
  poly_int64 size = GET_MODE_SIZE (GET_MODE (mem));
  rtx_insn *last_insn = NULL;
  machine_mode reg_mode = GET_MODE (inc_reg);

  switch (inc_insn.form)
    {
    case FORM_PRE_ADD:
    case FORM_PRE_INC:
      last_insn = mem_insn.insn;
      break;
    case FORM_POST_INC:
    case FORM_POST_ADD:
      last_insn = inc_insn.insn;
      break;
    case FORM_last:
    default:
      gcc_unreachable ();
    }

  /* Cannot handle auto inc of the stack.  */
  if (inc_reg == stack_pointer_rtx)
    {
      if (dump_file)
	fprintf (dump_file, "cannot inc stack %d failure\n", REGNO (inc_reg));
      return false;
    }

  /* Look to see if the inc register is dead after the memory
     reference.  If it is, do not do the combination.  */
  if (find_regno_note (last_insn, REG_DEAD, REGNO (inc_reg)))
    {
      if (dump_file)
	fprintf (dump_file, "dead failure %d\n", REGNO (inc_reg));
      return false;
    }

  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
    [inc_insn.reg1_state][mem_insn.reg1_state][inc_insn.form];

  if (dbg_cnt (auto_inc_dec) == false)
    return false;

  switch (gen_form)
    {
    default:
    case NOTHING:
      return false;

    case SIMPLE_PRE_INC:     /* ++size  */
      if (dump_file)
	fprintf (dump_file, "trying SIMPLE_PRE_INC\n");
      return attempt_change (gen_rtx_PRE_INC (reg_mode, inc_reg), inc_reg);

    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);

    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);

    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);

    case DISP_PRE:           /* ++con   */
      if (dump_file)
	fprintf (dump_file, "trying DISP_PRE\n");
      return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
						 inc_reg,
						 gen_rtx_PLUS (reg_mode,
							       inc_reg,
							       inc_insn.reg1)),
			     inc_reg);

    case DISP_POST:          /* con++   */
      if (dump_file)
	fprintf (dump_file, "trying POST_DISP\n");
      return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
						  inc_reg,
						  gen_rtx_PLUS (reg_mode,
								inc_reg,
								inc_insn.reg1)),
			     inc_reg);

    case REG_PRE:            /* ++reg   */
      if (dump_file)
	fprintf (dump_file, "trying PRE_REG\n");
      return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
						 inc_reg,
						 gen_rtx_PLUS (reg_mode,
							       inc_reg,
							       inc_insn.reg1)),
			     inc_reg);

    case REG_POST:            /* reg++   */
      if (dump_file)
	fprintf (dump_file, "trying POST_REG\n");
      return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
						  inc_reg,
						  gen_rtx_PLUS (reg_mode,
								inc_reg,
								inc_insn.reg1)),
			     inc_reg);
    }
}

/* Return the next insn that uses (if reg_next_use is passed in
   NEXT_ARRAY) or defines (if reg_next_def is passed in NEXT_ARRAY)
   REGNO in BB.  */

static rtx_insn *
get_next_ref (int regno, basic_block bb, rtx_insn **next_array)
{
  rtx_insn *insn = next_array[regno];

  /* Lazy about cleaning out the next_arrays.  */
  if (insn && BLOCK_FOR_INSN (insn) != bb)
    {
      next_array[regno] = NULL;
      insn = NULL;
    }

  return insn;
}


/* 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.

   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
   index register for some memory reference that is currently being
   processed.  */

static bool
parse_add_or_inc (rtx_insn *insn, bool before_mem)
{
  rtx pat = single_set (insn);
  if (!pat)
    return false;

  /* Result must be single reg.  */
  if (!REG_P (SET_DEST (pat)))
    return false;

  if ((GET_CODE (SET_SRC (pat)) != PLUS)
      && (GET_CODE (SET_SRC (pat)) != MINUS))
    return false;

  if (!REG_P (XEXP (SET_SRC (pat), 0)))
    return false;

  inc_insn.insn = insn;
  inc_insn.pat = pat;
  inc_insn.reg_res = SET_DEST (pat);
  inc_insn.reg0 = XEXP (SET_SRC (pat), 0);

  /* Block any auto increment of the frame pointer since it expands into
     an addition and cannot be removed by copy propagation.  */
  if (inc_insn.reg0 == frame_pointer_rtx)
    return false;

  if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg0))
    inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC;
  else
    inc_insn.form = before_mem ? FORM_PRE_ADD : FORM_POST_ADD;

  if (CONST_INT_P (XEXP (SET_SRC (pat), 1)))
    {
      /* Process a = b + c where c is a const.  */
      inc_insn.reg1_is_const = true;
      if (GET_CODE (SET_SRC (pat)) == PLUS)
	{
	  inc_insn.reg1 = XEXP (SET_SRC (pat), 1);
	  inc_insn.reg1_val = INTVAL (inc_insn.reg1);
	}
      else
	{
	  inc_insn.reg1_val = -INTVAL (XEXP (SET_SRC (pat), 1));
	  inc_insn.reg1 = GEN_INT (inc_insn.reg1_val);
	}
      return true;
    }
  else if ((HAVE_PRE_MODIFY_REG || HAVE_POST_MODIFY_REG)
	   && (REG_P (XEXP (SET_SRC (pat), 1)))
	   && GET_CODE (SET_SRC (pat)) == PLUS)
    {
      /* 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
	  || inc_insn.form == FORM_POST_INC)
	return true;
      else if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg1))
	{
	  /* Reverse the two operands and turn *_ADD into *_INC since
	     a = c + a.  */
	  std::swap (inc_insn.reg0, inc_insn.reg1);
	  inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC;
	  return true;
	}
      else
	return true;
    }

  return false;
}


/* A recursive function that checks all of the mem uses in
   ADDRESS_OF_X to see if any single one of them is compatible with
   what has been found in inc_insn.  To avoid accidental matches, we
   will only find MEMs with FINDREG, be it inc_insn.reg_res, be it
   inc_insn.reg0.

   -1 is returned for success.  0 is returned if nothing was found and
   1 is returned for failure. */

static int
find_address (rtx *address_of_x, rtx findreg)
{
  rtx x = *address_of_x;
  enum rtx_code code = GET_CODE (x);
  const char *const fmt = GET_RTX_FORMAT (code);
  int i;
  int value = 0;
  int tem;

  if (code == MEM && findreg == inc_insn.reg_res
      && rtx_equal_p (XEXP (x, 0), inc_insn.reg_res))
    {
      /* Match with *reg_res.  */
      mem_insn.mem_loc = address_of_x;
      mem_insn.reg0 = inc_insn.reg_res;
      mem_insn.reg1_is_const = true;
      mem_insn.reg1_val = 0;
      mem_insn.reg1 = GEN_INT (0);
      return -1;
    }
  if (code == MEM && inc_insn.reg1_is_const && inc_insn.reg0
      && findreg == inc_insn.reg0
      && rtx_equal_p (XEXP (x, 0), inc_insn.reg0))
    {
      /* Match with *reg0, assumed to be equivalent to
         *(reg_res - reg1_val); callers must check whether this is the case.  */
      mem_insn.mem_loc = address_of_x;
      mem_insn.reg0 = inc_insn.reg_res;
      mem_insn.reg1_is_const = true;
      mem_insn.reg1_val = -inc_insn.reg1_val;
      mem_insn.reg1 = GEN_INT (mem_insn.reg1_val);
      return -1;
    }
  if (code == MEM && findreg == inc_insn.reg_res
      && GET_CODE (XEXP (x, 0)) == PLUS
      && rtx_equal_p (XEXP (XEXP (x, 0), 0), inc_insn.reg_res))
    {
      rtx b = XEXP (XEXP (x, 0), 1);
      mem_insn.mem_loc = 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 (CONST_INT_P (b))
	{
	  /* Match with *(reg0 + reg1) where reg1 is a const. */
	  HOST_WIDE_INT val = INTVAL (b);
	  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))
	/* Match with *(reg0 + reg1). */
	return -1;
    }

  if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
    {
      /* If REG occurs inside a MEM used in a bit-field reference,
	 that is unacceptable.  */
      if (find_address (&XEXP (x, 0), findreg))
	return 1;
    }

  if (x == inc_insn.reg_res)
    return 1;

  /* Time for some deep diving.  */
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  tem = find_address (&XEXP (x, i), findreg);
	  /* If this is the first use, let it go so the rest of the
	     insn can be checked.  */
	  if (value == 0)
	    value = tem;
	  else if (tem != 0)
	    /* More than one match was found.  */
	    return 1;
	}
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      tem = find_address (&XVECEXP (x, i, j), findreg);
	      /* If this is the first use, let it go so the rest of
		 the insn can be checked.  */
	      if (value == 0)
		value = tem;
	      else if (tem != 0)
		/* More than one match was found.  */
		return 1;
	    }
	}
    }
  return value;
}

/* Once a suitable mem reference has been found and the MEM_INSN
   structure has been filled in, FIND_INC is called to see if there is
   a suitable add or inc insn that follows the mem reference and
   determine if it is suitable to merge.

   In the case where the MEM_INSN has two registers in the reference,
   this function may be called recursively.  The first time looking
   for an add of the first register, and if that fails, looking for an
   add of the second register.  The FIRST_TRY parameter is used to
   only allow the parameters to be reversed once.  */

static bool
find_inc (bool first_try)
{
  rtx_insn *insn;
  basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
  rtx_insn *other_insn;
  df_ref def;

  /* Make sure this reg appears only once in this insn.  */
  if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1)
    {
      if (dump_file)
	fprintf (dump_file, "mem count failure\n");
      return false;
    }

  if (dump_file)
    dump_mem_insn (dump_file);

  /* Find the next use that is an inc.  */
  insn = get_next_ref (REGNO (mem_insn.reg0),
		       BLOCK_FOR_INSN (mem_insn.insn),
		       reg_next_inc_use);
  if (!insn)
    return false;

  /* Even though we know the next use is an add or inc because it came
     from the reg_next_inc_use, we must still reparse.  */
  if (!parse_add_or_inc (insn, false))
    {
      /* 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)
	{
	  std::swap (mem_insn.reg0, mem_insn.reg1);
	  return find_inc (false);
	}
      else
	return false;
    }

  /* Need to assure that none of the operands of the inc instruction are
     assigned to by the mem insn.  */
  FOR_EACH_INSN_DEF (def, mem_insn.insn)
    {
      unsigned int regno = DF_REF_REGNO (def);
      if ((regno == REGNO (inc_insn.reg0))
	  || (regno == REGNO (inc_insn.reg_res)))
	{
	  if (dump_file)
	    fprintf (dump_file, "inc conflicts with store failure.\n");
	  return false;
	}
      if (!inc_insn.reg1_is_const && (regno == REGNO (inc_insn.reg1)))
	{
	  if (dump_file)
	    fprintf (dump_file, "inc conflicts with store failure.\n");
	  return false;
	}
    }

  if (dump_file)
    dump_inc_insn (dump_file);

  if (inc_insn.form == FORM_POST_ADD)
    {
      /* Make sure that there is no insn that assigns to inc_insn.res
	 between the mem_insn and the inc_insn.  */
      rtx_insn *other_insn = get_next_ref (REGNO (inc_insn.reg_res),
					   BLOCK_FOR_INSN (mem_insn.insn),
					   reg_next_def);
      if (other_insn != inc_insn.insn)
	{
	  if (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),
				 BLOCK_FOR_INSN (mem_insn.insn),
				 reg_next_use);
      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,
		     "result of add is used between mem and inc insns.\n");
	  return false;
	}

      /* For the post_add to work, the result_reg of the inc must not be
	 used in the mem insn since this will become the new index
	 register.  */
      if (reg_overlap_mentioned_p (inc_insn.reg_res, PATTERN (mem_insn.insn)))
	{
	  if (dump_file)
	    fprintf (dump_file, "base reg replacement failure.\n");
	  return false;
	}
    }

  if (mem_insn.reg1_is_const)
    {
      if (mem_insn.reg1_val == 0)
	{
	  if (!inc_insn.reg1_is_const)
	    {
	      /* The mem looks like *r0 and the rhs of the add has two
		 registers.  */
	      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,
		     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.  */
		  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");
		      return false;
		    }

		  /* We also need to make sure that the next use of
		     inc result is after the inc.  */
		  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))
		    std::swap (inc_insn.reg0, inc_insn.reg1);
		}

	      other_insn
		= get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
	      if (other_insn && luid > DF_INSN_LUID (other_insn))
		return false;
	    }
	}
      /* Both the inc/add and the mem have a constant.  Need to check
	 that the constants are ok. */
      else if ((mem_insn.reg1_val != inc_insn.reg1_val)
	       && (mem_insn.reg1_val != -inc_insn.reg1_val))
	return false;
    }
  else
    {
      /* The mem insn is of the form *(a + b) where a and b are both
	 regs.  It may be that in order to match the add or inc we
	 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_insn *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
	     must be a valid addressing reg.  */
	  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");
	      return false;
	    }

	  if (rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
	    {
	      if (!rtx_equal_p (mem_insn.reg1, inc_insn.reg1))
		{
		  /* See comment above on find_inc (false) call.  */
		  if (first_try)
		    {
		      std::swap (mem_insn.reg0, mem_insn.reg1);
		      return find_inc (false);
		    }
		  else
		    return false;
		}

	      /* Need to check that there are no assignments to b
		 before the add 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;
	      /* All ok for the next step.  */
	    }
	  else
	    {
	      /* We know that mem_insn.reg0 must equal inc_insn.reg1
		 or else we would not have found the inc insn.  */
	      std::swap (mem_insn.reg0, mem_insn.reg1);
	      if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
		{
		  /* See comment above on find_inc (false) call.  */
		  if (first_try)
		    return find_inc (false);
		  else
		    return false;
		}
	      /* 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
		= get_next_ref (REGNO (inc_insn.reg0), bb, reg_next_def);
	      if (other_insn && luid > DF_INSN_LUID (other_insn))
		return false;
	    }

	  /* 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
	    = 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.  */
	{
	  if (!rtx_equal_p (mem_insn.reg1, inc_insn.reg1))
	    /* See comment above on find_inc (false) call.  */
	    {
	      if (first_try)
		{
		  std::swap (mem_insn.reg0, mem_insn.reg1);
		  return find_inc (false);
		}
	      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
	    = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
	  if (other_insn && luid > DF_INSN_LUID (other_insn))
	    return false;
	}
    }

  if (inc_insn.form == FORM_POST_INC)
    {
      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
	 reg.  Because we are going to increment the reg
	 in this form, we need to make sure that there
	 were no intervening uses of reg.  */
      if (inc_insn.insn != other_insn)
	return false;
    }

  return try_merge ();
}


/* A recursive function that walks ADDRESS_OF_X to find all of the mem
   uses in pat that could be used as an auto inc or dec.  It then
   calls FIND_INC for each one.  */

static bool
find_mem (rtx *address_of_x)
{
  rtx x = *address_of_x;
  enum rtx_code code = GET_CODE (x);
  const char *const fmt = GET_RTX_FORMAT (code);
  int i;

  if (code == MEM && REG_P (XEXP (x, 0)))
    {
      /* Match with *reg0.  */
      mem_insn.mem_loc = address_of_x;
      mem_insn.reg0 = XEXP (x, 0);
      mem_insn.reg1_is_const = true;
      mem_insn.reg1_val = 0;
      mem_insn.reg1 = GEN_INT (0);
      if (find_inc (true))
	return true;
    }
  if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
      && REG_P (XEXP (XEXP (x, 0), 0)))
    {
      rtx reg1 = XEXP (XEXP (x, 0), 1);
      mem_insn.mem_loc = address_of_x;
      mem_insn.reg0 = XEXP (XEXP (x, 0), 0);
      mem_insn.reg1 = reg1;
      if (CONST_INT_P (reg1))
	{
	  mem_insn.reg1_is_const = true;
	  /* Match with *(reg0 + c) where c is a const. */
	  mem_insn.reg1_val = INTVAL (reg1);
	  if (find_inc (true))
	    return true;
	}
      else if (REG_P (reg1))
	{
	  /* Match with *(reg0 + reg1).  */
	  mem_insn.reg1_is_const = false;
	  if (find_inc (true))
	    return true;
	}
    }

  if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
    {
      /* If REG occurs inside a MEM used in a bit-field reference,
	 that is unacceptable.  */
      return false;
    }

  /* Time for some deep diving.  */
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  if (find_mem (&XEXP (x, i)))
	    return true;
	}
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    if (find_mem (&XVECEXP (x, i, j)))
	      return true;
	}
    }
  return false;
}


/* Try to combine all incs and decs by constant values with memory
   references in BB.  */

static void
merge_in_block (int max_reg, basic_block bb)
{
  rtx_insn *insn;
  rtx_insn *curr;
  int success_in_block = 0;

  if (dump_file)
    fprintf (dump_file, "\n\nstarting bb %d\n", bb->index);

  FOR_BB_INSNS_REVERSE_SAFE (bb, insn, curr)
    {
      bool insn_is_add_or_inc = true;

      if (!NONDEBUG_INSN_P (insn))
	{
	  if (DEBUG_BIND_INSN_P (insn))
	    {
	      df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
	      df_ref use;

	      if (dump_file)
		dump_insn_slim (dump_file, insn);

	      FOR_EACH_INSN_INFO_USE (use, insn_info)
		reg_next_debug_use[DF_REF_REGNO (use)] = insn;
	    }
	  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
	 combine a preincrement with a jump.  */
      if (JUMP_P (insn))
	continue;

      if (dump_file)
	dump_insn_slim (dump_file, insn);

      /* Does this instruction increment or decrement a register?  */
      if (parse_add_or_inc (insn, true))
	{
	  int regno = REGNO (inc_insn.reg_res);
	  /* Cannot handle case where there are three separate regs
	     before a mem ref.  Too many moves would be needed to be
	     profitable.  */
	  if ((inc_insn.form == FORM_PRE_INC) || inc_insn.reg1_is_const)
	    {
	      mem_insn.insn = get_next_ref (regno, bb, reg_next_use);
	      if (mem_insn.insn)
		{
		  bool ok = true;
		  if (!inc_insn.reg1_is_const)
		    {
		      /* We are only here if we are going to try a
			 HAVE_*_MODIFY_REG type transformation.  c is a
			 reg and we must sure that the path from the
			 inc_insn to the mem_insn.insn is both def and use
			 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_insn *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
			= 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),
					  inc_insn.reg_res) == -1)
		    {
		      if (dump_file)
			dump_mem_insn (dump_file);
		      if (try_merge ())
			{
			  success_in_block++;
			  insn_is_add_or_inc = false;
			}
		    }
		}

	      if (insn_is_add_or_inc
		  /* find_address will only recognize an address
		     with a reg0 that's not reg_res when
		     reg1_is_const, so cut it off early if we
		     already know it won't match.  */
		  && inc_insn.reg1_is_const
		  && inc_insn.reg0
		  && inc_insn.reg0 != inc_insn.reg_res)
		{
		  /* If we identified an inc_insn that uses two
		     different pseudos, it's of the form

		     (set reg_res (plus reg0 reg1))

		     where reg1 is a constant (*).

		     The next use of reg_res was not identified by
		     find_address as a mem_insn that we could turn
		     into auto-inc, so see if we find a suitable
		     MEM in the next use of reg0, as long as it's
		     before any subsequent use of reg_res:

		     ... (mem (... reg0 ...)) ...

		     ... reg_res ...

		     In this case, we can turn the plus into a
		     copy, and the reg0 in the MEM address into a
		     post_inc of reg_res:

		     (set reg_res reg0)

		     ... (mem (... (post_add reg_res reg1) ...)) ...

		     reg_res will then have the correct value at
		     subsequent uses, and reg0 will remain
		     unchanged.

		     (*) We could support non-const reg1, but then
		     we'd have to check that reg1 remains
		     unchanged all the way to the modified MEM,
		     and we'd have to extend find_address to
		     represent a non-const negated reg1.  */
		  regno = REGNO (inc_insn.reg0);
		  rtx_insn *reg0_use = get_next_ref (regno, bb,
						     reg_next_use);

		  /* Give up if the next use of reg0 is after the next
		     use of reg_res (same insn is ok; we might have
		     found a MEM with reg_res before, and that failed,
		     but now we try reg0, which might work), or defs
		     of reg_res (same insn is not ok, we'd introduce
		     another def in the same insn) or reg0.  */
		  if (reg0_use)
		    {
		      int luid = DF_INSN_LUID (reg0_use);

		      /* It might seem pointless to introduce an
			 auto-inc if there's no subsequent use of
			 reg_res (i.e., mem_insn.insn == NULL), but
			 the next use might be in the next iteration
			 of a loop, and it won't hurt if we make the
			 change even if it's not needed.  */
		      if (mem_insn.insn
			  && luid > DF_INSN_LUID (mem_insn.insn))
			reg0_use = NULL;

		      rtx_insn *other_insn
			= get_next_ref (REGNO (inc_insn.reg_res), bb,
					reg_next_def);

		      if (other_insn && luid >= DF_INSN_LUID (other_insn))
			reg0_use = NULL;

		      other_insn
			= get_next_ref (REGNO (inc_insn.reg0), bb,
					reg_next_def);

		      if (other_insn && luid > DF_INSN_LUID (other_insn))
			reg0_use = NULL;
		    }

		  mem_insn.insn = reg0_use;

		  if (mem_insn.insn
		      && find_address (&PATTERN (mem_insn.insn),
				       inc_insn.reg0) == -1)
		    {
		      if (dump_file)
			dump_mem_insn (dump_file);
		      if (try_merge ())
			{
			  success_in_block++;
			  insn_is_add_or_inc = false;
			}
		    }
		}
	    }
	}
      else
	{
	  insn_is_add_or_inc = false;
	  mem_insn.insn = insn;
	  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_info *insn_info = DF_INSN_INFO_GET (insn))
	{
	  df_ref def, use;

	  /* Need to update next use.  */
	  FOR_EACH_INSN_INFO_DEF (def, insn_info)
	    {
	      if (reg_next_debug_use)
		reg_next_debug_use[DF_REF_REGNO (def)] = NULL;
	      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_EACH_INSN_INFO_USE (use, insn_info)
	    {
	      if (reg_next_debug_use)
		/* This may seem surprising, but we know we may only
		   modify the value of a REG between an insn and the
		   next nondebug use thereof.  Any debug uses after
		   the next nondebug use can be left alone, the REG
		   will hold the expected value there.  */
		reg_next_debug_use[DF_REF_REGNO (use)] = NULL;
	      reg_next_use[DF_REF_REGNO (use)] = insn;
	      if (insn_is_add_or_inc)
		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",
		 INSN_UID (insn));
    }

  /* If we were successful, try again.  There may have been several
     opportunities that were interleaved.  This is rare but
     gcc.c-torture/compile/pr17273.c actually exhibits this.  */
  if (success_in_block)
    {
      /* In this case, we must clear these vectors since the trick of
	 testing if the stale insn in the block will not work.  */
      if (reg_next_debug_use)
	memset (reg_next_debug_use, 0, max_reg * sizeof (rtx));
      memset (reg_next_use, 0, max_reg * sizeof (rtx));
      memset (reg_next_inc_use, 0, max_reg * sizeof (rtx));
      memset (reg_next_def, 0, max_reg * sizeof (rtx));
      df_recompute_luids (bb);
      merge_in_block (max_reg, bb);
    }
}

/* Discover auto-inc auto-dec instructions.  */

namespace {

const pass_data pass_data_inc_dec =
{
  RTL_PASS, /* type */
  "auto_inc_dec", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_AUTO_INC_DEC, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_inc_dec : public rtl_opt_pass
{
public:
  pass_inc_dec (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_inc_dec, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      if (!AUTO_INC_DEC)
	return false;

      return (optimize > 0 && flag_auto_inc_dec);
    }


  unsigned int execute (function *);

}; // class pass_inc_dec

unsigned int
pass_inc_dec::execute (function *fun ATTRIBUTE_UNUSED)
{
  if (!AUTO_INC_DEC)
    return 0;

  basic_block bb;
  int max_reg = max_reg_num ();

  if (!initialized)
    init_decision_table ();

  mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX);

  df_note_add_problem ();
  df_analyze ();

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    reg_next_debug_use = XCNEWVEC (rtx_insn *, max_reg);
  else
    /* An earlier function may have had debug binds.  */
    reg_next_debug_use = NULL;
  reg_next_use = XCNEWVEC (rtx_insn *, max_reg);
  reg_next_inc_use = XCNEWVEC (rtx_insn *, max_reg);
  reg_next_def = XCNEWVEC (rtx_insn *, max_reg);
  FOR_EACH_BB_FN (bb, fun)
    merge_in_block (max_reg, bb);

  free (reg_next_debug_use);
  free (reg_next_use);
  free (reg_next_inc_use);
  free (reg_next_def);

  mem_tmp = NULL;

  return 0;
}

} // anon namespace

rtl_opt_pass *
make_pass_inc_dec (gcc::context *ctxt)
{
  return new pass_inc_dec (ctxt);
}
