/* Discovery of auto-inc and auto-dec instructions.
   Copyright (C) 2006-2021 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);
  int align = MEM_ALIGN (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;
  set_mem_align (mem_tmp, align);

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

      /* Reload should handle auto-inc within a jump correctly, while LRA
	 is known to have issues with autoinc.  */
      if (JUMP_P (insn) && targetm.lra_p ())
	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;
	  /* We can't use auto inc/dec for bare USEs and CLOBBERs,
	     since they aren't supposed to generate any code.  */
	  rtx_code code = GET_CODE (PATTERN (insn));
	  if (code != USE && code != CLOBBER)
	    {
	      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);
}
